Hi everyone,
I am trying use the ForwardDiff.gradient!
function to compute the in-place gradient of a function F with regard to 3 parameters.
F has ncx
entries and the function has 3 parameters per entry. I explicitly parse in an input vector of size of (3, ncx)
. I would expect that returned gradient should also have a size of (3, ncx)
. I have tried with the following MWE, but it seems that my definition of Poisson1D_grad!(dFdT, Poisson1D_v1!, F, Tmat, data)
is incorrect. It always returns an error about non-matching method. I have tried several modifications in order to match the method but without success. Would someone has a hint?
Cheers!
using SIMDDualNumbers, ForwardDiff, StaticArrays, LoopVectorization, SparseArrays, LinearAlgebra, Plots
function PoissonSparsity1D_v1!(x::AbstractMatrix{<:Real})
@views TC, TW, TE = x[1,:], x[2,:], x[3,:]
TW[2:end-0] .= TC[1:end-1];
TE[1:end-1] .= TC[2:end-0];
end
function Poisson1D_v1!(F::AbstractVector{<:Real},x::AbstractMatrix{<:Real}, data )
kx, dx, ncx, TW_BC, TE_BC = data
@turbo for i=1:ncx
TC, TW, TE = x[1,i], x[2,i], x[3,i]
TW1 = SIMDDualNumbers.ifelse(i==1, 2TW_BC-TC, TW)
TE1 = SIMDDualNumbers.ifelse(i==ncx, 2TE_BC-TC, TE)
qxW = -kx*(TC - TW1)/dx
qxE = -kx*(TE1 - TC)/dx
F[i] = (qxE - qxW)/dx
end
end
Poisson1D_grad!(g, Poisson1D_v1!, F, x, d) = ForwardDiff.gradient!(g, (F,x) -> Poisson1D_v1!(F, x, d), x )
function main()
# Initialise
ncx = 10
data = (kx=1.0, dx=0.1, ncx, TW_BC=1.0, TE_BC=2.0)
T = fill(0.0, ncx) # residual, solution field
Tmat = fill(0.0, 3, ncx) # Contains sparsity (3 stencil points)
# Get neigbour values and generate connectivity
Tmat[1,:] .= T
PoissonSparsity1D!(Tmat)
# Evaluate function
F = zero(T)
Poisson1D_v1!(F, Tmat, data)
# Compute and store gradient
dFdT = zero(Tmat)
Poisson1D_grad!(dFdT, Poisson1D_v1!, F, Tmat, data)
end
for it=1:2
@time main()
end