jipolanco / PencilArrays.jl

Distributed Julia arrays using the MPI protocol
https://jipolanco.github.io/PencilArrays.jl/dev/
MIT License
60 stars 8 forks source link

Type Issue with Transforms.NoTransform!() #84

Closed nick4110fi closed 11 months ago

nick4110fi commented 11 months ago

I am trying to take an existing 3d parallelized FFT plan function I've written and generalize it to be able to handle 1 and 2d plans as well. Our current function sets up a FFT Plan like so:

dims = (Nx, Ny, Nz)

proc_dims = let pdims = zeros(Int, 2)
     MPI.Dims_create!(mpi_size, pdims)
     pdims[1], pdims[2]
end

transform = (Transforms.FFT!(), Transforms.FFT!(), Transforms.FFT!())

plan = PencilFFTPlan(dims,transform, proc_dims, mpi_comm, float_type)

When the above code is run, things compile correctly for a 3d implementation.

The PencilFFT documentation states that Transforms.NoTransform!() is a valid choice of Transform to give the tuple so I thought the easiest way to generalize this 3d function to operate in 1 or 2d was to pass Transforms.NoTransform!() into the tuple on the dimensions I want the function to leave alone. However when the line

transform = (Transforms.FFT!(), Transforms.FFT!(), Transforms.FFT!())

is changed to

transform = (Transforms.FFT!(), Transforms.NoTransform!(),Transforms.NoTransform!())

I get the following type mismatch error:

ERROR: LoadError: MethodError: Cannot `convert` an object of type 
  PencilFFTs.PencilFFTPlan{ComplexF64, 3, true, 3, 2, 0, PencilFFTs.GlobalFFTParams{Float64, 3, true, Tuple{PencilFFTs.Transforms.FFT!, PencilFFTs.Transforms.NoTransform!, PencilFFTs.Transforms.NoTransform!}}, Tuple{PencilFFTs.PencilPlan1D{ComplexF64, ComplexF64, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.NoPermutation, Vector{UInt8}}, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.NoPermutation, Vector{UInt8}}, PencilFFTs.Transforms.FFT!, FFTW.cFFTWPlan{ComplexF64, -1, true, 3, Int64}, FFTW.cFFTWPlan{ComplexF64, 1, true, 3, Int64}}, PencilFFTs.PencilPlan1D{ComplexF64, ComplexF64, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(2, 1, 3), 3}, Vector{UInt8}}, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(2, 1, 3), 3}, Vector{UInt8}}, PencilFFTs.Transforms.NoTransform!, PencilFFTs.Transforms.IdentityPlan!, PencilFFTs.Transforms.IdentityPlan!}, PencilFFTs.PencilPlan1D{ComplexF64, ComplexF64, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(3, 2, 1), 3}, Vector{UInt8}}, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(3, 2, 1), 3}, Vector{UInt8}}, PencilFFTs.Transforms.NoTransform!, PencilFFTs.Transforms.IdentityPlan!, PencilFFTs.Transforms.IdentityPlan!}}, PencilArrays.Transpositions.PointToPoint, Vector{UInt8}} to an object of type 
  Union{PencilFFTs.PencilFFTPlan{ComplexF64, 3, true, 3, 2, 0, PencilFFTs.GlobalFFTParams{Float64, 3, true, Tuple{PencilFFTs.Transforms.FFT!, PencilFFTs.Transforms.FFT!, PencilFFTs.Transforms.FFT!}}, Tuple{PencilFFTs.PencilPlan1D{ComplexF64, ComplexF64, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.NoPermutation, Vector{UInt8}}, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.NoPermutation, Vector{UInt8}}, PencilFFTs.Transforms.FFT!, FFTW.cFFTWPlan{ComplexF64, -1, true, 3, Int64}, FFTW.cFFTWPlan{ComplexF64, 1, true, 3, Int64}}, PencilFFTs.PencilPlan1D{ComplexF64, ComplexF64, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(2, 1, 3), 3}, Vector{UInt8}}, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(2, 1, 3), 3}, Vector{UInt8}}, PencilFFTs.Transforms.FFT!, FFTW.cFFTWPlan{ComplexF64, -1, true, 3, Int64}, FFTW.cFFTWPlan{ComplexF64, 1, true, 3, Int64}}, PencilFFTs.PencilPlan1D{ComplexF64, ComplexF64, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(3, 2, 1), 3}, Vector{UInt8}}, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(3, 2, 1), 3}, Vector{UInt8}}, PencilFFTs.Transforms.FFT!, FFTW.cFFTWPlan{ComplexF64, -1, true, 3, Int64}, FFTW.cFFTWPlan{ComplexF64, 1, true, 3, Int64}}}, PencilArrays.Transpositions.PointToPoint}, PencilFFTs.PencilFFTPlan{ComplexF64, 3, false, 3, 2, 0, PencilFFTs.GlobalFFTParams{Float64, 3, false, Tuple{PencilFFTs.Transforms.FFT, PencilFFTs.Transforms.FFT, PencilFFTs.Transforms.FFT}}, Tuple{PencilFFTs.PencilPlan1D{ComplexF64, ComplexF64, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.NoPermutation, Vector{UInt8}}, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.NoPermutation, Vector{UInt8}}, PencilFFTs.Transforms.FFT, FFTW.cFFTWPlan{ComplexF64, -1, false, 3, Int64}, FFTW.cFFTWPlan{ComplexF64, 1, false, 3, Int64}}, PencilFFTs.PencilPlan1D{ComplexF64, ComplexF64, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(2, 1, 3), 3}, Vector{UInt8}}, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(2, 1, 3), 3}, Vector{UInt8}}, PencilFFTs.Transforms.FFT, FFTW.cFFTWPlan{ComplexF64, -1, false, 3, Int64}, FFTW.cFFTWPlan{ComplexF64, 1, false, 3, Int64}}, PencilFFTs.PencilPlan1D{ComplexF64, ComplexF64, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(3, 2, 1), 3}, Vector{UInt8}}, PencilArrays.Pencils.Pencil{3, 2, StaticPermutations.Permutation{(3, 2, 1), 3}, Vector{UInt8}}, PencilFFTs.Transforms.FFT, FFTW.cFFTWPlan{ComplexF64, -1, false, 3, Int64}, FFTW.cFFTWPlan{ComplexF64, 1, false, 3, Int64}}}, PencilArrays.Transpositions.PointToPoint}}
Closest candidates are:
  convert(::Type{T}, !Matched::T) where T at Base.jl:61

Could this be some sort of type or class issue within PencilArrays? The documentation in PencilFFTs seems pretty clear and I'm wondering if there's an odd interaction with PencilArrays.

jipolanco commented 11 months ago

Seems to work just fine for me.

Here is a full minimal example which runs without error:

using PencilFFTs
using MPI

MPI.Init()

mpi_comm = MPI.COMM_WORLD
mpi_size = MPI.Comm_size(mpi_comm)
const float_type = Float64
Nx, Ny, Nz = 16, 16, 16

dims = (Nx, Ny, Nz)

proc_dims = let pdims = zeros(Int, 2)
     MPI.Dims_create!(mpi_size, pdims)
     pdims[1], pdims[2]
end

# transform = (Transforms.FFT!(), Transforms.FFT!(), Transforms.FFT!())
transform = (Transforms.FFT!(), Transforms.NoTransform!(), Transforms.NoTransform!())

plan = PencilFFTPlan(dims,transform, proc_dims, mpi_comm, float_type)

I get the following plan:

julia> plan = PencilFFTPlan(dims,transform, proc_dims, mpi_comm, float_type)
Transforms: (FFT!, NoTransform!, NoTransform!)
Input type: ComplexF64
Global dimensions: (16, 16, 16) -> (16, 16, 16)
MPI topology: 2D decomposition (1×1 processes)

Which version of PencilFFTs and Julia are you using? Can you provide a full (runnable) minimal example where you get an error?

jipolanco commented 11 months ago

I'm closing this. Feel free to reopen if you still have issues, ideally providing the details mentioned in my previous answer.