示例#1
0
        private void BlockTransposeXtoY(CustomFftPlan data, UnsafeArray src, UnsafeArray dst)
        {
            var ny    = data.Ny;
            var locNx = data.LocalNx;
            var nm    = data.Nc;
            var nk    = data.NumberOfLocalFftsAlongSecondDimension;

            dst.ReShape(nm, locNx, ny);

            //Linear writting, nonlinear reading
            Iterate(nm, im =>
            {
                //for (int im = 0; im < nm; im++)
                for (int ix = 0; ix < locNx; ix++)
                {
                    for (int iy = 0; iy < ny; iy++)
                    {
                        var l0 = iy + im * ny;                    // place in XZ
                        var m0 = l0 - l0 % nk;                    //Ik = m0
                        var l  = l0 + ix * nk + m0 * (locNx - 1); //Ix + (Iy - 1)Nx + (Ic - 1)NxNyLoc

                        dst[im, ix, iy] = src[l];
                    }
                }
            });
        }
示例#2
0
 protected virtual void DistributedTranspose(CustomFftPlan data, UnsafeArray src, UnsafeArray dst)
 {
     FftwMpi.ExecuteR2r(data.TransposePlan.Handler, new IntPtr(src.Ptr), new IntPtr(dst.Ptr));
     //int size = data.NumberOfLocalFftsAlongSecondDimension * data.LocalNx;
     //_mpi.AllToAll(data.Output.Ptr, size, data.Input.Ptr, size);
     //All2All
 }
示例#3
0
        private void BlockTransposeYtoX(CustomFftPlan data, UnsafeArray src, UnsafeArray dst)
        {
            var locNx = data.LocalNx;
            var ny    = data.Ny;
            var np    = data.NumberOfMpiProcesses;
            var nk    = data.NumberOfLocalFftsAlongSecondDimension;

            var bufferSize = nk * np * locNx - 1;

            dst.ReShape(np, locNx, nk);

            //Linear writting, nonlinear reading
            Iterate(np, ip =>
            {
                //for (int ip = 0; ip < np; ip++)
                for (int ix = 0; ix < locNx; ix++)
                {
                    for (int ik = 0; ik < nk; ik++)
                    {
                        var l0 = ik + (ip) * nk;                             // place in XZ
                        var m0 = l0 - l0 % ny;
                        var l  = l0 + ix * ny + m0 * (locNx - 1);            //Ix + (Iy - 1)Nx + (Ic - 1)NxNyLoc
                        l      = (l + bufferSize - Abs(bufferSize - l)) / 2; // if l > M we are in "addition" zone

                        dst[ip, ix, ik] = src[l];
                    }
                }
            });
        }
示例#4
0
        protected virtual void InitialTranspose(CustomFftPlan data, UnsafeArray src, UnsafeArray dst)
        {
            var nxy = data.LocalNx * data.Ny;
            var nz  = data.Nc;

            LocalTranspose(src, dst, nz, nxy);
        }
示例#5
0
        private void FinalTranspose(CustomFftPlan data, UnsafeArray src, UnsafeArray dst)
        {
            var nxy = data.LocalNx * data.Ny;
            var nz  = data.Nc;

            LocalTranspose(src, dst, nxy, nz);
        }
示例#6
0
        private void CreateInternalPlans(CustomFftPlan data)
        {
            CreateTransposePlan(data, _flagsTranspose);
            Create1DFftPlansY(data, _flags1d);
            Create1DFftPlansX(data, _flags1d);

            if (data.Dimension == 3)
            {
                Create1DFftPlansZ(data, _flags1d);
            }
        }
示例#7
0
        private void CreateTransposePlan(CustomFftPlan data, uint flags)
        {
            var n   = new IntPtr(2 * data.NumberOfLocalFftsAlongSecondDimension * data.LocalNx);
            var np  = new IntPtr(data.NumberOfMpiProcesses);
            var one = new IntPtr(1);

            var input  = new IntPtr(data.Input.Ptr);
            var output = new IntPtr(data.Output.Ptr);

            var handler = FftwMpi.PlanManyTranspose(np, np, n, one, one, input, output, _mpi.Communicator, flags);

            data.TransposePlan = new FftwPlan(np.ToInt32(), np.ToInt32(), n.ToInt32(), handler);
        }
示例#8
0
        public CustomFftPlan CreatePlan(Complex *input, Complex *output, Mpi mpi, int fullNx, int fullNy, int nc, int dimension)
        {
            var localNx = mpi.CalcLocalNxLength(fullNx);
            var numberOfLocalFftsAlongSecondDimension = GetNumberOfLocalFftsAlongSecondDimension(mpi, fullNy, nc);

            var plan = new CustomFftPlan(input, output, dimension)
            {
                Ny = fullNy,
                Nc = nc,
                NumberOfMpiProcesses = mpi.Size,
                LocalNx = localNx,
                NumberOfLocalFftsAlongSecondDimension = numberOfLocalFftsAlongSecondDimension
            };

            CreateInternalPlans(plan);

            return(plan);
        }
示例#9
0
        private void Create1DFftPlansX(CustomFftPlan data, uint flags)
        {
            var pNx     = new int[] { data.LocalNx *data.NumberOfMpiProcesses };
            var howmany = data.NumberOfLocalFftsAlongSecondDimension;

            var input  = new IntPtr(data.Input.Ptr);
            var output = new IntPtr(data.Output.Ptr);

            var handlerPlanXForward
                = Fftw.PlanManyDft(1, pNx, howmany, input, pNx, howmany, 1, output, pNx, howmany, 1, (int)FftWrap.Direction.Forward, flags);

            var handlerPlanXBackward
                = Fftw.PlanManyDft(1, pNx, howmany, input, pNx, howmany, 1, output, pNx, howmany, 1, (int)FftWrap.Direction.Backward, flags);


            data.ForwardX  = new FftwPlan(0, 0, 0, handlerPlanXForward);
            data.BackwardX = new FftwPlan(0, 0, 0, handlerPlanXBackward);
        }
示例#10
0
        private void Create1DFftPlansY(CustomFftPlan data, uint flags)
        {
            var pNy     = new int[] { data.Ny, };
            var dy      = data.Ny;
            var howmany = data.LocalNx * data.Nc;

            var input  = new IntPtr(data.Output.Ptr);
            var output = new IntPtr(data.Input.Ptr);

            var handlerPlanYForward
                = Fftw.PlanManyDft(1, pNy, howmany, input, pNy, 1, dy, output, pNy, 1, dy, (int)FftWrap.Direction.Forward,
                                   flags);

            var handlerPlanYBackward
                = Fftw.PlanManyDft(1, pNy, howmany, input, pNy, 1, dy, output, pNy, 1, dy, (int)FftWrap.Direction.Backward,
                                   flags);

            data.ForwardY  = new FftwPlan(0, 0, 0, handlerPlanYForward);
            data.BackwardY = new FftwPlan(0, 0, 0, handlerPlanYBackward);
        }
示例#11
0
        private void Create1DFftPlansZ(CustomFftPlan data, uint flags)
        {
            var pNx     = new int[] { data.Nc };
            var howmany = data.LocalNx * data.Ny;

            var input  = new IntPtr(data.Input.Ptr);
            var output = new IntPtr(data.Output.Ptr);

            int stride = 1;
            int dist   = data.Nc;

            var handlerPlanZForward
                = Fftw.PlanManyDft(1, pNx, howmany, input, pNx, stride, dist, output, pNx, stride, dist, (int)FftWrap.Direction.Forward, flags);

            var handlerPlanZBackward
                = Fftw.PlanManyDft(1, pNx, howmany, input, pNx, stride, dist, output, pNx, stride, dist, (int)FftWrap.Direction.Backward, flags);


            data.ForwardZ  = new FftwPlan(0, 0, 0, handlerPlanZForward);
            data.BackwardZ = new FftwPlan(0, 0, 0, handlerPlanZBackward);
        }
示例#12
0
        private void Compute(CustomFftPlan data, Direction direction)
        {
            var buff1 = direction == Direction.Forward ? data.Input : data.Output;
            var buff2 = direction == Direction.Forward ? data.Output : data.Input;

            using (_profiler?.StartAuto(ProfilerEvent.CustomFft))
            {
                if (data.Dimension == 3)
                {
                    WithProfiler(ProfilerEvent.CustomFftFourierZ, () => FourierZ(data, direction, buff2, buff1));
                }

                WithProfiler(ProfilerEvent.CustomFftInitialTranspose, () => InitialTranspose(data, buff1, buff2));
                WithProfiler(ProfilerEvent.CustomFftFourierY, () => FourierY(data, direction, buff2, buff1));
                WithProfiler(ProfilerEvent.CustomFftBlockTransposeYtoX, () => BlockTransposeYtoX(data, buff1, buff2));
                WithProfiler(ProfilerEvent.CustomFftDistributedTranspose, () => DistributedTranspose(data, buff2, buff1));
                WithProfiler(ProfilerEvent.CustomFftFourierX, () => FourierX(data, direction, buff1, buff2));
                WithProfiler(ProfilerEvent.CustomFftDistributedTranspose, () => DistributedTranspose(data, buff2, buff1));
                WithProfiler(ProfilerEvent.CustomFftBlockTransposeXtoY, () => BlockTransposeXtoY(data, buff1, buff2));
                WithProfiler(ProfilerEvent.CustomFftFinalTranspose, () => FinalTranspose(data, buff2, buff1));
            }
        }
示例#13
0
        private void FourierZ(CustomFftPlan data, Direction direction, UnsafeArray src, UnsafeArray dst)
        {
            var plan = direction == Direction.Forward ? data.ForwardZ : data.BackwardZ;

            Fftw.ExecuteDft(plan.Handler, new IntPtr(src.Ptr), new IntPtr(dst.Ptr));
        }
示例#14
0
 public void ComputeBackward(CustomFftPlan data)
 => Compute(data, Direction.Backward);
示例#15
0
 public void ComputeForward(CustomFftPlan data)
 => Compute(data, Direction.Forward);
示例#16
0
 public CustomBuffer(Complex *buffer1Ptr, Complex *buffer2Ptr, int bufferLength, CustomFftPlan customFftPlan) : base(buffer1Ptr, buffer2Ptr, bufferLength)
 {
     CustomFftPlan = customFftPlan;
 }