Skip to content

Adapt.adapt with an element-typed target (e.g. Array{ComplexF32}) breaks FFTOp and NFFTOp #49

Closed

Description

@shukebeta

On main (5e781df), adapting FFTOp or NFFTOp to a target that carries an element type can fail: always for NFFTOp, and for FFTOp when the element type differs from the operator's.

FFTOp adapts, but the first multiplication throws:

using LinearOperatorCollection, Adapt, FFTW
F = FFTOp(ComplexF64; shape=(4, 4))
m = Adapt.adapt(Array{ComplexF32}, F)   # eltype(m) == ComplexF32
m * rand(ComplexF32, 16)
# MethodError: no method matching fft_multiply_shift!(::Vector{ComplexF32},
#   ::FFTW.cFFTWPlan{ComplexF32, -1, true, 2, Tuple{Int64, Int64}}, ::Vector{ComplexF32}, ::Tuple{Int64, Int64}, ::ComplexF64, ...)

The buffers and plan are ComplexF32, while the scaling factor stays ComplexF64. JLArray{ComplexF32} fails the same way; Array and Array{ComplexF64} work.

NFFTOp fails inside adapt, also for the matching precision, because the real-valued nodes are adapted with the target's element type:

using LinearOperatorCollection, Adapt, NFFT
N = NFFTOp(ComplexF64; shape=(8, 8), nodes=0.8 .* rand(2, 20) .- 0.4, S=Vector{ComplexF64})
Adapt.adapt(Array{ComplexF64}, N)
# MethodError: no method matching ceil(::Type{Int64}, ::ComplexF64)

With the NonuniformFFTs backend it is MethodError: no method matching NonuniformFFTs.NFFTPlan(::Matrix{ComplexF64}, ...).

A possible fix: _adapt_target_storage could reject a target whose element type differs from the operator's, and the NFFT plan arguments could be adapted to the target's array type without its element type.

Julia 1.10.12, Adapt 4.7.4, FFTW 1.10.0, NFFT 0.14.3, NonuniformFFTs 0.9.8.

Activity

  1. nHackel commented on Nov 3, 2026

    @nHackel
    Member

    I think while Adapts interface allows it, the intent is actually that you dont specify the element type. The T should just be the backing array type such as CuArray or ROCArray. I'd consider calling Array{ComplexF64} a user error.

    We can make a small note of that in our docs when we add a section to adapt or to a generic docstring on AbstractLinearOperatorFromCollection

  2. shukebeta commented on Nov 4, 2026

    @shukebeta
    ContributorAuthor

    Understood. We'll document the unparameterized backend-type target in the GPU guide and align the GradientOp docstring, keeping it distinct from the constructor's parameterized storage S. No FFT/NFFT precision-conversion change is proposed.

  3. nHackel commented on Nov 4, 2026

    @nHackel
    Member

    Closed with #50

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions