├── doc ├── code │ └── manual_min_c2c.c ├── fortran.tex ├── .gitignore ├── latexinc.sh.in ├── man_fftw_3don1d.tex ├── develop.tex ├── Makefile.am └── latex-manual.sh ├── TODO ├── api ├── build-f03-api.sh ├── Makefile.am ├── f03-wrap.sh ├── f03-api.sh ├── fortran-mangling.h └── pfft.f.in ├── AUTHORS ├── util ├── Makefile.am └── util.h ├── m4 ├── ax_disable.m4 ├── acx_fc_library_ldflags_fix.m4 ├── ax_check_dir.m4 ├── ax_fcs_direct.m4 ├── ax_gcc_version.m4 ├── ax_sort_lib.m4 ├── ac_fc_module_extension.m4 ├── ax_diff_library_ldflags.m4 ├── ax_fc_no_range_check.m4 ├── ax_fc_integer_kind.m4 ├── ax_compiler_vendor.m4 ├── acx_mpiexec.m4 ├── ax_check_compiler_flags.m4 ├── ac_fc_pp_define.m4 ├── ax_intrinsics.m4 ├── ax_gcc_x86_cpuid.m4 ├── ax_gcc_aligns_stack.m4 ├── ac_fc_fixedform.m4 ├── ax_filelist.m4 ├── ac_fc_module_flag.m4 └── ax_fcs_package.m4 ├── pfft.pc.in ├── .gitignore ├── gcell └── Makefile.am ├── scripts ├── make_release_gcc.sh ├── install_pfft_chic.sh ├── install_pfft_gcc_debug.sh ├── install_pfft_chic_debug.sh ├── install_pfft_intel.sh ├── install_pfft_intel_debug.sh ├── install_pfft_bgq.sh ├── install_pfft_bgp_debug.sh ├── install_pfft_bgq_debug.sh ├── build_release_gcc.sh ├── install_pfft_bgp.sh └── install_pfft_gcc.sh ├── kernel ├── Makefile.am ├── check.c └── malloc.c ├── NEWS ├── tests ├── openmp │ ├── Makefile.am │ ├── simple_check_c2c_transposed.c │ └── simple_check_c2c.c ├── f03 │ ├── Makefile.am │ ├── simple_check_c2c.F03 │ ├── simple_check_c2c_transposed.F03 │ ├── time_c2c.F03 │ └── time_c2c_transposed.F03 ├── fortran │ ├── Makefile.am │ ├── simple_check_c2c.F90 │ └── simple_check_c2c_transposed.F90 ├── manual_c2c_3d.c ├── man_fftw_3don1d.c ├── man_fftw_3don1d.ctex ├── simple_check_c2c_inplace.c ├── simple_check_c2c_transposed_inplace.c ├── simple_check_c2c_float.c ├── simple_check_c2c_ldouble.c ├── simple_check_c2c.c ├── simple_check_c2c_3d_on_3d.c ├── simple_check_c2c_4d.c ├── simple_check_c2c_transposed.c ├── simple_check_r2c.c ├── simple_check_c2c_4d_transposed.c ├── simple_check_c2c_3d_on_3d_transposed.c ├── simple_check_c2c_4d_on_3d.c ├── simple_check_r2c_3d_on_3d.c ├── simple_check_c2c_4d_on_3d_transposed.c ├── simple_check_r2c_4d_on_3d.c ├── simple_check_r2c_4d_on_3d_transposed.c ├── simple_check_r2c_4d.c ├── simple_check_r2c_4d_transposed.c ├── simple_check_r2r.c ├── minimal_check_c2c.c ├── minimal_check_c2c_transposed.c ├── simple_check_r2r_3d_on_3d.c ├── simple_check_r2r_3d_on_3d_transposed.c ├── simple_check_c2c_newarray.c ├── simple_check_c2c_transposed_newarray.c ├── simple_check_r2c_newarray.c ├── simple_check_r2c_transposed_newarray.c ├── build_checks.sh ├── simple_check_r2c_padded_newarray.c ├── simple_check_r2c_padded_transposed_newarray.c ├── simple_check_r2r_4d.c ├── simple_check_r2r_4d_transposed.c ├── simple_check_r2r_4d_on_3d.c └── simple_check_r2r_4d_on_3d_transposed.c ├── conf └── travis-install-mpi.sh ├── fconfig.h.in ├── .travis.yml ├── Makefile.am └── bootstrap.sh /doc/code/manual_min_c2c.c: -------------------------------------------------------------------------------- 1 | ../../tests/manual_min_c2c.c -------------------------------------------------------------------------------- /doc/fortran.tex: -------------------------------------------------------------------------------- 1 | \chapter{Fotran Interface} 2 | 3 | based on Fortran 90 -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - check all files for correct licence header and clearify which files are based on FFTW code (nearly all of them) 2 | - correct coding standard of all PFFT files corresponding to CONVENTIONS 3 | 4 | -------------------------------------------------------------------------------- /api/build-f03-api.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | ## Script to generate Fortran 2003 interface and wrappers. 3 | 4 | sh f03-api.sh d f > pfft.f03.in 5 | sh f03-api.sh l > pfftl.f03.in 6 | sh f03-wrap.sh > f03-wrap.c 7 | 8 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | The PFFT package was developed and is maintained by 2 | 3 | Michael Pippig 4 | TU Chemnitz, Fakultaet fuer Mathematik 5 | Reichenhainer Str. 39 6 | 09107 Chemnitz, GERMANY 7 | 8 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | # temporary Latex files # 2 | ########################## 3 | *.aux 4 | *.bbl 5 | *.blg 6 | *.idx 7 | *.ilg 8 | *.ind 9 | *.lof 10 | *.log 11 | *.lot 12 | *.out 13 | *.pdf 14 | *.synctex.gz 15 | *.tdo 16 | *.toc 17 | *.tex.backup 18 | 19 | -------------------------------------------------------------------------------- /util/Makefile.am: -------------------------------------------------------------------------------- 1 | # Directory of ipfft.h 2 | AM_CPPFLAGS = -I$(top_srcdir)/kernel 3 | 4 | # Directory of pfft.h 5 | AM_CPPFLAGS += -I$(top_srcdir)/api 6 | 7 | noinst_LTLIBRARIES = libutil.la 8 | 9 | # Group local sources into convenience lib. 10 | libutil_la_SOURCES = \ 11 | util.c \ 12 | util.h \ 13 | getargs.c 14 | 15 | -------------------------------------------------------------------------------- /m4/ax_disable.m4: -------------------------------------------------------------------------------- 1 | 2 | AC_DEFUN([AX_DISABLE],[ 3 | m4_foreach([id], [$1], [ 4 | m4_define([id_esc],AS_TR_SH(id)) 5 | m4_define([id_var],ax_disable_[]id_esc) 6 | id_var=no 7 | AC_ARG_ENABLE(id,AS_HELP_STRING([--disable-]id,[disable ]id), 8 | [test "x$enableval" = xno && id_var=yes], []) 9 | # echo "id_var: $id_var" 10 | ]) 11 | ]) 12 | -------------------------------------------------------------------------------- /pfft.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: PFFT 7 | Description: Parallel fast Fourier transform library 8 | URL: github.com/mpip/pfft 9 | Version: @VERSION@ 10 | Requires.private: fftw3 >= 3.3.3 11 | Libs: -L${libdir} -l@PFFT_PREFIX@pfft@PREC_SUFFIX@@OPENMP_SUFFIX@ 12 | Libs.private: -lm 13 | Cflags: -I${includedir} 14 | -------------------------------------------------------------------------------- /m4/acx_fc_library_ldflags_fix.m4: -------------------------------------------------------------------------------- 1 | # ACX_FC_LIBRARY_LDFLAGS_FIX 2 | # -------------------------- 3 | # Small fix to AC_FC_LIBRARY_LDFLAGS needed for xlf2003_r on BlueGene. 4 | AC_DEFUN([ACX_FC_LIBRARY_LDFLAGS_FIX], 5 | [new_FCLIBS= 6 | for flag in $FCLIBS 7 | do 8 | case $flag in #( 9 | -link) ;; # ignore this. ( 10 | *) new_FCLIBS="$new_FCLIBS $flag" ;; 11 | esac 12 | done 13 | FCLIBS=$new_FCLIBS 14 | ]) 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile.in 2 | configure 3 | autom4te.cache 4 | aclocal.m4 5 | lt~obsolete.m4 6 | ltversion.m4 7 | ltsugar.m4 8 | ltoptions.m4 9 | libtool.m4 10 | config.h.in 11 | config.h.in~ 12 | module.deps 13 | filelist.am 14 | a1conf.h.in 15 | a1conf.h.in~ 16 | missing 17 | ltmain.sh 18 | install-sh 19 | depcomp 20 | config.sub 21 | config.guess 22 | build*/ 23 | *~ 24 | *.o 25 | *.a 26 | *.lo 27 | *.la 28 | .directory 29 | 30 | -------------------------------------------------------------------------------- /gcell/Makefile.am: -------------------------------------------------------------------------------- 1 | # Directory of ipfft.h 2 | AM_CPPFLAGS = -I$(top_srcdir)/kernel 3 | 4 | # Directory of pfft.h 5 | AM_CPPFLAGS += -I$(top_srcdir)/api 6 | 7 | # Directory of util.h 8 | AM_CPPFLAGS += -I$(top_srcdir)/util 9 | 10 | noinst_LTLIBRARIES = libgcell.la 11 | 12 | # Group local sources into convenience lib. 13 | libgcell_la_SOURCES = \ 14 | gcells_plan.c \ 15 | gcells_RMA.c \ 16 | gcells_sendrecv.c \ 17 | gctimer.c 18 | -------------------------------------------------------------------------------- /scripts/make_release_gcc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # change version numbers before new release 4 | OLD_FFTW_VERSION=3.3.2 5 | NEW_FFTW_VERSION=3.3.3 6 | 7 | OLD_PFFT_VERSION=1.0.5-alpha 8 | NEW_PFFT_VERSION=1.0.6-alpha 9 | 10 | sed -i "s/\(^FFTW_VERSION=\)$OLD_FFTW_VERSION/\1$NEW_FFTW_VERSION/" *.sh 11 | sed -i "s/\(^PFFT_VERSION=\)$OLD_PFFT_VERSION/\1$NEW_PFFT_VERSION/" *.sh 12 | 13 | export BUILD_RELEASE_CALLED_FROM_MAKE_RELEASE="yes" 14 | sh build_release_gcc.sh 15 | 16 | -------------------------------------------------------------------------------- /kernel/Makefile.am: -------------------------------------------------------------------------------- 1 | # Directory of ipfft.h 2 | AM_CPPFLAGS = -I$(top_srcdir)/kernel 3 | 4 | # Directory of pfft.h 5 | AM_CPPFLAGS += -I$(top_srcdir)/api 6 | 7 | # Directory of util.h 8 | AM_CPPFLAGS += -I$(top_srcdir)/util 9 | 10 | noinst_LTLIBRARIES = libkernel.la 11 | 12 | # Group local sources into convenience lib. 13 | libkernel_la_SOURCES = \ 14 | block.c \ 15 | check.c \ 16 | ipfft.h \ 17 | malloc.c \ 18 | ousample.c \ 19 | outrafo.c \ 20 | partrafo-transposed.c \ 21 | partrafo.c \ 22 | sertrafo.c \ 23 | procmesh.c \ 24 | remap_3dto2d.c \ 25 | timer.c \ 26 | transpose.c 27 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | 2 | PFFT 1.0.6-alpha 3 | 4 | * Update documentation. 5 | 6 | 7 | PFFT 1.0.5-alpha 8 | 9 | * Added more natural modulation of pruned FFT. 10 | * Added support of single and long double precision. 11 | 12 | 13 | PFFT 1.0.4-alpha 14 | 15 | * Added support of arbitrary multi-dimensional process meshs. 16 | * Added r2c, c2r, r2r FFTs. 17 | 18 | 19 | PFFT 1.0.3-alpha 20 | 21 | * Added configure script. 22 | 23 | 24 | PFFT 1.0.2-alpha 25 | 26 | * Added new interface for arbitrary multi-dimensional parallel FFT. 27 | * Added Fortran interface. 28 | 29 | 30 | PFFT 1.0.1-alpha 31 | 32 | * First release of PFFT. 33 | -------------------------------------------------------------------------------- /tests/openmp/Makefile.am: -------------------------------------------------------------------------------- 1 | # Directory of ipfft.h 2 | AM_CPPFLAGS = -I$(top_srcdir)/kernel 3 | 4 | # Directory of pfft.h 5 | AM_CPPFLAGS += -I$(top_srcdir)/api 6 | 7 | # OpenMP support 8 | AM_CFLAGS = $(OPENMP_CFLAGS) 9 | 10 | # Libraries to add to all programs that are built. 11 | LDADD = $(top_builddir)/lib@PFFT_PREFIX@pfft@PREC_SUFFIX@_omp.la $(fftw3_openmp_LIBS) $(fftw3_mpi_LIBS) $(fftw3_LIBS) 12 | 13 | # These programs are built by 'make check' and may be tested afterwards. 14 | check_PROGRAMS = \ 15 | simple_check_c2c simple_check_c2c_transposed\ 16 | simple_check_c2c_omp omp_bench_c2c\ 17 | transpose_check_fftw 18 | -------------------------------------------------------------------------------- /m4/ax_check_dir.m4: -------------------------------------------------------------------------------- 1 | dnl @synopsis AX_CHECK_DIR(DIR, [ACTION-SUCCESS], [ACTION-FAILURE]) 2 | dnl @summary check for directory DIR 3 | dnl @category Misc 4 | dnl 5 | dnl Check whether the directory DIR exists. 6 | dnl 7 | dnl ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on 8 | dnl success/failure. 9 | dnl 10 | dnl @version 2008-12-07 11 | dnl @license GPLWithACException 12 | dnl @author Jens Keiner . 13 | AC_DEFUN([AX_CHECK_DIR], 14 | [ 15 | AC_MSG_CHECKING([whether directory $1 exists]) 16 | if test -d "$1"; then 17 | AC_MSG_RESULT(yes) 18 | m4_default([$2], :) 19 | else 20 | AC_MSG_RESULT(no) 21 | m4_default([$3], :) 22 | fi 23 | ])dnl AX_CHECK_DIR 24 | -------------------------------------------------------------------------------- /scripts/install_pfft_chic.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | myprefix=$HOME/local 4 | PFFT_VERSION=1.0.6-alpha 5 | FFTW_VERSION=3.3.3 6 | INSTDIR=$myprefix/pfft-$PFFT_VERSION 7 | FFTWDIR=$myprefix/fftw-$FFTW_VERSION 8 | TMP="tmp-pfft-$PFFT_VERSION" 9 | 10 | # bash check if directory exists 11 | if [ -d $TMP ]; then 12 | echo "Directory $TMP already exists. Delete it? (y/n)" 13 | read answer 14 | if [ ${answer} = "y" ]; then 15 | rm -rf $TMP 16 | else 17 | echo "Program aborted." 18 | exit 1 19 | fi 20 | fi 21 | 22 | mkdir $TMP && cd $TMP 23 | cd ../.. && ./bootstrap.sh && cd - 24 | ../../configure --prefix=$INSTDIR --with-fftw3=$FFTWDIR --disable-shared 25 | 26 | make -j 4 27 | make install 28 | -------------------------------------------------------------------------------- /scripts/install_pfft_gcc_debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | myprefix=$HOME/local 4 | PFFT_VERSION=1.0.6-alpha 5 | FFTW_VERSION=3.3.3 6 | INSTDIR=$myprefix/pfft-$PFFT_VERSION-debug 7 | FFTWDIR=$myprefix/fftw-$FFTW_VERSION-debug 8 | TMP="tmp-pfft-$PFFT_VERSION-debug" 9 | 10 | # bash check if directory exists 11 | if [ -d $TMP ]; then 12 | echo "Directory $TMP already exists. Delete it? (y/n)" 13 | read answer 14 | if [ ${answer} = "y" ]; then 15 | rm -rf $TMP 16 | else 17 | echo "Program aborted." 18 | exit 1 19 | fi 20 | fi 21 | 22 | mkdir $TMP && cd $TMP 23 | cd ../.. && ./bootstrap.sh && cd - 24 | ../../configure --prefix=$INSTDIR --with-fftw3=$FFTWDIR --enable-debug --disable-shared 25 | 26 | make -j 4 27 | make install 28 | 29 | -------------------------------------------------------------------------------- /scripts/install_pfft_chic_debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | myprefix=$HOME/local 4 | PFFT_VERSION=1.0.6-alpha 5 | FFTW_VERSION=3.3.3 6 | INSTDIR=$myprefix/pfft-$PFFT_VERSION-debug 7 | FFTWDIR=$myprefix/fftw-$FFTW_VERSION-debug 8 | TMP="tmp-pfft-$PFFT_VERSION-debug" 9 | 10 | # bash check if directory exists 11 | if [ -d $TMP ]; then 12 | echo "Directory $TMP already exists. Delete it? (y/n)" 13 | read answer 14 | if [ ${answer} = "y" ]; then 15 | rm -rf $TMP 16 | else 17 | echo "Program aborted." 18 | exit 1 19 | fi 20 | fi 21 | 22 | mkdir $TMP && cd $TMP 23 | cd ../.. && ./bootstrap.sh && cd - 24 | ../../configure --prefix=$INSTDIR --with-fftw3=$FFTWDIR --enable-debug --disable-shared 25 | 26 | make -j 4 27 | make install 28 | 29 | -------------------------------------------------------------------------------- /scripts/install_pfft_intel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | myprefix=$HOME/local 4 | PFFT_VERSION=1.0.6-alpha 5 | FFTW_VERSION=3.3.3 6 | INSTDIR=$myprefix/pfft-$PFFT_VERSION 7 | FFTWDIR=$myprefix/fftw-$FFTW_VERSION 8 | TMP="tmp-pfft-$PFFT_VERSION" 9 | 10 | # bash check if directory exists 11 | if [ -d $TMP ]; then 12 | echo "Directory $TMP exists. Cleanup before new build." 13 | exit 1 14 | fi 15 | 16 | mkdir $TMP && cd $TMP 17 | cd ../.. && ./bootstrap.sh && cd - 18 | ../../configure --prefix=$INSTDIR --with-fftw3=$FFTWDIR --disable-shared FC=mpif90 CC=mpicc MPICC=mpicc MPIFC=mpif90 19 | 20 | make -j 4 21 | make install 22 | # make check 23 | # ./configure --prefix=$INSTDIR --with-fftw3=$FFTWDIR FC="mpif90 -f90=gfortran" CC="mpicc -cc=gcc"&& make && make check && make install 24 | -------------------------------------------------------------------------------- /conf/travis-install-mpi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # this conf file is taken from the mpi4py project 3 | # http://mpi4py.scipy.org/ 4 | set -e 5 | case $1 in 6 | mpich1) set -x; 7 | sudo apt-get install -q gfortran mpich-shmem-bin libmpich-shmem1.0-dev;; 8 | mpich2) set -x; 9 | sudo apt-get install -q gfortran mpich2 libmpich2-3 libmpich2-dev;; 10 | mpich3) set -x; 11 | sudo apt-get install -q gfortran libcr0 default-jdk; 12 | wget -q http://www.cebacad.net/files/mpich/ubuntu/mpich-3.1/mpich_3.1-1ubuntu_amd64.deb; 13 | sudo dpkg -i ./mpich_3.1-1ubuntu_amd64.deb; 14 | rm -f ./mpich_3.1-1ubuntu_amd64.deb;; 15 | openmpi) set -x; 16 | sudo apt-get install -q gfortran openmpi-bin openmpi-common libopenmpi-dev;; 17 | *) 18 | echo "Unknown MPI implementation:" $1; exit 1;; 19 | esac 20 | -------------------------------------------------------------------------------- /scripts/install_pfft_intel_debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | myprefix=$HOME/local 4 | PFFT_VERSION=1.0.6-alpha 5 | FFTW_VERSION=3.3.3 6 | INSTDIR=$myprefix/pfft-$PFFT_VERSION-debug 7 | FFTWDIR=$myprefix/fftw-$FFTW_VERSION-debug 8 | TMP="tmp-pfft-$PFFT_VERSION-debug" 9 | 10 | # bash check if directory exists 11 | if [ -d $TMP ]; then 12 | echo "Directory $TMP exists. Cleanup before new build." 13 | exit 1 14 | fi 15 | 16 | mkdir $TMP && cd $TMP 17 | cd ../.. && ./bootstrap.sh && cd - 18 | ../../configure --prefix=$INSTDIR --with-fftw3=$FFTWDIR --disable-shared --enable-debug FC=mpif90 CC=mpicc MPICC=mpicc MPIFC=mpif90 19 | 20 | make -j 4 21 | make install 22 | #make check 23 | # ./configure --prefix=$INSTDIR --with-fftw3=$FFTWDIR FC="mpif90 -f90=gfortran" CC="mpicc -cc=gcc"&& make && make check && make install 24 | -------------------------------------------------------------------------------- /kernel/check.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 Michael Pippig 3 | * 4 | * This file is part of PFFT. 5 | * 6 | * PFFT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * PFFT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with PFFT. If not, see . 18 | * 19 | */ 20 | 21 | #include "pfft.h" 22 | #include "ipfft.h" 23 | 24 | 25 | -------------------------------------------------------------------------------- /scripts/install_pfft_bgq.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | myprefix=$HOME/local 4 | PFFT_VERSION=1.0.6-alpha 5 | FFTW_VERSION=3.3.3 6 | INSTDIR=$myprefix/pfft-$PFFT_VERSION 7 | FFTWDIR=$myprefix/fftw-$FFTW_VERSION 8 | TMP="tmp-pfft-$PFFT_VERSION" 9 | 10 | # bash check if directory exists 11 | if [ -d $TMP ]; then 12 | echo "Directory $TMP already exists. Delete it? (y/n)" 13 | read answer 14 | if [ ${answer} = "y" ]; then 15 | rm -rf $TMP 16 | else 17 | echo "Program aborted." 18 | exit 1 19 | fi 20 | fi 21 | 22 | mkdir $TMP && cd $TMP 23 | cd ../../ && ./bootstrap.sh && cd - 24 | 25 | ../../configure --build=powerpc64-bgq-linux-gnu --host=powerpc64-bgq-linux \ 26 | --prefix=$INSTDIR --with-fftw3=$FFTWDIR --disable-shared \ 27 | MPICC=mpixlc_r MPICXX=mpixlcxx_r MPIFC=mpixlf90_r \ 28 | CFLAGS='-O3 -g -qmaxmem=-1' \ 29 | FCFLAGS='-O3 -g -qmaxmem=-1' 30 | 31 | make -j 4 32 | make install 33 | 34 | -------------------------------------------------------------------------------- /scripts/install_pfft_bgp_debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | myprefix=$HOME/local 4 | PFFT_VERSION=1.0.6-alpha 5 | FFTW_VERSION=3.3.3 6 | INSTDIR=$myprefix/pfft-$PFFT_VERSION-debug 7 | FFTWDIR=$myprefix/fftw-$FFTW_VERSION-debug 8 | TMP="tmp-pfft-$PFFT_VERSION-debug" 9 | 10 | # bash check if directory exists 11 | if [ -d $TMP ]; then 12 | echo "Directory $TMP already exists. Delete it? (y/n)" 13 | read answer 14 | if [ ${answer} = "y" ]; then 15 | rm -rf $TMP 16 | else 17 | echo "Program aborted." 18 | exit 1 19 | fi 20 | fi 21 | 22 | mkdir $TMP && cd $TMP 23 | cd ../../ && ./bootstrap.sh && cd - 24 | 25 | ../../configure --build=powerpc64-bgp-linux-gnu --host=powerpc-ibm-cnk \ 26 | --prefix=$INSTDIR --with-fftw3=$FFTWDIR --enable-debug --disable-shared \ 27 | MPICC=mpixlc_r MPIFC=mpixlf90_r MPICXX=mpixlcxx_r \ 28 | CFLAGS='-O0 -g -qfullpath -qdbxextra -qcheck' FCFLAGS='-O0 -g -qfullpath' 29 | 30 | make -j 4 31 | make install 32 | 33 | -------------------------------------------------------------------------------- /scripts/install_pfft_bgq_debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | myprefix=$HOME/local 4 | PFFT_VERSION=1.0.6-alpha 5 | FFTW_VERSION=3.3.3 6 | INSTDIR=$myprefix/pfft-$PFFT_VERSION-debug 7 | FFTWDIR=$myprefix/fftw-$FFTW_VERSION-debug 8 | TMP="tmp-pfft-$PFFT_VERSION-debug" 9 | 10 | # bash check if directory exists 11 | if [ -d $TMP ]; then 12 | echo "Directory $TMP already exists. Delete it? (y/n)" 13 | read answer 14 | if [ ${answer} = "y" ]; then 15 | rm -rf $TMP 16 | else 17 | echo "Program aborted." 18 | exit 1 19 | fi 20 | fi 21 | 22 | mkdir $TMP && cd $TMP 23 | cd ../../ && ./bootstrap.sh && cd - 24 | 25 | ../../configure --build=powerpc64-bgq-linux-gnu --host=powerpc64-bgq-linux \ 26 | --prefix=$INSTDIR --with-fftw3=$FFTWDIR --enable-debug --disable-shared \ 27 | MPICC=mpixlc_r MPIFC=mpixlf90_r MPICXX=mpixlcxx_r \ 28 | CFLAGS='-O0 -g -qfullpath -qdbxextra -qcheck' \ 29 | FCFLAGS='-O0 -g -qfullpath' 30 | 31 | make -j 4 32 | make install 33 | 34 | -------------------------------------------------------------------------------- /api/Makefile.am: -------------------------------------------------------------------------------- 1 | # Directory of ipfft.h 2 | AM_CPPFLAGS = -I$(top_srcdir)/kernel 3 | 4 | # Directory of util.h 5 | AM_CPPFLAGS += -I$(top_srcdir)/util 6 | 7 | # OpenMP support 8 | AM_CFLAGS = $(OPENMP_CFLAGS) 9 | AM_CPPFLAGS += $(OPENMP_CFLAGS) 10 | 11 | # Headers that are installed. 12 | if ENABLE_HEADER_INSTALL 13 | include_HEADERS = pfft.h 14 | # provide separate header for long precision, since some compilers do not support it 15 | nodist_include_HEADERS = pfft.f pfft.f03 pfftl.f03 16 | else 17 | noinst_HEADERS = pfft.h 18 | endif 19 | 20 | noinst_LTLIBRARIES = libapi.la 21 | 22 | EXTRA_DIST = f03-api.sh f03-wrap.sh genf03-api.pl genf03-wrap.pl build-f03-api.sh 23 | 24 | # Group local sources into convenience lib. 25 | libapi_la_SOURCES = \ 26 | api-basic.c \ 27 | api-adv.c \ 28 | pfft.f.in \ 29 | fortran-api.c \ 30 | fortran-mangling.h \ 31 | fortran-prototypes.h \ 32 | fortran-wrappers.h \ 33 | pfft.f03.in \ 34 | pfftl.f03.in \ 35 | f03-wrap.c 36 | 37 | -------------------------------------------------------------------------------- /fconfig.h.in: -------------------------------------------------------------------------------- 1 | ! fconfig.h.in. Written manually, not generated. 2 | ! This contains only defines needed for Fortran. 3 | 4 | ! The size of `int *', as computed by sizeof. 5 | #undef SIZEOF_INT_P 6 | 7 | ! Fortran type that matches a C pointer. 8 | #define FCS_PTR integer*SIZEOF_INT_P 9 | 10 | ! Define to the MPI datatype that corresponds to the floating type to use for 11 | ! FCS. 12 | #undef FCS_MPI_REAL 13 | 14 | ! Define to the MPI datatype that corresponds to the integer type to use for 15 | ! FCS. 16 | #undef FCS_MPI_INTEGER 17 | 18 | ! Define to the Fortran floating type to use for FCS. 19 | #undef fcs_real 20 | 21 | ! Define to the Fortran integer type to use for FCS. 22 | #undef fcs_integer 23 | 24 | ! Define to the kind of fcs_real. 25 | #undef fcs_real_kind 26 | 27 | ! Define to the kind of fcs_integer. 28 | #undef fcs_integer_kind 29 | 30 | ! Define if info output is enabled. 31 | #undef FCS_ENABLE_INFO 32 | 33 | ! Define if debug output is enabled. 34 | #undef FCS_ENABLE_DEBUG 35 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | compiler: gcc 3 | os: linux 4 | 5 | addons: 6 | apt: 7 | packages: 8 | - gfortran 9 | - openmpi-bin 10 | - openmpi-common 11 | - libopenmpi-dev 12 | 13 | before_install: 14 | # unset $CC compiler variable since it is known to interfere with the MPI compiler 15 | # see https://docs.travis-ci.com/user/languages/c#MPI-projects 16 | - test -n $CC && unset CC 17 | 18 | install: 19 | - sh ./conf/travis-install-fftw.sh 20 | 21 | script: ./bootstrap.sh && ./configure CPPFLAGS="-I$HOME/local/fftw-3.3.4/include" LDFLAGS="-L$HOME/local/fftw-3.3.4/lib" FC=mpif90 CC=mpicc MPICC=mpicc MPIFC=mpif90 && make && make check 22 | 23 | ## Print config.log for debugging. 24 | after_failure: "cat config.log" 25 | 26 | ## Turn on email notifications. 27 | notifications: 28 | email: 29 | recipients: 30 | - michael.pippig.tuc@gmail.com 31 | on_success: change # choose between: always, change, never 32 | on_failure: always # choose between: always, change, never 33 | 34 | -------------------------------------------------------------------------------- /scripts/build_release_gcc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | if [ "x$BUILD_RELEASE_CALLED_FROM_MAKE_RELEASE" != "xyes" ]; then 4 | echo "!!! Error: This is a helper script that should not be called individually. Use the corresponding make_release script instead! !!!" 5 | exit 6 | fi 7 | 8 | myprefix=$HOME/local 9 | PFFT_VERSION=1.0.6-alpha 10 | # PFFT_VERSION=`grep AC_INIT ../configure.ac | grep -oE "\[([1-9]+[0-9\.]*\-?[a-zA-Z]*)\]" | sed "s/\[\(.*\)\]/\1/"` 11 | FFTW_VERSION=3.3.3 12 | INSTDIR=$myprefix/pfft-$PFFT_VERSION 13 | FFTWDIR=$myprefix/fftw-$FFTW_VERSION 14 | TMP="tmp-pfft-$PFFT_VERSION" 15 | 16 | # bash check if directory exists 17 | if [ -d $TMP ]; then 18 | echo "Directory $TMP already exists. Delete it? (y/n)" 19 | read answer 20 | if [ ${answer} = "y" ]; then 21 | rm -rf $TMP 22 | else 23 | echo "Program aborted." 24 | exit 1 25 | fi 26 | fi 27 | 28 | mkdir $TMP && cd $TMP 29 | cd ../.. && ./bootstrap.sh && cd - 30 | ../../configure --prefix=$INSTDIR --with-fftw3=$FFTWDIR --disable-shared 31 | 32 | make -j 4 distcheck 33 | 34 | -------------------------------------------------------------------------------- /scripts/install_pfft_bgp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | myprefix=$HOME/local 4 | PFFT_VERSION=1.0.6-alpha 5 | FFTW_VERSION=3.3.3 6 | INSTDIR=$myprefix/pfft-$PFFT_VERSION 7 | FFTWDIR=$myprefix/fftw-$FFTW_VERSION 8 | TMP="tmp-pfft-$PFFT_VERSION" 9 | 10 | # bash check if directory exists 11 | if [ -d $TMP ]; then 12 | echo "Directory $TMP already exists. Delete it? (y/n)" 13 | read answer 14 | if [ ${answer} = "y" ]; then 15 | rm -rf $TMP 16 | else 17 | echo "Program aborted." 18 | exit 1 19 | fi 20 | fi 21 | 22 | mkdir $TMP && cd $TMP 23 | cd ../../ && ./bootstrap.sh && cd - 24 | 25 | ../../configure --build=powerpc64-bgp-linux-gnu --host=powerpc-ibm-cnk \ 26 | --prefix=$INSTDIR --with-fftw3=$FFTWDIR --disable-shared \ 27 | MPICC=mpixlc_r MPICXX=mpixlcxx_r MPIFC=mpixlf90_r \ 28 | CPPFLAGS='-I/bgsys/drivers/ppcfloor/comm/include -I/bgsys/drivers/ppcfloor/arch/include' \ 29 | CFLAGS='-O3 -g -qmaxmem=-1 -qarch=450 -qtune=450' \ 30 | FCFLAGS='-O3 -g -qmaxmem=-1 -I/bgsys/drivers/ppcfloor/include -qarch=450 -qtune=450' \ 31 | LDFLAGS='-L/bgsys/drivers/ppcfloor/lib' 32 | 33 | make -j 4 34 | make install 35 | 36 | -------------------------------------------------------------------------------- /m4/ax_fcs_direct.m4: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2011 The ScaFaCoS project 2 | # 3 | # This file is part of ScaFaCoS. 4 | # 5 | # ScaFaCoS is free software: you can redistribute it and/or modify it 6 | # under the terms of the GNU Lesser Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # ScaFaCoS is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | AC_DEFUN_ONCE([AX_FCS_DIRECT_ARGS],[ 20 | 21 | ]) 22 | 23 | 24 | AC_DEFUN([AX_FCS_DIRECT_TOP],[ 25 | 26 | AX_FCS_DIRECT_ARGS 27 | 28 | #if $1 ; then 29 | # AC_MSG_NOTICE([do direct solver stuff in top-level configure]) 30 | #fi 31 | 32 | ]) 33 | 34 | 35 | AC_DEFUN([AX_FCS_DIRECT_SOLVER],[ 36 | 37 | AX_FCS_DIRECT_ARGS 38 | 39 | ]) 40 | -------------------------------------------------------------------------------- /tests/f03/Makefile.am: -------------------------------------------------------------------------------- 1 | # Get Fortran compile rules that include preprocessing. 2 | include $(top_srcdir)/build-aux/fortran-rules.am 3 | 4 | # Directory of pnfft.f (which is build first) 5 | AM_FCCPPFLAGS = -I$(top_builddir)/api 6 | 7 | # OpenMP support 8 | AM_FCFLAGS = $(OPENMP_FCFLAGS) 9 | 10 | # Libraries to add to all programs that are built. 11 | LDADD = $(top_builddir)/lib@PFFT_PREFIX@pfft@PREC_SUFFIX@@OPENMP_SUFFIX@.la $(fftw3_openmp_LIBS) $(fftw3_mpi_LIBS) $(fftw3_LIBS) 12 | 13 | # noinst_LTLIBRARIES = libtests.la 14 | 15 | # search for Fortran source files to build objects 16 | AM_DEFAULT_SOURCE_EXT = .F03 17 | 18 | check_PROGRAMS = 19 | 20 | # These programs are built by 'make check' and may be tested afterwards. 21 | #if ENABLE_COMMON_PNFFT 22 | # do not compile checks 23 | #else 24 | check_PROGRAMS += \ 25 | simple_check_c2c \ 26 | simple_check_c2c_transposed \ 27 | simple_check_r2c_4d_on_3d \ 28 | simple_check_r2c_4d_on_3d_transposed \ 29 | simple_check_ousam_c2c_4d_on_3d \ 30 | simple_check_ousam_c2c_4d_on_3d_transposed \ 31 | simple_check_ousam_r2c_4d_on_3d \ 32 | simple_check_ousam_r2c_4d_on_3d_transposed \ 33 | time_c2c \ 34 | time_c2c_transposed 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /tests/fortran/Makefile.am: -------------------------------------------------------------------------------- 1 | # Get Fortran compile rules that include preprocessing. 2 | include $(top_srcdir)/build-aux/fortran-rules.am 3 | 4 | # Directory of pfft.f (which is build first) 5 | AM_FCCPPFLAGS = -I$(top_builddir)/api 6 | 7 | # OpenMP support 8 | AM_FCFLAGS = $(OPENMP_FCFLAGS) 9 | 10 | # Libraries to add to all programs that are built. 11 | LDADD = $(top_builddir)/lib@PFFT_PREFIX@pfft@PREC_SUFFIX@@OPENMP_SUFFIX@.la $(fftw3_openmp_LIBS) $(fftw3_mpi_LIBS) $(fftw3_LIBS) 12 | 13 | # noinst_LTLIBRARIES = libtests.la 14 | 15 | # search for Fortran source files to build objects 16 | AM_DEFAULT_SOURCE_EXT = .F90 17 | 18 | # These programs are built by 'make check' and may be tested afterwards. 19 | check_PROGRAMS = \ 20 | simple_test 21 | 22 | #if ENABLE_COMMON_PFFT 23 | # do not compile checks 24 | #else 25 | check_PROGRAMS += \ 26 | simple_check_c2c simple_check_c2c_transposed \ 27 | simple_check_r2c simple_check_r2c_transposed \ 28 | simple_check_r2r simple_check_r2r_transposed 29 | 30 | check_PROGRAMS += \ 31 | simple_check_r2c_3d_on_3d simple_check_r2c_3d_on_3d_transposed 32 | 33 | check_PROGRAMS += \ 34 | simple_check_ghost_c2c simple_check_ghost_c2c_3d_on_3d 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /api/f03-wrap.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Script to generate Fortran 2003 wrappers for PFFT's MPI functions. This 4 | # is necessary because MPI provides no way to deal with C MPI_Comm handles 5 | # from Fortran (where MPI_Comm == integer), but does provide a way to 6 | # deal with Fortran MPI_Comm handles from C (via MPI_Comm_f2c). So, 7 | # every PFFT function that takes an MPI_Comm argument needs a wrapper 8 | # function that takes a Fortran integer and converts it to MPI_Comm. 9 | 10 | # Use this script in the following way: 11 | # ./f03-wrap.sh > f03-wrap.c 12 | 13 | # pfft.h depends on fftw3-mpi.h and fftw3.h 14 | # set these paths such that the preprocessor can find the required headers 15 | FFTW_INC=$HOME/local/fftw-3.3.3/include 16 | 17 | echo "/* Generated automatically. DO NOT EDIT! */" 18 | echo 19 | 20 | echo "#include \"pfft.h\"" 21 | echo "#include \"ipfft.h\"" 22 | echo 23 | 24 | # Declare prototypes using FFTW_EXTERN, important for Windows DLLs 25 | mpicc -E pfft.h -I${FFTW_INC} |grep 'pfftl_init' |tr ';' '\n' |grep 'MPI_Comm' |grep -v 'printf' |perl genf03-wrap.pl |grep "MPI_Fint" |sed 's/^/PFFT_EXTERN /;s/$/;/' 26 | mpicc -E pfft.h -I${FFTW_INC} |grep 'pfftl_init' |tr ';' '\n' |grep 'MPI_Comm' |grep -v 'printf' |perl genf03-wrap.pl 27 | 28 | -------------------------------------------------------------------------------- /doc/latexinc.sh.in: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2011 The ScaFaCoS project 2 | # 3 | # This file is part of ScaFaCoS. 4 | # 5 | # ScaFaCoS is free software: you can redistribute it and/or modify it 6 | # under the terms of the GNU Lesser Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # ScaFaCoS is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | # This file is included from latex-manual.sh and sets the default 20 | # paths for latexing the documentation. 21 | if test -z "$TEXINPUTS"; then 22 | TEXINPUTS=.:@abs_srcdir@: 23 | else 24 | TEXINPUTS=.:@abs_srcdir@:$TEXINPUTS: 25 | fi 26 | 27 | if test -z "$BIBINPUTS"; then 28 | BIBINPUTS=.:@abs_srcdir@: 29 | else 30 | BIBINPUTS=.:@abs_srcdir@:$BIBINPUTS: 31 | fi 32 | 33 | export TEXINPUTS BIBINPUTS 34 | 35 | PDFLATEX=@PDFLATEX@ 36 | BIBTEX=@BIBTEX@ 37 | MAKEINDEX=@MAKEINDEX@ 38 | -------------------------------------------------------------------------------- /m4/ax_gcc_version.m4: -------------------------------------------------------------------------------- 1 | dnl @synopsis AX_GCC_VERSION(MAJOR, MINOR, PATCHLEVEL, [ACTION-SUCCESS], [ACTION-FAILURE]) 2 | dnl @summary check wither gcc is at least version MAJOR.MINOR.PATCHLEVEL 3 | dnl @category InstalledPackages 4 | dnl 5 | dnl Check whether we are using gcc and, if so, whether its version 6 | dnl is at least MAJOR.MINOR.PATCHLEVEL 7 | dnl 8 | dnl ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on 9 | dnl success/failure. 10 | dnl 11 | dnl @version 2005-05-30 12 | dnl @license GPLWithACException 13 | dnl @author Steven G. Johnson and Matteo Frigo. 14 | AC_DEFUN([AX_GCC_VERSION], 15 | [ 16 | AC_REQUIRE([AC_PROG_CC]) 17 | AC_CACHE_CHECK(whether we are using gcc $1.$2.$3 or later, ax_cv_gcc_$1_$2_$3, 18 | [ 19 | ax_cv_gcc_$1_$2_$3=no 20 | if test "$GCC" = "yes"; then 21 | dnl The semicolon after "yes" below is to pacify NeXT's syntax-checking cpp. 22 | AC_EGREP_CPP(yes, [ 23 | #ifdef __GNUC__ 24 | # if (__GNUC__ > $1) || (__GNUC__ == $1 && __GNUC_MINOR__ > $2) \ 25 | || (__GNUC__ == $1 && __GNUC_MINOR__ == $2 && __GNUC_PATCHLEVEL__ >= $3) 26 | yes; 27 | # endif 28 | #endif 29 | ], [ax_cv_gcc_$1_$2_$3=yes]) 30 | fi 31 | ]) 32 | if test "$ax_cv_gcc_$1_$2_$3" = yes; then 33 | m4_default([$4], :) 34 | else 35 | m4_default([$5], :) 36 | fi 37 | ]) 38 | 39 | -------------------------------------------------------------------------------- /m4/ax_sort_lib.m4: -------------------------------------------------------------------------------- 1 | 2 | AC_DEFUN([AX_SORT_LIB],[ 3 | 4 | # Get the MPI C compiler. 5 | AC_REQUIRE([AX_PROG_CC_MPI],[AX_PROG_CC_MPI(,,AC_MSG_FAILURE([The Sorting Library requires an MPI C compiler.]))]) 6 | 7 | # Try to put the C compiler in C99 mode (this macro is relatively new in Autoconf). 8 | #m4_ifdef([AC_PROG_CC_C99], 9 | # [AC_REQUIRE([AC_PROG_CC_C99])]) 10 | 11 | # Redefine "inline" if the C compiler has problems with it. 12 | AC_REQUIRE([AC_C_INLINE]) 13 | 14 | # We need the math library. 15 | AC_SEARCH_LIBS([log], [m]) 16 | 17 | # Blue Gene specific checks 18 | AC_CHECK_HEADERS([spi/kernel_interface.h common/bgp_personality.h common/bgp_personality_inlines.h], 19 | [], [], 20 | [[#ifdef HAVE_SPI_KERNEL_INTERFACES_H 21 | # include 22 | #endif 23 | #ifdef HAVE_COMMON_BGP_PERSONALITY_H 24 | # include 25 | #endif]]) 26 | 27 | AC_CHECK_TYPES([_BGP_Personality_t], 28 | [], [], 29 | [AC_INCLUDES_DEFAULT 30 | [#ifdef HAVE_SPI_KERNEL_INTERFACES_H 31 | # include 32 | #endif 33 | #ifdef HAVE_COMMON_BGP_PERSONALITY_H 34 | # include 35 | #endif 36 | #ifdef HAVE_COMMON_BGP_PERSONALITY_INLINES_H 37 | # include 38 | #endif]]) 39 | 40 | ]) 41 | -------------------------------------------------------------------------------- /m4/ac_fc_module_extension.m4: -------------------------------------------------------------------------------- 1 | # This macro has been submitted for inclusion into the Autoconf 2.69 tree. 2 | # Use the upstream version when it is defined. 3 | m4_version_prereq([2.69], [], 4 | [ 5 | 6 | # AC_FC_MODULE_EXTENSION 7 | # ---------------------- 8 | # Find the Fortran 90 module file extension. The module extension is stored 9 | # in the variable FC_MODEXT and empty if it cannot be determined. The result 10 | # or "unknown" is cached in the cache variable ac_cv_fc_module_ext. 11 | AC_DEFUN([AC_FC_MODULE_EXTENSION], 12 | [AC_CACHE_CHECK([Fortran 90 module extension], [ac_cv_fc_module_ext], 13 | [AC_LANG_PUSH(Fortran) 14 | mkdir conftest.dir 15 | cd conftest.dir 16 | ac_cv_fc_module_ext=unknown 17 | AC_COMPILE_IFELSE([[ 18 | module conftest_module 19 | contains 20 | subroutine conftest_routine 21 | write(*,'(a)') 'gotcha!' 22 | end subroutine 23 | end module]], 24 | [ac_cv_fc_module_ext=`ls | sed -n 's,conftest_module\.,,p'` 25 | if test x$ac_cv_fc_module_ext = x; then 26 | dnl Some F90 compilers use upper case characters for the module file name. 27 | ac_cv_fc_module_ext=`ls | sed -n 's,CONFTEST_MODULE\.,,p'` 28 | fi]) 29 | cd .. 30 | rm -rf conftest.dir 31 | AC_LANG_POP(Fortran) 32 | ]) 33 | FC_MODEXT=$ac_cv_fc_module_ext 34 | if test "$FC_MODEXT" = unknown; then 35 | FC_MODEXT= 36 | fi 37 | AC_SUBST([FC_MODEXT])dnl 38 | ]) 39 | 40 | ])dnl m4_version_prereq([2.69]) 41 | -------------------------------------------------------------------------------- /doc/man_fftw_3don1d.tex: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) 4 | { 5 | const ptrdiff_t n0 = 4, n1 = 4, n2 = 4; 6 | fftw_plan plan; 7 | fftw_complex *data; 8 | ptrdiff_t alloc_local, local_n0, local_0_start, i, j, k; 9 | 10 | MPI_Init(&argc, &argv); 11 | fftw_mpi_init(); 12 | 13 | /* get local data size and allocate */ 14 | alloc_local = fftw_mpi_local_size_3d(n0, n1, n2, MPI_COMM_WORLD, 15 | &local_n0, &local_0_start); 16 | data = fftw_alloc_complex(alloc_local); 17 | 18 | /* create plan for in-place forward DFT */ 19 | plan = fftw_mpi_plan_dft_3d(n0, n1, n2, data, data, MPI_COMM_WORLD, 20 | FFTW_FORWARD, FFTW_ESTIMATE); 21 | 22 | /* initialize data to some function my_function(x,y) */ 23 | for (i = 0; i < local_n0; ++i) 24 | for (j = 0; j < n1; ++j) 25 | for (k = 0; k < n2; ++k) 26 | data[i*n1*n2 + j*n2 + k] = my_function(local_0_start + i, j, k); 27 | 28 | ptrdiff_t local_ni[3] = {local_n0, n1, n2}, local_i_start[3] = {local_0_start, 0, 0}; 29 | pfft_apr_complex_3d(data, local_ni, local_i_start, "input:", MPI_COMM_WORLD); 30 | 31 | /* compute transforms, in-place, as many times as desired */ 32 | fftw_execute(plan); 33 | 34 | ptrdiff_t local_no[3] = {local_n0, n1, n2}, local_o_start[3] = {local_0_start, 0, 0}; 35 | pfft_apr_complex_3d(data, local_no, local_o_start, "output:", MPI_COMM_WORLD); 36 | 37 | (*@\color{red} 38 | fftw\_destroy\_plan(plan); 39 | @*) 40 | 41 | MPI_Finalize(); 42 | } 43 | -------------------------------------------------------------------------------- /kernel/malloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003, 2007-8 Matteo Frigo 3 | * Copyright (c) 2003, 2007-8 Massachusetts Institute of Technology 4 | * Copyright (c) 2002, 2009 Jens Keiner, Stefan Kunis, Daniel Potts 5 | * Copyright (c) 2010-2013 Michael Pippig 6 | * 7 | * This file is part of PFFT. 8 | * 9 | * PFFT is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * PFFT is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with PFFT. If not, see . 21 | * 22 | */ 23 | 24 | #include "pfft.h" 25 | #include "ipfft.h" 26 | 27 | 28 | void *PX(malloc)(size_t n){ 29 | return X(malloc)(n); 30 | } 31 | 32 | R *PX(alloc_real)(size_t n){ 33 | return X(alloc_real)(n); 34 | } 35 | 36 | C *PX(alloc_complex)(size_t n){ 37 | return X(alloc_complex)(n); 38 | } 39 | 40 | void PX(free)(void *p){ 41 | X(free)(p); 42 | } 43 | 44 | 45 | void PX(die)( 46 | const char *s, MPI_Comm comm 47 | ) 48 | { 49 | fflush(stdout); 50 | PX(fprintf)(comm, stderr, s); 51 | PX(cleanup)(); 52 | MPI_Finalize(); 53 | exit(EXIT_FAILURE); 54 | } 55 | -------------------------------------------------------------------------------- /m4/ax_diff_library_ldflags.m4: -------------------------------------------------------------------------------- 1 | 2 | AC_DEFUN([AX_DIFF_LIBRARY_LDFLAGS_CXX],[ 3 | AX_CC_LIBRARY_LDFLAGS 4 | AX_CXX_LIBRARY_LDFLAGS 5 | AC_CACHE_CHECK([difference between LDFLAGS of C++ and C.],ax_cv_diff_library_ldflags_cxx,[ 6 | ax_clibs=$CLIBS 7 | ax_cxxlibs=" $CXXLIBS " 8 | #echo "ax_clibs: $ax_clibs" 9 | #echo "ax_cxxlibs: $ax_cxxlibs" 10 | for ax_l in ${ax_clibs} ; do 11 | ax_cxxlibs=`echo "${ax_cxxlibs}" | sed -e "s! ${ax_l} ! !g"` 12 | done 13 | ax_cv_diff_library_ldflags_cxx= 14 | for ax_x in ${ax_cxxlibs} ; do ax_cv_diff_library_ldflags_cxx="${ax_cv_diff_library_ldflags_cxx} ${ax_x}" ; done 15 | ax_cv_diff_library_ldflags_cxx="${ax_cv_diff_library_ldflags_cxx# }" 16 | ]) 17 | CXXLIBS_DIFF=${ax_cv_diff_library_ldflags_cxx} 18 | AC_SUBST([CXXLIBS_DIFF]) 19 | ]) 20 | 21 | 22 | AC_DEFUN([AX_DIFF_LIBRARY_LDFLAGS_FC],[ 23 | AX_CC_LIBRARY_LDFLAGS 24 | AC_FC_LIBRARY_LDFLAGS 25 | m4_ifdef([ACX_FC_LIBRARY_LDFLAGS_FIX],[ACX_FC_LIBRARY_LDFLAGS_FIX]) 26 | AC_CACHE_CHECK([difference between LDFLAGS of Fortran and C.],ax_cv_diff_library_ldflags_fc,[ 27 | ax_clibs=$CLIBS 28 | ax_fclibs=" $FCLIBS " 29 | #echo "ax_clibs: $ax_clibs" 30 | #echo "ax_fclibs: $ax_fclibs" 31 | for ax_l in ${ax_clibs} ; do 32 | ax_fclibs=`echo "${ax_fclibs}" | sed -e "s! ${ax_l} ! !g"` 33 | done 34 | ax_cv_diff_library_ldflags_fc= 35 | for ax_x in ${ax_fclibs} ; do ax_cv_diff_library_ldflags_fc="${ax_cv_diff_library_ldflags_fc} ${ax_x}" ; done 36 | ax_cv_diff_library_ldflags_fc="${ax_cv_diff_library_ldflags_fc# }" 37 | ]) 38 | FCLIBS_DIFF=${ax_cv_diff_library_ldflags_fc} 39 | AC_SUBST([FCLIBS_DIFF]) 40 | ]) 41 | -------------------------------------------------------------------------------- /m4/ax_fc_no_range_check.m4: -------------------------------------------------------------------------------- 1 | # AX_FC_NO_RANGE_CHECK([ACTION-IF-SUCCESS], [ACTION-IF-FAILURE]) 2 | # -------------------------------------------------------------- 3 | # Look for a compiler flag to make the Fortran (FC) disable range checking on 4 | # results of simplification of constant expressions during compilation, and 5 | # add it to FCFLAGS. 6 | # Call ACTION-IF-SUCCESS (defaults to nothing) if successful and 7 | # ACTION-IF-FAILURE (defaults to nothing) if not. 8 | # 9 | # The known flags are: 10 | # gfortran: -fno-range-check 11 | # HP: +check=truncate:none 12 | 13 | AC_DEFUN([AX_FC_NO_RANGE_CHECK], 14 | [AC_LANG_PUSH([Fortran])dnl 15 | AC_CACHE_CHECK( 16 | [for Fortran flag needed to turn off range checking], 17 | [ax_cv_fc_no_range_check], 18 | [ax_cv_fc_no_range_check=unknown 19 | ax_fc_no_range_check_FCFLAGS_save=$FCFLAGS 20 | for ax_flag in none -fno-range-check +check=truncate:none 21 | do 22 | test "x$ax_flag" != xnone && FCFLAGS="$ax_fc_no_range_check_FCFLAGS_save $ax_flag" 23 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ 24 | INTEGER (kind=4) :: i 25 | i = -2147483648]])], 26 | [ax_cv_fc_no_range_check=$ax_flag; break]) 27 | done 28 | rm -f conftest.err conftest.$ac_objext conftest.$ac_ext 29 | FCFLAGS=$ax_fc_no_range_check_FCFLAGS_save 30 | ]) 31 | if test "x$ax_cv_fc_no_range_check" = xunknown; then 32 | m4_default([$3], [:]) 33 | else 34 | if test "x$ax_cv_fc_no_range_check" != xnone; then 35 | FCFLAGS="$FCFLAGS $ax_cv_fc_no_range_check" 36 | fi 37 | $2 38 | fi 39 | AC_LANG_POP([Fortran])dnl 40 | ])# AX_FC_NO_RANGE_CHECK 41 | -------------------------------------------------------------------------------- /tests/manual_c2c_3d.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv){ 4 | int np[2]; 5 | ptrdiff_t n[3]; 6 | ptrdiff_t alloc_local; 7 | ptrdiff_t local_ni[3], local_i_start[3]; 8 | ptrdiff_t local_no[3], local_o_start[3]; 9 | pfft_complex *in, *out; 10 | pfft_plan plan=NULL; 11 | MPI_Comm comm_cart_2d; 12 | 13 | /* Set size of FFT and process mesh */ 14 | n[0] = 2; n[1] = 2; n[2] = 4; 15 | np[0] = 2; np[1] = 2; 16 | 17 | /* Initialize MPI and PFFT */ 18 | MPI_Init(&argc, &argv); 19 | pfft_init(); 20 | 21 | /* Create two-dimensional process grid of size np[0] x np[1] */ 22 | pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], 23 | &comm_cart_2d); 24 | 25 | /* Get parameters of data distribution */ 26 | alloc_local = pfft_local_size_dft_3d( 27 | n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 28 | local_ni, local_i_start, local_no, local_o_start); 29 | 30 | /* Allocate memory */ 31 | in = pfft_alloc_complex(alloc_local); 32 | out = pfft_alloc_complex(alloc_local); 33 | 34 | /* Plan parallel forward FFT */ 35 | plan = pfft_plan_dft_3d(n, in, out, comm_cart_2d, 36 | PFFT_FORWARD, PFFT_TRANSPOSED_NONE); 37 | 38 | /* Initialize input with random numbers */ 39 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 40 | in); 41 | 42 | /* Execute parallel forward FFT */ 43 | pfft_execute(plan); 44 | 45 | /* free mem and finalize MPI */ 46 | pfft_destroy_plan(plan); 47 | MPI_Comm_free(&comm_cart_2d); 48 | pfft_free(in); pfft_free(out); 49 | MPI_Finalize(); 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /doc/develop.tex: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | \chapter{Developers Guide}\label{chap:develop} 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | 5 | 6 | 7 | \section{Search and replace patterns} 8 | 9 | Correct alignment of pfft.h header 10 | \begin{lstlisting} 11 | %s/^\( [^ ]\+[^\\]*\) \\/ \1\\/g 12 | \end{lstlisting} 13 | 14 | Expand most macros of pfft.h to generate the function reference of this manual: 15 | \begin{lstlisting}[language=bash,prebreak=\textbackslash,] 16 | sed -e 's/ *\\$//g' -e 's/PFFT_EXTERN //g' \ 17 | -e 's/PX(\([^)]*\))/pfft_\1/g' -e 's/ INT/ ptrdiff_t/g' \ 18 | -e 's/ R/ double/g' -e 's/ C/ pfft_complex/g' \ 19 | -e 's/^ //g' pfft.h > pfft.h.expanded 20 | \end{lstlisting} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 30 | \chapter{ToDo}\label{chap:todo} 31 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 32 | 33 | \begin{itemize} 34 | \item \code{PFFT_FORWARD} is defined as \code{FFTW_FORWARD} 35 | \item \code{FFTW_FORWARD} is defined as $-1$ 36 | \item PFFT allows to chose between \code{FFTW_FORWARD} and \code{FFTW_BACKWARD}, which is not implemented by FFTW. 37 | \item Matlab uses the same sign convention, i.e., $-1$ for \code{fft} and $+1$ for \code{ifftn} 38 | \end{itemize} 39 | 40 | \section{Measuring parallel run times} 41 | Use \code{MPI_Barrier} in front of every call to \code{pfft_} function to avoid unbalanced run times. 42 | 43 | -------------------------------------------------------------------------------- /m4/ax_fc_integer_kind.m4: -------------------------------------------------------------------------------- 1 | # _AX_FC_INTEGER_4_FLAGS 2 | # ---------------------- 3 | # Flags to set INTEGER kind to 4 bytes. 4 | AC_DEFUN([_AX_FC_INTEGER_4_FLAGS], 5 | [-fdefault-integer-4 -qintsize=4 "-integer-size 32" -CcdII4 "-s integer32" -xtypemap=integer:32 -i4 +i4 -nlong]) 6 | 7 | # _AX_FC_INTEGER_8_FLAGS 8 | # ---------------------- 9 | # Flags to set INTEGER kind to 8 bytes. 10 | AC_DEFUN([_AX_FC_INTEGER_8_FLAGS], 11 | [-fdefault-integer-8 -qintsize=8 "-integer-size 64" -CcdII8 "-s integer64" -xtypemap=integer:64 -i8 +i8 -long]) 12 | 13 | # AX_FC_INTEGER_KIND(KIND, [ACTION-IF-SUCCESS], [ACTION-IF-FAILURE = FAILURE]) 14 | # ---------------------------------------------------------------------------- 15 | AC_DEFUN([AX_FC_INTEGER_KIND], 16 | [m4_case([$1], [4], [], [8], [], 17 | [m4_fatal([$0: KIND argument must be 4 or 8])])dnl 18 | AC_LANG_PUSH([Fortran])dnl 19 | AC_CACHE_CHECK( 20 | [for Fortran flag needed to enable $1 byte default integer kinds], 21 | [ax_cv_fc_integer_kind_$1], 22 | [ax_cv_fc_integer_kind_$1=unknown 23 | ax_fc_integer_kind_FCFLAGS_save=$FCFLAGS 24 | for ax_flag in none _AX_FC_INTEGER_]$1[_FLAGS 25 | do 26 | test "x$ax_flag" != xnone && FCFLAGS="$ax_fc_integer_kind_FCFLAGS_save $ax_flag" 27 | AX_CHECK_KINDOF([integer], [silent]) 28 | if test "$ax_check_kindof" = $1; then 29 | ax_cv_fc_integer_kind_$1=$ax_flag 30 | break 31 | fi 32 | done 33 | FCFLAGS=$ax_fc_integer_kind_FCFLAGS_save 34 | ]) 35 | if test "x$ax_cv_fc_integer_kind_$1" = xunknown; then 36 | m4_default([$3], [:]) 37 | else 38 | m4_default([$2], [:]) 39 | fi 40 | AC_LANG_POP([Fortran])dnl 41 | ]) 42 | -------------------------------------------------------------------------------- /m4/ax_compiler_vendor.m4: -------------------------------------------------------------------------------- 1 | dnl @synopsis AX_COMPILER_VENDOR 2 | dnl @summary find the vendor (gnu, intel, etc.) of the C/C++ compiler 3 | dnl @category C 4 | dnl @category C++ 5 | dnl 6 | dnl Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, 7 | dnl sun, hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, 8 | dnl microsoft, watcom, etc. The vendor is returned in the cache variable 9 | dnl $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++. 10 | dnl 11 | dnl @version 2007-08-01 12 | dnl @license GPLWithACException 13 | dnl @author Steven G. Johnson with Matteo Frigo 14 | 15 | AC_DEFUN([AX_COMPILER_VENDOR], 16 | [ 17 | AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, 18 | [ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown 19 | # note: don't check for gcc first since some other compilers define __GNUC__ 20 | for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ pathscale:__PATHCC__,__PATHSCALE__ apple:__APPLE_CC__,__APPLE__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do 21 | vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")" 22 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ 23 | #if !($vencpp) 24 | thisisanerror; 25 | #endif 26 | ])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break]) 27 | done 28 | ]) 29 | ]) 30 | 31 | -------------------------------------------------------------------------------- /m4/acx_mpiexec.m4: -------------------------------------------------------------------------------- 1 | # ACX_MPIEXEC([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) 2 | # ----------------------------------------------------- 3 | # A few heuristics to find out how to start an MPI job. 4 | # This is currently very incomplete, see test/defs.in for 5 | # helper functions which do the actual work for the known 6 | # set of systems. 7 | # 8 | # We should probably have facilities to specify not only 9 | # the total number of processes but also the number of 10 | # processes per node etc. 11 | AC_DEFUN([ACX_MPIEXEC], [ 12 | AC_REQUIRE([ACX_MPI])dnl 13 | 14 | AC_CHECK_PROGS([MPIEXEC], [llrun msub qsub mpiexec mpirun mpprun], [false]) 15 | AC_ARG_VAR([MPIEXEC], [program to start MPI jobs on the host system]) 16 | 17 | AC_CACHE_CHECK([how to pass the number of processes to $MPIEXEC], 18 | [acx_cv_mpiexec_minus_n], [ 19 | if test "${MPIEXEC_MINUS_N+set}" = set; then 20 | acx_cv_mpiexec_minus_n=$MPIEXEC_MINUS_N 21 | else 22 | case $MPIEXEC in #( 23 | mpiexec|*/mpiexec) acx_cv_mpiexec_minus_n="-n " ;; #( 24 | mpprun|*/mpprun) acx_cv_mpiexec_minus_n="-n " ;; #( 25 | mpirun|*/mpirun) acx_cv_mpiexec_minus_n="-np " ;; #( 26 | llrun|*/llrun) acx_cv_mpiexec_minus_n="-np ";; #( 27 | msub|*/msub) acx_cv_mpiexec_minus_n="" ;; # write a script instead ( 28 | qsub|*/qsub) acx_cv_mpiexec_minus_n="" ;; # write a script instead ( 29 | *) acx_cv_mpiexec_minus_n=unknown ;; 30 | esac 31 | fi 32 | ]) 33 | if test "x$acx_cv_mpiexec_minus_n" = xunknown; then 34 | MPIEXEC_MINUS_N= 35 | else 36 | MPIEXEC_MINUS_N=$acx_cv_mpiexec_minus_n 37 | fi 38 | AC_SUBST([MPIEXEC_MINUS_N])dnl 39 | ])dnl ACX_MPIEXEC 40 | -------------------------------------------------------------------------------- /tests/man_fftw_3don1d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // static fftw_complex my_function(ptrdiff_t i, ptrdiff_t k, ptrdiff_t j){return i +1.0/(j+1) + I*1.0/(k+1);} 6 | static fftw_complex my_function(ptrdiff_t i, ptrdiff_t k, ptrdiff_t j){return 1.0;} 7 | 8 | int main(int argc, char **argv) 9 | { 10 | const ptrdiff_t n0 = 4, n1 = 4, n2 = 4; 11 | fftw_plan plan; 12 | fftw_complex *data; 13 | ptrdiff_t alloc_local, local_n0, local_0_start, i, j, k; 14 | 15 | MPI_Init(&argc, &argv); 16 | fftw_mpi_init(); 17 | 18 | /* get local data size and allocate */ 19 | alloc_local = fftw_mpi_local_size_3d(n0, n1, n2, MPI_COMM_WORLD, 20 | &local_n0, &local_0_start); 21 | data = fftw_alloc_complex(alloc_local); 22 | 23 | /* create plan for in-place forward DFT */ 24 | plan = fftw_mpi_plan_dft_3d(n0, n1, n2, data, data, MPI_COMM_WORLD, 25 | FFTW_FORWARD, FFTW_ESTIMATE); 26 | 27 | /* initialize data to some function my_function(x,y) */ 28 | for (i = 0; i < local_n0; ++i) 29 | for (j = 0; j < n1; ++j) 30 | for (k = 0; k < n2; ++k) 31 | data[i*n1*n2 + j*n2 + k] = my_function(local_0_start + i, j, k); 32 | 33 | ptrdiff_t local_ni[3] = {local_n0, n1, n2}, local_i_start[3] = {local_0_start, 0, 0}; 34 | pfft_apr_complex_3d(data, local_ni, local_i_start, "input:", MPI_COMM_WORLD); 35 | 36 | /* compute transforms, in-place, as many times as desired */ 37 | fftw_execute(plan); 38 | 39 | ptrdiff_t local_no[3] = {local_n0, n1, n2}, local_o_start[3] = {local_0_start, 0, 0}; 40 | pfft_apr_complex_3d(data, local_no, local_o_start, "output:", MPI_COMM_WORLD); 41 | 42 | fftw_destroy_plan(plan); 43 | 44 | MPI_Finalize(); 45 | } 46 | -------------------------------------------------------------------------------- /tests/man_fftw_3don1d.ctex: -------------------------------------------------------------------------------- 1 | \del§#include § 2 | #include 3 | \del§#include § 4 | 5 | \del§ 6 | // static fftw_complex my_function(ptrdiff_t i, ptrdiff_t k, ptrdiff_t j){return i +1.0/(j+1) + I*1.0/(k+1);} 7 | static fftw_complex my_function(ptrdiff_t i, ptrdiff_t k, ptrdiff_t j){return 1.0;} 8 | 9 | § 10 | int main(int argc, char **argv) 11 | { 12 | const ptrdiff_t n0 = 4, n1 = 4, n2 = 4; 13 | fftw_plan plan; 14 | fftw_complex *data; 15 | ptrdiff_t alloc_local, local_n0, local_0_start, i, j, k; 16 | 17 | MPI_Init(&argc, &argv); 18 | fftw_mpi_init(); 19 | 20 | /* get local data size and allocate */ 21 | alloc_local = fftw_mpi_local_size_3d(n0, n1, n2, MPI_COMM_WORLD, 22 | &local_n0, &local_0_start); 23 | data = fftw_alloc_complex(alloc_local); 24 | 25 | /* create plan for in-place forward DFT */ 26 | plan = fftw_mpi_plan_dft_3d(n0, n1, n2, data, data, MPI_COMM_WORLD, 27 | FFTW_FORWARD, FFTW_ESTIMATE); 28 | 29 | /* initialize data to some function my_function(x,y) */ 30 | for (i = 0; i < local_n0; ++i) 31 | for (j = 0; j < n1; ++j) 32 | for (k = 0; k < n2; ++k) 33 | data[i*n1*n2 + j*n2 + k] = my_function(local_0_start + i, j, k); 34 | 35 | ptrdiff_t local_ni[3] = {local_n0, n1, n2}, local_i_start[3] = {local_0_start, 0, 0}; 36 | pfft_apr_complex_3d(data, local_ni, local_i_start, "input:", MPI_COMM_WORLD); 37 | 38 | /* compute transforms, in-place, as many times as desired */ 39 | fftw_execute(plan); 40 | 41 | ptrdiff_t local_no[3] = {local_n0, n1, n2}, local_o_start[3] = {local_0_start, 0, 0}; 42 | pfft_apr_complex_3d(data, local_no, local_o_start, "output:", MPI_COMM_WORLD); 43 | 44 | \red§ 45 | fftw_destroy_plan(plan); 46 | § 47 | 48 | MPI_Finalize(); 49 | } 50 | -------------------------------------------------------------------------------- /m4/ax_check_compiler_flags.m4: -------------------------------------------------------------------------------- 1 | dnl @synopsis AX_CHECK_COMPILER_FLAGS(FLAGS, [ACTION-SUCCESS], [ACTION-FAILURE]) 2 | dnl @summary check whether FLAGS are accepted by the compiler 3 | dnl @category Misc 4 | dnl 5 | dnl Check whether the given compiler FLAGS work with the current language's 6 | dnl compiler, or whether they give an error. (Warnings, however, are 7 | dnl ignored.) 8 | dnl 9 | dnl ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on 10 | dnl success/failure. 11 | dnl 12 | dnl @version 2005-05-30 13 | dnl @license GPLWithACException 14 | dnl @author Steven G. Johnson and Matteo Frigo. 15 | AC_DEFUN([AX_CHECK_COMPILER_FLAGS], 16 | [AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX 17 | AC_MSG_CHECKING([whether _AC_LANG compiler accepts $1]) 18 | dnl Some hackery here since AC_CACHE_VAL can't handle a non-literal varname: 19 | AS_LITERAL_IF([$1], 20 | [AC_CACHE_VAL(AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1), [ 21 | ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS 22 | _AC_LANG_PREFIX[]FLAGS="$1" 23 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], 24 | AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=yes, 25 | AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=no) 26 | _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])], 27 | [ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS 28 | _AC_LANG_PREFIX[]FLAGS="$1" 29 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], 30 | eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=yes, 31 | eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=no) 32 | _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS]) 33 | eval ax_check_compiler_flags=$AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1) 34 | AC_MSG_RESULT($ax_check_compiler_flags) 35 | if test "x$ax_check_compiler_flags" = xyes; then 36 | m4_default([$2], :) 37 | else 38 | m4_default([$3], :) 39 | fi 40 | ])dnl AX_CHECK_COMPILER_FLAGS 41 | -------------------------------------------------------------------------------- /m4/ac_fc_pp_define.m4: -------------------------------------------------------------------------------- 1 | # This macro has been submitted for inclusion into the Autoconf 2.69 tree. 2 | # Use the upstream version when it is defined. 3 | m4_version_prereq([2.69], [], 4 | [ 5 | 6 | # AC_FC_PP_DEFINE([ACTION-IF-SUCCESS], [ACTION-IF-FAILURE = FAILURE]) 7 | # ------------------------------------------------------------------- 8 | # Find a flag to specify defines for preprocessed Fortran. Not all 9 | # Fortran compilers use -D. Substitutes FC_DEFINE with the result and 10 | # calls ACTION-IF-SUCCESS (defaults to nothing) if successful, and 11 | # ACTION-IF-FAILURE (defaults to failing with an error message) if not. 12 | # 13 | # Known flags: 14 | # IBM: -WF,-D 15 | # Lahey/Fujitsu: -Wp,-D older versions??? 16 | # f2c: -D or -Wc,-D 17 | # others: -D 18 | AC_DEFUN([AC_FC_PP_DEFINE], 19 | [AC_LANG_PUSH([Fortran])dnl 20 | ac_fc_pp_define_srcext_save=$ac_fc_srcext 21 | AC_FC_SRCEXT([F]) 22 | AC_CACHE_CHECK([how to define symbols for preprocessed Fortran], 23 | [ac_cv_fc_pp_define], 24 | [ac_fc_pp_define_srcext_save=$ac_fc_srcext 25 | ac_cv_fc_pp_define=unknown 26 | ac_fc_pp_define_FCFLAGS_save=$FCFLAGS 27 | for ac_flag in -D -WF,-D -Wp,-D -Wc,-D 28 | do 29 | FCFLAGS="$ac_fc_pp_define_FCFLAGS_save ${ac_flag}FOOBAR ${ac_flag}ZORK=42" 30 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ 31 | #ifndef FOOBAR 32 | choke me 33 | #endif 34 | #if ZORK != 42 35 | choke me 36 | #endif]])], 37 | [ac_cv_fc_pp_define=$ac_flag; break]) 38 | done 39 | FCFLAGS=$ac_fc_pp_define_FCFLAGS_save 40 | ]) 41 | ac_fc_srcext=$ac_fc_pp_define_srcext_save 42 | if test "x$ac_cv_fc_pp_define" = xunknown; then 43 | FC_DEFINE= 44 | m4_default([$2], 45 | [AC_MSG_ERROR([Fortran does not allow to define preprocessor symbols], 77)]) 46 | else 47 | FC_DEFINE=$ac_cv_fc_pp_define 48 | $1 49 | fi 50 | AC_SUBST([FC_DEFINE])dnl 51 | AC_LANG_POP([Fortran])dnl 52 | ]) 53 | 54 | ])dnl m4_version_prereq([2.69]) 55 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | # add all source files here 3 | manual_FILES = \ 4 | manual.tex \ 5 | intro.tex \ 6 | install.tex \ 7 | fortran.tex \ 8 | shortcuts.tex \ 9 | tutorial.tex \ 10 | features.tex \ 11 | bibliography.bib 12 | 13 | EXTRA_DIST = $(manual_FILES) 14 | CLEANFILES = 15 | MOSTLYCLEANFILES = 16 | 17 | .PHONY: doc manual 18 | 19 | doc: manual 20 | 21 | if ENABLE_DOC 22 | if HAVE_LATEX 23 | manual: manual.pdf 24 | else 25 | manual: 26 | @echo "No complete LaTeX-installation was not found in your PATH." 27 | @echo "Can't build the User's Guide without pdflatex, makeindex and bibtex." 28 | @echo "Install these and rerun configure." 29 | endif 30 | else 31 | manual: 32 | @echo "Skip build of documentation because of --disable-doc." 33 | endif 34 | 35 | if ENABLE_DOC 36 | if HAVE_LATEX 37 | %.tex: ../tests/%.ctex 38 | cat $< \ 39 | | sed '/^\\del§[^§]*§$$/d; # erase whole line if \del spans from start to end' \ 40 | | sed '/\\del§/{s,\\del§[^§]*§,,g} # apply single-line \del' \ 41 | | sed '/^\\del§$$/,/^§$$/d # apply multi-line \del' \ 42 | | sed ':a s,\\red§\([^§]*[^\\]\)_\([^§]*\)§,\\red§\1\\_\2§,; ta # replace _ by \_ in single-line \red' \ 43 | | sed '/^\\red§$$/,/^§$$/{s/_/\\_/g} # replace _ by \_ in multi-line \red' \ 44 | | sed 's/\\red§/(\*@\\color{red}/g; s/§/@\*)/g # convert \red tags into LaTeX (single- and multi-line)' \ 45 | > $(builddir)/$@ 46 | 47 | # Following files are not part of EXTRA_DIST, since they are built from .ctex files 48 | gentex_FILES = \ 49 | man_fftw_3don1d.tex 50 | 51 | manual.pdf: $(manual_FILES) $(gentex_FILES) latex-manual.sh latexinc.sh 52 | sh latex-manual.sh 53 | 54 | EXTRA_DIST += manual.pdf 55 | CLEANFILES += manual.pdf 56 | MOSTLYCLEANFILES += \ 57 | *.aux *.aux.bak\ 58 | manual.bbl manual.blg \ 59 | manual.idx manual.idx.bak manual.ilg manual.ind\ 60 | manual.log manual.out manual.toc manual.lof manual.lot manual.tdo \ 61 | $(gentex_FILES) 62 | endif 63 | endif 64 | 65 | -------------------------------------------------------------------------------- /m4/ax_intrinsics.m4: -------------------------------------------------------------------------------- 1 | 2 | AC_DEFUN([AX_CHECK_IBM_INTRINSICS],[ 3 | AC_CACHE_CHECK( 4 | [for IBM intrinsics in Fortran], 5 | [ax_cv_have_ibm_f_intrinsics], 6 | [save_FCFLAGS=$FCFLAGS 7 | FCFLAGS="$FCFLAGS -qarch=450d" 8 | AC_LANG_PUSH([Fortran]) 9 | AC_LINK_IFELSE( 10 | [AC_LANG_PROGRAM([],[[ 11 | real(kind=8) :: scr(2) 12 | complex(kind=8) :: reg 13 | call alignx(16, scr) 14 | reg = loadfp(scr(1)) 15 | ]])],[ax_cv_have_ibm_f_intrinsics=yes],[ax_cv_have_ibm_f_intrinsics=no]) 16 | AC_LANG_POP([Fortran]) 17 | FCFLAGS=$save_FCFLAGS 18 | ]) 19 | if test "x${ax_cv_have_ibm_f_intrinsics}" = xyes ; then 20 | AC_DEFINE([HAVE_IBM_F_INTRINSICS],[1],[Define if IBM intrinsics can be used in Fortran.]) 21 | fi 22 | ax_intrinsics_ibm_f="${ax_cv_have_ibm_f_intrinsics}" 23 | ]) 24 | 25 | AC_DEFUN([AX_CHECK_SSE_INTRINSICS],[ 26 | AC_CACHE_CHECK( 27 | [for SSE intrinsics in C], 28 | [ax_cv_have_sse_c_intrinsics], 29 | [AC_LINK_IFELSE([ 30 | AC_LANG_PROGRAM([[ 31 | #include 32 | __m128 testfunc(float *a, float *b) { 33 | return _mm_add_ps(_mm_loadu_ps(a), _mm_loadu_ps(b)); 34 | } 35 | ]])],[ax_cv_have_sse_c_intrinsics=yes],[ax_cv_have_sse_c_intrinsics=no]) 36 | ]) 37 | if test "x${ax_cv_have_sse_c_intrinsics}" = xyes ; then 38 | AC_DEFINE([HAVE_SSE_C_INTRINSICS],[1],[Define if SSE intrinsics can be used in C.]) 39 | fi 40 | ax_intrinsics_sse_c="${ax_cv_have_sse_c_intrinsics}" 41 | ]) 42 | 43 | AC_DEFUN([AX_CHECK_SSE2_INTRINSICS],[ 44 | AC_CACHE_CHECK( 45 | [for SSE2 intrinsics in C], 46 | [ax_cv_have_sse2_c_intrinsics], 47 | [AC_LINK_IFELSE([ 48 | AC_LANG_PROGRAM([[ 49 | #include 50 | __m128d testfunc(double *a, double *b) { 51 | return _mm_add_pd(_mm_loadu_pd(a), _mm_loadu_pd(b)); 52 | } 53 | ]])],[ax_cv_have_sse2_c_intrinsics=yes],[ax_cv_have_sse2_c_intrinsics=no]) 54 | ]) 55 | if test "x${ax_cv_have_sse2_c_intrinsics}" = xyes ; then 56 | AC_DEFINE([HAVE_SSE2_C_INTRINSICS],[1],[Define if SSE2 intrinsics can be used in C.]) 57 | fi 58 | ax_intrinsics_sse2_c="${ax_cv_have_sse2_c_intrinsics}" 59 | ]) 60 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this file with automake to create Makefile.in 2 | 3 | # Makefile for PFFT. 4 | 5 | LIBTOOL_DEPS = @LIBTOOL_DEPS@ 6 | 7 | libtool: $(LIBTOOL_DEPS) 8 | $(SHELL) ./config.status --recheck 9 | 10 | # Let aclocal find the add-on macros. 11 | ACLOCAL_AMFLAGS = -I m4 12 | 13 | # pass location of FFTW to make distcheck 14 | AM_DISTCHECK_CONFIGURE_FLAGS = \ 15 | "CPPFLAGS=@CPPFLAGS@" \ 16 | "LDFLAGS=@LDFLAGS@" 17 | 18 | # Traverse these subdirectories, the current one first (for config.h). 19 | SUBDIRS = kernel gcell util api . 20 | 21 | if ENABLE_TESTS 22 | SUBDIRS += tests 23 | endif 24 | 25 | if ENABLE_DOC 26 | SUBDIRS += doc 27 | endif 28 | 29 | EXTRA_DIST = bootstrap.sh CONVENTIONS pfft.pc.in 30 | 31 | # Libraries that are built and installed. 32 | # set library name according to precision 33 | if ENABLE_LIBRARY_INSTALL 34 | lib_LTLIBRARIES = lib@PFFT_PREFIX@pfft@PREC_SUFFIX@@OPENMP_SUFFIX@.la 35 | else 36 | noinst_LTLIBRARIES = lib@PFFT_PREFIX@pfft@PREC_SUFFIX@@OPENMP_SUFFIX@.la 37 | endif 38 | 39 | 40 | # Libtool convenience libraries. 41 | lib@PFFT_PREFIX@pfft@PREC_SUFFIX@@OPENMP_SUFFIX@_la_SOURCES = 42 | lib@PFFT_PREFIX@pfft@PREC_SUFFIX@@OPENMP_SUFFIX@_la_LIBADD = \ 43 | kernel/libkernel.la \ 44 | util/libutil.la \ 45 | api/libapi.la \ 46 | gcell/libgcell.la 47 | 48 | lib@PFFT_PREFIX@pfft@PREC_SUFFIX@@OPENMP_SUFFIX@_la_LDFLAGS = -no-undefined -version-info @SHARED_VERSION_INFO@ 49 | lib@PFFT_PREFIX@pfft@PREC_SUFFIX@@OPENMP_SUFFIX@_la_CFLAGS = $(OPENMP_CFLAGS) 50 | 51 | # Get Fortran compile rules that include preprocessing. 52 | include $(top_srcdir)/build-aux/fortran-rules.am 53 | 54 | pfft1@PREC_SUFFIX@@OPENMP_SUFFIX@.pc: pfft.pc 55 | cp -f pfft.pc pfft1@PREC_SUFFIX@@OPENMP_SUFFIX@.pc 56 | 57 | # Install pkg-config file in correct location. 58 | pkgconfigdir = $(libdir)/pkgconfig 59 | pkgconfig_DATA = pfft.pc 60 | 61 | ################################################################# 62 | # Documentation 63 | ################################################################# 64 | if ENABLE_DOC 65 | .PHONY: FORCE doc manual 66 | doc manual: FORCE 67 | cd doc; $(MAKE) --print-directory $@ 68 | FORCE: 69 | endif 70 | -------------------------------------------------------------------------------- /m4/ax_gcc_x86_cpuid.m4: -------------------------------------------------------------------------------- 1 | dnl @synopsis AX_GCC_X86_CPUID(OP) 2 | dnl @summary run x86 cpuid instruction OP using gcc inline assembler 3 | dnl @category Misc 4 | dnl 5 | dnl On Pentium and later x86 processors, with gcc or a compiler that 6 | dnl has a compatible syntax for inline assembly instructions, run 7 | dnl a small program that executes the cpuid instruction with 8 | dnl input OP. This can be used to detect the CPU type. 9 | dnl 10 | dnl On output, the values of the eax, ebx, ecx, and edx registers 11 | dnl are stored as hexadecimal strings as "eax:ebx:ecx:edx" in 12 | dnl the cache variable ax_cv_gcc_x86_cpuid_OP. 13 | dnl 14 | dnl If the cpuid instruction fails (because you are running a cross-compiler, 15 | dnl or because you are not using gcc, or because you are on a processor 16 | dnl that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP is set 17 | dnl to the string "unknown". 18 | dnl 19 | dnl This macro mainly exists to be used in AX_GCC_ARCHFLAG. 20 | dnl 21 | dnl @version 2006-04-20 22 | dnl @license GPLWithACException 23 | dnl @author Steven G. Johnson and Matteo Frigo. 24 | AC_DEFUN([AX_GCC_X86_CPUID], 25 | [AC_REQUIRE([AC_PROG_CC]) 26 | AC_LANG_PUSH([C]) 27 | AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1, 28 | [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include ], [ 29 | int op = $1, eax, ebx, ecx, edx; 30 | FILE *f; 31 | __asm__("push %%ebx\n\t" 32 | "cpuid\n\t" 33 | "pop %%ebx" 34 | : "=a" (eax), "=c" (ecx), "=d" (edx) 35 | : "a" (op)); 36 | __asm__("push %%ebx\n\t" 37 | "cpuid\n\t" 38 | "mov %%ebx, %%eax\n\t" 39 | "pop %%ebx" 40 | : "=a" (ebx), "=c" (ecx), "=d" (edx) 41 | : "a" (op)); 42 | f = fopen("conftest_cpuid", "w"); if (!f) return 1; 43 | fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx); 44 | fclose(f); 45 | return 0; 46 | ])], 47 | [ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid], 48 | [ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid], 49 | [ax_cv_gcc_x86_cpuid_$1=unknown])]) 50 | AC_LANG_POP([C]) 51 | ]) 52 | -------------------------------------------------------------------------------- /util/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2013 Michael Pippig 3 | * 4 | * This file is part of PFFT. 5 | * 6 | * PFFT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * PFFT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with PFFT. If not, see . 18 | * 19 | */ 20 | 21 | 22 | /* PFFT util header file */ 23 | #ifndef PFFT_UTIL_H 24 | #define PFFT_UTIL_H 1 25 | 26 | #include "ipfft.h" 27 | 28 | void PX(get_coords)( 29 | int rnk_pm, const MPI_Comm *comms_pm, 30 | int *coords_pm); 31 | void PX(decompose)( 32 | const INT *pn, const INT* block, 33 | int rnk_pm, const int *coords_pm, 34 | INT *local_n, INT *local_start); 35 | void PX(decompose_1d)( 36 | INT n, INT block_size, int which_block, 37 | INT *local_n, INT *local_n_start); 38 | int PX(pos_mod)(int dividend, int divisor); 39 | void PX(evaluate_user_block_size)( 40 | int rnk_pm, const INT *pn, const INT *block, const int *np_pm, 41 | INT *block_intern); 42 | void PX(evaluate_user_gcells)( 43 | int rnk_n, const INT *gc_below, const INT *gc_above, 44 | INT *gc_below_intern, INT *gc_above_intern); 45 | 46 | int PX(flag_active)( 47 | unsigned flags, unsigned search_flag); 48 | int PX(flag_not_active)( 49 | unsigned flags, unsigned search_flag); 50 | 51 | void PX(physical_dft_size)( 52 | int rnk_n, const INT *n, unsigned trafo_flag, 53 | INT *pn); 54 | INT PX(physical_dft_size_1d)( 55 | INT n, unsigned trafo_flag); 56 | 57 | INT* PX(malloc_INT)( 58 | size_t size); 59 | int* PX(malloc_int)( 60 | size_t size); 61 | unsigned* PX(malloc_unsigned)( 62 | size_t size); 63 | 64 | int PX(needs_3dto2d_remap)( 65 | int rnk_n, MPI_Comm comm_cart); 66 | 67 | 68 | #endif /* !PFFT_UTIL_H */ 69 | -------------------------------------------------------------------------------- /m4/ax_gcc_aligns_stack.m4: -------------------------------------------------------------------------------- 1 | dnl @synopsis AX_GCC_ALIGNS_STACK([ACTION-IF-YES], [ACTION-IF-NO]) 2 | dnl @summary check whether gcc can align stack to 8-byte boundary 3 | dnl @category Misc 4 | dnl 5 | dnl Check to see if we are using a version of gcc that aligns the stack 6 | dnl (true in gcc-2.95+, which have the -mpreferred-stack-boundary flag). 7 | dnl Also, however, checks whether main() is correctly aligned by the 8 | dnl OS/libc/..., as well as for a bug in the stack alignment of gcc-2.95.x 9 | dnl (see http://gcc.gnu.org/ml/gcc-bugs/1999-11/msg00259.html). 10 | dnl 11 | dnl ACTION-IF-YES/ACTION-IF-NO are shell commands to execute if we are 12 | dnl using gcc and the stack is/isn't aligned, respectively. 13 | dnl 14 | dnl Requires macro: AX_CHECK_COMPILER_FLAGS, AX_GCC_VERSION 15 | dnl 16 | dnl @version 2005-05-30 17 | dnl @license GPLWithACException 18 | dnl @author Steven G. Johnson 19 | AC_DEFUN([AX_GCC_ALIGNS_STACK], 20 | [ 21 | AC_REQUIRE([AC_PROG_CC]) 22 | ax_gcc_aligns_stack=no 23 | if test "$GCC" = "yes"; then 24 | AX_CHECK_COMPILER_FLAGS(-mpreferred-stack-boundary=4, [ 25 | AC_MSG_CHECKING([whether the stack is at least 8-byte aligned by gcc]) 26 | save_CFLAGS="$CFLAGS" 27 | CFLAGS="-O" 28 | AX_CHECK_COMPILER_FLAGS(-malign-double, CFLAGS="$CFLAGS -malign-double") 29 | AC_TRY_RUN([#include 30 | # include 31 | struct yuck { int blechh; }; 32 | int one(void) { return 1; } 33 | struct yuck ick(void) { struct yuck y; y.blechh = 3; return y; } 34 | # define CHK_ALIGN(x) if ((((long) &(x)) & 0x7)) { fprintf(stderr, "bad alignment of " #x "\n"); exit(1); } 35 | void blah(int foo) { double foobar; CHK_ALIGN(foobar); } 36 | int main2(void) {double ok1; struct yuck y; double ok2; CHK_ALIGN(ok1); 37 | CHK_ALIGN(ok2); y = ick(); blah(one()); return 0;} 38 | int main(void) { if ((((long) (__builtin_alloca(0))) & 0x7)) __builtin_alloca(4); return main2(); } 39 | ], [ax_gcc_aligns_stack=yes; ax_gcc_stack_align_bug=no], 40 | ax_gcc_stack_align_bug=yes, [AX_GCC_VERSION(3,0,0, ax_gcc_stack_align_bug=no, ax_gcc_stack_align_bug=yes)]) 41 | CFLAGS="$save_CFLAGS" 42 | AC_MSG_RESULT($ax_gcc_aligns_stack) 43 | ]) 44 | fi 45 | if test "$ax_gcc_aligns_stack" = yes; then 46 | m4_default([$1], :) 47 | else 48 | m4_default([$2], :) 49 | fi 50 | ]) 51 | -------------------------------------------------------------------------------- /api/f03-api.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Script to generate Fortran 2003 interface declarations for PFFT from 4 | # the pfft.h header file. 5 | 6 | # Use this script in the following way: 7 | # ./f03-api.sh d f > pfft.f03.in 8 | # ./f03-api.sh l > pfftl.f03.in 9 | 10 | # This is designed so that the Fortran caller can do: 11 | # use, intrinsic :: iso_c_binding 12 | # implicit none 13 | # include 'pfft.f03' 14 | # and then call the C PFFT functions directly, with type checking. 15 | 16 | 17 | # pfft.h depends on fftw3-mpi.h and fftw3.h 18 | # set these paths such that the preprocessor can find the required headers 19 | FFTW_INC=$HOME/local/fftw-3.3.3/include 20 | 21 | if [ ! -e $FFTW_INC/fftw3-mpi.h ]; then 22 | echo "Error: Correct include path to fftw3-mpi.h needed." 23 | exit 1 24 | fi 25 | 26 | echo "! Generated automatically. DO NOT EDIT!" 27 | 28 | # C_FFTW_R2R_KIND is determined by configure and inserted by the Makefile 29 | # echo " integer, parameter :: C_FFTW_R2R_KIND = @C_FFTW_R2R_KIND@" 30 | 31 | # Extract constants 32 | echo 33 | echo "! integers" 34 | perl -pe 's/([A-Z0-9_]+)=([+-]?[0-9]+)/\n integer\(C_INT\), parameter :: \1 = \2\n/g' < pfft.h | grep 'integer(C_INT)' 35 | echo 36 | echo "! unsigned" 37 | perl -pe 's/#define +([A-Z0-9_]+) +\(([+-]?[0-9]+)U?\)/\n integer\(C_INT\), parameter :: \1 = \2\n/g' < pfft.h | grep 'integer(C_INT)' 38 | echo 39 | echo "! shifted unsigned" 40 | perl -pe 'if (/#define +([A-Z0-9_]+) +\(([0-9]+)U? *<< *([0-9]+)\)/) { print "\n integer\(C_INT\), parameter :: $1 = ",$2 << $3,"\n"; }' < pfft.h | grep 'integer(C_INT)' 41 | echo 42 | echo "! redirections" 43 | perl -pe 'if (/#define +([A-Z0-9_]+) +\(*(PFFT_[A-Z0-9_| ]+)\)*/) { print "\n integer\(C_INT\), parameter :: $1 = $2\n"; }' < pfft.h | grep 'integer(C_INT)' | sed 's/| / \&\n + /g' 44 | perl -pe 'if (/#define +(PFFT_[A-Z0-9_]+) +\(*(FFTW_[A-Z0-9_]+)\)*/) { print "\n integer\(C_INT\), parameter :: $1 = $2\n"; }' < pfft.h | grep 'integer(C_INT)' | sed 's/| / \&\n + /g' 45 | 46 | 47 | # Extract function declarations 48 | for p in $*; do 49 | if test "$p" = "d"; then p=""; fi 50 | 51 | echo 52 | # cat < $1 && 23 | ]m4_ifblank($6,[printf],[echo]) var_name[' =' >> $1 && 24 | for ax_p in ]m4_ifblank(ign_list,"",ign_list)[ ; do 25 | # echo "p: ${ax_p}" 26 | eval ax_f_list="${ax_p}" 27 | for ax_f in ${ax_f_list} ; do 28 | # echo "f: ${ax_f}" 29 | ax_f_list_ign="${ax_f_list_ign} ${ax_f}" 30 | done 31 | done >> $1 && 32 | ax_filelist_num=0 && 33 | for ax_p in ]m4_ifblank(pat_list,"",pat_list)[ ; do 34 | # echo "p: ${ax_p}" 35 | eval ax_f_list="${ax_p}" 36 | for ax_filelist_name in ${ax_f_list} ; do 37 | case " ${ax_f_list_ign} " in 38 | *\ ${ax_filelist_name}\ *) 39 | # echo "ignoring ${ax_filelist_name}" 40 | ;; 41 | *) 42 | if test -f "${ax_filelist_name}" ; then 43 | ax_filelist_num=$((ax_filelist_num+1)) 44 | # echo "f: ${ax_filelist_name}" 45 | ]m4_ifblank($6,[ 46 | echo " \\" 47 | printf "${ax_filelist_name}" 48 | ],[ 49 | echo "if $6" 50 | echo " var_name += ${ax_filelist_name}" 51 | echo "endif" 52 | ])[ 53 | fi 54 | ;; 55 | esac 56 | done 57 | done >> $1])])dnl 58 | m4_ifval(filelist_build_error, 59 | [m4_fatal([generating filelists failed: ]filelist_build_error[.])])dnl 60 | m4_popdef([filelist_build_error])dnl 61 | ]) 62 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_inplace.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = in; 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_3d( 41 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_3d( 45 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* execute parallel backward FFT */ 55 | pfft_execute(plan_back); 56 | 57 | /* Scale data */ 58 | ptrdiff_t l; 59 | for(l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 60 | in[l] /= (n[0]*n[1]*n[2]); 61 | 62 | /* Print error of back transformed data */ 63 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d); 64 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 65 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 66 | 67 | /* free mem and finalize */ 68 | pfft_destroy_plan(plan_forw); 69 | pfft_destroy_plan(plan_back); 70 | MPI_Comm_free(&comm_cart_2d); 71 | pfft_free(in); 72 | MPI_Finalize(); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /scripts/install_pfft_gcc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | myprefix=$HOME/local 4 | PFFT_VERSION=1.0.8-alpha 5 | FFTW_VERSION=3.3.4 6 | 7 | # ---- set path where the PFFT configure can be found ----------------- 8 | CONFDIR="$(pwd)/.." 9 | 10 | # ---- set paths where the FFTW-MPI headers and libs can be found ----- 11 | # ---- choose between lib and lib64 depending on your system ---------- 12 | FFTWDIR=$myprefix/fftw-$FFTW_VERSION 13 | FFTWINC=$FFTWDIR/include 14 | FFTWLIB=$FFTWDIR/lib64 15 | 16 | # ---- set PFFT install path --------------------------------------- 17 | INSTDIR=$myprefix/pfft-$PFFT_VERSION 18 | 19 | # ---- set build directory and name of the log file ------------------ 20 | BUILDDIR="/LOCAL/builds/pfft-$PFFT_VERSION" 21 | LOGFILE="$BUILDDIR/build.log" 22 | 23 | 24 | # ---- set MPI compilers and compiler flags ------------------------ 25 | # ---- choose between debugging and optimization flags ------------- 26 | COMP="CC=mpicc FC=mpif90 MPICC=mpicc MPIFC=mpif90" 27 | echo "Use PFFT debugging flags? (y/n)" 28 | read answer 29 | if [ ${answer} = "y" ]; then 30 | INSTDIR="$INSTDIR-dbg" 31 | BUILDDIR="$BUILDDIR-dbg" 32 | CFLAGS="-O0 -ggdb -Wall" 33 | FCFLAGS="-O0 -ggdb -Wall" 34 | PFFTDBG="--enable-debug" 35 | else 36 | CFLAGS="-O3 -ffast-math -Wall" 37 | FCFLAGS="-O3 -Wall" 38 | PFFTDBG="" 39 | fi 40 | 41 | # ---- bash check if directory exists ----------------------------- 42 | if [ -d $BUILDDIR ]; then 43 | echo "Directory $BUILDDIR already exists. Delete it? (y/n)" 44 | read answer 45 | if [ ${answer} = "y" ]; then 46 | rm -rf $BUILDDIR 47 | else 48 | echo "Install script aborted." 49 | exit 1 50 | fi 51 | fi 52 | mkdir -p $BUILDDIR 53 | 54 | # ---- Normally, we should not have to rerun bootstrap ----------- 55 | echo "Rerun bootstrap? (y/n)" 56 | read answer 57 | if [ ${answer} = "y" ]; then 58 | cd $CONFDIR 59 | ./bootstrap.sh 2>&1 | tee $LOGFILE 60 | cd - 61 | fi 62 | 63 | # ---- configure, build, install ---------------------------------- 64 | cd $BUILDDIR 65 | $CONFDIR/configure --prefix=$INSTDIR --disable-shared \ 66 | $PFFTDBG \ 67 | CPPFLAGS="-I$FFTWINC" LDFLAGS="-L$FFTWLIB" \ 68 | $COMP \ 69 | CFLAGS="$CFLAGS" FCFLAGS="$FCFLAGS" \ 70 | 2>&1 | tee -a $LOGFILE 71 | echo "*** PFFT successfully build in" 72 | echo " $BUILDDIR" 73 | 74 | make -j4 check 2>&1 | tee -a $LOGFILE 75 | make install 2>&1 | tee -a $LOGFILE 76 | 77 | # ---- status output --------------------------------------------- 78 | echo "*** PFFT build in" 79 | echo " $BUILDDIR" 80 | echo "*** PFFT installed in" 81 | echo " $INSTDIR" 82 | echo "*** For details, look at the log file" 83 | echo " $LOGFILE" 84 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_transposed_inplace.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_OUT, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = in; 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_3d( 41 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_3d( 45 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* execute parallel backward FFT */ 55 | pfft_execute(plan_back); 56 | 57 | /* Scale data */ 58 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 59 | in[l] /= (n[0]*n[1]*n[2]); 60 | 61 | /* Print error of back transformed data */ 62 | MPI_Barrier(MPI_COMM_WORLD); 63 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d); 64 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 65 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 66 | 67 | /* free mem and finalize */ 68 | pfft_destroy_plan(plan_forw); 69 | pfft_destroy_plan(plan_back); 70 | MPI_Comm_free(&comm_cart_2d); 71 | pfft_free(in); 72 | MPI_Finalize(); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_float.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | float err; 12 | pfftf_complex *in, *out; 13 | pfftf_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfftf_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfftf_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfftf_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfftf_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfftf_alloc_complex(alloc_local); 37 | out = pfftf_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfftf_plan_dft_3d( 41 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfftf_plan_dft_3d( 45 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfftf_init_input_complex_3d(n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfftf_execute(plan_forw); 53 | 54 | /* execute parallel backward FFT */ 55 | pfftf_execute(plan_back); 56 | 57 | /* Scale data */ 58 | ptrdiff_t l; 59 | for(l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 60 | in[l] /= (n[0]*n[1]*n[2]); 61 | 62 | /* Print error of back transformed data */ 63 | err = pfftf_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d); 64 | pfftf_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 65 | pfftf_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 66 | 67 | /* free mem and finalize */ 68 | pfftf_destroy_plan(plan_forw); 69 | pfftf_destroy_plan(plan_back); 70 | MPI_Comm_free(&comm_cart_2d); 71 | pfftf_free(in); pfftf_free(out); 72 | MPI_Finalize(); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_ldouble.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | long double err; 12 | pfftl_complex *in, *out; 13 | pfftl_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfftl_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfftl_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfftl_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfftl_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfftl_alloc_complex(alloc_local); 37 | out = pfftl_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfftl_plan_dft_3d( 41 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfftl_plan_dft_3d( 45 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfftl_init_input_complex_3d(n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfftl_execute(plan_forw); 53 | 54 | /* execute parallel backward FFT */ 55 | pfftl_execute(plan_back); 56 | 57 | /* Scale data */ 58 | ptrdiff_t l; 59 | for(l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 60 | in[l] /= (n[0]*n[1]*n[2]); 61 | 62 | /* Print error of back transformed data */ 63 | err = pfftl_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d); 64 | pfftl_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 65 | pfftl_printf(comm_cart_2d, "maxerror = %6.2Le;\n", err); 66 | 67 | /* free mem and finalize */ 68 | pfftl_destroy_plan(plan_forw); 69 | pfftl_destroy_plan(plan_back); 70 | MPI_Comm_free(&comm_cart_2d); 71 | pfftl_free(in); pfftl_free(out); 72 | MPI_Finalize(); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /tests/simple_check_c2c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_3d( 41 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_3d( 45 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_complex_3d(n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | ptrdiff_t l; 63 | for(l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 64 | in[l] /= (n[0]*n[1]*n[2]); 65 | 66 | /* Print error of back transformed data */ 67 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d); 68 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 69 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 70 | 71 | /* free mem and finalize */ 72 | pfft_destroy_plan(plan_forw); 73 | pfft_destroy_plan(plan_back); 74 | MPI_Comm_free(&comm_cart_2d); 75 | pfft_free(in); pfft_free(out); 76 | MPI_Finalize(); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_3d_on_3d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[3]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_3d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; np[2] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create three-dimensional process grid of size np[0] x np[1] x np[2], if possible */ 25 | if( pfft_create_procmesh(3, MPI_COMM_WORLD, np, &comm_cart_3d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]*np[2]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_3d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_3d( 41 | n, in, out, comm_cart_3d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_3d( 45 | n, out, in, comm_cart_3d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_complex_3d(n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]); 64 | 65 | /* Print error of back transformed data */ 66 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_3d); 67 | pfft_printf(comm_cart_3d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 68 | pfft_printf(comm_cart_3d, "maxerror = %6.2e;\n", err); 69 | 70 | /* free mem and finalize */ 71 | pfft_destroy_plan(plan_forw); 72 | pfft_destroy_plan(plan_back); 73 | MPI_Comm_free(&comm_cart_3d); 74 | pfft_free(in); pfft_free(out); 75 | MPI_Finalize(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_4d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft(4, n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft( 41 | 4, n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft( 45 | 4, n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex(4, n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_complex(4, n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]*n[3]); 64 | 65 | /* Print error of back transformed data */ 66 | err = pfft_check_output_complex(4, n, local_ni, local_i_start, in, comm_cart_2d); 67 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 68 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 69 | 70 | /* free mem and finalize */ 71 | pfft_destroy_plan(plan_forw); 72 | pfft_destroy_plan(plan_back); 73 | MPI_Comm_free(&comm_cart_2d); 74 | pfft_free(in); pfft_free(out); 75 | MPI_Finalize(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_transposed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_OUT, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_3d( 41 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_3d( 45 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_complex_3d(n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]); 64 | 65 | /* Print error of back transformed data */ 66 | MPI_Barrier(MPI_COMM_WORLD); 67 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d); 68 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 69 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 70 | 71 | /* free mem and finalize */ 72 | pfft_destroy_plan(plan_forw); 73 | pfft_destroy_plan(plan_back); 74 | MPI_Comm_free(&comm_cart_2d); 75 | pfft_free(in); pfft_free(out); 76 | MPI_Finalize(); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /tests/simple_check_r2c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err, *in; 12 | pfft_complex *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 32; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_r2c_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_real(2 * alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_r2c_3d( 41 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_c2r_3d( 45 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with deterministic numbers */ 48 | pfft_init_input_real(3, n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_real(3, n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]); 64 | 65 | /* Print error of back transformed data */ 66 | MPI_Barrier(MPI_COMM_WORLD); 67 | err = pfft_check_output_real(3, n, local_ni, local_i_start, in, comm_cart_2d); 68 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 69 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 70 | 71 | /* free mem and finalize */ 72 | pfft_destroy_plan(plan_forw); 73 | pfft_destroy_plan(plan_back); 74 | MPI_Comm_free(&comm_cart_2d); 75 | pfft_free(in); pfft_free(out); 76 | MPI_Finalize(); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_4d_transposed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft(4, n, comm_cart_2d, PFFT_TRANSPOSED_OUT, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft( 41 | 4, n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft( 45 | 4, n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex(4, n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_complex(4, n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]*n[3]); 64 | 65 | /* Print error of back transformed data */ 66 | err = pfft_check_output_complex(4, n, local_ni, local_i_start, in, comm_cart_2d); 67 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 68 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 69 | 70 | /* free mem and finalize */ 71 | pfft_destroy_plan(plan_forw); 72 | pfft_destroy_plan(plan_back); 73 | MPI_Comm_free(&comm_cart_2d); 74 | pfft_free(in); pfft_free(out); 75 | MPI_Finalize(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /doc/latex-manual.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright (C) 2011 The ScaFaCoS project 4 | # 5 | # This file is part of ScaFaCoS. 6 | # 7 | # ScaFaCoS is free software: you can redistribute it and/or modify it 8 | # under the terms of the GNU Lesser Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # ScaFaCoS is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU Lesser Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser Public License 18 | # along with this program. If not, see . 19 | # 20 | 21 | # Default values for pdflatex, bibtex and makeindex 22 | PDFLATEX=pdflatex 23 | BIBTEX=bibtex 24 | MAKEINDEX=makeindex 25 | 26 | # If the incfile exists, source it 27 | INCFILE=latexinc.sh 28 | test -f ./$INCFILE && . ./$INCFILE 29 | 30 | TEXFILE=manual 31 | 32 | echo "TEXINPUTS=$TEXINPUTS" 33 | 34 | PDFLATEX_CALL="$PDFLATEX -halt-on-error -interaction=batchmode" 35 | 36 | echo "Running LaTeX stage 1..." 37 | 38 | $PDFLATEX_CALL $TEXFILE 39 | EC=$? 40 | if test $EC -ne 0; then 41 | echo "ERROR: LaTeX stage 1 failed." 42 | echo "These are the last 20 lines of $TEXFILE.log:" 43 | echo "--------------------------------------------" 44 | tail -n 20 $TEXFILE.log 45 | echo "--------------------------------------------" 46 | test -f $TEXFILE.pdf && rm $TEXFILE.pdf 47 | exit $EC 48 | fi 49 | 50 | echo "Running bibtex..." 51 | # Don't fail on bibtex error: it fails if no .bib-file is there! 52 | $BIBTEX $TEXFILE 53 | 54 | echo "Running LaTeX stage 2..." 55 | $PDFLATEX_CALL $TEXFILE 56 | EC=$? 57 | if test $EC -ne 0; then 58 | echo "ERROR: LaTeX stage 2 failed." 59 | echo "These are the last 20 lines of $TEXFILE.log:" 60 | echo "--------------------------------------------" 61 | tail -n 20 $TEXFILE.log 62 | echo "--------------------------------------------" 63 | test -f $TEXFILE.pdf && rm $TEXFILE.pdf 64 | exit $EC 65 | fi 66 | 67 | if test -e $TEXFILE.idx; then 68 | echo "Running makeindex..." 69 | $MAKEINDEX $TEXFILE || exit $? 70 | fi 71 | 72 | echo "Running LaTeX stage 3..." 73 | $PDFLATEX_CALL $TEXFILE 74 | EC=$? 75 | if test $EC -ne 0; then 76 | echo "ERROR: LaTeX stage 3 failed." 77 | echo "These are the last 20 lines of $TEXFILE.log:" 78 | echo "--------------------------------------------" 79 | tail -n 20 $TEXFILE.log 80 | echo "--------------------------------------------" 81 | test -f $TEXFILE.pdf && rm $TEXFILE.pdf 82 | exit $EC 83 | fi 84 | 85 | echo "See LaTeX output in $TEXFILE.log." 86 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_3d_on_3d_transposed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[3]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_3d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; np[2] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create three-dimensional process grid of size np[0] x np[1] x np[2], if possible */ 25 | if( pfft_create_procmesh(3, MPI_COMM_WORLD, np, &comm_cart_3d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]*np[2]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_3d, PFFT_TRANSPOSED_OUT, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_3d( 41 | n, in, out, comm_cart_3d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_3d( 45 | n, out, in, comm_cart_3d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_complex_3d(n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]); 64 | 65 | /* Print error of back transformed data */ 66 | MPI_Barrier(MPI_COMM_WORLD); 67 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_3d); 68 | pfft_printf(comm_cart_3d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 69 | pfft_printf(comm_cart_3d, "maxerror = %6.2e;\n", err); 70 | 71 | /* free mem and finalize */ 72 | pfft_destroy_plan(plan_forw); 73 | pfft_destroy_plan(plan_back); 74 | MPI_Comm_free(&comm_cart_3d); 75 | pfft_free(in); pfft_free(out); 76 | MPI_Finalize(); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_4d_on_3d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[3]; 7 | ptrdiff_t n[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_3d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; np[2] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create three-dimensional process grid of size np[0] x np[1] x np[2], if possible */ 25 | if( pfft_create_procmesh(3, MPI_COMM_WORLD, np, &comm_cart_3d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]*np[2]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft(4, n, comm_cart_3d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft( 41 | 4, n, in, out, comm_cart_3d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft( 45 | 4, n, out, in, comm_cart_3d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex(4, n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_complex(4, n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]*n[3]); 64 | 65 | /* Print error of back transformed data */ 66 | err = pfft_check_output_complex(4, n, local_ni, local_i_start, in, comm_cart_3d); 67 | pfft_printf(comm_cart_3d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 68 | pfft_printf(comm_cart_3d, "maxerror = %6.2e;\n", err); 69 | 70 | /* free mem and finalize */ 71 | pfft_destroy_plan(plan_forw); 72 | pfft_destroy_plan(plan_back); 73 | MPI_Comm_free(&comm_cart_3d); 74 | pfft_free(in); pfft_free(out); 75 | MPI_Finalize(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /tests/simple_check_r2c_3d_on_3d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[3]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err, *in; 12 | pfft_complex *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_3d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; np[2] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create three-dimensional process grid of size np[0] x np[1] x np[2], if possible */ 25 | if( pfft_create_procmesh(3, MPI_COMM_WORLD, np, &comm_cart_3d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]*np[2]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_r2c_3d(n, comm_cart_3d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_real(2 * alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_r2c_3d( 41 | n, in, out, comm_cart_3d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_c2r_3d( 45 | n, out, in, comm_cart_3d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_real(3, n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_real(3, n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]); 64 | 65 | /* Print error of back transformed data */ 66 | MPI_Barrier(MPI_COMM_WORLD); 67 | err = pfft_check_output_real(3, n, local_ni, local_i_start, in, comm_cart_3d); 68 | pfft_printf(comm_cart_3d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 69 | pfft_printf(comm_cart_3d, "maxerror = %6.2e;\n", err); 70 | 71 | /* free mem and finalize */ 72 | pfft_destroy_plan(plan_forw); 73 | pfft_destroy_plan(plan_back); 74 | MPI_Comm_free(&comm_cart_3d); 75 | pfft_free(in); pfft_free(out); 76 | MPI_Finalize(); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_4d_on_3d_transposed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[3]; 7 | ptrdiff_t n[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_3d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; np[2] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create three-dimensional process grid of size np[0] x np[1] x np[2], if possible */ 25 | if( pfft_create_procmesh(3, MPI_COMM_WORLD, np, &comm_cart_3d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]*np[2]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft(4, n, comm_cart_3d, PFFT_TRANSPOSED_OUT, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft( 41 | 4, n, in, out, comm_cart_3d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft( 45 | 4, n, out, in, comm_cart_3d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex(4, n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_complex(4, n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]*n[3]); 64 | 65 | /* Print error of back transformed data */ 66 | err = pfft_check_output_complex(4, n, local_ni, local_i_start, in, comm_cart_3d); 67 | pfft_printf(comm_cart_3d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 68 | pfft_printf(comm_cart_3d, "maxerror = %6.2e;\n", err); 69 | 70 | /* free mem and finalize */ 71 | pfft_destroy_plan(plan_forw); 72 | pfft_destroy_plan(plan_back); 73 | MPI_Comm_free(&comm_cart_3d); 74 | pfft_free(in); pfft_free(out); 75 | MPI_Finalize(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /tests/simple_check_r2c_4d_on_3d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[3]; 7 | ptrdiff_t n[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err, *in; 12 | pfft_complex *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_3d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; np[2] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create three-dimensional process grid of size np[0] x np[1] x np[2], if possible */ 25 | if( pfft_create_procmesh(3, MPI_COMM_WORLD, np, &comm_cart_3d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]*np[2]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_r2c(4, n, comm_cart_3d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_real(2 * alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_r2c( 41 | 4, n, in, out, comm_cart_3d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_c2r( 45 | 4, n, out, in, comm_cart_3d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_real(4, n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_real(4, n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]*n[3]); 64 | 65 | /* Print error of back transformed data */ 66 | err = pfft_check_output_real(4, n, local_ni, local_i_start, in, comm_cart_3d); 67 | pfft_printf(comm_cart_3d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 68 | pfft_printf(comm_cart_3d, "maxerror = %6.2e;\n", err); 69 | 70 | /* free mem and finalize */ 71 | pfft_destroy_plan(plan_forw); 72 | pfft_destroy_plan(plan_back); 73 | MPI_Comm_free(&comm_cart_3d); 74 | pfft_free(in); pfft_free(out); 75 | MPI_Finalize(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /tests/simple_check_r2c_4d_on_3d_transposed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[3]; 7 | ptrdiff_t n[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err, *in; 12 | pfft_complex *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_3d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; np[2] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create three-dimensional process grid of size np[0] x np[1] x np[2], if possible */ 25 | if( pfft_create_procmesh(3, MPI_COMM_WORLD, np, &comm_cart_3d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]*np[2]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_r2c(4, n, comm_cart_3d, PFFT_TRANSPOSED_OUT, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_real(2 * alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_r2c( 41 | 4, n, in, out, comm_cart_3d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_c2r( 45 | 4, n, out, in, comm_cart_3d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_real(4, n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_real(4, n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]*n[3]); 64 | 65 | /* Print error of back transformed data */ 66 | err = pfft_check_output_real(4, n, local_ni, local_i_start, in, comm_cart_3d); 67 | pfft_printf(comm_cart_3d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 68 | pfft_printf(comm_cart_3d, "maxerror = %6.2e;\n", err); 69 | 70 | /* free mem and finalize */ 71 | pfft_destroy_plan(plan_forw); 72 | pfft_destroy_plan(plan_back); 73 | MPI_Comm_free(&comm_cart_3d); 74 | pfft_free(in); pfft_free(out); 75 | MPI_Finalize(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /tests/simple_check_r2c_4d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err, *in; 12 | pfft_complex *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_r2c(4, n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_real(2 * alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_r2c( 41 | 4, n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_c2r( 45 | 4, n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_real(4, n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_real(4, n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]*n[3]); 64 | 65 | /* Print error of back transformed data */ 66 | MPI_Barrier(MPI_COMM_WORLD); 67 | err = pfft_check_output_real(4, n, local_ni, local_i_start, in, comm_cart_2d); 68 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 69 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 70 | 71 | /* free mem and finalize */ 72 | pfft_destroy_plan(plan_forw); 73 | pfft_destroy_plan(plan_back); 74 | MPI_Comm_free(&comm_cart_2d); 75 | pfft_free(in); pfft_free(out); 76 | MPI_Finalize(); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /tests/simple_check_r2c_4d_transposed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err, *in; 12 | pfft_complex *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_r2c(4, n, comm_cart_2d, PFFT_TRANSPOSED_OUT, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_real(2 * alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_r2c( 41 | 4, n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_c2r( 45 | 4, n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_real(4, n, local_ni, local_i_start, 49 | in); 50 | 51 | /* execute parallel forward FFT */ 52 | pfft_execute(plan_forw); 53 | 54 | /* clear the old input */ 55 | pfft_clear_input_real(4, n, local_ni, local_i_start, 56 | in); 57 | 58 | /* execute parallel backward FFT */ 59 | pfft_execute(plan_back); 60 | 61 | /* Scale data */ 62 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 63 | in[l] /= (n[0]*n[1]*n[2]*n[3]); 64 | 65 | /* Print error of back transformed data */ 66 | MPI_Barrier(MPI_COMM_WORLD); 67 | err = pfft_check_output_real(4, n, local_ni, local_i_start, in, comm_cart_2d); 68 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 69 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 70 | 71 | /* free mem and finalize */ 72 | pfft_destroy_plan(plan_forw); 73 | pfft_destroy_plan(plan_back); 74 | MPI_Comm_free(&comm_cart_2d); 75 | pfft_free(in); pfft_free(out); 76 | MPI_Finalize(); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /tests/openmp/simple_check_c2c_transposed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | int main(int argc, char **argv) 7 | { 8 | int np[2]; 9 | ptrdiff_t n[3]; 10 | ptrdiff_t alloc_local; 11 | ptrdiff_t local_ni[3], local_i_start[3]; 12 | ptrdiff_t local_no[3], local_o_start[3]; 13 | double err; 14 | pfft_complex *in, *out; 15 | pfft_plan plan_forw=NULL, plan_back=NULL; 16 | MPI_Comm comm_cart_2d; 17 | 18 | 19 | /* Set size of FFT and process mesh */ 20 | n[0] = 29; n[1] = 27; n[2] = 31; 21 | np[0] = 2; np[1] = 2; 22 | 23 | /* Initialize MPI and PFFT (including OpenMP) */ 24 | MPI_Init(&argc, &argv); 25 | pfft_init(); 26 | 27 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 28 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 29 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 30 | MPI_Finalize(); 31 | return 1; 32 | } 33 | 34 | /* Get parameters of data distribution */ 35 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_OUT, 36 | local_ni, local_i_start, local_no, local_o_start); 37 | 38 | /* Allocate memory */ 39 | in = pfft_alloc_complex(alloc_local); 40 | out = pfft_alloc_complex(alloc_local); 41 | 42 | /* Plan parallel forward FFT */ 43 | plan_forw = pfft_plan_dft_3d( 44 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 45 | 46 | /* Plan parallel backward FFT */ 47 | plan_back = pfft_plan_dft_3d( 48 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 49 | 50 | /* Initialize input with random numbers */ 51 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 52 | in); 53 | 54 | /* execute parallel forward FFT */ 55 | pfft_execute(plan_forw); 56 | 57 | /* clear the old input */ 58 | pfft_clear_input_complex_3d(n, local_ni, local_i_start, 59 | in); 60 | 61 | /* execute parallel backward FFT */ 62 | pfft_execute(plan_back); 63 | 64 | /* Scale data */ 65 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 66 | in[l] /= (n[0]*n[1]*n[2]); 67 | 68 | /* Print error of back transformed data */ 69 | MPI_Barrier(MPI_COMM_WORLD); 70 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d); 71 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 72 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 73 | 74 | /* free mem and finalize */ 75 | pfft_destroy_plan(plan_forw); 76 | pfft_destroy_plan(plan_back); 77 | MPI_Comm_free(&comm_cart_2d); 78 | pfft_free(in); pfft_free(out); 79 | MPI_Finalize(); 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # $Id$ 4 | # 5 | # Copyright (c) 2003, 2006 Matteo Frigo 6 | # Copyright (c) 2003, 2006 Massachusetts Institute of Technology 7 | # Copyright (c) 2007 Jens Keiner 8 | # Copyright (c) 2010 Michael Pippig 9 | # 10 | # This program is free software; you can redistribute it and/or modify it under 11 | # the terms of the GNU General Public License as published by the Free Software 12 | # Foundation; either version 2 of the License, or (at your option) any later 13 | # version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 | # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 18 | # details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, write to the Free Software Foundation, Inc., 51 22 | # Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 23 | # 24 | ################################################################################ 25 | # NOTE: If you just want to build PFFT, do not use this file. Just follow the 26 | # installation instructions as described in the tutorial found under 27 | # doc/tutorial. 28 | # 29 | # This file is based on the bootstrap.sh script from NFFT 3.2 by Jens Keiner, 30 | # which in turn is based on the bootstrap.sh script from FFTW 3.1.2 by 31 | # M. Frigo and S. G. Johnson 32 | ################################################################################ 33 | 34 | # alias to allow for systems having glibtoolize 35 | alias libtoolize=$(type -p glibtoolize libtoolize | head -1) 36 | 37 | touch ChangeLog 38 | 39 | echo "PLEASE IGNORE WARNINGS AND ERRORS" 40 | 41 | rm -rf autom4te.cache 42 | libtoolize 43 | autoreconf --verbose --install --force 44 | 45 | rm -f config.cache 46 | 47 | # Add dependency tracking support for IBM C/C++ xlc/xlC Compilers 48 | if grep 'xlc' build-aux/depcomp >/dev/null 2>&1 49 | then : 50 | else 51 | patch -b -p0 2>/dev/null <<\EOF 52 | --- build-aux/depcomp.orig 53 | +++ build-aux/depcomp 54 | @@ -102,6 +102,12 @@ 55 | depmode=msvc7 56 | fi 57 | 58 | +if test "$depmode" = xlc; then 59 | + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations. 60 | + gccflag=-qmakedep=gcc,-MF 61 | + depmode=gcc 62 | +fi 63 | + 64 | case "$depmode" in 65 | gcc3) 66 | ## gcc 3 implements dependency tracking that does exactly what 67 | @@ -226,6 +232,13 @@ 68 | rm -f "$tmpdepfile" 69 | ;; 70 | 71 | +xlc) 72 | + # This case exists only to let depend.m4 do its work. It works by 73 | + # looking at the text of this script. This case will never be run, 74 | + # since it is checked for above. 75 | + exit 1 76 | + ;; 77 | + 78 | aix) 79 | # The C for AIX Compiler uses -M and outputs the dependencies 80 | # in a .u file. In older versions, this file always lives in the 81 | EOF 82 | fi 83 | -------------------------------------------------------------------------------- /api/fortran-mangling.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003, 2007-8 Matteo Frigo 3 | * Copyright (c) 2003, 2007-8 Massachusetts Institute of Technology 4 | * Copyright (c) 2010-2013 Michael Pippig 5 | * 6 | * This file is part of PFFT. 7 | * 8 | * PFFT is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * PFFT is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with PFFT. If not, see . 20 | * 21 | */ 22 | 23 | #ifndef FORTRAN_MANGLING_H 24 | #define FORTRAN_MANGLING_H 1 25 | 26 | /* Fortran-like (e.g. as in BLAS) type prefixes for Fortran interface */ 27 | #if defined(PFFT_PREC_SINGLE) 28 | # define pxf(name) CONCAT(spfft_, name) 29 | # define PXF(NAME) CONCAT(SPFFT_, NAME) 30 | #elif defined(PFFT_PREC_LDOUBLE) 31 | /* FIXME: what is best? BLAS uses D..._X, apparently. Ugh. */ 32 | # define pxf(name) CONCAT(lpfft_, name) 33 | # define PXF(NAME) CONCAT(LPFFT_, NAME) 34 | #else 35 | # define pxf(name) CONCAT(dpfft_, name) 36 | # define PXF(NAME) CONCAT(DPFFT_, NAME) 37 | #endif 38 | 39 | /* If FC_FUNC is not defined and the user didn't explicitly specify 40 | --disable-fortran, then make our best guess at default wrappers 41 | (since FC_FUNC_EQUIV should not be defined in this case, we 42 | will use both double-underscored g77 wrappers and single- or 43 | non-underscored wrappers). This saves us from dealing with 44 | complaints in the cases where the user failed to specify 45 | an Fortran compiler or wrapper detection failed for some reason. */ 46 | #if !defined(FC_FUNC) && !defined(DISABLE_FORTRAN) 47 | # if (defined(_WIN32) || defined(__WIN32__)) && !defined(WINDOWS_FC_MANGLING) 48 | # define WINDOWS_FC_MANGLING 1 49 | # endif 50 | # if defined(_AIX) || defined(__hpux) || defined(hpux) 51 | # define FC_FUNC(a, A) a 52 | # elif defined(CRAY) || defined(_CRAY) || defined(_UNICOS) 53 | # define FC_FUNC(a, A) A 54 | # else 55 | # define FC_FUNC(a, A) a ## _ 56 | # endif 57 | # define FC_FUNC_(a, A) a ## __ 58 | #endif 59 | 60 | #if defined(WITH_G77_WRAPPERS) && !defined(DISABLE_FORTRAN) 61 | # undef FC_FUNC_ 62 | # define FC_FUNC_(a, A) a ## __ 63 | # undef FC_FUNC_EQUIV 64 | #endif 65 | 66 | /* annoying Windows syntax for shared-library declarations */ 67 | #if defined(PFFT_DLL) && (defined(_WIN32) || defined(__WIN32__)) 68 | # define PFFT_VOIDFUNC __declspec(dllexport) void 69 | #else 70 | # define PFFT_VOIDFUNC void 71 | #endif 72 | 73 | #endif /* !FORTRAN_MANGLING_H */ 74 | -------------------------------------------------------------------------------- /tests/openmp/simple_check_c2c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char **argv) 6 | { 7 | int np[2]; 8 | ptrdiff_t n[3]; 9 | ptrdiff_t alloc_local; 10 | ptrdiff_t local_ni[3], local_i_start[3]; 11 | ptrdiff_t local_no[3], local_o_start[3]; 12 | double err; 13 | pfft_complex *in, *out; 14 | pfft_plan plan_forw=NULL, plan_back=NULL; 15 | MPI_Comm comm_cart_2d; 16 | 17 | /* Set size of FFT and process mesh */ 18 | n[0] = 128; n[1] = 128; n[2] = 128; 19 | np[0] = 1; np[1] = 1; 20 | 21 | /* Initialize MPI and PFFT (including OpenMP) */ 22 | MPI_Init(&argc, &argv); 23 | pfft_init(); 24 | 25 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 26 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 27 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 28 | MPI_Finalize(); 29 | return 1; 30 | } 31 | 32 | /* Get parameters of data distribution */ 33 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 34 | local_ni, local_i_start, local_no, local_o_start); 35 | 36 | /* Allocate memory */ 37 | in = pfft_alloc_complex(alloc_local); 38 | out = pfft_alloc_complex(alloc_local); 39 | 40 | /* Plan parallel forward FFT */ 41 | plan_forw = pfft_plan_dft_3d( 42 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 43 | 44 | /* Plan parallel backward FFT */ 45 | plan_back = pfft_plan_dft_3d( 46 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 47 | 48 | /* Initialize input with random numbers */ 49 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 50 | in); 51 | 52 | /* execute parallel forward FFT */ 53 | pfft_execute(plan_forw); 54 | 55 | pfft_print_average_timer(plan_forw, MPI_COMM_WORLD); 56 | 57 | /* clear the old input */ 58 | pfft_clear_input_complex_3d(n, local_ni, local_i_start, 59 | in); 60 | 61 | /* execute parallel backward FFT */ 62 | pfft_execute(plan_back); 63 | 64 | pfft_print_average_timer(plan_back, MPI_COMM_WORLD); 65 | 66 | /* Scale data */ 67 | ptrdiff_t l; 68 | for(l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 69 | in[l] /= (n[0]*n[1]*n[2]); 70 | 71 | /* Print error of back transformed data */ 72 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d); 73 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 74 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 75 | 76 | /* free mem and finalize */ 77 | pfft_destroy_plan(plan_forw); 78 | pfft_destroy_plan(plan_back); 79 | MPI_Comm_free(&comm_cart_2d); 80 | pfft_free(in); pfft_free(out); 81 | MPI_Finalize(); 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /api/pfft.f.in: -------------------------------------------------------------------------------- 1 | integer, parameter :: PFFT_REDFT00 = FFTW_REDFT00 2 | integer, parameter :: PFFT_REDFT01 = FFTW_REDFT01 3 | integer, parameter :: PFFT_REDFT10 = FFTW_REDFT10 4 | integer, parameter :: PFFT_REDFT11 = FFTW_REDFT11 5 | integer, parameter :: PFFT_RODFT00 = FFTW_RODFT00 6 | integer, parameter :: PFFT_RODFT01 = FFTW_RODFT01 7 | integer, parameter :: PFFT_RODFT10 = FFTW_RODFT10 8 | integer, parameter :: PFFT_RODFT11 = FFTW_RODFT11 9 | 10 | integer, parameter :: PFFT_TRANSPOSED_NONE = 0 11 | integer, parameter :: PFFT_TRANSPOSED_IN = 1 12 | integer, parameter :: PFFT_TRANSPOSED_OUT = 2 13 | integer, parameter :: PFFT_SHIFTED_NONE = 0 14 | integer, parameter :: PFFT_SHIFTED_IN = 4 15 | integer, parameter :: PFFT_SHIFTED_OUT = 8 16 | integer, parameter :: PFFT_MEASURE = 0 17 | integer, parameter :: PFFT_ESTIMATE = 16 18 | integer, parameter :: PFFT_PATIENT = 32 19 | integer, parameter :: PFFT_EXHAUSTIVE = 64 20 | integer, parameter :: PFFT_NO_TUNE = 0 21 | integer, parameter :: PFFT_TUNE = 128 22 | integer, parameter :: PFFT_PRESERVE_INPUT = 256 23 | integer, parameter :: PFFT_DESTROY_INPUT = 512 24 | integer, parameter :: PFFT_BUFFERED_INPLACE = 1024 25 | integer, parameter :: PFFT_PADDED_R2C = 2048 26 | integer, parameter :: PFFT_PADDED_C2R = PFFT_PADDED_R2C 27 | 28 | integer, parameter :: PFFT_GC_TRANSPOSED_NONE = 0 29 | integer, parameter :: PFFT_GC_TRANSPOSED = 1 30 | integer, parameter :: PFFT_GC_SENDRECV = 2 31 | integer, parameter :: PFFT_GC_RMA = 4 32 | integer, parameter :: PFFT_GC_R2C = 8 33 | integer, parameter :: PFFT_GC_PADDED = 16 34 | 35 | integer, parameter :: PFFT_GC_C2R = PFFT_GC_R2C 36 | integer, parameter :: PFFT_GC_PADDED_R2C = PFFT_GC_R2C & 37 | + PFFT_GC_PADDED 38 | integer, parameter :: PFFT_GC_PADDED_C2R = PFFT_GC_C2R & 39 | + PFFT_GC_PADDED 40 | 41 | integer, parameter :: PFFT_INT = 1 42 | integer, parameter :: PFFT_PTRDIFF_T = 2 43 | integer, parameter :: PFFT_FLOAT = 3 44 | integer, parameter :: PFFT_DOUBLE = 4 45 | integer, parameter :: PFFT_LDOUBLE = 5 46 | integer, parameter :: PFFT_UNSIGNED = 6 47 | integer, parameter :: PFFT_SWITCH = 7 48 | 49 | integer, parameter :: PFFT_FORWARD = -1 50 | integer, parameter :: PFFT_BACKWARD = +1 51 | 52 | integer, parameter ::ptrdiff_t_kind = @PTRDIFF_T_KIND@ 53 | 54 | integer(ptrdiff_t_kind), parameter :: PFFT_DEFAULT_BLOCK = 0 55 | integer(ptrdiff_t_kind), parameter :: PFFT_DEFAULT_BLOCKS = -1 56 | integer(ptrdiff_t_kind), parameter :: PFFT_NO_GCELLS = -1 57 | 58 | 59 | -------------------------------------------------------------------------------- /tests/f03/simple_check_c2c.F03: -------------------------------------------------------------------------------- 1 | program main 2 | use, intrinsic :: iso_c_binding 3 | use mpi 4 | implicit none 5 | include "fftw3-mpi.f03" 6 | include "pfft.f03" 7 | 8 | integer np(2) 9 | integer(C_INTPTR_T) :: n(3) 10 | integer(C_INTPTR_T) :: alloc_local 11 | integer(C_INTPTR_T) :: local_ni(3), local_i_start(3) 12 | integer(C_INTPTR_T) :: local_no(3), local_o_start(3) 13 | double precision err 14 | complex(C_DOUBLE_COMPLEX), pointer :: in(:,:,:), out(:,:,:) 15 | type(C_PTR) :: plan_forw, plan_back, cin, cout 16 | integer comm_cart_2d 17 | 18 | integer myrank, ierror 19 | 20 | n = [31,27,29] 21 | np = [2,2] 22 | 23 | ! Initialize MPI and PFFT 24 | call MPI_Init(ierror) 25 | call pfft_init() 26 | call MPI_Comm_rank(MPI_COMM_WORLD, myrank, ierror) 27 | 28 | ! Create two-dimensional process grid of size np(1) x np(2), if possible 29 | ierror = pfft_create_procmesh_2d(MPI_COMM_WORLD, np(1), np(2), comm_cart_2d) 30 | if (ierror .ne. 0) then 31 | if(myrank .eq. 0) then 32 | write(*,*) "Error: This test file only works with ", np(1)*np(2), " processes" 33 | endif 34 | call MPI_Finalize(ierror) 35 | call exit(1) 36 | endif 37 | 38 | ! Get parameters of data distribution 39 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, & 40 | local_ni, local_i_start, local_no, local_o_start); 41 | 42 | ! Allocate memory 43 | cin = pfft_alloc_complex(alloc_local) 44 | cout = pfft_alloc_complex(alloc_local) 45 | 46 | ! Convert data pointers to Fortran format 47 | call c_f_pointer(cin, in, [local_ni(3), local_ni(2), local_ni(1)]) 48 | call c_f_pointer(cout, out, [local_no(3), local_no(2), local_no(1)]) 49 | 50 | ! Plan parallel forward FFT 51 | plan_forw = pfft_plan_dft_3d( & 52 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE + PFFT_MEASURE + PFFT_DESTROY_INPUT) 53 | 54 | ! Plan parallel backward FFT 55 | plan_back = pfft_plan_dft_3d( & 56 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE + PFFT_MEASURE + PFFT_DESTROY_INPUT) 57 | 58 | ! Initialize input with random numbers 59 | call pfft_init_input_complex_3d(n, local_ni, local_i_start, & 60 | in) 61 | 62 | ! Execute parallel forward FFT 63 | call pfft_execute(plan_forw) 64 | 65 | ! Execute parallel backward FFT 66 | call pfft_execute(plan_back) 67 | 68 | ! Scale data 69 | in = in / (n(1)*n(2)*n(3)) 70 | 71 | ! Print error of back transformed data 72 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d) 73 | if(myrank .eq. 0) then 74 | write(*,*) "Error after one forward and backward trafo of size n=(", n(1), ", ", n(2), ", ", n(3), "):" 75 | write(*,*) "maxerror = ", err 76 | endif 77 | 78 | ! Free mem and finalize 79 | call pfft_destroy_plan(plan_forw) 80 | call pfft_destroy_plan(plan_back) 81 | call MPI_Comm_free(comm_cart_2d, ierror) 82 | call pfft_free(cin) 83 | call pfft_free(cout) 84 | call MPI_Finalize(ierror) 85 | end program main 86 | 87 | -------------------------------------------------------------------------------- /tests/f03/simple_check_c2c_transposed.F03: -------------------------------------------------------------------------------- 1 | program main 2 | use, intrinsic :: iso_c_binding 3 | use mpi 4 | implicit none 5 | include "fftw3-mpi.f03" 6 | include "pfft.f03" 7 | 8 | integer np(2) 9 | integer(C_INTPTR_T) :: n(3) 10 | integer(C_INTPTR_T) :: alloc_local 11 | integer(C_INTPTR_T) :: local_ni(3), local_i_start(3) 12 | integer(C_INTPTR_T) :: local_no(3), local_o_start(3) 13 | double precision err 14 | complex(C_DOUBLE_COMPLEX), pointer :: in(:,:,:), out(:,:,:) 15 | type(C_PTR) :: plan_forw, plan_back, cin, cout 16 | integer comm_cart_2d 17 | 18 | integer myrank, ierror 19 | 20 | n = [31,27,29] 21 | np = [2,2] 22 | 23 | ! Initialize MPI and PFFT 24 | call MPI_Init(ierror) 25 | call pfft_init() 26 | call MPI_Comm_rank(MPI_COMM_WORLD, myrank, ierror) 27 | 28 | ! Create two-dimensional process grid of size np(1) x np(2), if possible 29 | ierror = pfft_create_procmesh_2d(MPI_COMM_WORLD, np(1), np(2), comm_cart_2d) 30 | if (ierror .ne. 0) then 31 | if(myrank .eq. 0) then 32 | write(*,*) "Error: This test file only works with ", np(1)*np(2), " processes" 33 | endif 34 | call MPI_Finalize(ierror) 35 | call exit(1) 36 | endif 37 | 38 | ! Get parameters of data distribution 39 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_OUT, & 40 | local_ni, local_i_start, local_no, local_o_start); 41 | 42 | ! Allocate memory 43 | cin = pfft_alloc_complex(alloc_local) 44 | cout = pfft_alloc_complex(alloc_local) 45 | 46 | ! Convert data pointers to Fortran format 47 | call c_f_pointer(cin, in, [local_ni(3), local_ni(2), local_ni(1)]) 48 | call c_f_pointer(cout, out, [local_no(3), local_no(1), local_no(2)]) 49 | 50 | ! Plan parallel forward FFT 51 | plan_forw = pfft_plan_dft_3d( & 52 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT + PFFT_MEASURE + PFFT_DESTROY_INPUT) 53 | 54 | ! Plan parallel backward FFT 55 | plan_back = pfft_plan_dft_3d( & 56 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN + PFFT_MEASURE + PFFT_DESTROY_INPUT) 57 | 58 | ! Initialize input with random numbers 59 | call pfft_init_input_complex_3d(n, local_ni, local_i_start, & 60 | in) 61 | 62 | ! Execute parallel forward FFT 63 | call pfft_execute(plan_forw) 64 | 65 | ! Execute parallel backward FFT 66 | call pfft_execute(plan_back) 67 | 68 | ! Scale data 69 | in = in / (n(1)*n(2)*n(3)) 70 | 71 | ! Print error of back transformed data 72 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d) 73 | if(myrank .eq. 0) then 74 | write(*,*) "Error after one forward and backward trafo of size n=(", n(1), ", ", n(2), ", ", n(3), "):" 75 | write(*,*) "maxerror = ", err 76 | endif 77 | 78 | ! Free mem and finalize 79 | call pfft_destroy_plan(plan_forw) 80 | call pfft_destroy_plan(plan_back) 81 | call MPI_Comm_free(comm_cart_2d, ierror) 82 | call pfft_free(cin) 83 | call pfft_free(cout) 84 | call MPI_Finalize(ierror) 85 | end program main 86 | 87 | -------------------------------------------------------------------------------- /tests/simple_check_r2r.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3], N[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err, *in, *out; 12 | pfft_plan plan_forw=NULL, plan_back=NULL; 13 | MPI_Comm comm_cart_2d; 14 | pfft_r2r_kind kinds_forw[3], kinds_back[3]; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Set PFFT kinds of 1d R2R trafos */ 21 | kinds_forw[0] = PFFT_REDFT00; kinds_back[0] = PFFT_REDFT00; 22 | kinds_forw[1] = PFFT_REDFT01; kinds_back[1] = PFFT_REDFT10; 23 | kinds_forw[2] = PFFT_RODFT00; kinds_back[2] = PFFT_RODFT00; 24 | 25 | /* Set logical DFT sizes corresponding to FFTW manual: 26 | * for REDFT00 N=2*(n-1), for RODFT00 N=2*(n+1), otherwise N=2*n */ 27 | N[0] = 2*(n[0]-1); 28 | N[1] = 2*n[1]; 29 | N[2] = 2*(n[2]+1); 30 | 31 | /* Initialize MPI and PFFT */ 32 | MPI_Init(&argc, &argv); 33 | pfft_init(); 34 | 35 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 36 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 37 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 38 | MPI_Finalize(); 39 | return 1; 40 | } 41 | 42 | /* Get parameters of data distribution */ 43 | alloc_local = pfft_local_size_r2r_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 44 | local_ni, local_i_start, local_no, local_o_start); 45 | 46 | /* Allocate memory */ 47 | in = pfft_alloc_real(alloc_local); 48 | out = pfft_alloc_real(alloc_local); 49 | 50 | /* Plan parallel forward FFT */ 51 | plan_forw = pfft_plan_r2r_3d( 52 | n, in, out, comm_cart_2d, kinds_forw, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 53 | 54 | /* Plan parallel backward FFT */ 55 | plan_back = pfft_plan_r2r_3d( 56 | n, out, in, comm_cart_2d, kinds_back, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 57 | 58 | /* Initialize input with random numbers */ 59 | pfft_init_input_real_3d(n, local_ni, local_i_start, 60 | in); 61 | 62 | /* execute parallel forward FFT */ 63 | pfft_execute(plan_forw); 64 | 65 | /* clear the old input */ 66 | pfft_clear_input_real_3d(n, local_ni, local_i_start, 67 | in); 68 | 69 | /* execute parallel backward FFT */ 70 | pfft_execute(plan_back); 71 | 72 | /* Scale data */ 73 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 74 | in[l] /= (N[0]*N[1]*N[2]); 75 | 76 | /* Print error of back transformed data */ 77 | err = pfft_check_output_real_3d(n, local_ni, local_i_start, in, comm_cart_2d); 78 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 79 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 80 | 81 | /* free mem and finalize */ 82 | pfft_destroy_plan(plan_forw); 83 | pfft_destroy_plan(plan_back); 84 | MPI_Comm_free(&comm_cart_2d); 85 | pfft_free(in); pfft_free(out); 86 | MPI_Finalize(); 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /tests/minimal_check_c2c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 2; n[1] = 2; n[2] = 4; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_3d( 41 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_3d( 45 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 49 | in); 50 | 51 | /* Print input data */ 52 | pfft_apr_complex_3d( 53 | in, local_ni, local_i_start, 54 | "PFFT, g_hat", MPI_COMM_WORLD); 55 | 56 | /* execute parallel forward FFT */ 57 | pfft_execute(plan_forw); 58 | 59 | /* clear the old input */ 60 | pfft_clear_input_complex_3d(n, local_ni, local_i_start, 61 | in); 62 | 63 | /* Print transformed data */ 64 | pfft_apr_complex_3d( 65 | out, local_no, local_o_start, 66 | "PFFT, g", MPI_COMM_WORLD); 67 | 68 | /* execute parallel backward FFT */ 69 | pfft_execute(plan_back); 70 | 71 | /* Scale data */ 72 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 73 | in[l] /= (n[0]*n[1]*n[2]); 74 | 75 | /* Print back transformed data */ 76 | pfft_apr_complex_3d( 77 | in, local_ni, local_i_start, 78 | "PFFT^H, g_hat", MPI_COMM_WORLD); 79 | 80 | /* Print error of back transformed data */ 81 | MPI_Barrier(MPI_COMM_WORLD); 82 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d); 83 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 84 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 85 | 86 | /* free mem and finalize MPI */ 87 | pfft_destroy_plan(plan_forw); 88 | pfft_destroy_plan(plan_back); 89 | MPI_Comm_free(&comm_cart_2d); 90 | pfft_free(in); pfft_free(out); 91 | MPI_Finalize(); 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /tests/minimal_check_c2c_transposed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | pfft_complex *in, *out; 13 | pfft_plan plan_forw=NULL, plan_back=NULL; 14 | MPI_Comm comm_cart_2d; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 2; n[1] = 2; n[2] = 4; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Initialize MPI and PFFT */ 21 | MPI_Init(&argc, &argv); 22 | pfft_init(); 23 | 24 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 25 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 26 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with 4 processes.\n"); 27 | MPI_Finalize(); 28 | return 1; 29 | } 30 | 31 | /* Get parameters of data distribution */ 32 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_OUT, 33 | local_ni, local_i_start, local_no, local_o_start); 34 | 35 | /* Allocate memory */ 36 | in = pfft_alloc_complex(alloc_local); 37 | out = pfft_alloc_complex(alloc_local); 38 | 39 | /* Plan parallel forward FFT */ 40 | plan_forw = pfft_plan_dft_3d( 41 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 42 | 43 | /* Plan parallel backward FFT */ 44 | plan_back = pfft_plan_dft_3d( 45 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 46 | 47 | /* Initialize input with random numbers */ 48 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 49 | in); 50 | 51 | /* Print input data */ 52 | pfft_apr_complex_3d( 53 | in, local_ni, local_i_start, 54 | "PFFT, g_hat", MPI_COMM_WORLD); 55 | 56 | /* execute parallel forward FFT */ 57 | pfft_execute(plan_forw); 58 | 59 | /* clear the old input */ 60 | pfft_clear_input_complex_3d(n, local_ni, local_i_start, 61 | in); 62 | 63 | /* Print transformed data */ 64 | pfft_apr_complex_permuted_3d( 65 | out, local_no, local_o_start, 1, 2, 0, 66 | "PFFT, g", MPI_COMM_WORLD); 67 | 68 | /* execute parallel backward FFT */ 69 | pfft_execute(plan_back); 70 | 71 | /* Scale data */ 72 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 73 | in[l] /= (n[0]*n[1]*n[2]); 74 | 75 | /* Print back transformed data */ 76 | pfft_apr_complex_3d( 77 | in, local_ni, local_i_start, 78 | "PFFT^H, g_hat", MPI_COMM_WORLD); 79 | 80 | /* Print error of back transformed data */ 81 | MPI_Barrier(MPI_COMM_WORLD); 82 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d); 83 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 84 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 85 | 86 | /* free mem and finalize */ 87 | pfft_destroy_plan(plan_forw); 88 | pfft_destroy_plan(plan_back); 89 | MPI_Comm_free(&comm_cart_2d); 90 | pfft_free(in); pfft_free(out); 91 | MPI_Finalize(); 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /tests/simple_check_r2r_3d_on_3d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[3]; 7 | ptrdiff_t n[3], N[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err, *in, *out; 12 | pfft_plan plan_forw=NULL, plan_back=NULL; 13 | MPI_Comm comm_cart_3d; 14 | pfft_r2r_kind kinds_forw[3], kinds_back[3]; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; np[2] = 2; 19 | 20 | /* Set PFFT kinds of 1d R2R trafos */ 21 | kinds_forw[0] = PFFT_REDFT00; kinds_back[0] = PFFT_REDFT00; 22 | kinds_forw[1] = PFFT_REDFT01; kinds_back[1] = PFFT_REDFT10; 23 | kinds_forw[2] = PFFT_RODFT00; kinds_back[2] = PFFT_RODFT00; 24 | 25 | /* Set logical DFT sizes corresponding to FFTW manual: 26 | * for REDFT00 N=2*(n-1), for RODFT00 N=2*(n+1), otherwise N=2*n */ 27 | N[0] = 2*(n[0]-1); 28 | N[1] = 2*n[1]; 29 | N[2] = 2*(n[2]+1); 30 | 31 | /* Initialize MPI and PFFT */ 32 | MPI_Init(&argc, &argv); 33 | pfft_init(); 34 | 35 | /* Create three-dimensional process grid of size np[0] x np[1] x np[2], if possible */ 36 | if( pfft_create_procmesh(3, MPI_COMM_WORLD, np, &comm_cart_3d) ){ 37 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]*np[2]); 38 | MPI_Finalize(); 39 | return 1; 40 | } 41 | 42 | /* Get parameters of data distribution */ 43 | alloc_local = pfft_local_size_r2r_3d(n, comm_cart_3d, PFFT_TRANSPOSED_NONE, 44 | local_ni, local_i_start, local_no, local_o_start); 45 | 46 | /* Allocate memory */ 47 | in = pfft_alloc_real(alloc_local); 48 | out = pfft_alloc_real(alloc_local); 49 | 50 | /* Plan parallel forward FFT */ 51 | plan_forw = pfft_plan_r2r_3d( 52 | n, in, out, comm_cart_3d, kinds_forw, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 53 | 54 | /* Plan parallel backward FFT */ 55 | plan_back = pfft_plan_r2r_3d( 56 | n, out, in, comm_cart_3d, kinds_back, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 57 | 58 | /* Initialize input with random numbers */ 59 | pfft_init_input_real_3d(n, local_ni, local_i_start, 60 | in); 61 | 62 | /* execute parallel forward FFT */ 63 | pfft_execute(plan_forw); 64 | 65 | /* clear the old input */ 66 | pfft_clear_input_real_3d(n, local_ni, local_i_start, 67 | in); 68 | 69 | /* execute parallel backward FFT */ 70 | pfft_execute(plan_back); 71 | 72 | /* Scale data */ 73 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 74 | in[l] /= (N[0]*N[1]*N[2]); 75 | 76 | /* Print error of back transformed data */ 77 | err = pfft_check_output_real_3d(n, local_ni, local_i_start, in, comm_cart_3d); 78 | pfft_printf(comm_cart_3d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 79 | pfft_printf(comm_cart_3d, "maxerror = %6.2e;\n", err); 80 | 81 | /* free mem and finalize */ 82 | pfft_destroy_plan(plan_forw); 83 | pfft_destroy_plan(plan_back); 84 | MPI_Comm_free(&comm_cart_3d); 85 | pfft_free(in); pfft_free(out); 86 | MPI_Finalize(); 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /tests/simple_check_r2r_3d_on_3d_transposed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[3]; 7 | ptrdiff_t n[3], N[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err, *in, *out; 12 | pfft_plan plan_forw=NULL, plan_back=NULL; 13 | MPI_Comm comm_cart_3d; 14 | pfft_r2r_kind kinds_forw[3], kinds_back[3]; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 29; n[1] = 27; n[2] = 31; 18 | np[0] = 2; np[1] = 2; np[2] = 2; 19 | 20 | /* Set FFTW kinds of 1d R2R trafos */ 21 | kinds_forw[0] = PFFT_REDFT00; kinds_back[0] = PFFT_REDFT00; 22 | kinds_forw[1] = PFFT_REDFT01; kinds_back[1] = PFFT_REDFT10; 23 | kinds_forw[2] = PFFT_RODFT00; kinds_back[2] = PFFT_RODFT00; 24 | 25 | /* Set logical DFT sizes corresponding to FFTW manual: 26 | * for REDFT00 N=2*(n-1), for RODFT00 N=2*(n+1), otherwise N=2*n */ 27 | N[0] = 2*(n[0]-1); 28 | N[1] = 2*n[1]; 29 | N[2] = 2*(n[2]+1); 30 | 31 | /* Initialize MPI and PFFT */ 32 | MPI_Init(&argc, &argv); 33 | pfft_init(); 34 | 35 | /* Create three-dimensional process grid of size np[0] x np[1] x np[2], if possible */ 36 | if( pfft_create_procmesh(3, MPI_COMM_WORLD, np, &comm_cart_3d) ){ 37 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]*np[2]); 38 | MPI_Finalize(); 39 | return 1; 40 | } 41 | 42 | /* Get parameters of data distribution */ 43 | alloc_local = pfft_local_size_r2r_3d(n, comm_cart_3d, PFFT_TRANSPOSED_OUT, 44 | local_ni, local_i_start, local_no, local_o_start); 45 | 46 | /* Allocate memory */ 47 | in = pfft_alloc_real(alloc_local); 48 | out = pfft_alloc_real(alloc_local); 49 | 50 | /* Plan parallel forward FFT */ 51 | plan_forw = pfft_plan_r2r_3d( 52 | n, in, out, comm_cart_3d, kinds_forw, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 53 | 54 | /* Plan parallel backward FFT */ 55 | plan_back = pfft_plan_r2r_3d( 56 | n, out, in, comm_cart_3d, kinds_back, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 57 | 58 | /* Initialize input with random numbers */ 59 | pfft_init_input_real_3d(n, local_ni, local_i_start, 60 | in); 61 | 62 | /* execute parallel forward FFT */ 63 | pfft_execute(plan_forw); 64 | 65 | /* clear the old input */ 66 | pfft_clear_input_real_3d(n, local_ni, local_i_start, 67 | in); 68 | 69 | /* execute parallel backward FFT */ 70 | pfft_execute(plan_back); 71 | 72 | /* Scale data */ 73 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 74 | in[l] /= (N[0]*N[1]*N[2]); 75 | 76 | /* Print error of back transformed data */ 77 | err = pfft_check_output_real_3d(n, local_ni, local_i_start, in, comm_cart_3d); 78 | pfft_printf(comm_cart_3d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 79 | pfft_printf(comm_cart_3d, "maxerror = %6.2e;\n", err); 80 | 81 | /* free mem and finalize */ 82 | pfft_destroy_plan(plan_forw); 83 | pfft_destroy_plan(plan_back); 84 | MPI_Comm_free(&comm_cart_3d); 85 | pfft_free(in); pfft_free(out); 86 | MPI_Finalize(); 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /m4/ac_fc_module_flag.m4: -------------------------------------------------------------------------------- 1 | # This macro has been submitted for inclusion into the Autoconf 2.69 tree. 2 | # Use the upstream version when it is defined. 3 | m4_version_prereq([2.69], [], 4 | [ 5 | 6 | # AC_FC_MODULE_FLAG([ACTION-IF-SUCCESS], [ACTION-IF-FAILURE = FAILURE]) 7 | # --------------------------------------------------------------------- 8 | # Find a flag to include Fortran 90 modules from another directory. 9 | # If successful, run ACTION-IF-SUCCESS (defaults to nothing), otherwise 10 | # run ACTION-IF-FAILURE (defaults to failing with an error message). 11 | # The module flag is cached in the ac_cv_fc_module_flag variable. 12 | # It may contain significant trailing whitespace. 13 | # 14 | # Known flags: 15 | # gfortran: -Idir, -I dir (-M dir, -Mdir (deprecated), -Jdir for writing) 16 | # g95: -I dir (-fmod=dir for writing) 17 | # SUN: -Mdir, -M dir (-moddir=dir for writing; 18 | # -Idir for includes is also searched) 19 | # HP: -Idir, -I dir (+moddir=dir for writing) 20 | # IBM: -Idir (-qmoddir=dir for writing) 21 | # Intel: -Idir -I dir (-mod dir for writing) 22 | # Absoft: -pdir 23 | # Lahey: -mod dir 24 | # Cray: -module dir, -p dir (-J dir for writing) 25 | # -e m is needed to enable writing .mod files at all 26 | # Compaq: -Idir 27 | # NAGWare: -I dir 28 | # PathScale: -I dir (but -module dir is looked at first) 29 | # Portland: -module dir (first -module also names dir for writing) 30 | # Fujitsu: -Am -Idir (-Mdir for writing is searched first, then '.', then -I) 31 | # (-Am indicates how module information is saved) 32 | AC_DEFUN([AC_FC_MODULE_FLAG],[ 33 | AC_CACHE_CHECK([Fortran 90 module inclusion flag], [ac_cv_fc_module_flag], 34 | [AC_LANG_PUSH([Fortran]) 35 | ac_cv_fc_module_flag=unknown 36 | mkdir conftest.dir 37 | cd conftest.dir 38 | AC_COMPILE_IFELSE([[ 39 | module conftest_module 40 | contains 41 | subroutine conftest_routine 42 | write(*,'(a)') 'gotcha!' 43 | end subroutine 44 | end module]], 45 | [cd .. 46 | ac_fc_module_flag_FCFLAGS_save=$FCFLAGS 47 | # Flag ordering is significant for gfortran and Sun. 48 | for ac_flag in -M -I '-I ' '-M ' -p '-mod ' '-module ' '-Am -I'; do 49 | # Add the flag twice to prevent matching an output flag. 50 | FCFLAGS="$ac_fc_module_flag_FCFLAGS_save ${ac_flag}conftest.dir ${ac_flag}conftest.dir" 51 | AC_COMPILE_IFELSE([[ 52 | program main 53 | use conftest_module 54 | call conftest_routine 55 | end program]], 56 | [ac_cv_fc_module_flag="$ac_flag"]) 57 | if test "$ac_cv_fc_module_flag" != unknown; then 58 | break 59 | fi 60 | done 61 | FCFLAGS=$ac_fc_module_flag_FCFLAGS_save 62 | ]) 63 | rm -rf conftest.dir 64 | AC_LANG_POP([Fortran]) 65 | ]) 66 | if test "$ac_cv_fc_module_flag" != unknown; then 67 | FC_MODINC=$ac_cv_fc_module_flag 68 | $1 69 | else 70 | FC_MODINC= 71 | m4_default([$2], 72 | [AC_MSG_ERROR([unable to find compiler flag for module search path])]) 73 | fi 74 | AC_SUBST([FC_MODINC]) 75 | # Ensure trailing whitespace is preserved in a Makefile. 76 | AC_SUBST([ac_empty], [""]) 77 | AC_CONFIG_COMMANDS_PRE([case $FC_MODINC in #( 78 | *\ ) FC_MODINC=$FC_MODINC'${ac_empty}' ;; 79 | esac])dnl 80 | ]) 81 | 82 | ])dnl m4_version_prereq([2.69]) 83 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_newarray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | pfft_complex *planned_in, *executed_in; 13 | pfft_complex *planned_out, *executed_out; 14 | pfft_plan plan_forw=NULL, plan_back=NULL; 15 | MPI_Comm comm_cart_2d; 16 | 17 | /* Set size of FFT and process mesh */ 18 | n[0] = 29; n[1] = 27; n[2] = 31; 19 | np[0] = 2; np[1] = 2; 20 | 21 | /* Initialize MPI and PFFT */ 22 | MPI_Init(&argc, &argv); 23 | pfft_init(); 24 | 25 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 26 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 27 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 28 | MPI_Finalize(); 29 | return 1; 30 | } 31 | 32 | /* Get parameters of data distribution */ 33 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 34 | local_ni, local_i_start, local_no, local_o_start); 35 | 36 | /* Allocate memory */ 37 | planned_in = pfft_alloc_complex(alloc_local); 38 | planned_out = pfft_alloc_complex(alloc_local); 39 | 40 | /* Plan parallel forward FFT */ 41 | plan_forw = pfft_plan_dft_3d( 42 | n, planned_in, planned_out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 43 | 44 | /* Plan parallel backward FFT */ 45 | plan_back = pfft_plan_dft_3d( 46 | n, planned_out, planned_in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 47 | 48 | /* Free planning arrays since we use other arrays for execution */ 49 | pfft_free(planned_in); pfft_free(planned_out); 50 | 51 | /* Allocate memory for execution */ 52 | executed_in = pfft_alloc_complex(alloc_local); 53 | executed_out = pfft_alloc_complex(alloc_local); 54 | 55 | /* Initialize input with random numbers */ 56 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 57 | executed_in); 58 | 59 | /* execute parallel forward FFT */ 60 | pfft_execute_dft(plan_forw, executed_in, executed_out); 61 | 62 | /* clear the old input */ 63 | pfft_clear_input_complex_3d(n, local_ni, local_i_start, 64 | executed_in); 65 | 66 | /* execute parallel backward FFT */ 67 | pfft_execute_dft(plan_back, executed_out, executed_in); 68 | 69 | /* Scale data */ 70 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 71 | executed_in[l] /= (n[0]*n[1]*n[2]); 72 | 73 | /* Print error of back transformed data */ 74 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, executed_in, comm_cart_2d); 75 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 76 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 77 | 78 | /* free mem and finalize */ 79 | pfft_destroy_plan(plan_forw); 80 | pfft_destroy_plan(plan_back); 81 | MPI_Comm_free(&comm_cart_2d); 82 | pfft_free(executed_in); pfft_free(executed_out); 83 | MPI_Finalize(); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /tests/f03/time_c2c.F03: -------------------------------------------------------------------------------- 1 | program main 2 | use, intrinsic :: iso_c_binding 3 | use mpi 4 | implicit none 5 | include "fftw3-mpi.f03" 6 | include "pfft.f03" 7 | 8 | integer np(2) 9 | integer(C_INTPTR_T) :: n(3) 10 | integer(C_INTPTR_T) :: alloc_local 11 | integer(C_INTPTR_T) :: local_ni(3), local_i_start(3) 12 | integer(C_INTPTR_T) :: local_no(3), local_o_start(3) 13 | double precision err 14 | complex(C_DOUBLE_COMPLEX), pointer :: in(:,:,:), out(:,:,:) 15 | type(C_PTR) :: plan_forw, plan_back, cin, cout 16 | integer comm_cart_2d 17 | 18 | integer myrank, ierror 19 | 20 | n = [31,27,29] 21 | np = [2,2] 22 | 23 | ! Initialize MPI and PFFT 24 | call MPI_Init(ierror) 25 | call pfft_init() 26 | call MPI_Comm_rank(MPI_COMM_WORLD, myrank, ierror) 27 | 28 | ! Create two-dimensional process grid of size np(1) x np(2), if possible 29 | ierror = pfft_create_procmesh_2d(MPI_COMM_WORLD, np(1), np(2), comm_cart_2d) 30 | if (ierror .ne. 0) then 31 | if(myrank .eq. 0) then 32 | write(*,*) "Error: This test file only works with ", np(1)*np(2), " processes" 33 | endif 34 | call MPI_Finalize(ierror) 35 | call exit(1) 36 | endif 37 | 38 | ! Get parameters of data distribution 39 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, & 40 | local_ni, local_i_start, local_no, local_o_start); 41 | 42 | ! Allocate memory 43 | cin = pfft_alloc_complex(alloc_local) 44 | cout = pfft_alloc_complex(alloc_local) 45 | 46 | ! Convert data pointers to Fortran format 47 | call c_f_pointer(cin, in, [local_ni(3), local_ni(2), local_ni(1)]) 48 | call c_f_pointer(cout, out, [local_no(3), local_no(2), local_no(1)]) 49 | 50 | ! Plan parallel forward FFT 51 | plan_forw = pfft_plan_dft_3d( & 52 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE + PFFT_MEASURE + PFFT_DESTROY_INPUT) 53 | 54 | ! Plan parallel backward FFT 55 | plan_back = pfft_plan_dft_3d( & 56 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE + PFFT_MEASURE + PFFT_DESTROY_INPUT) 57 | 58 | ! Initialize input with random numbers 59 | call pfft_init_input_complex_3d(n, local_ni, local_i_start, & 60 | in) 61 | 62 | ! Execute parallel forward FFT 63 | call MPI_Barrier(MPI_COMM_WORLD, ierror) 64 | call pfft_execute(plan_forw) 65 | 66 | ! Execute parallel backward FFT 67 | call MPI_Barrier(MPI_COMM_WORLD, ierror) 68 | call pfft_execute(plan_back) 69 | 70 | ! Scale data 71 | in = in / (n(1)*n(2)*n(3)) 72 | 73 | ! Print pfft timer 74 | call pfft_print_average_timer_adv(plan_forw, comm_cart_2d) 75 | call pfft_print_average_timer_adv(plan_back, comm_cart_2d) 76 | 77 | ! Print error of back transformed data 78 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d) 79 | if(myrank .eq. 0) then 80 | write(*,*) "Error after one forward and backward trafo of size n=(", n(1), ", ", n(2), ", ", n(3), "):" 81 | write(*,*) "maxerror = ", err 82 | endif 83 | 84 | ! Free mem and finalize 85 | call pfft_destroy_plan(plan_forw) 86 | call pfft_destroy_plan(plan_back) 87 | call MPI_Comm_free(comm_cart_2d, ierror) 88 | call pfft_free(cin) 89 | call pfft_free(cout) 90 | call MPI_Finalize(ierror) 91 | end program main 92 | 93 | -------------------------------------------------------------------------------- /tests/simple_check_c2c_transposed_newarray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | pfft_complex *planned_in, *executed_in; 13 | pfft_complex *planned_out, *executed_out; 14 | pfft_plan plan_forw=NULL, plan_back=NULL; 15 | MPI_Comm comm_cart_2d; 16 | 17 | /* Set size of FFT and process mesh */ 18 | n[0] = 29; n[1] = 27; n[2] = 31; 19 | np[0] = 2; np[1] = 2; 20 | 21 | /* Initialize MPI and PFFT */ 22 | MPI_Init(&argc, &argv); 23 | pfft_init(); 24 | 25 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 26 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 27 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 28 | MPI_Finalize(); 29 | return 1; 30 | } 31 | 32 | /* Get parameters of data distribution */ 33 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_OUT, 34 | local_ni, local_i_start, local_no, local_o_start); 35 | 36 | /* Allocate memory */ 37 | planned_in = pfft_alloc_complex(alloc_local); 38 | planned_out = pfft_alloc_complex(alloc_local); 39 | 40 | /* Plan parallel forward FFT */ 41 | plan_forw = pfft_plan_dft_3d( 42 | n, planned_in, planned_out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 43 | 44 | /* Plan parallel backward FFT */ 45 | plan_back = pfft_plan_dft_3d( 46 | n, planned_out, planned_in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 47 | 48 | /* Free planning arrays since we use other arrays for execution */ 49 | pfft_free(planned_in); pfft_free(planned_out); 50 | 51 | /* Allocate memory for execution */ 52 | executed_in = pfft_alloc_complex(alloc_local); 53 | executed_out = pfft_alloc_complex(alloc_local); 54 | 55 | /* Initialize input with random numbers */ 56 | pfft_init_input_complex_3d(n, local_ni, local_i_start, 57 | executed_in); 58 | 59 | /* execute parallel forward FFT */ 60 | pfft_execute_dft(plan_forw, executed_in, executed_out); 61 | 62 | /* clear the old input */ 63 | pfft_clear_input_complex_3d(n, local_ni, local_i_start, 64 | executed_in); 65 | 66 | /* execute parallel backward FFT */ 67 | pfft_execute_dft(plan_back, executed_out, executed_in); 68 | 69 | /* Scale data */ 70 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 71 | executed_in[l] /= (n[0]*n[1]*n[2]); 72 | 73 | /* Print error of back transformed data */ 74 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, executed_in, comm_cart_2d); 75 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 76 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 77 | 78 | /* free mem and finalize */ 79 | pfft_destroy_plan(plan_forw); 80 | pfft_destroy_plan(plan_back); 81 | MPI_Comm_free(&comm_cart_2d); 82 | pfft_free(executed_in); pfft_free(executed_out); 83 | MPI_Finalize(); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /tests/f03/time_c2c_transposed.F03: -------------------------------------------------------------------------------- 1 | program main 2 | use, intrinsic :: iso_c_binding 3 | use mpi 4 | implicit none 5 | include "fftw3-mpi.f03" 6 | include "pfft.f03" 7 | 8 | integer np(2) 9 | integer(C_INTPTR_T) :: n(3) 10 | integer(C_INTPTR_T) :: alloc_local 11 | integer(C_INTPTR_T) :: local_ni(3), local_i_start(3) 12 | integer(C_INTPTR_T) :: local_no(3), local_o_start(3) 13 | double precision err 14 | complex(C_DOUBLE_COMPLEX), pointer :: in(:,:,:), out(:,:,:) 15 | type(C_PTR) :: plan_forw, plan_back, cin, cout 16 | integer comm_cart_2d 17 | 18 | integer myrank, ierror 19 | 20 | n = [31,27,29] 21 | np = [2,2] 22 | 23 | ! Initialize MPI and PFFT 24 | call MPI_Init(ierror) 25 | call pfft_init() 26 | call MPI_Comm_rank(MPI_COMM_WORLD, myrank, ierror) 27 | 28 | ! Create two-dimensional process grid of size np(1) x np(2), if possible 29 | ierror = pfft_create_procmesh_2d(MPI_COMM_WORLD, np(1), np(2), comm_cart_2d) 30 | if (ierror .ne. 0) then 31 | if(myrank .eq. 0) then 32 | write(*,*) "Error: This test file only works with ", np(1)*np(2), " processes" 33 | endif 34 | call MPI_Finalize(ierror) 35 | call exit(1) 36 | endif 37 | 38 | ! Get parameters of data distribution 39 | alloc_local = pfft_local_size_dft_3d(n, comm_cart_2d, PFFT_TRANSPOSED_OUT, & 40 | local_ni, local_i_start, local_no, local_o_start); 41 | 42 | ! Allocate memory 43 | cin = pfft_alloc_complex(alloc_local) 44 | cout = pfft_alloc_complex(alloc_local) 45 | 46 | ! Convert data pointers to Fortran format 47 | call c_f_pointer(cin, in, [local_ni(3), local_ni(2), local_ni(1)]) 48 | call c_f_pointer(cout, out, [local_no(3), local_no(1), local_no(2)]) 49 | 50 | ! Plan parallel forward FFT 51 | plan_forw = pfft_plan_dft_3d( & 52 | n, in, out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT + PFFT_MEASURE + PFFT_DESTROY_INPUT) 53 | 54 | ! Plan parallel backward FFT 55 | plan_back = pfft_plan_dft_3d( & 56 | n, out, in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN + PFFT_MEASURE + PFFT_DESTROY_INPUT) 57 | 58 | ! Initialize input with random numbers 59 | call pfft_init_input_complex_3d(n, local_ni, local_i_start, & 60 | in) 61 | 62 | ! Execute parallel forward FFT 63 | call MPI_Barrier(MPI_COMM_WORLD, ierror) 64 | call pfft_execute(plan_forw) 65 | 66 | ! Execute parallel backward FFT 67 | call MPI_Barrier(MPI_COMM_WORLD, ierror) 68 | call pfft_execute(plan_back) 69 | 70 | ! Scale data 71 | in = in / (n(1)*n(2)*n(3)) 72 | 73 | ! Print pfft timer 74 | call pfft_print_average_timer_adv(plan_forw, comm_cart_2d) 75 | call pfft_print_average_timer_adv(plan_back, comm_cart_2d) 76 | 77 | ! Print error of back transformed data 78 | err = pfft_check_output_complex_3d(n, local_ni, local_i_start, in, comm_cart_2d) 79 | if(myrank .eq. 0) then 80 | write(*,*) "Error after one forward and backward trafo of size n=(", n(1), ", ", n(2), ", ", n(3), "):" 81 | write(*,*) "maxerror = ", err 82 | endif 83 | 84 | ! Free mem and finalize 85 | call pfft_destroy_plan(plan_forw) 86 | call pfft_destroy_plan(plan_back) 87 | call MPI_Comm_free(comm_cart_2d, ierror) 88 | call pfft_free(cin) 89 | call pfft_free(cout) 90 | call MPI_Finalize(ierror) 91 | end program main 92 | 93 | -------------------------------------------------------------------------------- /tests/simple_check_r2c_newarray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | double *planned_in, *executed_in; 13 | pfft_complex *planned_out, *executed_out; 14 | pfft_plan plan_forw=NULL, plan_back=NULL; 15 | MPI_Comm comm_cart_2d; 16 | 17 | /* Set size of FFT and process mesh */ 18 | n[0] = 29; n[1] = 27; n[2] = 31; 19 | np[0] = 2; np[1] = 2; 20 | 21 | /* Initialize MPI and PFFT */ 22 | MPI_Init(&argc, &argv); 23 | pfft_init(); 24 | 25 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 26 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 27 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 28 | MPI_Finalize(); 29 | return 1; 30 | } 31 | 32 | /* Get parameters of data distribution */ 33 | alloc_local = pfft_local_size_dft_r2c_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 34 | local_ni, local_i_start, local_no, local_o_start); 35 | 36 | /* Allocate memory for planning */ 37 | planned_in = pfft_alloc_real (2 * alloc_local); 38 | planned_out = pfft_alloc_complex(alloc_local); 39 | 40 | /* Plan parallel forward FFT */ 41 | plan_forw = pfft_plan_dft_r2c_3d( 42 | n, planned_in, planned_out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 43 | 44 | /* Plan parallel backward FFT */ 45 | plan_back = pfft_plan_dft_c2r_3d( 46 | n, planned_out, planned_in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 47 | 48 | /* Free planning arrays since we use other arrays for execution */ 49 | pfft_free(planned_in); pfft_free(planned_out); 50 | 51 | /* Allocate memory for execution */ 52 | executed_in = pfft_alloc_real(2 * alloc_local); 53 | executed_out = pfft_alloc_complex(alloc_local); 54 | 55 | /* Initialize input with random numbers */ 56 | pfft_init_input_real(3, n, local_ni, local_i_start, 57 | executed_in); 58 | 59 | /* execute parallel forward FFT */ 60 | pfft_execute_dft_r2c(plan_forw, executed_in, executed_out); 61 | 62 | /* clear the old input */ 63 | pfft_clear_input_real(3, n, local_ni, local_i_start, 64 | executed_in); 65 | 66 | /* execute parallel backward FFT */ 67 | pfft_execute_dft_c2r(plan_back, executed_out, executed_in); 68 | 69 | /* Scale data */ 70 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 71 | executed_in[l] /= (n[0]*n[1]*n[2]); 72 | 73 | /* Print error of back transformed data */ 74 | err = pfft_check_output_real(3, n, local_ni, local_i_start, executed_in, comm_cart_2d); 75 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 76 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 77 | 78 | /* free mem and finalize */ 79 | pfft_destroy_plan(plan_forw); 80 | pfft_destroy_plan(plan_back); 81 | MPI_Comm_free(&comm_cart_2d); 82 | pfft_free(executed_in); pfft_free(executed_out); 83 | MPI_Finalize(); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /tests/simple_check_r2c_transposed_newarray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | double *planned_in, *executed_in; 13 | pfft_complex *planned_out, *executed_out; 14 | pfft_plan plan_forw=NULL, plan_back=NULL; 15 | MPI_Comm comm_cart_2d; 16 | 17 | /* Set size of FFT and process mesh */ 18 | n[0] = 29; n[1] = 27; n[2] = 31; 19 | np[0] = 2; np[1] = 2; 20 | 21 | /* Initialize MPI and PFFT */ 22 | MPI_Init(&argc, &argv); 23 | pfft_init(); 24 | 25 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 26 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 27 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 28 | MPI_Finalize(); 29 | return 1; 30 | } 31 | 32 | /* Get parameters of data distribution */ 33 | alloc_local = pfft_local_size_dft_r2c_3d(n, comm_cart_2d, PFFT_TRANSPOSED_OUT, 34 | local_ni, local_i_start, local_no, local_o_start); 35 | 36 | /* Allocate memory for planning */ 37 | planned_in = pfft_alloc_real (2 * alloc_local); 38 | planned_out = pfft_alloc_complex(alloc_local); 39 | 40 | /* Plan parallel forward FFT */ 41 | plan_forw = pfft_plan_dft_r2c_3d( 42 | n, planned_in, planned_out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 43 | 44 | /* Plan parallel backward FFT */ 45 | plan_back = pfft_plan_dft_c2r_3d( 46 | n, planned_out, planned_in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 47 | 48 | /* Free planning arrays since we use other arrays for execution */ 49 | pfft_free(planned_in); pfft_free(planned_out); 50 | 51 | /* Allocate memory for execution */ 52 | executed_in = pfft_alloc_real(2 * alloc_local); 53 | executed_out = pfft_alloc_complex(alloc_local); 54 | 55 | /* Initialize input with random numbers */ 56 | pfft_init_input_real(3, n, local_ni, local_i_start, 57 | executed_in); 58 | 59 | /* execute parallel forward FFT */ 60 | pfft_execute_dft_r2c(plan_forw, executed_in, executed_out); 61 | 62 | /* clear the old input */ 63 | pfft_clear_input_real(3, n, local_ni, local_i_start, 64 | executed_in); 65 | 66 | /* execute parallel backward FFT */ 67 | pfft_execute_dft_c2r(plan_back, executed_out, executed_in); 68 | 69 | /* Scale data */ 70 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 71 | executed_in[l] /= (n[0]*n[1]*n[2]); 72 | 73 | /* Print error of back transformed data */ 74 | err = pfft_check_output_real(3, n, local_ni, local_i_start, executed_in, comm_cart_2d); 75 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 76 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 77 | 78 | /* free mem and finalize */ 79 | pfft_destroy_plan(plan_forw); 80 | pfft_destroy_plan(plan_back); 81 | MPI_Comm_free(&comm_cart_2d); 82 | pfft_free(executed_in); pfft_free(executed_out); 83 | MPI_Finalize(); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /tests/build_checks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | FFTWDIR=$HOME/local/fftw-3.3-debug 4 | SRCDIR=../../.. 5 | 6 | # test_files="$test_files adv_check_ghost_c2c" 7 | # test_files="$test_files manual_min_c2c" 8 | test_files="$test_files minimal_check_c2c" 9 | test_files="$test_files minimal_check_c2c_transposed" 10 | # test_files="$test_files serial_c2c" 11 | test_files="$test_files simple_check_c2c" 12 | test_files="$test_files simple_check_c2c_3d_on_3d" 13 | test_files="$test_files simple_check_c2c_3d_on_3d_transposed" 14 | test_files="$test_files simple_check_c2c_4d" 15 | test_files="$test_files simple_check_c2c_4d_on_3d" 16 | test_files="$test_files simple_check_c2c_4d_on_3d_transposed" 17 | test_files="$test_files simple_check_c2c_4d_transposed" 18 | test_files="$test_files simple_check_c2c_transposed" 19 | test_files="$test_files simple_check_c2r_c2c" 20 | test_files="$test_files simple_check_c2r_c2c_ousam_shifted" 21 | test_files="$test_files simple_check_c2r_c2c_shifted" 22 | test_files="$test_files simple_check_ghost_c2c" 23 | test_files="$test_files simple_check_ghost_c2c_3d_on_3d" 24 | test_files="$test_files simple_check_ghost_r2c_input" 25 | test_files="$test_files simple_check_ghost_r2c_output" 26 | test_files="$test_files simple_check_ousam_c2c" 27 | test_files="$test_files simple_check_ousam_c2c_4d" 28 | test_files="$test_files simple_check_ousam_c2c_4d_on_3d" 29 | test_files="$test_files simple_check_ousam_c2c_4d_on_3d_transposed" 30 | test_files="$test_files simple_check_ousam_c2c_4d_transposed" 31 | test_files="$test_files simple_check_ousam_c2c_transposed" 32 | test_files="$test_files simple_check_ousam_c2r" 33 | test_files="$test_files simple_check_ousam_r2c" 34 | test_files="$test_files simple_check_ousam_r2c_4d" 35 | test_files="$test_files simple_check_ousam_r2c_4d_on_3d" 36 | test_files="$test_files simple_check_ousam_r2c_4d_on_3d_transposed" 37 | test_files="$test_files simple_check_ousam_r2c_4d_transposed" 38 | test_files="$test_files simple_check_ousam_r2c_transposed" 39 | test_files="$test_files simple_check_ousam_r2r" 40 | test_files="$test_files simple_check_ousam_r2r_transposed" 41 | test_files="$test_files simple_check_r2c" 42 | test_files="$test_files simple_check_r2c_3d_on_3d" 43 | test_files="$test_files simple_check_r2c_3d_on_3d_transposed" 44 | test_files="$test_files simple_check_r2c_4d" 45 | test_files="$test_files simple_check_r2c_4d_on_3d" 46 | test_files="$test_files simple_check_r2c_4d_on_3d_transposed" 47 | test_files="$test_files simple_check_r2c_4d_transposed" 48 | test_files="$test_files simple_check_r2c_transposed" 49 | test_files="$test_files simple_check_r2r" 50 | test_files="$test_files simple_check_r2r_3d_on_3d" 51 | test_files="$test_files simple_check_r2r_3d_on_3d_transposed" 52 | test_files="$test_files simple_check_r2r_4d" 53 | test_files="$test_files simple_check_r2r_4d_on_3d" 54 | test_files="$test_files simple_check_r2r_4d_on_3d_transposed" 55 | test_files="$test_files simple_check_r2r_4d_transposed" 56 | test_files="$test_files simple_check_r2r_transposed" 57 | 58 | test_files="$test_files simple_check_ousam_r2c_padded" 59 | 60 | PFFTLIB=../.libs/lib*pfft*.a 61 | 62 | cd .. && make && cd - 63 | for name in $test_files; do 64 | mpicc $SRCDIR/tests/${name}.c -o ${name} \ 65 | -I$FFTWDIR/include -I$SRCDIR/api -std=gnu99 -g -Wall \ 66 | $PFFTLIB $FFTWDIR/lib/libfcs_fftw3.a 67 | done 68 | -------------------------------------------------------------------------------- /tests/simple_check_r2c_padded_newarray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | double *planned_in, *executed_in; 13 | pfft_complex *planned_out, *executed_out; 14 | pfft_plan plan_forw=NULL, plan_back=NULL; 15 | MPI_Comm comm_cart_2d; 16 | 17 | /* Set size of FFT and process mesh */ 18 | n[0] = 29; n[1] = 27; n[2] = 31; 19 | np[0] = 2; np[1] = 2; 20 | 21 | /* Initialize MPI and PFFT */ 22 | MPI_Init(&argc, &argv); 23 | pfft_init(); 24 | 25 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 26 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 27 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 28 | MPI_Finalize(); 29 | return 1; 30 | } 31 | 32 | /* Get parameters of data distribution */ 33 | alloc_local = pfft_local_size_dft_r2c_3d(n, comm_cart_2d, PFFT_TRANSPOSED_NONE| PFFT_PADDED_R2C, 34 | local_ni, local_i_start, local_no, local_o_start); 35 | 36 | /* Allocate memory for planning */ 37 | planned_in = pfft_alloc_real (2 * alloc_local); 38 | planned_out = pfft_alloc_complex(alloc_local); 39 | 40 | /* Plan parallel forward FFT */ 41 | plan_forw = pfft_plan_dft_r2c_3d( 42 | n, planned_in, planned_out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT| PFFT_PADDED_R2C); 43 | 44 | /* Plan parallel backward FFT */ 45 | plan_back = pfft_plan_dft_c2r_3d( 46 | n, planned_out, planned_in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT| PFFT_PADDED_C2R); 47 | 48 | /* Free planning arrays since we use other arrays for execution */ 49 | pfft_free(planned_in); pfft_free(planned_out); 50 | 51 | /* Allocate memory for execution */ 52 | executed_in = pfft_alloc_real(2 * alloc_local); 53 | executed_out = pfft_alloc_complex(alloc_local); 54 | 55 | /* Initialize input with random numbers */ 56 | pfft_init_input_real(3, n, local_ni, local_i_start, 57 | executed_in); 58 | 59 | /* execute parallel forward FFT */ 60 | pfft_execute_dft_r2c(plan_forw, executed_in, executed_out); 61 | 62 | /* clear the old input */ 63 | pfft_clear_input_real(3, n, local_ni, local_i_start, 64 | executed_in); 65 | 66 | /* execute parallel backward FFT */ 67 | pfft_execute_dft_c2r(plan_back, executed_out, executed_in); 68 | 69 | /* Scale data */ 70 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 71 | executed_in[l] /= (n[0]*n[1]*n[2]); 72 | 73 | /* Print error of back transformed data */ 74 | err = pfft_check_output_real(3, n, local_ni, local_i_start, executed_in, comm_cart_2d); 75 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 76 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 77 | 78 | /* free mem and finalize */ 79 | pfft_destroy_plan(plan_forw); 80 | pfft_destroy_plan(plan_back); 81 | MPI_Comm_free(&comm_cart_2d); 82 | pfft_free(executed_in); pfft_free(executed_out); 83 | MPI_Finalize(); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /tests/fortran/simple_check_c2c.F90: -------------------------------------------------------------------------------- 1 | 2 | program test 3 | 4 | implicit none 5 | 6 | include "mpif.h" 7 | #include "fftw3.f" 8 | include "pfft.f" 9 | 10 | integer np(2), myrank, ierror, comm_cart_2d 11 | integer(ptrdiff_t_kind) :: l, m 12 | integer(ptrdiff_t_kind) :: n(3) 13 | integer(ptrdiff_t_kind) :: alloc_local 14 | integer(ptrdiff_t_kind) :: local_ni(3), local_i_start(3) 15 | integer(ptrdiff_t_kind) :: local_no(3), local_o_start(3) 16 | integer(8) plan_forw, plan_back 17 | complex(8), allocatable :: data_in(:) 18 | complex(8), allocatable :: data_out(:) 19 | real(8) error 20 | 21 | n = (/ 29,27,31 /) 22 | np = (/ 2,2 /) 23 | 24 | ! Initialize MPI and PFFT 25 | call MPI_Init(ierror) 26 | call dpfft_init(); 27 | 28 | call MPI_Comm_rank(MPI_COMM_WORLD, myrank, ierror) 29 | 30 | ! Create two-dimensional process grid of 31 | ! size np(1) x np(2), if possible 32 | call dpfft_create_procmesh_2d(ierror, MPI_COMM_WORLD, & 33 | & np(1), np(2), comm_cart_2d) 34 | if (ierror .ne. 0) then 35 | if(myrank .eq. 0) then 36 | write(*,*) "Error: This test file only works with 4 processes" 37 | endif 38 | call MPI_Finalize(ierror) 39 | call exit(1) 40 | endif 41 | 42 | ! Get parameters of data distribution 43 | call dpfft_local_size_dft_3d( & 44 | & alloc_local, n, comm_cart_2d, PFFT_TRANSPOSED_NONE, & 45 | & local_ni, local_i_start, local_no, local_o_start); 46 | 47 | ! Allocate memory 48 | allocate(data_in(alloc_local)) 49 | allocate(data_out(alloc_local)) 50 | 51 | ! Plan parallel forward FFT 52 | call dpfft_plan_dft_3d(plan_forw, n, data_in, data_out, comm_cart_2d, & 53 | & PFFT_FORWARD, PFFT_TRANSPOSED_NONE + PFFT_MEASURE + PFFT_DESTROY_INPUT) 54 | 55 | ! Plan parallel backward FFT 56 | call dpfft_plan_dft_3d(plan_back, n, data_out, data_in, comm_cart_2d, & 57 | & PFFT_BACKWARD, PFFT_TRANSPOSED_NONE + PFFT_MEASURE + PFFT_DESTROY_INPUT) 58 | 59 | ! Initialize input with random numbers 60 | call dpfft_init_input_complex_3d(n, local_ni, local_i_start, & 61 | & data_in) 62 | 63 | ! Execute parallel forward FFT 64 | call dpfft_execute(plan_forw) 65 | 66 | ! Execute parallel backward FFT 67 | call dpfft_execute(plan_back) 68 | 69 | ! Scale data 70 | m=1 71 | do l=1,n(1) * local_ni(2) * local_ni(3) 72 | data_in(l) = data_in(l) / (n(1)*n(2)*n(3)) 73 | m = m+1 74 | enddo 75 | 76 | ! Print error of back transformed data 77 | call dpfft_check_output_complex_3d(error, n, local_ni, local_i_start, & 78 | & data_in, comm_cart_2d) 79 | 80 | if(myrank .eq. 0) then 81 | write(*,*) "Error after one forward and backward& 82 | & trafo of size n=(", n(1), n(2), n(3), "):" 83 | write(*,*) "maxerror = ", error 84 | endif 85 | 86 | ! free mem and finalize 87 | call dpfft_destroy_plan(plan_forw) 88 | call dpfft_destroy_plan(plan_back) 89 | call MPI_Comm_free(comm_cart_2d, ierror) 90 | deallocate(data_out) 91 | deallocate(data_in) 92 | 93 | ! Finalize MPI 94 | call MPI_Finalize(ierror) 95 | end 96 | 97 | -------------------------------------------------------------------------------- /tests/fortran/simple_check_c2c_transposed.F90: -------------------------------------------------------------------------------- 1 | 2 | program test 3 | 4 | implicit none 5 | 6 | include "mpif.h" 7 | #include "fftw3.f" 8 | include "pfft.f" 9 | 10 | integer np(2), myrank, ierror, comm_cart_2d 11 | integer(ptrdiff_t_kind) :: l, m 12 | integer(ptrdiff_t_kind) :: n(3) 13 | integer(ptrdiff_t_kind) :: alloc_local 14 | integer(ptrdiff_t_kind) :: local_ni(3), local_i_start(3) 15 | integer(ptrdiff_t_kind) :: local_no(3), local_o_start(3) 16 | integer(8) plan_forw, plan_back 17 | complex(8), allocatable :: data_in(:) 18 | complex(8), allocatable :: data_out(:) 19 | real(8) error 20 | 21 | n = (/ 29,27,31 /) 22 | np = (/ 2,2 /) 23 | 24 | ! Initialize MPI and PFFT 25 | call MPI_Init(ierror) 26 | call dpfft_init(); 27 | 28 | call MPI_Comm_rank(MPI_COMM_WORLD, myrank, ierror) 29 | 30 | ! Create two-dimensional process grid of 31 | ! size np(1) x np(2), if possible 32 | call dpfft_create_procmesh_2d(ierror, MPI_COMM_WORLD, & 33 | & np(1), np(2), comm_cart_2d) 34 | if (ierror .ne. 0) then 35 | if(myrank .eq. 0) then 36 | write(*,*) "Error: This test file only works with 4 processes" 37 | endif 38 | call MPI_Finalize(ierror) 39 | call exit(1) 40 | endif 41 | 42 | ! Get parameters of data distribution 43 | call dpfft_local_size_dft_3d( & 44 | & alloc_local, n, comm_cart_2d, PFFT_TRANSPOSED_OUT, & 45 | & local_ni, local_i_start, local_no, local_o_start); 46 | 47 | ! Allocate memory 48 | allocate(data_in(alloc_local)) 49 | allocate(data_out(alloc_local)) 50 | 51 | ! Plan parallel forward FFT 52 | call dpfft_plan_dft_3d(plan_forw, n, data_in, data_out, comm_cart_2d, & 53 | & PFFT_FORWARD, PFFT_TRANSPOSED_OUT + PFFT_MEASURE + PFFT_DESTROY_INPUT) 54 | 55 | ! Plan parallel backward FFT 56 | call dpfft_plan_dft_3d(plan_back, n, data_out, data_in, comm_cart_2d, & 57 | & PFFT_BACKWARD, PFFT_TRANSPOSED_IN + PFFT_MEASURE + PFFT_DESTROY_INPUT) 58 | 59 | ! Initialize input with random numbers 60 | call dpfft_init_input_complex_3d(n, local_ni, local_i_start, & 61 | & data_in) 62 | 63 | ! Execute parallel forward FFT 64 | call dpfft_execute(plan_forw) 65 | 66 | ! Execute parallel backward FFT 67 | call dpfft_execute(plan_back) 68 | 69 | ! Scale data 70 | m=1 71 | do l=1,n(1) * local_ni(2) * local_ni(3) 72 | data_in(l) = data_in(l) / (n(1)*n(2)*n(3)) 73 | m = m+1 74 | enddo 75 | 76 | ! Print error of back transformed data 77 | call dpfft_check_output_complex_3d(error, n, local_ni, local_i_start, & 78 | & data_in, comm_cart_2d) 79 | 80 | if(myrank .eq. 0) then 81 | write(*,*) "Error after one forward and backward& 82 | & trafo of size n=(", n(1), n(2), n(3), "):" 83 | write(*,*) "maxerror = ", error 84 | endif 85 | 86 | ! free mem and finalize 87 | call dpfft_destroy_plan(plan_forw) 88 | call dpfft_destroy_plan(plan_back) 89 | call MPI_Comm_free(comm_cart_2d, ierror) 90 | deallocate(data_out) 91 | deallocate(data_in) 92 | 93 | ! Finalize MPI 94 | call MPI_Finalize(ierror) 95 | end 96 | 97 | -------------------------------------------------------------------------------- /tests/simple_check_r2c_padded_transposed_newarray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[3]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[3], local_i_start[3]; 10 | ptrdiff_t local_no[3], local_o_start[3]; 11 | double err; 12 | double *planned_in, *executed_in; 13 | pfft_complex *planned_out, *executed_out; 14 | pfft_plan plan_forw=NULL, plan_back=NULL; 15 | MPI_Comm comm_cart_2d; 16 | 17 | /* Set size of FFT and process mesh */ 18 | n[0] = 29; n[1] = 27; n[2] = 31; 19 | np[0] = 2; np[1] = 2; 20 | 21 | /* Initialize MPI and PFFT */ 22 | MPI_Init(&argc, &argv); 23 | pfft_init(); 24 | 25 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 26 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 27 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 28 | MPI_Finalize(); 29 | return 1; 30 | } 31 | 32 | /* Get parameters of data distribution */ 33 | alloc_local = pfft_local_size_dft_r2c_3d(n, comm_cart_2d, PFFT_TRANSPOSED_OUT| PFFT_PADDED_R2C, 34 | local_ni, local_i_start, local_no, local_o_start); 35 | 36 | /* Allocate memory for planning */ 37 | planned_in = pfft_alloc_real (2 * alloc_local); 38 | planned_out = pfft_alloc_complex(alloc_local); 39 | 40 | /* Plan parallel forward FFT */ 41 | plan_forw = pfft_plan_dft_r2c_3d( 42 | n, planned_in, planned_out, comm_cart_2d, PFFT_FORWARD, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT| PFFT_PADDED_R2C); 43 | 44 | /* Plan parallel backward FFT */ 45 | plan_back = pfft_plan_dft_c2r_3d( 46 | n, planned_out, planned_in, comm_cart_2d, PFFT_BACKWARD, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT| PFFT_PADDED_C2R); 47 | 48 | /* Free planning arrays since we use other arrays for execution */ 49 | pfft_free(planned_in); pfft_free(planned_out); 50 | 51 | /* Allocate memory for execution */ 52 | executed_in = pfft_alloc_real(2 * alloc_local); 53 | executed_out = pfft_alloc_complex(alloc_local); 54 | 55 | /* Initialize input with random numbers */ 56 | pfft_init_input_real(3, n, local_ni, local_i_start, 57 | executed_in); 58 | 59 | /* execute parallel forward FFT */ 60 | pfft_execute_dft_r2c(plan_forw, executed_in, executed_out); 61 | 62 | /* clear the old input */ 63 | pfft_clear_input_real(3, n, local_ni, local_i_start, 64 | executed_in); 65 | 66 | /* execute parallel backward FFT */ 67 | pfft_execute_dft_c2r(plan_back, executed_out, executed_in); 68 | 69 | /* Scale data */ 70 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2]; l++) 71 | executed_in[l] /= (n[0]*n[1]*n[2]); 72 | 73 | /* Print error of back transformed data */ 74 | err = pfft_check_output_real(3, n, local_ni, local_i_start, executed_in, comm_cart_2d); 75 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td):\n", n[0], n[1], n[2]); 76 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 77 | 78 | /* free mem and finalize */ 79 | pfft_destroy_plan(plan_forw); 80 | pfft_destroy_plan(plan_back); 81 | MPI_Comm_free(&comm_cart_2d); 82 | pfft_free(executed_in); pfft_free(executed_out); 83 | MPI_Finalize(); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /tests/simple_check_r2r_4d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[4], N[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err, *in, *out; 12 | pfft_plan plan_forw=NULL, plan_back=NULL; 13 | MPI_Comm comm_cart_2d; 14 | pfft_r2r_kind kinds_forw[4], kinds_back[4]; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Set FFTW kinds of 1d R2R trafos */ 21 | kinds_forw[0] = PFFT_REDFT00; kinds_back[0] = PFFT_REDFT00; 22 | kinds_forw[1] = PFFT_REDFT01; kinds_back[1] = PFFT_REDFT10; 23 | kinds_forw[2] = PFFT_RODFT00; kinds_back[2] = PFFT_RODFT00; 24 | kinds_forw[3] = PFFT_RODFT10; kinds_back[3] = PFFT_RODFT01; 25 | 26 | /* Set logical DFT sizes corresponding to FFTW manual: 27 | * for REDFT00 N=2*(n-1), for RODFT00 N=2*(n+1), otherwise N=2*n */ 28 | N[0] = 2*(n[0]-1); 29 | N[1] = 2*n[1]; 30 | N[2] = 2*(n[2]+1); 31 | N[3] = 2*n[3]; 32 | 33 | /* Initialize MPI and PFFT */ 34 | MPI_Init(&argc, &argv); 35 | pfft_init(); 36 | 37 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 38 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 39 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 40 | MPI_Finalize(); 41 | return 1; 42 | } 43 | 44 | /* Get parameters of data distribution */ 45 | alloc_local = pfft_local_size_r2r(4, n, comm_cart_2d, PFFT_TRANSPOSED_NONE, 46 | local_ni, local_i_start, local_no, local_o_start); 47 | 48 | /* Allocate memory */ 49 | in = pfft_alloc_real(alloc_local); 50 | out = pfft_alloc_real(alloc_local); 51 | 52 | /* Plan parallel forward FFT */ 53 | plan_forw = pfft_plan_r2r( 54 | 4, n, in, out, comm_cart_2d, kinds_forw, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 55 | 56 | /* Plan parallel backward FFT */ 57 | plan_back = pfft_plan_r2r( 58 | 4, n, out, in, comm_cart_2d, kinds_back, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 59 | 60 | /* Initialize input with random numbers */ 61 | pfft_init_input_real(4, n, local_ni, local_i_start, 62 | in); 63 | 64 | /* execute parallel forward FFT */ 65 | pfft_execute(plan_forw); 66 | 67 | /* clear the old input */ 68 | pfft_clear_input_real(4, n, local_ni, local_i_start, 69 | in); 70 | 71 | /* execute parallel backward FFT */ 72 | pfft_execute(plan_back); 73 | 74 | /* Scale data */ 75 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 76 | in[l] /= (N[0]*N[1]*N[2]*N[3]); 77 | 78 | /* Print error of back transformed data */ 79 | MPI_Barrier(MPI_COMM_WORLD); 80 | err = pfft_check_output_real(4, n, local_ni, local_i_start, in, comm_cart_2d); 81 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 82 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 83 | 84 | /* free mem and finalize */ 85 | pfft_destroy_plan(plan_forw); 86 | pfft_destroy_plan(plan_back); 87 | MPI_Comm_free(&comm_cart_2d); 88 | pfft_free(in); pfft_free(out); 89 | MPI_Finalize(); 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /tests/simple_check_r2r_4d_transposed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[2]; 7 | ptrdiff_t n[4], N[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err, *in, *out; 12 | pfft_plan plan_forw=NULL, plan_back=NULL; 13 | MPI_Comm comm_cart_2d; 14 | pfft_r2r_kind kinds_forw[4], kinds_back[4]; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; 19 | 20 | /* Set FFTW kinds of 1d R2R trafos */ 21 | kinds_forw[0] = PFFT_REDFT00; kinds_back[0] = PFFT_REDFT00; 22 | kinds_forw[1] = PFFT_REDFT01; kinds_back[1] = PFFT_REDFT10; 23 | kinds_forw[2] = PFFT_RODFT00; kinds_back[2] = PFFT_RODFT00; 24 | kinds_forw[3] = PFFT_RODFT10; kinds_back[3] = PFFT_RODFT01; 25 | 26 | /* Set logical DFT sizes corresponding to FFTW manual: 27 | * for REDFT00 N=2*(n-1), for RODFT00 N=2*(n+1), otherwise N=2*n */ 28 | N[0] = 2*(n[0]-1); 29 | N[1] = 2*n[1]; 30 | N[2] = 2*(n[2]+1); 31 | N[3] = 2*n[3]; 32 | 33 | /* Initialize MPI and PFFT */ 34 | MPI_Init(&argc, &argv); 35 | pfft_init(); 36 | 37 | /* Create two-dimensional process grid of size np[0] x np[1], if possible */ 38 | if( pfft_create_procmesh_2d(MPI_COMM_WORLD, np[0], np[1], &comm_cart_2d) ){ 39 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]); 40 | MPI_Finalize(); 41 | return 1; 42 | } 43 | 44 | /* Get parameters of data distribution */ 45 | alloc_local = pfft_local_size_r2r(4, n, comm_cart_2d, PFFT_TRANSPOSED_OUT, 46 | local_ni, local_i_start, local_no, local_o_start); 47 | 48 | /* Allocate memory */ 49 | in = pfft_alloc_real(alloc_local); 50 | out = pfft_alloc_real(alloc_local); 51 | 52 | /* Plan parallel forward FFT */ 53 | plan_forw = pfft_plan_r2r( 54 | 4, n, in, out, comm_cart_2d, kinds_forw, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 55 | 56 | /* Plan parallel backward FFT */ 57 | plan_back = pfft_plan_r2r( 58 | 4, n, out, in, comm_cart_2d, kinds_back, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 59 | 60 | /* Initialize input with random numbers */ 61 | pfft_init_input_real(4, n, local_ni, local_i_start, 62 | in); 63 | 64 | /* execute parallel forward FFT */ 65 | pfft_execute(plan_forw); 66 | 67 | /* clear the old input */ 68 | pfft_clear_input_real(4, n, local_ni, local_i_start, 69 | in); 70 | 71 | /* execute parallel backward FFT */ 72 | pfft_execute(plan_back); 73 | 74 | /* Scale data */ 75 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 76 | in[l] /= (N[0]*N[1]*N[2]*N[3]); 77 | 78 | /* Print error of back transformed data */ 79 | MPI_Barrier(MPI_COMM_WORLD); 80 | err = pfft_check_output_real(4, n, local_ni, local_i_start, in, comm_cart_2d); 81 | pfft_printf(comm_cart_2d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 82 | pfft_printf(comm_cart_2d, "maxerror = %6.2e;\n", err); 83 | 84 | /* free mem and finalize */ 85 | pfft_destroy_plan(plan_forw); 86 | pfft_destroy_plan(plan_back); 87 | MPI_Comm_free(&comm_cart_2d); 88 | pfft_free(in); pfft_free(out); 89 | MPI_Finalize(); 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /m4/ax_fcs_package.m4: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2011 The ScaFaCoS project 2 | # 3 | # This file is part of ScaFaCoS. 4 | # 5 | # ScaFaCoS is free software: you can redistribute it and/or modify it 6 | # under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # ScaFaCoS is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser Public License 16 | # along with this program. If not, see . 17 | # 18 | 19 | AC_DEFUN([AX_FCS_PACKAGE_RESET],[ 20 | ax_fcs_package_file="fcs-package.info" 21 | test -n "$1" && ax_fcs_package_file="$1/${ax_fcs_package_file}" 22 | rm -f ${ax_fcs_package_file} 23 | ]) 24 | 25 | 26 | AC_DEFUN([AX_FCS_PACKAGE_ADD],[ 27 | ax_fcs_package_file="fcs-package.info" 28 | test -n "$3" && ax_fcs_package_file="$3/${ax_fcs_package_file}" 29 | echo "$1=$2" >> ${ax_fcs_package_file} 30 | ]) 31 | 32 | 33 | AC_DEFUN([AX_FCS_PACKAGE_PROCESS],[ 34 | ax_fcs_topdir="$1" 35 | ax_fcs_pkgdirs="$2" 36 | ax_fcs_package_file="fcs-package.info" 37 | ax_nl=" 38 | " 39 | test "x${ax_fcs_topdir}" != x && ax_fcs_topdir="${ax_fcs_topdir%/}/" 40 | while test -n "${ax_fcs_pkgdirs}" ; do 41 | # echo "packages: ${ax_fcs_pkgdirs}" 42 | ax_p="${ax_fcs_pkgdirs%% *}" 43 | if test "${ax_p}" = "${ax_fcs_pkgdirs}" ; then 44 | ax_fcs_pkgdirs= 45 | else 46 | ax_fcs_pkgdirs="${ax_fcs_pkgdirs#* }" 47 | fi 48 | ax_p="${ax_p%/}/" 49 | ax_p="${ax_p%./}" 50 | # echo "ax_p: $ax_p" 51 | ax_f="${ax_fcs_topdir}${ax_p}${ax_fcs_package_file}" 52 | # echo "ax_f: ${ax_f}" 53 | if test -f "${ax_f}" ; then 54 | ax_cfg=`cat ${ax_f}` 55 | # echo "$ax_cfg" 56 | _ifs="${IFS}" 57 | IFS="${ax_nl}" 58 | for ax_l in $ax_cfg ; do 59 | IFS="${_ifs}" 60 | # echo "ax_l: ${ax_l}" 61 | ax_var="${ax_l%%=*}" 62 | ax_val="${ax_l#*=}" 63 | # echo "-> $ax_var / $ax_val" 64 | test "x${ax_var}" = x -o "x${ax_val}" = x && continue 65 | if test "x${ax_var}" = xSUB_PACKAGES ; then 66 | for ax_x in ${ax_val} ; do 67 | ax_fcs_pkgdirs="${ax_p}${ax_x} ${ax_fcs_pkgdirs}" 68 | done 69 | continue 70 | fi 71 | if test "x${ax_var%LIBS_A}" != "x${ax_var}" ; then 72 | ax_val_new= 73 | for ax_x in ${ax_val} ; do 74 | if test "x${ax_x#/}" = "x${ax_x}" ; then 75 | ax_x="${ax_p}${ax_x}" 76 | fi 77 | ax_val_new="${ax_val_new} ${ax_x}" 78 | done 79 | ax_val="${ax_val_new# }" 80 | fi 81 | eval ax_old=\"\$ax_fcs_package_${ax_var}\" 82 | # echo "-> old: ${ax_old}" 83 | if test "x${ax_old}" = x ; then 84 | eval ax_fcs_package_${ax_var}=\"${ax_val}\" 85 | else 86 | eval ax_fcs_package_${ax_var}=\"\$ax_fcs_package_${ax_var} ${ax_val}\" 87 | fi 88 | # eval ax_new=\"\$ax_fcs_package_${ax_var}\" 89 | # echo "-> new: ${ax_new}" 90 | IFS="${ax_nl}" 91 | done 92 | IFS="${_ifs}" 93 | fi 94 | done 95 | ]) 96 | -------------------------------------------------------------------------------- /tests/simple_check_r2r_4d_on_3d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[3]; 7 | ptrdiff_t n[4], N[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err, *in, *out; 12 | pfft_plan plan_forw=NULL, plan_back=NULL; 13 | MPI_Comm comm_cart_3d; 14 | pfft_r2r_kind kinds_forw[4], kinds_back[4]; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; np[2] = 2; 19 | 20 | /* Set FFTW kinds of 1d R2R trafos */ 21 | kinds_forw[0] = PFFT_REDFT00; kinds_back[0] = PFFT_REDFT00; 22 | kinds_forw[1] = PFFT_REDFT01; kinds_back[1] = PFFT_REDFT10; 23 | kinds_forw[2] = PFFT_RODFT00; kinds_back[2] = PFFT_RODFT00; 24 | kinds_forw[3] = PFFT_RODFT10; kinds_back[3] = PFFT_RODFT01; 25 | 26 | /* Set logical DFT sizes corresponding to FFTW manual: 27 | * for REDFT00 N=2*(n-1), for RODFT00 N=2*(n+1), otherwise N=2*n */ 28 | N[0] = 2*(n[0]-1); 29 | N[1] = 2*n[1]; 30 | N[2] = 2*(n[2]+1); 31 | N[3] = 2*n[3]; 32 | 33 | /* Initialize MPI and PFFT */ 34 | MPI_Init(&argc, &argv); 35 | pfft_init(); 36 | 37 | /* Create three-dimensional process grid of size np[0] x np[1] x np[2], if possible */ 38 | if( pfft_create_procmesh(3, MPI_COMM_WORLD, np, &comm_cart_3d) ){ 39 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]*np[2]); 40 | MPI_Finalize(); 41 | return 1; 42 | } 43 | 44 | /* Get parameters of data distribution */ 45 | alloc_local = pfft_local_size_r2r(4, n, comm_cart_3d, PFFT_TRANSPOSED_NONE, 46 | local_ni, local_i_start, local_no, local_o_start); 47 | 48 | /* Allocate memory */ 49 | in = pfft_alloc_real(alloc_local); 50 | out = pfft_alloc_real(alloc_local); 51 | 52 | /* Plan parallel forward FFT */ 53 | plan_forw = pfft_plan_r2r( 54 | 4, n, in, out, comm_cart_3d, kinds_forw, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 55 | 56 | /* Plan parallel backward FFT */ 57 | plan_back = pfft_plan_r2r( 58 | 4, n, out, in, comm_cart_3d, kinds_back, PFFT_TRANSPOSED_NONE| PFFT_MEASURE| PFFT_DESTROY_INPUT); 59 | 60 | /* Initialize input with random numbers */ 61 | pfft_init_input_real(4, n, local_ni, local_i_start, 62 | in); 63 | 64 | /* execute parallel forward FFT */ 65 | pfft_execute(plan_forw); 66 | 67 | /* clear the old input */ 68 | pfft_clear_input_real(4, n, local_ni, local_i_start, 69 | in); 70 | 71 | /* execute parallel backward FFT */ 72 | pfft_execute(plan_back); 73 | 74 | /* Scale data */ 75 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 76 | in[l] /= (N[0]*N[1]*N[2]*N[3]); 77 | 78 | /* Print error of back transformed data */ 79 | MPI_Barrier(MPI_COMM_WORLD); 80 | err = pfft_check_output_real(4, n, local_ni, local_i_start, in, comm_cart_3d); 81 | pfft_printf(comm_cart_3d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 82 | pfft_printf(comm_cart_3d, "maxerror = %6.2e;\n", err); 83 | 84 | /* free mem and finalize */ 85 | pfft_destroy_plan(plan_forw); 86 | pfft_destroy_plan(plan_back); 87 | MPI_Comm_free(&comm_cart_3d); 88 | pfft_free(in); pfft_free(out); 89 | MPI_Finalize(); 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /tests/simple_check_r2r_4d_on_3d_transposed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | int np[3]; 7 | ptrdiff_t n[4], N[4]; 8 | ptrdiff_t alloc_local; 9 | ptrdiff_t local_ni[4], local_i_start[4]; 10 | ptrdiff_t local_no[4], local_o_start[4]; 11 | double err, *in, *out; 12 | pfft_plan plan_forw=NULL, plan_back=NULL; 13 | MPI_Comm comm_cart_3d; 14 | pfft_r2r_kind kinds_forw[4], kinds_back[4]; 15 | 16 | /* Set size of FFT and process mesh */ 17 | n[0] = 13; n[1] = 14; n[2] = 19; n[3] = 17; 18 | np[0] = 2; np[1] = 2; np[2] = 2; 19 | 20 | /* Set FFTW kinds of 1d R2R trafos */ 21 | kinds_forw[0] = PFFT_REDFT00; kinds_back[0] = PFFT_REDFT00; 22 | kinds_forw[1] = PFFT_REDFT01; kinds_back[1] = PFFT_REDFT10; 23 | kinds_forw[2] = PFFT_RODFT00; kinds_back[2] = PFFT_RODFT00; 24 | kinds_forw[3] = PFFT_RODFT10; kinds_back[3] = PFFT_RODFT01; 25 | 26 | /* Set logical DFT sizes corresponding to FFTW manual: 27 | * for REDFT00 N=2*(n-1), for RODFT00 N=2*(n+1), otherwise N=2*n */ 28 | N[0] = 2*(n[0]-1); 29 | N[1] = 2*n[1]; 30 | N[2] = 2*(n[2]+1); 31 | N[3] = 2*n[3]; 32 | 33 | /* Initialize MPI and PFFT */ 34 | MPI_Init(&argc, &argv); 35 | pfft_init(); 36 | 37 | /* Create three-dimensional process grid of size np[0] x np[1] x np[2], if possible */ 38 | if( pfft_create_procmesh(3, MPI_COMM_WORLD, np, &comm_cart_3d) ){ 39 | pfft_fprintf(MPI_COMM_WORLD, stderr, "Error: This test file only works with %d processes.\n", np[0]*np[1]*np[2]); 40 | MPI_Finalize(); 41 | return 1; 42 | } 43 | 44 | /* Get parameters of data distribution */ 45 | alloc_local = pfft_local_size_r2r(4, n, comm_cart_3d, PFFT_TRANSPOSED_OUT, 46 | local_ni, local_i_start, local_no, local_o_start); 47 | 48 | /* Allocate memory */ 49 | in = pfft_alloc_real(alloc_local); 50 | out = pfft_alloc_real(alloc_local); 51 | 52 | /* Plan parallel forward FFT */ 53 | plan_forw = pfft_plan_r2r( 54 | 4, n, in, out, comm_cart_3d, kinds_forw, PFFT_TRANSPOSED_OUT| PFFT_MEASURE| PFFT_DESTROY_INPUT); 55 | 56 | /* Plan parallel backward FFT */ 57 | plan_back = pfft_plan_r2r( 58 | 4, n, out, in, comm_cart_3d, kinds_back, PFFT_TRANSPOSED_IN| PFFT_MEASURE| PFFT_DESTROY_INPUT); 59 | 60 | /* Initialize input with random numbers */ 61 | pfft_init_input_real(4, n, local_ni, local_i_start, 62 | in); 63 | 64 | /* execute parallel forward FFT */ 65 | pfft_execute(plan_forw); 66 | 67 | /* clear the old input */ 68 | pfft_clear_input_real(4, n, local_ni, local_i_start, 69 | in); 70 | 71 | /* execute parallel backward FFT */ 72 | pfft_execute(plan_back); 73 | 74 | /* Scale data */ 75 | for(ptrdiff_t l=0; l < local_ni[0] * local_ni[1] * local_ni[2] * local_ni[3]; l++) 76 | in[l] /= (N[0]*N[1]*N[2]*N[3]); 77 | 78 | /* Print error of back transformed data */ 79 | MPI_Barrier(MPI_COMM_WORLD); 80 | err = pfft_check_output_real(4, n, local_ni, local_i_start, in, comm_cart_3d); 81 | pfft_printf(comm_cart_3d, "Error after one forward and backward trafo of size n=(%td, %td, %td, %td):\n", n[0], n[1], n[2], n[3]); 82 | pfft_printf(comm_cart_3d, "maxerror = %6.2e;\n", err); 83 | 84 | /* free mem and finalize */ 85 | pfft_destroy_plan(plan_forw); 86 | pfft_destroy_plan(plan_back); 87 | MPI_Comm_free(&comm_cart_3d); 88 | pfft_free(in); pfft_free(out); 89 | MPI_Finalize(); 90 | return 0; 91 | } 92 | --------------------------------------------------------------------------------