EnzymeTestUtils fails for FFT plans / structs with undefined references
- Dominant language
- Julia
- Stars
- 586
- Forks
- 108
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 44
Description
I am currently in the process of writing some custom rules for code that involves FFT plans. While testing those `EnzymeTestUtils` fails.
`EnzymeTestUtils` tests with `test_approx` if two variables are approximately equal. For structs like FFT it checks all of their fields. For most FFT plans this is bound to fail because FFT plans have an uninitialised field `pinv` for the inverse plan:
```Julia
using AbstractFFTs, FFTW
x = rand(10)
plan = plan_fft(x)
plan.pinv
```
returns
```
ERROR: UndefRefError: access to undefined reference
```
`pinv` gets assigned once the adjoint/inverse is called the first time (e.g. with `\`). But the inverse again has a field `pinv` which has a field `pinv` and so on. For most purposes that's not a problem, but for `EnzymeTestUtils` it is currently.
So, as far as I can see it `test_approx` will always return an
`ERROR: UndefRefError: access to undefined reference` if an FFT plan is handed over
`isdefined` and `isassigned` don't work in this case unfortunately. For my personal use I just fixed that by defining
```Julia
function EnzymeTestUtils.test_approx(x::AbstractFFTs.Plan, y::AbstractFFTs.Plan, msg; kwargs...)
EnzymeTestUtils.@test_msg "$msg: types must match" typeof(x) == typeof(y)
names = fieldnames(typeof(x))[1:end-1]
if isempty(names)
EnzymeTestUtils.@test_msg msg x == y
else
for k in names
if k isa Symbol && hasproperty(x, k)
msg_new = "$msg: ::$(typeof(x)).$k"
else
msg_new = "$msg: getfield(::$(typeof(x)), $k)"
end
EnzymeTestUtils.test_approx(getfield(x, k), getfield(y, k), msg_new; kwargs...)
end
end
return nothing
end
```
That's the same as the generic `test_approx`, it just excludes the last field, which is `pinv`. That' a quite hacky solution, I am sure there's a way to solve this in a better, more elegant way.
Contributor guide
Assessment
This issue has not been assessed yet.