Skip to content

Commit 4fea1f9

Browse files
misc stuff for v0.15 release (#2534)
Co-authored-by: Michael Abbott <32575566+mcabbott@users.noreply.github.com>
1 parent bde153e commit 4fea1f9

39 files changed

+238
-246
lines changed

.buildkite/pipeline.yml

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
steps:
2-
- label: "CUDA GPU with julia v1"
2+
- label: "CUDA - Julia 1"
33
plugins:
44
- JuliaCI/julia#v1:
55
version: "1"
@@ -17,17 +17,7 @@ steps:
1717
FLUX_TEST_ENZYME: "false"
1818
timeout_in_minutes: 60
1919

20-
# - label: "GPU nightly"
21-
# plugins:
22-
# - JuliaCI/julia#v1:
23-
# version: "nightly"
24-
# - JuliaCI/julia-test#v1: ~
25-
# agents:
26-
# queue: "juliagpu"
27-
# cuda: "*"
28-
# timeout_in_minutes: 60
29-
30-
- label: "Metal with julia v1"
20+
- label: "Metal - Julia 1"
3121
plugins:
3222
- JuliaCI/julia#v1:
3323
version: "1"
@@ -41,32 +31,18 @@ steps:
4131
queue: "juliaecosystem"
4232
os: "macos"
4333
arch: "aarch64"
44-
commands: |
45-
julia --project -e '
46-
# make sure the 1.8-era Manifest works on this Julia version
47-
using Pkg
48-
Pkg.resolve()'
49-
commands: |
50-
printf "[Flux]\ngpu_backend = \"Metal\"\n" > LocalPreferences.toml
51-
5234
if: build.message !~ /\[skip tests\]/
5335
timeout_in_minutes: 60
5436
env:
5537
FLUX_TEST_METAL: "true"
5638
FLUX_TEST_CPU: "false"
5739
FLUX_TEST_ENZYME: "false"
58-
matrix:
59-
setup:
60-
julia:
61-
# - "1.9"
62-
- "1"
63-
# - "nightly"
6440

65-
- label: "AMD GPU with Julia 1"
41+
- label: "AMDGPU - Julia 1"
6642
plugins:
6743
- JuliaCI/julia#v1:
6844
version: "1"
69-
- JuliaCI/julia-test#v1:
45+
- JuliaCI/julia-test#v1: ~
7046
- JuliaCI/julia-coverage#v1:
7147
dirs:
7248
- src
@@ -75,8 +51,6 @@ steps:
7551
queue: "juliagpu"
7652
rocm: "*"
7753
rocmgpu: "*"
78-
commands: |
79-
printf "[Flux]\ngpu_backend = \"AMDGPU\"\n" > LocalPreferences.toml
8054
timeout_in_minutes: 60
8155
env:
8256
JULIA_AMDGPU_CORE_MUST_LOAD: "1"
@@ -86,5 +60,6 @@ steps:
8660
FLUX_TEST_CPU: "false"
8761
FLUX_TEST_ENZYME: "false"
8862
JULIA_NUM_THREADS: 4
63+
8964
env:
9065
SECRET_CODECOV_TOKEN: "fAV/xwuaV0l5oaIYSAXRQIor8h7yHdlrpLUZFwNVnchn7rDk9UZoz0oORG9vlKLc1GK2HhaPRAy+fTkJ3GM/8Y0phHh3ANK8f5UsGm2DUTNsnf6u9izgnwnoRTcsWu+vSO0fyYrxBvBCoJwljL+yZbDFz3oE16DP7HPIzxfQagm+o/kMEszVuoUXhuLXXH0LxT6pXl214qjqs04HfMRmKIIiup48NB6fBLdhGlQz64MdMNHBfgDa/fafB7eNvn0X6pEOxysoy6bDQLUhKelOXgcDx1UsTo34Yiqr+QeJPAeKcO//PWurwQhPoUoHfLad2da9DN4uQk4YQLqAlcIuAA==;U2FsdGVkX1+mRXF2c9soCXT7DYymY3msM+vrpaifiTp8xA+gMpbQ0G63WY3tJ+6V/fJcVnxYoKZVXbjcg8fl4Q=="

.github/workflows/ci.yml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,9 @@ jobs:
5252
${{ runner.os }}-test-
5353
${{ runner.os }}-
5454
- uses: julia-actions/julia-buildpkg@v1
55-
- name: "Run test without coverage report"
56-
uses: julia-actions/julia-runtest@v1
57-
if: matrix.version != '1' || matrix.os != 'ubuntu-latest'
58-
with:
59-
coverage: false
60-
- name: "Run test with coverage report"
61-
uses: julia-actions/julia-runtest@v1
62-
if: matrix.version == '1' && matrix.os == 'ubuntu-latest'
55+
- uses: julia-actions/julia-runtest@v1
6356
- uses: julia-actions/julia-processcoverage@v1
64-
if: matrix.version == '1' && matrix.os == 'ubuntu-latest'
6557
- uses: codecov/codecov-action@v5
66-
if: matrix.version == '1' && matrix.os == 'ubuntu-latest'
6758
with:
6859
files: lcov.info
6960

.github/workflows/pr_comment.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
steps:
99
- name: Create PR comment
1010
if: github.event_name == 'pull_request' && github.repository == github.event.pull_request.head.repo.full_name && github.event.label.name == 'documentation' # if this is a pull request build AND the pull request is NOT made from a fork
11-
uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6
11+
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b
1212
with:
1313
message: 'Once the build has completed, you can preview any updated documentation at this URL: https://fluxml.ai/Flux.jl/previews/PR${{ github.event.number }}/ in ~20 minutes'
14-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14+
github-token: ${{ secrets.GITHUB_TOKEN }}

NEWS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ See also [github's page](https://github.com/FluxML/Flux.jl/releases) for a compl
1313
The module is still available for now, but will be removed in a future release.
1414
* Most Flux layers will [re-use memory via `NNlib.bias_act!`](https://github.com/FluxML/Flux.jl/pull/2327), when possible.
1515
* Further support for Enzyme.jl, via methods of `Flux.gradient(loss, Duplicated(model))`.
16-
Flux now owns & exports `gradient`, but without `Duplicated` this still defaults to calling Zygote.jl.
16+
Flux now owns & exports `gradient` and `withgradient`, but without `Duplicated` this still defaults to calling Zygote.jl.
1717
* `Flux.params` has been deprecated. Use Zygote's explicit differentiation instead,
1818
`gradient(m -> loss(m, x, y), model)`, or use `Flux.trainables(model)` to get the trainable parameters.
19-
* Flux now requires Functors.jl v0.5. This new release of Functors assumes all types to be functors by default. Therefore, applying `@layer` or `@functor` to a type is no longer strictly necessary for Flux's models. However, it is still recommended to use `@layer Model` for additional functionality like pretty printing.
19+
* Flux now requires Functors.jl v0.5. This new release of Functors assumes all types to be functors by default. Therefore, applying `Flux.@layer` or `Functors.@functor` to a type is no longer strictly necessary for Flux's models. However, it is still recommended to use `@layer Model` for additional functionality like pretty printing.
20+
* `@layer Model`now behaves the same as `@layer :expand Model`, which means that the model is expanded into its sublayers (if there are any) when printed. To force compact printing, use `@layer :noexpand Model`.
2021

2122
## v0.14.22
2223
* Data movement between devices is now provided by [MLDataDevices.jl](https://github.com/LuxDL/MLDataDevices.jl).

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "Flux"
22
uuid = "587475ba-b771-5e3f-ad9e-33799f191a9c"
3-
version = "0.15.0-DEV"
3+
version = "0.15.0"
44

55
[deps]
66
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"

docs/make.jl

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,25 @@ using Documenter, Flux, NNlib, Functors, MLUtils, BSON, Optimisers,
22
OneHotArrays, Zygote, ChainRulesCore, Plots, MLDatasets, Statistics,
33
DataFrames, JLD2, MLDataDevices
44

5+
56
DocMeta.setdocmeta!(Flux, :DocTestSetup, :(using Flux); recursive = true)
67

78
makedocs(
9+
## This should be
10+
## modules = [Flux], checkdocs = :all,
11+
## but we get errors.
812
modules = [Flux, NNlib, Functors, MLUtils, Zygote, OneHotArrays, Optimisers, ChainRulesCore, MLDataDevices],
913
sitename = "Flux",
14+
doctest = false, # done later
15+
checkdocs = :none, # :all, :exports, :none
16+
# checkdocs_ignored_modules = [NNlib, Functors, MLUtils, Zygote, OneHotArrays, Optimisers, ChainRulesCore, MLDataDevices],
17+
warnonly = [:cross_references],
18+
format = Documenter.HTML(
19+
sidebar_sitename = false,
20+
analytics = "UA-36890222-9",
21+
assets = ["assets/flux.css"],
22+
prettyurls = get(ENV, "CI", nothing) == "true"
23+
),
1024
pages = [
1125
"Welcome" => "index.md",
1226
"Guide" => [
@@ -58,17 +72,7 @@ makedocs(
5872
"Deep Convolutional GAN" => "tutorials/2021-10-08-dcgan-mnist.md",
5973
=#
6074
],
61-
],
62-
format = Documenter.HTML(
63-
sidebar_sitename = false,
64-
analytics = "UA-36890222-9",
65-
assets = ["assets/flux.css"],
66-
prettyurls = get(ENV, "CI", nothing) == "true"
67-
),
68-
doctest = false, # done later
69-
checkdocs = :none, # :exports # Do not check if all functions appear in the docs
70-
# since it considers all packages
71-
warnonly = [:cross_references]
75+
]
7276
)
7377

7478
doctest(Flux) # only test Flux modules

docs/src/guide/gpu.md

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
Most work on neural networks involves the use of GPUs, as they can typically perform the required computation much faster.
44
This page describes how Flux co-operates with various other packages, which talk to GPU hardware.
55

6-
## Basic GPU use: from `Array` to `CuArray` with `cu`
6+
For those in a hurry, see the [quickstart](@ref man-quickstart) page. Or do `using CUDA` and then call `gpu` on both the model and the data.
7+
8+
## Basic GPU use: from `Array` to `CuArray`
79

810
Julia's GPU packages work with special array types, in place of the built-in `Array`.
911
The most used is `CuArray` provided by [CUDA.jl](https://github.com/JuliaGPU/CUDA.jl), for GPUs made by NVIDIA.
@@ -119,7 +121,7 @@ model = Chain(...) |> device
119121
The reason they work on Flux models is that `Flux.@layer Layer` defines methods of `Adapt.adapt_structure(to, lay::Layer)`.
120122

121123

122-
## Automatic GPU choice with `gpu`
124+
## Automatic GPU choice with `gpu` and `gpu_device`
123125

124126
Flux also provides a more automatic way of choosing which GPU (or none) to use. This is the function `gpu`:
125127
* By default it does nothing.
@@ -131,19 +133,28 @@ Flux also provides a more automatic way of choosing which GPU (or none) to use.
131133
For the most part, this means that a script which says `model |> gpu` and `data |> gpu` will just work.
132134
It should always run, and if a GPU package is loaded (and finds the correct hardware) then that will be used.
133135

134-
The function `gpu` uses a lower-level function called `get_device()` from [MLDataDevices.jl](https://github.com/LuxDL/MLDataDevices.jl),
135-
which checks what to do & then returns some device object. In fact, the entire implementation is just this:
136+
The function `gpu` uses a lower-level function called [`gpu_device`](@ref) from MLDataDevices.jl,
137+
which checks what to do and then returns some device object. In fact, the entire implementation is just this:
136138

137139
```julia
138140
gpu(x) = gpu_device()(x)
139141
cpu(x) = cpu_device()(x)
140142
```
141143

144+
Automatic backend selection through `gpu` is not type-stable. That doesn't matter if you do it once, or once per large batch -- it costs a few microseconds. But it might matter if you do it within some loop.
142145

143-
## Manually selecting devices
146+
To avoid this, you can first obtain a "device object" with `device = gpu_device()`, once, and then use this as the function to transfer data. Something like this:
147+
```julia
148+
to_device = gpu_device()
149+
gpu_model = model |> to_device
144150

145-
I thought there was a whole `Flux.gpu_backend!` and Preferences.jl story we had to tell??
151+
for epoch in 1:num_epochs
152+
for (x, y) in dataloader
153+
x_gpu, y_gpu = (x, y) |> to_device
154+
# training code...
155+
```
146156

157+
Finally, setting a backend prefence with [`gpu_backend!`](@ref) gives type stability to the whole pipeline.
147158

148159
## Transferring Training Data
149160

@@ -408,7 +419,7 @@ julia> set_preferences!("Flux", "FluxDistributedMPICUDAAware" => true)
408419

409420
By default, Flux will run the checks on your system to see if it can support GPU functionality. You can check if Flux identified a valid GPU setup by typing the following:
410421

411-
```julia
422+
```julia-repl
412423
julia> using CUDA
413424
414425
julia> CUDA.functional()
@@ -417,7 +428,7 @@ true
417428

418429
For AMD GPU:
419430

420-
```julia
431+
```julia-repl
421432
julia> using AMDGPU
422433
423434
julia> AMDGPU.functional()
@@ -429,7 +440,7 @@ true
429440

430441
For Metal GPU:
431442

432-
```julia
443+
```julia-repl
433444
julia> using Metal
434445
435446
julia> Metal.functional()

docs/src/guide/models/basics.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ julia> df(x) = gradient(f, x)[1]; # df/dx = 6x + 2
1313
1414
julia> df(2)
1515
14.0
16-
17-
julia> d2f(x) = gradient(df, x)[1]; # d²f/dx² = 6
18-
19-
julia> d2f(2)
20-
6.0
2116
```
2217

2318
When a function has many parameters, we can get gradients of each one at the same time:

docs/src/guide/models/custom_layers.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ Join(combine, paths...) = Join(combine, paths)
109109
```
110110
Notice again that we parameterized the type of the `combine` and `paths` fields. In addition to the performance considerations of concrete types, this allows either field to be `Vector`s, `Tuple`s, or one of each - we don't need to pay attention to which.
111111

112-
The next step is to use [`Flux.@layer`](@ref) to make our struct behave like a Flux layer. This is important so that calling `Flux.setup` on a `Join` maps over the underlying trainable arrays on each path.
112+
The next step is to use [`Flux.@layer`](@ref) to make our struct behave like a Flux layer.
113+
In Flux < v0.15 this used to be important so that calling `Flux.setup` on a `Join` maps over the underlying trainable arrays on each path. Since Flux v0.15, this is no longer necessary, since now Functors.jl automatically traverses custom types. However, [`Flux.@layer`](@ref) is still recommended for pretty printing and other niceties.
114+
113115
```julia
114116
Flux.@layer Join
115117
```

docs/src/guide/models/quickstart.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ plot(p_true, p_raw, p_done, layout=(1,3), size=(1000,330))
6767
```
6868

6969
```@raw html
70-
<img align="right" width="300px" src="../../assets/quickstart/loss.png">
70+
<img align="right" width="300px" src="../../../assets/quickstart/loss.png">
7171
```
7272

7373
Here's the loss during training:

0 commit comments

Comments
 (0)