Skip to content

Commit 34ed26e

Browse files
torfjeldezuhengxucpfiffersunxd3github-actions[bot]
authored
Initial work on CUDA-compat (#25)
* added CUDA extension * fixed merge issue * rm extra weakdeps * edit toml * @require cuda ext * minor update tests * try to fix ambiguity * rm tmp test file * wip on randdevice interface * move cuda part in ext * rename sampler.jl to sample.jl * update objectives/elbo.jl to use rand_device * update test/cuda.jl * rm exmaple/test.jl * fix CI test error * fix CI error * update flux compat for test/ * rm tmp test file * fix cuda err diffresults.gradient_result * Documentation (#27) * add NF intro * set up doc files * add gitignore * minor update to readme * update home page * update docs for each funciton * update docs * src * update function docs * update docs * fix readme math rendering issue * update docs * update example doc * update customize layer docs * finish docs * finish docs * Update README.md Co-authored-by: Cameron Pfiffer <[email protected]> * Update README.md Co-authored-by: Cameron Pfiffer <[email protected]> * Update README.md Co-authored-by: Cameron Pfiffer <[email protected]> * Update docs/src/index.md Co-authored-by: Xianda Sun <[email protected]> * Update README.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/index.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/customized_layer.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/customized_layer.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/customized_layer.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/customized_layer.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/customized_layer.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/index.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/index.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/index.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/example.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/example.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/example.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/example.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/example.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/example.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/example.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/customized_layer.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/customized_layer.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/customized_layer.md Co-authored-by: Xianda Sun <[email protected]> * Update docs/src/customized_layer.md Co-authored-by: Xianda Sun <[email protected]> * minor ed * minor ed to fix latex issue * minor update --------- Co-authored-by: Cameron Pfiffer <[email protected]> Co-authored-by: Xianda Sun <[email protected]> * add more synthetic targets (#20) * add Neal's Funnel and Warped Gaussian * fixed bug in warped gaussian * add reference for warped Gauss * add Cross dsitribution * udpate docs for cross * Update example/targets/cross.jl change comment into docs Co-authored-by: Tor Erlend Fjelde <[email protected]> * Update example/targets/cross.jl Co-authored-by: Tor Erlend Fjelde <[email protected]> * update cross docs * minor ed * Update example/targets/neal_funnel.jl Co-authored-by: Tor Erlend Fjelde <[email protected]> * Update example/targets/neal_funnel.jl Co-authored-by: Tor Erlend Fjelde <[email protected]> * doc banana using * fixing docs with latex * baanan docs with latex * add NF quick intro * Revert "add NF quick intro" This reverts commit e399274. * rm unnecesary code for cross * rm example/manifest * Update example/targets/neal_funnel.jl Co-authored-by: Tor Erlend Fjelde <[email protected]> * Update example/targets/cross.jl Co-authored-by: Tor Erlend Fjelde <[email protected]> * Update example/targets/cross.jl Co-authored-by: Tor Erlend Fjelde <[email protected]> * minor update to cross docs --------- Co-authored-by: Tor Erlend Fjelde <[email protected]> * Fix math display errors in readme (#28) * fix readme math err * minor update readme * add PR links to TODO * CompatHelper: bump compat for Optimisers to 0.3, (keep existing compat) (#29) * CompatHelper: bump compat for Optimisers to 0.3, (keep existing compat) * bump version to 0.1.1 --------- Co-authored-by: CompatHelper Julia <[email protected]> Co-authored-by: Zuheng <[email protected]> * CompatHelper: bump compat for ADTypes to 0.2, (keep existing compat) (#31) Co-authored-by: CompatHelper Julia <[email protected]> * CompatHelper: bump compat for ADTypes to 1, (keep existing compat) (#32) Co-authored-by: CompatHelper Julia <[email protected]> Co-authored-by: Hong Ge <[email protected]> * CompatHelper: bump compat for Enzyme in [weakdeps] to 0.12, (keep existing compat) (#34) Co-authored-by: CompatHelper Julia <[email protected]> * fix doc build failure (#35) * minor doc dep update * rm unnecessary dep * add distributions random linearalgebra to docs env * Create DocNav.yml * CompatHelper: bump compat for Bijectors to 0.14, (keep existing compat) (#41) Co-authored-by: CompatHelper Julia <[email protected]> * Documentation and Turing Navigation CI improvement (#45) * Update CI.yml * Create Docs.yml * Update DocNav.yml * No need of deploydocs() after using new Docs & DocsNav workflows * CompatHelper: bump compat for Enzyme in [weakdeps] to 0.13, (keep existing compat) (#39) Co-authored-by: CompatHelper Julia <[email protected]> * Change to DifferentiationInterface (#46) * switch to differentiationinterface from diffresults * rename train.jl to optimize.jl * fix some compat issue and bump version * update tests to new interface * add Moonkcake to extras * rm all ext for now * rm enzyme test, and import mooncake for test * fixing compat and test with mooncake * fixing test bug * fix _value_and_grad wrapper bug * fix AutoReverseDiff argument typo * minor ed * minor ed * fixing test * minor ed * rm test for mooncake * fix doc * chagne CI * update CI * streamline project toml * Apply suggestions from code review Co-authored-by: David Widmann <[email protected]> * add enzyme to tests * add Enzyme to using list * fixing enzyme readonly error by wrapping loss in Const * mv enzyme related edits to ext/ and fix tests * fixing extension loading error * Update Project.toml Co-authored-by: Guillaume Dalle <[email protected]> * remove Requires Co-authored-by: Guillaume Dalle <[email protected]> * remove explit load ext Co-authored-by: Guillaume Dalle <[email protected]> * Update src/objectives/loglikelihood.jl Co-authored-by: Guillaume Dalle <[email protected]> * make ext dep explicit * rm empty argument specialization for _prep_grad and _value_grad * signal empty rng arg * drop Requires * drop Requires * update test to include mooncake * rm unnecessary EnzymeCoreExt * minor update of readme * typo fix in readme * Update src/NormalizingFlows.jl Co-authored-by: David Widmann <[email protected]> * Update src/NormalizingFlows.jl Co-authored-by: David Widmann <[email protected]> * rm time_elapsed from train_flow * Update docs/src/api.md Co-authored-by: David Widmann <[email protected]> --------- Co-authored-by: Hong Ge <[email protected]> Co-authored-by: Xianda Sun <[email protected]> Co-authored-by: Xianda Sun <[email protected]> Co-authored-by: David Widmann <[email protected]> Co-authored-by: Guillaume Dalle <[email protected]> * add CUDA extension * undo change * add CUDA to test dep * add `rand_device` in main package * fix test error * move CUDA test to separate folder for gpu testing * add some preliminary gpu test CI code * remove cuda.jl from testing * update gpu test pipeline setup * update test file path * try fix error in CI setup * move files * try to debug * fix error * fix cuda testing project.toml * cosmetic fixed -- resolve linter complaints * fix test error * clean up * fix more errors * try to fix test error * add back allowscalar * refactoring * try fixing doc error * try fix doc again * add ref link --------- Co-authored-by: Zuheng <[email protected]> Co-authored-by: David Xu <[email protected]> Co-authored-by: Cameron Pfiffer <[email protected]> Co-authored-by: Xianda Sun <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: CompatHelper Julia <[email protected]> Co-authored-by: Hong Ge <[email protected]> Co-authored-by: Shravan Goswami <[email protected]> Co-authored-by: Xianda Sun <[email protected]> Co-authored-by: David Widmann <[email protected]> Co-authored-by: Guillaume Dalle <[email protected]>
1 parent 4a018d8 commit 34ed26e

File tree

13 files changed

+243
-27
lines changed

13 files changed

+243
-27
lines changed

.buildkite/pipeline.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
env:
2+
# SECRET_CODECOV_TOKEN can be added here if needed for coverage reporting
3+
4+
steps:
5+
- label: "Julia v{{matrix.version}}, {{matrix.label}}"
6+
plugins:
7+
- JuliaCI/julia#v1:
8+
version: "{{matrix.version}}"
9+
# - JuliaCI/julia-coverage#v1:
10+
# dirs:
11+
# - src
12+
# - ext
13+
command: julia --eval='println(pwd()); println(readdir()); include("test/ext/CUDA/cuda.jl")'
14+
agents:
15+
queue: "juliagpu"
16+
cuda: "*"
17+
if: build.message !~ /\[skip tests\]/
18+
timeout_in_minutes: 60
19+
env:
20+
LABEL: "{{matrix.label}}"
21+
TEST_TYPE: ext
22+
matrix:
23+
setup:
24+
version:
25+
- "1"
26+
- "1.10"
27+
label:
28+
- "cuda"

Project.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca"
1414
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1515
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
1616

17+
[weakdeps]
18+
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
19+
20+
[extensions]
21+
NormalizingFlowsCUDAExt = "CUDA"
22+
1723
[compat]
1824
ADTypes = "1"
1925
Bijectors = "0.12.6, 0.13, 0.14, 0.15"

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ makedocs(;
1616
"Example" => "example.md",
1717
"Customize your own flow layer" => "customized_layer.md",
1818
],
19+
checkdocs=:exports,
1920
)

example/targets/banana.jl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,19 @@ $(FIELDS)
1515
The banana distribution is obtained by applying a transformation ϕ to a multivariate normal
1616
distribution ``\\mathcal{N}(0, \\text{diag}(var, 1, 1, …, 1))``. The transformation ϕ is defined as
1717
```math
18-
\phi(x_1, … , x_p) = (x_1, x_2 - B x_1^² + \text{var}*B, x_3, … , x_p)
19-
````
18+
\\phi(x_1, … , x_p) = (x_1, x_2 - B x_1^² + \\text{var}*B, x_3, … , x_p)
19+
```
2020
which has a unit Jacobian determinant.
2121
2222
Hence the density "fb" of a p-dimensional banana distribution is given by
2323
```math
24-
fb(x_1, \dots, x_p) = \exp\left[ -\frac{1}{2}\frac{x_1^2}{\text{var}} -
25-
\frac{1}{2}(x_2 + B x_1^2 - \text{var}*B)^2 - \frac{1}{2}(x_3^2 + x_4^2 + \dots
26-
+ x_p^2) \right] / Z,
24+
fb(x_1, \\dots, x_p) = \\exp\\left[ -\\frac{1}{2}\\frac{x_1^2}{\\text{var}} -
25+
\\frac{1}{2}(x_2 + B x_1^2 - \\text{var}*B)^2 - \\frac{1}{2}(x_3^2 + x_4^2 + \\dots
26+
+ x_p^2) \\right] / Z,
2727
```
2828
where "B" is the "banananicity" constant, determining the curvature of a banana, and
2929
``Z = \\sqrt{\\text{var} * (2\\pi)^p)}`` is the normalization constant.
3030
31-
3231
# Reference
3332
3433
Gareth O. Roberts and Jeffrey S. Rosenthal

example/targets/cross.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ The Cross distribution is a 2-dimension 4-component Gaussian distribution with a
1111
shape that is symmetric about the y- and x-axises. The mixture is defined as
1212
1313
```math
14-
\begin{aligned}
14+
\\begin{aligned}
1515
p(x) =
16-
& 0.25 \mathcal{N}(x | (0, \mu), (\sigma, 1)) + \\
17-
& 0.25 \mathcal{N}(x | (\mu, 0), (1, \sigma)) + \\
18-
& 0.25 \mathcal{N}(x | (0, -\mu), (\sigma, 1)) + \\
19-
& 0.25 \mathcal{N}(x | (-\mu, 0), (1, \sigma)))
20-
\end{aligned}
16+
& 0.25 \\mathcal{N}(x | (0, \\mu), (\\sigma, 1)) + \\\\
17+
& 0.25 \\mathcal{N}(x | (\\mu, 0), (1, \\sigma)) + \\\\
18+
& 0.25 \\mathcal{N}(x | (0, -\\mu), (\\sigma, 1)) + \\\\
19+
& 0.25 \\mathcal{N}(x | (-\\mu, 0), (1, \\sigma))
20+
\\end{aligned}
2121
```
2222
2323
where ``μ`` and ``σ`` are the mean and standard deviation of the Gaussian components,

example/targets/neal_funnel.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@ $(FIELDS)
1313
The Neal's Funnel distribution is a p-dimensional distribution with a funnel shape,
1414
originally proposed by Radford Neal in [2].
1515
The marginal distribution of ``x_1`` is Gaussian with mean "μ" and standard
16-
deviation "σ". The conditional distribution of ``x_2, \dots, x_p | x_1`` are independent
16+
deviation "σ". The conditional distribution of ``x_2, \\dots, x_p | x_1`` are independent
1717
Gaussian distributions with mean 0 and standard deviation ``\\exp(x_1/2)``.
1818
The generative process is given by
1919
```math
20-
x_1 \sim \mathcal{N}(\mu, \sigma^2), \quad x_2, \ldots, x_p \sim \mathcal{N}(0, \exp(x_1))
20+
x_1 \\sim \\mathcal{N}(\\mu, \\sigma^2), \\quad x_2, \\ldots, x_p \\sim \\mathcal{N}(0, \\exp(x_1))
2121
```
2222
23-
2423
# Reference
2524
[1] Stan User’s Guide:
2625
https://mc-stan.org/docs/2_18/stan-users-guide/reparameterization-section.html#ref-Neal:2003

example/targets/warped_gaussian.jl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@ $(FIELDS)
1313
The banana distribution is obtained by applying a transformation ϕ to a 2-dimensional normal
1414
distribution ``\\mathcal{N}(0, diag(\\sigma_1, \\sigma_2))``. The transformation ϕ(x) is defined as
1515
```math
16-
ϕ(x_1, x_2) = (r*\cos(\theta + r/2), r*\sin(\theta + r/2)),
16+
\\phi(x_1, x_2) = (r*\\cos(\\theta + r/2), r*\\sin(\\theta + r/2)),
1717
```
18-
where ``r = \\sqrt{x\_1^2 + x_2^2}``, ``\\theta = \\atan(x₂, x₁)``,
19-
and "atan(y, x) [-π, π]" is the angle, in radians, between the positive x axis and the
18+
where ``r = \\sqrt{x_1^2 + x_2^2}``, ``\\theta = \\atan(x_2, x_1)``,
19+
and ``\\atan(y, x) \\in [-\\pi, \\pi]`` is the angle, in radians, between the positive x axis and the
2020
ray to the point "(x, y)". See page 18. of [1] for reference.
2121
22-
2322
# Reference
2423
[1] Zuheng Xu, Naitong Chen, Trevor Campbell
2524
"MixFlows: principled variational inference via mixed flows."

ext/NormalizingFlowsCUDAExt.jl

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
module NormalizingFlowsCUDAExt
2+
3+
using CUDA
4+
using NormalizingFlows
5+
using NormalizingFlows: Bijectors, Distributions, Random
6+
7+
function NormalizingFlows._device_specific_rand(
8+
rng::CUDA.RNG,
9+
s::Distributions.Sampleable{<:Distributions.ArrayLikeVariate,Distributions.Continuous},
10+
)
11+
return _cuda_rand(rng, s)
12+
end
13+
14+
function NormalizingFlows._device_specific_rand(
15+
rng::CUDA.RNG,
16+
s::Distributions.Sampleable{<:Distributions.ArrayLikeVariate,Distributions.Continuous},
17+
n::Int,
18+
)
19+
return _cuda_rand(rng, s, n)
20+
end
21+
22+
function _cuda_rand(
23+
rng::CUDA.RNG,
24+
s::Distributions.Sampleable{<:Distributions.ArrayLikeVariate,Distributions.Continuous},
25+
)
26+
return @inbounds Distributions.rand!(
27+
rng, Distributions.sampler(s), CuArray{float(eltype(s))}(undef, size(s))
28+
)
29+
end
30+
31+
function _cuda_rand(
32+
rng::CUDA.RNG,
33+
s::Distributions.Sampleable{<:Distributions.ArrayLikeVariate,Distributions.Continuous},
34+
n::Int,
35+
)
36+
return @inbounds Distributions.rand!(
37+
rng, Distributions.sampler(s), CuArray{float(eltype(s))}(undef, size(s)..., n)
38+
)
39+
end
40+
41+
# ! this is type piracy
42+
# replacing original function with scalar indexing
43+
function Distributions._rand!(rng::CUDA.RNG, d::Distributions.MvNormal, x::CuVecOrMat)
44+
Random.randn!(rng, x)
45+
Distributions.unwhiten!(d.Σ, x)
46+
x .+= d.μ
47+
return x
48+
end
49+
50+
# to enable `_device_specific_rand(rng:CUDA.RNG, flow[, num_samples])`
51+
function NormalizingFlows._device_specific_rand(rng::CUDA.RNG, td::Bijectors.TransformedDistribution)
52+
return _cuda_rand(rng, td)
53+
end
54+
55+
function NormalizingFlows._device_specific_rand(
56+
rng::CUDA.RNG, td::Bijectors.TransformedDistribution, num_samples::Int
57+
)
58+
return _cuda_rand(rng, td, num_samples)
59+
end
60+
61+
function _cuda_rand(rng::CUDA.RNG, td::Bijectors.TransformedDistribution)
62+
return td.transform(_cuda_rand(rng, td.dist))
63+
end
64+
65+
function _cuda_rand(rng::CUDA.RNG, td::Bijectors.TransformedDistribution, num_samples::Int)
66+
samples = _cuda_rand(rng, td.dist, num_samples)
67+
res = reduce(
68+
hcat,
69+
map(axes(samples, 2)) do i
70+
return td.transform(view(samples, :, i))
71+
end,
72+
)
73+
return res
74+
end
75+
76+
end

src/NormalizingFlows.jl

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
module NormalizingFlows
22

3+
using ADTypes
34
using Bijectors
5+
using Distributions
6+
using LinearAlgebra
47
using Optimisers
5-
using LinearAlgebra, Random, Distributions, StatsBase
68
using ProgressMeter
7-
using ADTypes
9+
using Random
10+
using StatsBase
811
import DifferentiationInterface as DI
912

1013
using DocStringExtensions
@@ -22,7 +25,6 @@ Train the given normalizing flow `flow` by calling `optimize`.
2225
- `flow`: normalizing flow to be trained, we recommend to define flow as `<:Bijectors.TransformedDistribution`
2326
- `args...`: additional arguments for `vo`
2427
25-
2628
# Keyword Arguments
2729
- `max_iters::Int=1000`: maximum number of iterations
2830
- `optimiser::Optimisers.AbstractRule=Optimisers.ADAM()`: optimiser to compute the steps
@@ -81,6 +83,44 @@ function train_flow(
8183
end
8284

8385
include("optimize.jl")
84-
include("objectives.jl")
86+
87+
# objectives
88+
include("objectives/elbo.jl")
89+
include("objectives/loglikelihood.jl") # not fully tested
90+
91+
"""
92+
_device_specific_rand
93+
94+
By default dispatch to `Random.rand`, but maybe overload when the random number
95+
generator is device specific (e.g. `CUDA.RNG`).
96+
"""
97+
function _device_specific_rand end
98+
99+
function _device_specific_rand(
100+
rng::Random.AbstractRNG,
101+
s::Distributions.Sampleable{<:Distributions.ArrayLikeVariate,Distributions.Continuous},
102+
)
103+
return Random.rand(rng, s)
104+
end
105+
106+
function _device_specific_rand(
107+
rng::Random.AbstractRNG,
108+
s::Distributions.Sampleable{<:Distributions.ArrayLikeVariate,Distributions.Continuous},
109+
n::Int,
110+
)
111+
return Random.rand(rng, s, n)
112+
end
113+
114+
function _device_specific_rand(
115+
rng::Random.AbstractRNG, td::Bijectors.TransformedDistribution
116+
)
117+
return Random.rand(rng, td)
118+
end
119+
120+
function _device_specific_rand(
121+
rng::Random.AbstractRNG, td::Bijectors.TransformedDistribution, n::Int
122+
)
123+
return Random.rand(rng, td, n)
124+
end
85125

86126
end

src/objectives.jl

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)