Skip to content

Commit 786cf4f

Browse files
authored
New test environment (#17)
1 parent 2d708a6 commit 786cf4f

6 files changed

Lines changed: 261 additions & 16 deletions

File tree

Project.toml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,43 @@ NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd"
1515
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1616
Tullio = "bc48ee85-29a4-5162-ae0b-a64e1601d4bc"
1717

18+
[sources]
19+
CoupledNODE = {rev = "main", url = "https://github.com/DEEPDIP-project/CoupledNODE.jl.git"}
20+
NeuralClosure = {rev = "main", url = "https://github.com/DEEPDIP-project/NeuralClosure.jl.git"}
21+
1822
[compat]
1923
CUDA = "5"
2024
ChainRules = "1"
2125
ComponentArrays = "0.15"
26+
DifferentialEquations = "7.16.0"
2227
FFTW = "1"
2328
JuliaFormatter = "1.0.62"
2429
Lux = "1"
2530
LuxCore = "1"
2631
NNlib = "0.9"
32+
Optimization = "4.1.1"
33+
OptimizationOptimisers = "0.3.7"
34+
Plots = "1.40.10"
35+
TestImages = "1.9.0"
2736
Tullio = "0.3"
2837
julia = "1.10"
38+
39+
[extras]
40+
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
41+
CoupledNODE = "88291d29-22ea-41b1-bc0b-03785bffce48"
42+
DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa"
43+
IncompressibleNavierStokes = "5e318141-6589-402b-868d-77d7df8c442e"
44+
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
45+
NeuralClosure = "099dac27-d7f2-4047-93d5-0baee36b9c25"
46+
Optimisers = "3bd65402-5787-11e9-1adc-39752487f4e2"
47+
Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba"
48+
OrdinaryDiffEqTsit5 = "b1df2697-797e-41e3-8120-5422d3b24e4a"
49+
OptimizationOptimisers = "42dfb2eb-d2b4-4451-abcd-913932933ac1"
50+
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
51+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
52+
TestImages = "5e47fb64-e119-507b-a336-dd2b206d9990"
53+
TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a"
54+
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
55+
56+
[targets]
57+
test = ["Test", "TestImages", "Adapt", "CoupledNODE", "IncompressibleNavierStokes", "JLD2", "NeuralClosure", "Optimisers", "OrdinaryDiffEqTsit5", "TestItemRunner", "Zygote", "Plots", "DifferentialEquations", "Optimization", "OptimizationOptimisers"]

src/models.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,6 @@ function ((;)::CNO)(x, params, state)
285285
@assert size(x, i) == N "ERROR: x has dimension $i = $(size(x, i)) but it should be $N"
286286
end
287287

288-
289288
# we have to keep track of each downsampled state
290289
intermediate_states = []
291290

test/Project.toml

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

test/config.yaml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
docreatedata: true
2+
docomp: true
3+
ntrajectory: 8
4+
T: "Float32"
5+
params:
6+
D: 2
7+
lims: [0.0, 1.0]
8+
Re: 6000.0
9+
tburn: 0.5
10+
tsim: 2.0
11+
savefreq: 100
12+
ndns: 32
13+
nles: [16]
14+
filters: ["FaceAverage()"]
15+
icfunc: "(setup, psolver, rng) -> random_field(setup, T(0); kp=20, psolver, rng)"
16+
method: "RKMethods.Wray3(; T)"
17+
bodyforce: "(dim, x, y, t) -> (dim == 1) * 5 * sinpi(8 * y)"
18+
issteadybodyforce: true
19+
processors: "(; log = timelogger(; nupdate=100))"
20+
Δt: 0.0001
21+
seeds:
22+
dns: 123
23+
θ_start: 234
24+
prior: 345
25+
post: 456
26+
closure:
27+
name: "cno_5"
28+
type: cno
29+
size: 32
30+
cutoff: 10
31+
channels: [2, 2]
32+
activations: ["relu", "identity"]
33+
down_factors: [2, 2]
34+
radii: [2, 2]
35+
bottleneck_depths: [2, 2, 2]
36+
rng: "Xoshiro(seeds.θ_start)"
37+
priori:
38+
dotrain: true
39+
nepoch: 300
40+
batchsize: 32
41+
opt: "OptimiserChain(Adam(T(1.0e-3)), ClipGrad(0.1))"
42+
do_plot: false
43+
plot_train: false
44+
posteriori:
45+
dotrain: true
46+
projectorders: "(ProjectOrder.Last, )"
47+
nepoch: 20
48+
opt: "OptimiserChain(Adam(T(1.0e-3)), ClipGrad(0.1))"
49+
nunroll: 3
50+
nunroll_valid: 5
51+
dt: T(1e-4)
52+
do_plot: false
53+
plot_train: false

test/data_train.jld2

1020 KB
Binary file not shown.

test/skiptest-couplednode.jl

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
using Test
2+
using Adapt
3+
using Lux
4+
using JLD2
5+
using ConvolutionalNeuralOperators: create_CNOdownsampler, create_CNO
6+
using ComponentArrays: ComponentArray
7+
using Optimisers: Adam, ClipGrad, OptimiserChain
8+
using Random
9+
using Zygote: Zygote
10+
using CUDA
11+
using CoupledNODE
12+
using IncompressibleNavierStokes
13+
using NeuralClosure
14+
using OrdinaryDiffEqTsit5
15+
16+
@testset "CoupledNode integration" begin
17+
18+
# Define parameters for the model
19+
nles = 16
20+
T = Float32
21+
N = nles
22+
D = 2
23+
rng = Xoshiro(123)
24+
r = [2, 2]
25+
c = [2, 2]
26+
σ = [tanh, identity]
27+
b = [true, false]
28+
emb_sizes = [4, 4]
29+
Ns = reverse([N + 2 * sum(r[1:i]) for i = 1:length(r)])
30+
patch_sizes = [8, 5]
31+
n_heads = [2, 2]
32+
use_attention = [true, true]
33+
sum_attention = [false, false]
34+
35+
# Create the model
36+
ch_ = [2, 2]
37+
act = [tanh_fast, identity]
38+
df = [2, 2]
39+
k_rad = [3, 3]
40+
bd = [2, 2, 2]
41+
cutoff = 10
42+
closure, θ_start, st = cno(
43+
T = T,
44+
N = N,
45+
D = D,
46+
cutoff = cutoff,
47+
ch_sizes = ch_,
48+
activations = act,
49+
down_factors = df,
50+
k_radii = k_rad,
51+
bottleneck_depths = bd,
52+
rng = rng,
53+
use_cuda = false,
54+
)
55+
56+
# Define input tensor and pass through model
57+
batch = 4
58+
input_tensor = rand(T, N, N, D, batch)
59+
output = Lux.apply(closure, input_tensor, θ_start, st)[1]
60+
@test size(output) == size(input_tensor)
61+
62+
63+
# Read conf
64+
NS = Base.get_extension(CoupledNODE, :NavierStokes)
65+
conf = NS.read_config("./config.yaml")
66+
conf["params"]["backend"] = CPU()
67+
68+
# get params
69+
params = NS.load_params(conf)
70+
device(x) = adapt(params.backend, x)
71+
72+
# Get the setup in the format expected by the CoupledNODE
73+
function getsetup(; params, nles)
74+
Setup(;
75+
x = ntuple-> range(params.lims..., nles + 1), params.D),
76+
params.Re,
77+
params.backend,
78+
params.bodyforce,
79+
params.issteadybodyforce,
80+
)
81+
end
82+
setup = getsetup(; params, nles)
83+
psolver = default_psolver(setup)
84+
setup = []
85+
for nl in nles
86+
x = ntuple-> LinRange(T(0.0), T(1.0), nl + 1), params.D)
87+
push!(setup, Setup(; x = x, Re = params.Re, params.backend))
88+
end
89+
90+
# Load data
91+
function namedtupleload(file)
92+
dict = load(file)
93+
k, v = keys(dict), values(dict)
94+
pairs = @. Symbol(k) => v
95+
(; pairs...)
96+
end
97+
data_train = []
98+
data_i = namedtupleload("data_train.jld2")
99+
push!(data_train, hcat(data_i))
100+
101+
102+
# Create the io array
103+
NS = Base.get_extension(CoupledNODE, :NavierStokes)
104+
io_train = NS.create_io_arrays_posteriori(data_train, setup)
105+
106+
# Create the dataloader
107+
θ = device(copy(θ_start))
108+
nunroll = 2
109+
nunroll_valid = 2
110+
dataloader_post = NS.create_dataloader_posteriori(
111+
io_train[1];
112+
nunroll = nunroll,
113+
rng = Random.Xoshiro(24),
114+
device = device,
115+
)
116+
117+
# Create the right hand side and the loss
118+
dudt_nn = NS.create_right_hand_side_with_closure(setup[1], psolver, closure, st)
119+
loss = CoupledNODE.create_loss_post_lux(
120+
dudt_nn;
121+
sciml_solver = Tsit5(),
122+
dt = T(conf["params"]["Δt"]),
123+
use_cuda = CUDA.functional(),
124+
)
125+
callbackstate = trainstate = nothing
126+
127+
128+
# For testing reason, explicitely set up the probelm
129+
# Notice that this is automatically done in CoupledNODE
130+
u, t = dataloader_post()
131+
griddims = ((:) for _ = 1:(ndims(u)-2))
132+
x = u[griddims..., :, 1]
133+
y = u[griddims..., :, 2:end] # remember to discard sol at the initial time step
134+
tspan, dt, prob, pred = nothing, nothing, nothing, nothing # initialize variable outside allowscalar do.
135+
dt = @views t[2:2] .- t[1:1]
136+
dt = only(Array(dt))
137+
function get_tspan(t)
138+
return (Array(t)[1], Array(t)[end])
139+
end
140+
tspan = get_tspan(t)
141+
prob = ODEProblem(dudt_nn, x, tspan, θ)
142+
pred = Array(
143+
solve(prob, Tsit5(); u0 = x, p = θ, adaptive = false, saveat = Array(t), dt = dt),
144+
)
145+
146+
# Test the forward pass
147+
@test size(pred[:, :, :, 2:end]) == size(y)
148+
149+
150+
# Test the backward pass
151+
p = prob.p
152+
y = prob.u0
153+
f = prob.f
154+
λ = zero(prob.u0)
155+
_dy, back = Zygote.pullback(y, p) do u, p
156+
vec(f(u, p, t))
157+
end
158+
tmp1, tmp2 = back(λ)
159+
@test size(tmp1) == (18, 18, 2)
160+
@test size(tmp2) == (94118,)
161+
162+
# Final integration test of the entire train interface
163+
l, trainstate = CoupledNODE.train(
164+
closure,
165+
θ,
166+
st,
167+
dataloader_post,
168+
loss;
169+
tstate = trainstate,
170+
nepochs = 2,
171+
#alg = OptimiserChain(Adam(T(1.0e-3)), ClipGrad(0.1)),
172+
alg = Adam(T(1.0e-3)),
173+
cpu = true,
174+
)
175+
@test isnan(l) == false
176+
@test trainstate.step == 2
177+
@test any(isnan, trainstate.parameters) == false
178+
179+
end

0 commit comments

Comments
 (0)