Cool, that helped. Now after a lot of iterations I got this code.
Importing packages and defining parameters
using LinearAlgebra
using Parameters,BenchmarkTools
using Flux
using PyPlot
using Sobol
using CUDA
using OneHotArrays
σ = Float32(0.1) |>gpu
d = Int32(2) |>gpu
BATCH_SIZE = 1000 |>gpu
const Δx = Float32(1e-2) |>gpu
const Δt = Float32(1e-2) |>gpu
Define initial condition and derivatives:
function fExpl0(x)
sol = 1/(4*π*σ)^(d/2)*exp.(-sum(x.^2, dims=1) ./(4*σ))
return Float32.(sol)
end
function ∂t(f,point)
t = point[1:1,:]
x = point[2:end,:]
return (f([t .+ Δt;x]) .- f([t;x]))./(Δt)
end
function Δ(f,point)
t = point[1:1,:]
x = point[2:end,:]
Δf = CUDA.zeros(1,size(point)[end])
for i = 1:d
direction = OneHotVector(i,Int64(d))
Δf = Δf .+ (f([t;x .+ Δx .* direction]) .- 2*f([t;x]) .+ f([t;x .+ (-Δx) .* direction]))./Δx^2
end
return Δf
end
Define the network and loss function
struct NNInitialCondition
chain::Chain
f0::Function
end
function (m::NNInitialCondition)(point)
t = point[1:1,:]
x = point[2:end,:]
return t .* m.chain(point) .+ (1 .- t) .* m.f0(x)
end
Flux.@functor NNInitialCondition
NN = Chain(
Dense(d+1 => 32, tanh),
Dense(32 => 32, tanh),
Dense(32 => 32, tanh),
Dense(32 => 1)
) |> gpu
function loss(f,point)
lossVal = sum((∂t(f,point) .- σ*Δ(f,point) ).^2)/size(point)[2]
return lossVal
end
Defining datapoints, the network and evaluate the loss function and compute the gradient:
NPtTrain = 1000
s = SobolSeq(d+1)
evalPointsTrain = vcat([Float32.(next!(s)) for i in 1:NPtTrain]'...) |> gpu
NNCustom = NNInitialCondition(NN,fExpl0)
loss(NNCustom,evalPointsTrain')
grads = Flux.gradient( m -> loss(m,evalPointsTrain'), NNCustom)
I have 2 issues:
1 - the interpreter continues to complain about scalar indexing, what am I doing wrong?
2 - I cannot compute the gradients because I get a very cryptic error below
Also, am I approaching the problem in a very wrong way? It took me 30 mins max to do the same in pytorch so I’m thinking that maybe I’m using the wrong approach here.
ERROR: `llvmcall` must be compiled to be called
Stacktrace:
[1] macro expansion
@ C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface2.jl:101 [inlined]
[2] _pullback(::Zygote.Context{false}, ::Core.IntrinsicFunction, ::String, ::Type{Int64}, ::Type{Tuple{Ptr{Int64}}}, ::Ptr{Int64})
@ Zygote C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface2.jl:101
[3] _pullback
@ .\atomics.jl:358 [inlined]
[4] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\lib\utils\threading.jl:25 [inlined]
[5] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\lib\utils\threading.jl:24 [inlined]
[6] macro expansion
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\lib\utils\memoization.jl:66 [inlined]
[7] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\pool.jl:160 [inlined]
[8] _pullback(ctx::Zygote.Context{false}, f::typeof(CUDA.stream_ordered), args::CuDevice)
@ Zygote C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface2.jl:0
[9] macro expansion
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\pool.jl:414 [inlined]
[10] macro expansion
@ .\timing.jl:393 [inlined]
[11] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\pool.jl:413 [inlined]
[12] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\pool.jl:408 [inlined]
[13] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\pool.jl:398 [inlined]
[14] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\pool.jl:392 [inlined]
[15] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\array.jl:93 [inlined]
[16] _pullback(::Zygote.Context{false}, ::Type{CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}}, ::UndefInitializer, ::Tuple{Int64, Int64})
@ Zygote C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface2.jl:0
[17] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\array.jl:176 [inlined]
[18] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\array.jl:187 [inlined]
[19] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\array.jl:189 [inlined]
[20] _pullback(::Zygote.Context{false}, ::Type{CuArray{Float32}}, ::UndefInitializer, ::Int64, ::Int64)
@ Zygote C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface2.jl:0
[21] _apply(::Function, ::Vararg{Any})
@ Core .\boot.jl:838
[22] adjoint
@ C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\lib\lib.jl:203 [inlined]
[23] _pullback
@ C:\Users\MARCO\.julia\packages\ZygoteRules\OgCVT\src\adjoint.jl:66 [inlined]
[24] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\array.jl:655 [inlined]
[25] _pullback(::Zygote.Context{false}, ::typeof(CUDA.zeros), ::Type{Float32}, ::Int64, ::Int64)
@ Zygote C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface2.jl:0
[26] _apply(::Function, ::Vararg{Any})
@ Core .\boot.jl:838
[27] adjoint
@ C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\lib\lib.jl:203 [inlined]
[28] _pullback
@ C:\Users\MARCO\.julia\packages\ZygoteRules\OgCVT\src\adjoint.jl:66 [inlined]
[29] _pullback
@ C:\Users\MARCO\.julia\packages\CUDA\pCcGc\src\array.jl:657 [inlined]
[30] _pullback(::Zygote.Context{false}, ::typeof(CUDA.zeros), ::Int64, ::Int64)
@ Zygote C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface2.jl:0
[31] _pullback
@ c:\Users\MARCO\Dropbox\cricci francischello\neuralPDEMasterEq\tests\HeatEQ\testLossFD.jl:39 [inlined]
[32] _pullback(::Zygote.Context{false}, ::typeof(Δ), ::NNInitialCondition, ::Adjoint{Float32, CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}})
@ Zygote C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface2.jl:0
[33] _pullback
@ c:\Users\MARCO\Dropbox\cricci francischello\neuralPDEMasterEq\tests\HeatEQ\testLossFD.jl:87 [inlined]
[34] _pullback(::Zygote.Context{false}, ::typeof(loss), ::NNInitialCondition, ::Adjoint{Float32, CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}})
@ Zygote C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface2.jl:0
[35] _pullback
@ c:\Users\MARCO\Dropbox\cricci francischello\neuralPDEMasterEq\tests\HeatEQ\testLossFD.jl:99 [inlined]
[36] _pullback(ctx::Zygote.Context{false}, f::var"#17#18", args::NNInitialCondition)
@ Zygote C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface2.jl:0
[37] pullback(f::Function, cx::Zygote.Context{false}, args::NNInitialCondition)
@ Zygote C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface.jl:44
[38] pullback
@ C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface.jl:42 [inlined]
[39] gradient(f::Function, args::NNInitialCondition)
@ Zygote C:\Users\MARCO\.julia\packages\Zygote\HTsWj\src\compiler\interface.jl:96
[40] top-level scope
@ c:\Users\MARCO\Dropbox\cricci francischello\neuralPDEMasterEq\tests\HeatEQ\testLossFD.jl:99