Merge branch 'master' into ZSMv1
This commit is contained in:
commit
378f6a957b
|
@ -25,6 +25,10 @@ set(SYSTEM_SDL2_DEFAULT OFF)
|
|||
if (ANDROID)
|
||||
set(USE_RTMIDI_DEFAULT OFF)
|
||||
set(USE_BACKWARD_DEFAULT OFF)
|
||||
find_library(TERMUX rt)
|
||||
if (TERMUX)
|
||||
message(STATUS "Termux detected")
|
||||
endif()
|
||||
else()
|
||||
set(USE_RTMIDI_DEFAULT ON)
|
||||
set(USE_BACKWARD_DEFAULT ON)
|
||||
|
@ -44,6 +48,7 @@ option(USE_SDL2 "Build with SDL2. Required to build with GUI." ${USE_SDL2_DEFAUL
|
|||
option(USE_SNDFILE "Build with libsndfile. Required in order to work with audio files." ${USE_SNDFILE_DEFAULT})
|
||||
option(USE_BACKWARD "Use backward-cpp to print a backtrace on crash/abort." ${USE_BACKWARD_DEFAULT})
|
||||
option(WITH_JACK "Whether to build with JACK support. Auto-detects if JACK is available" ${WITH_JACK_DEFAULT})
|
||||
option(SYSTEM_FFTW "Use a system-installed version of FFTW instead of the vendored one" OFF)
|
||||
option(SYSTEM_FMT "Use a system-installed version of fmt instead of the vendored one" OFF)
|
||||
option(SYSTEM_LIBSNDFILE "Use a system-installed version of libsndfile instead of the vendored one" OFF)
|
||||
option(SYSTEM_RTMIDI "Use a system-installed version of RtMidi instead of the vendored one" OFF)
|
||||
|
@ -53,7 +58,7 @@ option(WARNINGS_ARE_ERRORS "Whether warnings in furnace's C++ code should be tre
|
|||
|
||||
set(DEPENDENCIES_INCLUDE_DIRS "")
|
||||
|
||||
if (ANDROID)
|
||||
if (ANDROID AND NOT TERMUX)
|
||||
set(DEPENDENCIES_DEFINES "IS_MOBILE")
|
||||
else()
|
||||
set(DEPENDENCIES_DEFINES "")
|
||||
|
@ -76,6 +81,26 @@ list(APPEND DEPENDENCIES_INCLUDE_DIRS "extern/SAASound/include")
|
|||
find_package(Threads REQUIRED)
|
||||
list(APPEND DEPENDENCIES_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
if (SYSTEM_FFTW)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(FFTW REQUIRED fftw3>=3.3)
|
||||
list(APPEND DEPENDENCIES_INCLUDE_DIRS ${FFTW_INCLUDE_DIRS})
|
||||
list(APPEND DEPENDENCIES_COMPILE_OPTIONS ${FFTW_CFLAGS_OTHER})
|
||||
list(APPEND DEPENDENCIES_LIBRARIES ${FFTW_LIBRARIES})
|
||||
list(APPEND DEPENDENCIES_LIBRARY_DIRS ${FFTW_LIBRARY_DIRS})
|
||||
list(APPEND DEPENDENCIES_LINK_OPTIONS ${FFTW_LDFLAGS_OTHER})
|
||||
list(APPEND DEPENDENCIES_LEGACY_LDFLAGS ${FFTW_LDFLAGS})
|
||||
message(STATUS "Using system-installed FFTW")
|
||||
else()
|
||||
if (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(WITH_OUR_MALLOC ON CACHE BOOL "aaa" FORCE)
|
||||
endif()
|
||||
add_subdirectory(extern/fftw EXCLUDE_FROM_ALL)
|
||||
list(APPEND DEPENDENCIES_INCLUDE_DIRS extern/fftw/api)
|
||||
list(APPEND DEPENDENCIES_LIBRARIES fftw3)
|
||||
message(STATUS "Using vendored FFTW")
|
||||
endif()
|
||||
|
||||
if (SYSTEM_FMT)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(FMT fmt>=7.1.0)
|
||||
|
@ -188,7 +213,7 @@ if (USE_SDL2)
|
|||
endif()
|
||||
message(STATUS "Using system-installed SDL2")
|
||||
else()
|
||||
if (ANDROID)
|
||||
if (ANDROID AND NOT TERMUX)
|
||||
set(SDL_SHARED ON CACHE BOOL "Force no dynamically-linked SDL" FORCE)
|
||||
set(SDL_STATIC OFF CACHE BOOL "Force statically-linked SDL" FORCE)
|
||||
else()
|
||||
|
@ -203,7 +228,7 @@ if (USE_SDL2)
|
|||
add_subdirectory(extern/SDL EXCLUDE_FROM_ALL)
|
||||
list(APPEND DEPENDENCIES_DEFINES HAVE_SDL2)
|
||||
list(APPEND DEPENDENCIES_INCLUDE_DIRS extern/SDL/include)
|
||||
if (ANDROID)
|
||||
if (ANDROID AND NOT TERMUX)
|
||||
list(APPEND DEPENDENCIES_LIBRARIES SDL2)
|
||||
else()
|
||||
list(APPEND DEPENDENCIES_LIBRARIES SDL2-static)
|
||||
|
@ -471,6 +496,7 @@ src/gui/doAction.cpp
|
|||
src/gui/editing.cpp
|
||||
src/gui/editControls.cpp
|
||||
src/gui/effectList.cpp
|
||||
src/gui/findReplace.cpp
|
||||
src/gui/insEdit.cpp
|
||||
src/gui/log.cpp
|
||||
src/gui/mixer.cpp
|
||||
|
@ -511,6 +537,9 @@ if (USE_BACKWARD)
|
|||
if (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
list(APPEND DEPENDENCIES_LIBRARIES dbghelp psapi)
|
||||
endif()
|
||||
message(STATUS "Using backward-cpp")
|
||||
else()
|
||||
message(STATUS "Not using backward-cpp")
|
||||
endif()
|
||||
|
||||
if (BUILD_GUI)
|
||||
|
@ -573,7 +602,7 @@ endif()
|
|||
|
||||
if (MSVC)
|
||||
add_executable(furnace WIN32 ${USED_SOURCES})
|
||||
elseif(ANDROID)
|
||||
elseif(ANDROID AND NOT TERMUX)
|
||||
add_library(furnace SHARED ${USED_SOURCES})
|
||||
else()
|
||||
add_executable(furnace ${USED_SOURCES})
|
||||
|
@ -596,7 +625,7 @@ if (PKG_CONFIG_FOUND AND (SYSTEM_FMT OR SYSTEM_LIBSNDFILE OR SYSTEM_ZLIB OR SYST
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT ANDROID)
|
||||
if (NOT ANDROID OR TERMUX)
|
||||
install(TARGETS furnace RUNTIME DESTINATION bin)
|
||||
|
||||
if (NOT WIN32 AND NOT APPLE)
|
||||
|
|
21
TODO.md
21
TODO.md
|
@ -1,21 +1,12 @@
|
|||
# to-do for 0.6pre1
|
||||
|
||||
- additional YM2612 features
|
||||
- CSM
|
||||
- MSM6258 pitch and clock select
|
||||
- MSM6295 clock select
|
||||
- Game Boy envelope macro/sequence
|
||||
- drag-and-drop ins/wave/sample loading
|
||||
- "set loop" in right click menu of sample editor
|
||||
- sample editor preview in selection
|
||||
- rewrite the system name detection function anyway
|
||||
- unified data view
|
||||
- volume commands should work on Game Boy
|
||||
- add another FM editor layout
|
||||
- try to find out why does VSlider not accept keyboard input
|
||||
- if macros have release, note off should release them
|
||||
- add ability to select a column by double clicking
|
||||
- add ability to move selection by dragging
|
||||
- Apply button in settings
|
||||
- find and replace
|
||||
- add mono/poly note preview button
|
||||
- implement Defle slide bug when using E1xy/E2xy and repeating origin note (requires format change)
|
||||
|
||||
# to-do for 0.6pre2 (as this requires new data structures)
|
||||
|
||||
- Game Boy envelope macro/sequence
|
||||
- volume commands should work on Game Boy
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -4252,7 +4252,20 @@ public:
|
|||
st.load_here(32, reinterpret_cast<void *>(uctx), info->si_addr);
|
||||
}
|
||||
|
||||
FILE* crashDump=fopen("furnace_crash.txt","w");
|
||||
#ifdef _WIN32
|
||||
MessageBox(NULL,"Error","Furnace has crashed! please report this to the issue tracker immediately:\r\nhttps://github.com/tildearrow/furnace/issues/new\r\n\r\na file called furnace_crash.txt will be created in your user directory.\r\nthis will be important for locating the origin of the crash.",MB_OK|MB_ICONERROR);
|
||||
std::string crashLocation;
|
||||
char* userProfile=getenv("USERPROFILE");
|
||||
if (userProfile==NULL) {
|
||||
crashLocation="C:\\furnace_crash.txt";
|
||||
} else {
|
||||
crashLocation=userProfile;
|
||||
crashLocation+="\\furnace_crash.txt";
|
||||
}
|
||||
FILE* crashDump=fopen(crashLocation.c_str(),"w");
|
||||
#else
|
||||
FILE* crashDump=fopen("/tmp/furnace_crash.txt","w");
|
||||
#endif
|
||||
|
||||
Printer printer;
|
||||
printer.address = true;
|
||||
|
@ -4263,6 +4276,16 @@ public:
|
|||
printer.address = true;
|
||||
printer.print(st, crashDump);
|
||||
fclose(crashDump);
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
std::string str;
|
||||
Printer failedPrinter;
|
||||
failedPrinter.address = true;
|
||||
failedPrinter.print(st, str);
|
||||
str+="\r\ncould not open furnace_crash.txt!\r\nplease take a screenshot of this error message box!";
|
||||
fprintf(stderr,"NOTICE: could not open furnace_crash.txt!\n");
|
||||
MessageBox(NULL,"Error",str.c_str(),MB_OK|MB_ICONERROR);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || \
|
||||
|
@ -4467,6 +4490,38 @@ private:
|
|||
|
||||
printer.address = true;
|
||||
printer.print(st, std::cerr);
|
||||
|
||||
#ifdef _WIN32
|
||||
MessageBox(NULL,"Furnace has crashed! please report this to the issue tracker immediately:\r\nhttps://github.com/tildearrow/furnace/issues/new\r\n\r\na file called furnace_crash.txt will be created in your user directory.\r\nthis will be important for locating the origin of the crash.","Error",MB_OK|MB_ICONERROR);
|
||||
std::string crashLocation;
|
||||
char* userProfile=getenv("USERPROFILE");
|
||||
if (userProfile==NULL) {
|
||||
crashLocation="furnace_crash.txt";
|
||||
} else {
|
||||
crashLocation=userProfile;
|
||||
crashLocation+="\\furnace_crash.txt";
|
||||
}
|
||||
FILE* crashDump=fopen(crashLocation.c_str(),"w");
|
||||
#else
|
||||
FILE* crashDump=fopen("/tmp/furnace_crash.txt","w");
|
||||
#endif
|
||||
|
||||
if (crashDump!=NULL) {
|
||||
Printer printer;
|
||||
printer.address = true;
|
||||
printer.print(st, crashDump);
|
||||
fclose(crashDump);
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
std::string str;
|
||||
//Printer failedPrinter;
|
||||
//failedPrinter.address = true;
|
||||
//failedPrinter.print(st, str);
|
||||
str+="\r\ncould not open furnace_crash.txt!\r\nplease take a screenshot of this error message box!";
|
||||
fprintf(stderr,"NOTICE: could not open furnace_crash.txt!\n");
|
||||
MessageBox(NULL,str.c_str(),"Error",MB_OK|MB_ICONERROR);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
Authors of FFTW (reachable at fftw@fftw.org):
|
||||
|
||||
Matteo Frigo <athena@fftw.org>
|
||||
Steven G. Johnson <stevenj@alum.mit.edu>
|
||||
|
||||
Stefan Kral <skral@fftw.org> wrote genfft-k7/*.ml*, which was
|
||||
added in fftw-3.0 and removed in fftw-3.2.
|
||||
|
||||
Romain Dolbeau contributed support for AVX512 and KCvi.
|
||||
|
||||
Erik Lindahl contributed support for AVX2 and Power8 VSX.
|
||||
|
||||
Support for the Cell Broadband Engine was graciously donated by the
|
||||
IBM Austin Research Lab, which was added in fftw-3.2 and removed in
|
||||
fftw-3.3.
|
||||
|
||||
Support for MIPS64 paired-single SIMD instructions was graciously
|
||||
donated by CodeSourcery, Inc.
|
|
@ -0,0 +1,438 @@
|
|||
cmake_minimum_required (VERSION 3.0)
|
||||
|
||||
if (NOT DEFINED CMAKE_BUILD_TYPE)
|
||||
set (CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
|
||||
endif ()
|
||||
|
||||
project (fftw)
|
||||
|
||||
if (POLICY CMP0042)
|
||||
cmake_policy (SET CMP0042 NEW)
|
||||
endif ()
|
||||
|
||||
option (BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||
option (BUILD_TESTS "Build tests" ON)
|
||||
|
||||
option (ENABLE_OPENMP "Use OpenMP for multithreading" OFF)
|
||||
option (ENABLE_THREADS "Use pthread for multithreading" OFF)
|
||||
option (WITH_COMBINED_THREADS "Merge thread library" OFF)
|
||||
option (WITH_OUR_MALLOC "Use own aligned malloc()/free() implementation" OFF)
|
||||
|
||||
option (ENABLE_FLOAT "single-precision" OFF)
|
||||
option (ENABLE_LONG_DOUBLE "long-double precision" OFF)
|
||||
option (ENABLE_QUAD_PRECISION "quadruple-precision" OFF)
|
||||
|
||||
option (ENABLE_SSE "Compile with SSE instruction set support" OFF)
|
||||
option (ENABLE_SSE2 "Compile with SSE2 instruction set support" OFF)
|
||||
option (ENABLE_AVX "Compile with AVX instruction set support" OFF)
|
||||
option (ENABLE_AVX2 "Compile with AVX2 instruction set support" OFF)
|
||||
|
||||
option (DISABLE_FORTRAN "Disable Fortran wrapper routines" OFF)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
|
||||
include (CheckIncludeFile)
|
||||
check_include_file (alloca.h HAVE_ALLOCA_H)
|
||||
check_include_file (altivec.h HAVE_ALTIVEC_H)
|
||||
check_include_file (c_asm.h HAVE_C_ASM_H)
|
||||
check_include_file (dlfcn.h HAVE_DLFCN_H)
|
||||
check_include_file (intrinsics.h HAVE_INTRINSICS_H)
|
||||
check_include_file (inttypes.h HAVE_INTTYPES_H)
|
||||
check_include_file (libintl.h HAVE_LIBINTL_H)
|
||||
check_include_file (limits.h HAVE_LIMITS_H)
|
||||
check_include_file (mach/mach_time.h HAVE_MACH_MACH_TIME_H)
|
||||
check_include_file (malloc.h HAVE_MALLOC_H)
|
||||
check_include_file (memory.h HAVE_MEMORY_H)
|
||||
check_include_file (stddef.h HAVE_STDDEF_H)
|
||||
check_include_file (stdint.h HAVE_STDINT_H)
|
||||
check_include_file (stdlib.h HAVE_STDLIB_H)
|
||||
check_include_file (string.h HAVE_STRING_H)
|
||||
check_include_file (strings.h HAVE_STRINGS_H)
|
||||
check_include_file (sys/types.h HAVE_SYS_TYPES_H)
|
||||
check_include_file (sys/time.h HAVE_SYS_TIME_H)
|
||||
check_include_file (sys/stat.h HAVE_SYS_STAT_H)
|
||||
check_include_file (sys/sysctl.h HAVE_SYS_SYSCTL_H)
|
||||
check_include_file (time.h HAVE_TIME_H)
|
||||
check_include_file (uintptr.h HAVE_UINTPTR_H)
|
||||
check_include_file (unistd.h HAVE_UNISTD_H)
|
||||
if (HAVE_TIME_H AND HAVE_SYS_TIME_H)
|
||||
set (TIME_WITH_SYS_TIME TRUE)
|
||||
endif ()
|
||||
|
||||
include (CheckPrototypeDefinition)
|
||||
check_prototype_definition (drand48 "double drand48 (void)" "0" stdlib.h HAVE_DECL_DRAND48)
|
||||
check_prototype_definition (srand48 "void srand48(long int seedval)" "0" stdlib.h HAVE_DECL_SRAND48)
|
||||
check_prototype_definition (cosl "long double cosl( long double arg )" "0" math.h HAVE_DECL_COSL)
|
||||
check_prototype_definition (sinl "long double sinl( long double arg )" "0" math.h HAVE_DECL_SINL)
|
||||
check_prototype_definition (memalign "void *memalign(size_t alignment, size_t size)" "0" malloc.h HAVE_DECL_MEMALIGN)
|
||||
check_prototype_definition (posix_memalign "int posix_memalign(void **memptr, size_t alignment, size_t size)" "0" stdlib.h HAVE_DECL_POSIX_MEMALIGN)
|
||||
|
||||
include (CheckSymbolExists)
|
||||
check_symbol_exists (clock_gettime time.h HAVE_CLOCK_GETTIME)
|
||||
check_symbol_exists (gettimeofday sys/time.h HAVE_GETTIMEOFDAY)
|
||||
check_symbol_exists (getpagesize unistd.h HAVE_GETPAGESIZE)
|
||||
check_symbol_exists (drand48 stdlib.h HAVE_DRAND48)
|
||||
check_symbol_exists (srand48 stdlib.h HAVE_SRAND48)
|
||||
check_symbol_exists (memalign malloc.h HAVE_MEMALIGN)
|
||||
check_symbol_exists (posix_memalign stdlib.h HAVE_POSIX_MEMALIGN)
|
||||
check_symbol_exists (mach_absolute_time mach/mach_time.h HAVE_MACH_ABSOLUTE_TIME)
|
||||
check_symbol_exists (alloca alloca.h HAVE_ALLOCA)
|
||||
if (NOT HAVE_ALLOCA)
|
||||
unset (HAVE_ALLOCA CACHE)
|
||||
check_symbol_exists (alloca malloc.h HAVE_ALLOCA)
|
||||
endif ()
|
||||
check_symbol_exists (isnan math.h HAVE_ISNAN)
|
||||
check_symbol_exists (snprintf stdio.h HAVE_SNPRINTF)
|
||||
check_symbol_exists (strchr string.h HAVE_STRCHR)
|
||||
check_symbol_exists (sysctl unistd.h HAVE_SYSCTL)
|
||||
|
||||
if (UNIX)
|
||||
set (CMAKE_REQUIRED_LIBRARIES m)
|
||||
endif ()
|
||||
check_symbol_exists (cosl math.h HAVE_COSL)
|
||||
check_symbol_exists (sinl math.h HAVE_SINL)
|
||||
|
||||
include (CheckTypeSize)
|
||||
check_type_size ("float" SIZEOF_FLOAT)
|
||||
check_type_size ("double" SIZEOF_DOUBLE)
|
||||
check_type_size ("int" SIZEOF_INT)
|
||||
check_type_size ("long" SIZEOF_LONG)
|
||||
check_type_size ("long long" SIZEOF_LONG_LONG)
|
||||
check_type_size ("unsigned int" SIZEOF_UNSIGNED_INT)
|
||||
check_type_size ("unsigned long" SIZEOF_UNSIGNED_LONG)
|
||||
check_type_size ("unsigned long long" SIZEOF_UNSIGNED_LONG_LONG)
|
||||
check_type_size ("size_t" SIZEOF_SIZE_T)
|
||||
check_type_size ("ptrdiff_t" SIZEOF_PTRDIFF_T)
|
||||
math (EXPR SIZEOF_INT_BITS "8 * ${SIZEOF_INT}")
|
||||
set (C_FFTW_R2R_KIND "C_INT${SIZEOF_INT_BITS}_T")
|
||||
|
||||
find_library (LIBM_LIBRARY NAMES m)
|
||||
if (LIBM_LIBRARY)
|
||||
set (HAVE_LIBM TRUE)
|
||||
endif ()
|
||||
|
||||
|
||||
if (ENABLE_THREADS)
|
||||
find_package (Threads)
|
||||
endif ()
|
||||
if (Threads_FOUND)
|
||||
if(CMAKE_USE_PTHREADS_INIT)
|
||||
set (USING_POSIX_THREADS 1)
|
||||
endif ()
|
||||
set (HAVE_THREADS TRUE)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_OPENMP)
|
||||
find_package (OpenMP)
|
||||
endif ()
|
||||
if (OPENMP_FOUND)
|
||||
set (HAVE_OPENMP TRUE)
|
||||
endif ()
|
||||
|
||||
include (CheckCCompilerFlag)
|
||||
|
||||
if (ENABLE_SSE)
|
||||
foreach (FLAG "-msse" "/arch:SSE")
|
||||
unset (HAVE_SSE CACHE)
|
||||
unset (HAVE_SSE)
|
||||
check_c_compiler_flag (${FLAG} HAVE_SSE)
|
||||
if (HAVE_SSE)
|
||||
set (SSE_FLAG ${FLAG})
|
||||
break()
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
if (ENABLE_SSE2)
|
||||
foreach (FLAG "-msse2" "/arch:SSE2")
|
||||
unset (HAVE_SSE2 CACHE)
|
||||
unset (HAVE_SSE2)
|
||||
check_c_compiler_flag (${FLAG} HAVE_SSE2)
|
||||
if (HAVE_SSE2)
|
||||
set (SSE2_FLAG ${FLAG})
|
||||
break()
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
if (ENABLE_AVX)
|
||||
foreach (FLAG "-mavx" "/arch:AVX")
|
||||
unset (HAVE_AVX CACHE)
|
||||
unset (HAVE_AVX)
|
||||
check_c_compiler_flag (${FLAG} HAVE_AVX)
|
||||
if (HAVE_AVX)
|
||||
set (AVX_FLAG ${FLAG})
|
||||
break()
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
if (ENABLE_AVX2)
|
||||
foreach (FLAG "-mavx2" "/arch:AVX2")
|
||||
unset (HAVE_AVX2 CACHE)
|
||||
unset (HAVE_AVX2)
|
||||
check_c_compiler_flag (${FLAG} HAVE_AVX2)
|
||||
if (HAVE_AVX2)
|
||||
set (AVX2_FLAG ${FLAG})
|
||||
break()
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
# AVX2 codelets require FMA support as well
|
||||
if (ENABLE_AVX2)
|
||||
foreach (FLAG "-mfma" "/arch:FMA")
|
||||
unset (HAVE_FMA CACHE)
|
||||
unset (HAVE_FMA)
|
||||
check_c_compiler_flag (${FLAG} HAVE_FMA)
|
||||
if (HAVE_FMA)
|
||||
set (FMA_FLAG ${FLAG})
|
||||
break()
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
if (HAVE_SSE2 OR HAVE_AVX)
|
||||
set (HAVE_SIMD TRUE)
|
||||
endif ()
|
||||
file(GLOB fftw_api_SOURCE api/*.c api/*.h)
|
||||
file(GLOB fftw_dft_SOURCE dft/*.c dft/*.h)
|
||||
file(GLOB fftw_dft_scalar_SOURCE dft/scalar/*.c dft/scalar/*.h)
|
||||
file(GLOB fftw_dft_scalar_codelets_SOURCE dft/scalar/codelets/*.c dft/scalar/codelets/*.h)
|
||||
file(GLOB fftw_dft_simd_SOURCE dft/simd/*.c dft/simd/*.h)
|
||||
|
||||
file(GLOB fftw_dft_simd_sse2_SOURCE dft/simd/sse2/*.c dft/simd/sse2/*.h)
|
||||
file(GLOB fftw_dft_simd_avx_SOURCE dft/simd/avx/*.c dft/simd/avx/*.h)
|
||||
file(GLOB fftw_dft_simd_avx2_SOURCE dft/simd/avx2/*.c dft/simd/avx2/*.h dft/simd/avx2-128/*.c dft/simd/avx2-128/*.h)
|
||||
file(GLOB fftw_kernel_SOURCE kernel/*.c kernel/*.h)
|
||||
file(GLOB fftw_rdft_SOURCE rdft/*.c rdft/*.h)
|
||||
file(GLOB fftw_rdft_scalar_SOURCE rdft/scalar/*.c rdft/scalar/*.h)
|
||||
|
||||
file(GLOB fftw_rdft_scalar_r2cb_SOURCE rdft/scalar/r2cb/*.c
|
||||
rdft/scalar/r2cb/*.h)
|
||||
file(GLOB fftw_rdft_scalar_r2cf_SOURCE rdft/scalar/r2cf/*.c
|
||||
rdft/scalar/r2cf/*.h)
|
||||
file(GLOB fftw_rdft_scalar_r2r_SOURCE rdft/scalar/r2r/*.c
|
||||
rdft/scalar/r2r/*.h)
|
||||
|
||||
file(GLOB fftw_rdft_simd_SOURCE rdft/simd/*.c rdft/simd/*.h)
|
||||
file(GLOB fftw_rdft_simd_sse2_SOURCE rdft/simd/sse2/*.c rdft/simd/sse2/*.h)
|
||||
file(GLOB fftw_rdft_simd_avx_SOURCE rdft/simd/avx/*.c rdft/simd/avx/*.h)
|
||||
file(GLOB fftw_rdft_simd_avx2_SOURCE rdft/simd/avx2/*.c rdft/simd/avx2/*.h rdft/simd/avx2-128/*.c rdft/simd/avx2-128/*.h)
|
||||
|
||||
file(GLOB fftw_reodft_SOURCE reodft/*.c reodft/*.h)
|
||||
file(GLOB fftw_simd_support_SOURCE simd-support/*.c simd-support/*.h)
|
||||
file(GLOB fftw_libbench2_SOURCE libbench2/*.c libbench2/*.h)
|
||||
list (REMOVE_ITEM fftw_libbench2_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/libbench2/useropt.c)
|
||||
|
||||
set(SOURCEFILES
|
||||
${fftw_api_SOURCE}
|
||||
${fftw_dft_SOURCE}
|
||||
${fftw_dft_scalar_SOURCE}
|
||||
${fftw_dft_scalar_codelets_SOURCE}
|
||||
${fftw_dft_simd_SOURCE}
|
||||
${fftw_kernel_SOURCE}
|
||||
${fftw_rdft_SOURCE}
|
||||
${fftw_rdft_scalar_SOURCE}
|
||||
|
||||
${fftw_rdft_scalar_r2cb_SOURCE}
|
||||
${fftw_rdft_scalar_r2cf_SOURCE}
|
||||
${fftw_rdft_scalar_r2r_SOURCE}
|
||||
|
||||
${fftw_rdft_simd_SOURCE}
|
||||
${fftw_reodft_SOURCE}
|
||||
${fftw_simd_support_SOURCE}
|
||||
${fftw_threads_SOURCE}
|
||||
)
|
||||
|
||||
set(fftw_par_SOURCE
|
||||
threads/api.c
|
||||
threads/conf.c
|
||||
threads/ct.c
|
||||
threads/dft-vrank-geq1.c
|
||||
threads/f77api.c
|
||||
threads/hc2hc.c
|
||||
threads/rdft-vrank-geq1.c
|
||||
threads/vrank-geq1-rdft2.c)
|
||||
|
||||
set (fftw_threads_SOURCE ${fftw_par_SOURCE} threads/threads.c)
|
||||
set (fftw_omp_SOURCE ${fftw_par_SOURCE} threads/openmp.c)
|
||||
|
||||
|
||||
include_directories (.)
|
||||
|
||||
|
||||
if (WITH_COMBINED_THREADS)
|
||||
list (APPEND SOURCEFILES ${fftw_threads_SOURCE})
|
||||
endif ()
|
||||
|
||||
|
||||
if (HAVE_SSE2)
|
||||
list (APPEND SOURCEFILES ${fftw_dft_simd_sse2_SOURCE} ${fftw_rdft_simd_sse2_SOURCE})
|
||||
endif ()
|
||||
|
||||
if (HAVE_AVX)
|
||||
list (APPEND SOURCEFILES ${fftw_dft_simd_avx_SOURCE} ${fftw_rdft_simd_avx_SOURCE})
|
||||
endif ()
|
||||
|
||||
if (HAVE_AVX2)
|
||||
list (APPEND SOURCEFILES ${fftw_dft_simd_avx2_SOURCE} ${fftw_rdft_simd_avx2_SOURCE})
|
||||
endif ()
|
||||
|
||||
set (FFTW_VERSION 3.3.9)
|
||||
|
||||
set (PREC_SUFFIX)
|
||||
if (ENABLE_FLOAT)
|
||||
set (FFTW_SINGLE TRUE)
|
||||
set (BENCHFFT_SINGLE TRUE)
|
||||
set (PREC_SUFFIX f)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_LONG_DOUBLE)
|
||||
set (FFTW_LDOUBLE TRUE)
|
||||
set (BENCHFFT_LDOUBLE TRUE)
|
||||
set (PREC_SUFFIX l)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_QUAD_PRECISION)
|
||||
set (FFTW_QUAD TRUE)
|
||||
set (BENCHFFT_QUAD TRUE)
|
||||
set (PREC_SUFFIX q)
|
||||
endif ()
|
||||
set (fftw3_lib fftw3${PREC_SUFFIX})
|
||||
|
||||
configure_file (cmake.config.h.in config.h @ONLY)
|
||||
include_directories (${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
add_definitions (-DFFTW_DLL)
|
||||
endif ()
|
||||
|
||||
add_library (${fftw3_lib} ${SOURCEFILES})
|
||||
target_include_directories (${fftw3_lib} INTERFACE $<INSTALL_INTERFACE:include>)
|
||||
if (WITH_OUR_MALLOC)
|
||||
target_compile_definitions (${fftw3_lib} PRIVATE WITH_OUR_MALLOC)
|
||||
endif ()
|
||||
if (MSVC AND NOT (CMAKE_C_COMPILER_ID STREQUAL "Intel"))
|
||||
target_compile_definitions (${fftw3_lib} PRIVATE /bigobj)
|
||||
endif ()
|
||||
if (HAVE_SSE)
|
||||
target_compile_options (${fftw3_lib} PRIVATE ${SSE_FLAG})
|
||||
endif ()
|
||||
if (HAVE_SSE2)
|
||||
target_compile_options (${fftw3_lib} PRIVATE ${SSE2_FLAG})
|
||||
endif ()
|
||||
if (HAVE_AVX)
|
||||
target_compile_options (${fftw3_lib} PRIVATE ${AVX_FLAG})
|
||||
endif ()
|
||||
if (HAVE_AVX2)
|
||||
target_compile_options (${fftw3_lib} PRIVATE ${AVX2_FLAG})
|
||||
endif ()
|
||||
if (HAVE_FMA)
|
||||
target_compile_options (${fftw3_lib} PRIVATE ${FMA_FLAG})
|
||||
endif ()
|
||||
if (HAVE_LIBM)
|
||||
target_link_libraries (${fftw3_lib} m)
|
||||
endif ()
|
||||
|
||||
set (subtargets ${fftw3_lib})
|
||||
|
||||
if (Threads_FOUND)
|
||||
if (WITH_COMBINED_THREADS)
|
||||
target_link_libraries (${fftw3_lib} ${CMAKE_THREAD_LIBS_INIT})
|
||||
else ()
|
||||
add_library (${fftw3_lib}_threads ${fftw_threads_SOURCE})
|
||||
target_include_directories (${fftw3_lib}_threads INTERFACE $<INSTALL_INTERFACE:include>)
|
||||
target_link_libraries (${fftw3_lib}_threads ${fftw3_lib})
|
||||
target_link_libraries (${fftw3_lib}_threads ${CMAKE_THREAD_LIBS_INIT})
|
||||
list (APPEND subtargets ${fftw3_lib}_threads)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (OPENMP_FOUND)
|
||||
add_library (${fftw3_lib}_omp ${fftw_omp_SOURCE})
|
||||
target_include_directories (${fftw3_lib}_omp INTERFACE $<INSTALL_INTERFACE:include>)
|
||||
target_link_libraries (${fftw3_lib}_omp ${fftw3_lib})
|
||||
target_link_libraries (${fftw3_lib}_omp ${CMAKE_THREAD_LIBS_INIT})
|
||||
list (APPEND subtargets ${fftw3_lib}_omp)
|
||||
target_compile_options (${fftw3_lib}_omp PRIVATE ${OpenMP_C_FLAGS})
|
||||
endif ()
|
||||
|
||||
foreach(subtarget ${subtargets})
|
||||
set_target_properties (${subtarget} PROPERTIES SOVERSION 3.6.9 VERSION 3)
|
||||
install (TARGETS ${subtarget}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endforeach ()
|
||||
install(TARGETS ${fftw3_lib}
|
||||
EXPORT FFTW3LibraryDepends
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
install (FILES api/fftw3.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
if (EXISTS ${CMAKE_SOURCE_DIR}/api/fftw3.f)
|
||||
install (FILES api/fftw3.f api/fftw3l.f03 api/fftw3q.f03 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
endif ()
|
||||
if (EXISTS ${CMAKE_SOURCE_DIR}/api/fftw3.f03.in)
|
||||
file (READ api/fftw3.f03.in FFTW3_F03_IN OFFSET 42)
|
||||
file (WRITE ${CMAKE_CURRENT_BINARY_DIR}/fftw3.f03 "! Generated automatically. DO NOT EDIT!\n\n")
|
||||
file (APPEND ${CMAKE_CURRENT_BINARY_DIR}/fftw3.f03 " integer, parameter :: C_FFTW_R2R_KIND = ${C_FFTW_R2R_KIND}\n\n")
|
||||
file (APPEND ${CMAKE_CURRENT_BINARY_DIR}/fftw3.f03 "${FFTW3_F03_IN}")
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/fftw3.f03 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
endif ()
|
||||
|
||||
if (BUILD_TESTS)
|
||||
|
||||
add_executable (bench ${fftw_libbench2_SOURCE} tests/bench.c tests/hook.c tests/fftw-bench.c)
|
||||
|
||||
if (ENABLE_THREADS AND NOT WITH_COMBINED_THREADS)
|
||||
target_link_libraries (bench ${fftw3_lib}_threads)
|
||||
else ()
|
||||
target_link_libraries (bench ${fftw3_lib})
|
||||
endif ()
|
||||
|
||||
|
||||
enable_testing ()
|
||||
|
||||
if (Threads_FOUND)
|
||||
|
||||
macro (fftw_add_test problem)
|
||||
add_test (NAME ${problem} COMMAND bench -s ${problem})
|
||||
endmacro ()
|
||||
|
||||
fftw_add_test (32x64)
|
||||
fftw_add_test (ib256)
|
||||
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# pkgconfig file
|
||||
set (prefix ${CMAKE_INSTALL_PREFIX})
|
||||
set (exec_prefix ${CMAKE_INSTALL_PREFIX})
|
||||
set (libdir ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
set (includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
|
||||
set (VERSION ${FFTW_VERSION})
|
||||
configure_file (fftw.pc.in fftw3${PREC_SUFFIX}.pc @ONLY)
|
||||
install (FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/fftw3${PREC_SUFFIX}.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
||||
COMPONENT Development)
|
||||
|
||||
# cmake file
|
||||
set (FFTW3_LIBRARIES "FFTW3::${fftw3_lib}")
|
||||
configure_file (FFTW3Config.cmake.in FFTW3${PREC_SUFFIX}Config.cmake @ONLY)
|
||||
configure_file (FFTW3ConfigVersion.cmake.in FFTW3${PREC_SUFFIX}ConfigVersion.cmake @ONLY)
|
||||
install (FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/FFTW3${PREC_SUFFIX}Config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/FFTW3${PREC_SUFFIX}ConfigVersion.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/fftw3${PREC_SUFFIX}
|
||||
COMPONENT Development)
|
||||
|
||||
export (TARGETS ${fftw3_lib} NAMESPACE FFTW3:: FILE ${PROJECT_BINARY_DIR}/FFTW3LibraryDepends.cmake)
|
||||
install(EXPORT FFTW3LibraryDepends
|
||||
NAMESPACE FFTW3::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/fftw3${PREC_SUFFIX}
|
||||
COMPONENT Development)
|
|
@ -0,0 +1,65 @@
|
|||
Code conventions used internally by fftw3 (not in API):
|
||||
|
||||
LEARN FROM THE MASTERS: read Ken Thompson's C compiler in Plan 9.
|
||||
Avoid learning from C++/Java programs.
|
||||
|
||||
INDENTATION: K&R, 5 spaces/tab. In case of doubt, indent -kr -i5.
|
||||
|
||||
NAMES: keep them short. Shorter than you think. The Bible was written
|
||||
without vowels. Don't outsmart the Bible.
|
||||
|
||||
Common names:
|
||||
|
||||
R : real type, aka fftw_real
|
||||
E : real type for local variables (possibly extra precision)
|
||||
C : complex type
|
||||
sz : size
|
||||
vecsz : vector size
|
||||
is, os : input/output stride
|
||||
ri, ii : real/imag input (complex data)
|
||||
ro, io : real/imag output (complex data)
|
||||
I, O : real input/output (real data)
|
||||
A : assert
|
||||
CK : check
|
||||
S : solver, defined internally to each solver file
|
||||
P : plan, defined internally to each solver file
|
||||
k : codelet
|
||||
X(...) : used for mangling of external names (see below)
|
||||
K(...) : floating-point constant, in E precision
|
||||
|
||||
If a name is used often and must have the form fftw_foo to avoid
|
||||
namespace pollution, #define FOO fftw_foo and use the short name.
|
||||
|
||||
Leave that hungarian crap to MS. foo_t counts as hungarian: use
|
||||
foo instead. foo is lowercase so that it does not look like a DOS
|
||||
program. Exception: typedef struct foo_s {...} foo; instead of
|
||||
typedef struct foo {...} foo; for C++ compatibility.
|
||||
|
||||
NAME MANGLING: use X(foo) for external names instead of fftw_foo.
|
||||
X(foo) expands to fftwf_foo or fftw_foo, depending on the
|
||||
precision. (Unfortunately, this is a ugly form of hungarian
|
||||
notation. Grrr...) Names that are not exported do not need to be
|
||||
mangled.
|
||||
|
||||
REPEATED CODE: favor a table. E.g., do not write
|
||||
|
||||
foo("xxx", 1);
|
||||
foo("yyy", 2);
|
||||
foo("zzz", -1);
|
||||
|
||||
Instead write
|
||||
|
||||
struct { const char *nam, int arg } footab[] = {
|
||||
{ "xxx", 1 },
|
||||
{ "yyy", 2 },
|
||||
{ "zzz", -1 }
|
||||
};
|
||||
|
||||
and loop over footab. Rationale: it saves code space.
|
||||
Similarly, replace a switch statement with a table whenever
|
||||
possible.
|
||||
|
||||
C++: The code should compile as a C++ program. Run the code through
|
||||
gcc -xc++ . The extra C++ restrictions are unnecessary, of
|
||||
course, but this will save us from a flood of complaints when
|
||||
we release the code.
|
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,17 @@
|
|||
# defined since 2.8.3
|
||||
if (CMAKE_VERSION VERSION_LESS 2.8.3)
|
||||
get_filename_component (CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||
endif ()
|
||||
|
||||
# Allows loading FFTW3 settings from another project
|
||||
set (FFTW3_CONFIG_FILE "${CMAKE_CURRENT_LIST_FILE}")
|
||||
|
||||
set (FFTW3@PREC_SUFFIX@_LIBRARIES fftw3@PREC_SUFFIX@)
|
||||
set (FFTW3@PREC_SUFFIX@_LIBRARY_DIRS @CMAKE_INSTALL_FULL_LIBDIR@)
|
||||
set (FFTW3@PREC_SUFFIX@_INCLUDE_DIRS @CMAKE_INSTALL_FULL_INCLUDEDIR@)
|
||||
|
||||
include ("${CMAKE_CURRENT_LIST_DIR}/FFTW3LibraryDepends.cmake")
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS 2.8.3)
|
||||
set (CMAKE_CURRENT_LIST_DIR)
|
||||
endif ()
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
set (PACKAGE_VERSION "@FFTW_VERSION@")
|
||||
|
||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||
if ("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||
set (PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else ()
|
||||
set (PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||
set (PACKAGE_VERSION_EXACT TRUE)
|
||||
endif ()
|
||||
endif ()
|
|
@ -0,0 +1,368 @@
|
|||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. This file is offered as-is,
|
||||
without warranty of any kind.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Briefly, the shell command './configure && make && make install'
|
||||
should configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the 'README' file for
|
||||
instructions specific to this package. Some packages provide this
|
||||
'INSTALL' file but do not implement all of the features documented
|
||||
below. The lack of an optional feature in a given package is not
|
||||
necessarily a bug. More recommendations for GNU packages can be found
|
||||
in *note Makefile Conventions: (standards)Makefile Conventions.
|
||||
|
||||
The 'configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a 'Makefile' in each directory of the package.
|
||||
It may also create one or more '.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script 'config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file 'config.log' containing compiler output (useful mainly for
|
||||
debugging 'configure').
|
||||
|
||||
It can also use an optional file (typically called 'config.cache' and
|
||||
enabled with '--cache-file=config.cache' or simply '-C') that saves the
|
||||
results of its tests to speed up reconfiguring. Caching is disabled by
|
||||
default to prevent problems with accidental use of stale cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how 'configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the 'README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point 'config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file 'configure.ac' (or 'configure.in') is used to create
|
||||
'configure' by a program called 'autoconf'. You need 'configure.ac' if
|
||||
you want to change it or regenerate 'configure' using a newer version of
|
||||
'autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. 'cd' to the directory containing the package's source code and type
|
||||
'./configure' to configure the package for your system.
|
||||
|
||||
Running 'configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type 'make' to compile the package.
|
||||
|
||||
3. Optionally, type 'make check' to run any self-tests that come with
|
||||
the package, generally using the just-built uninstalled binaries.
|
||||
|
||||
4. Type 'make install' to install the programs and any data files and
|
||||
documentation. When installing into a prefix owned by root, it is
|
||||
recommended that the package be configured and built as a regular
|
||||
user, and only the 'make install' phase executed with root
|
||||
privileges.
|
||||
|
||||
5. Optionally, type 'make installcheck' to repeat any self-tests, but
|
||||
this time using the binaries in their final installed location.
|
||||
This target does not install anything. Running this target as a
|
||||
regular user, particularly if the prior 'make install' required
|
||||
root privileges, verifies that the installation completed
|
||||
correctly.
|
||||
|
||||
6. You can remove the program binaries and object files from the
|
||||
source code directory by typing 'make clean'. To also remove the
|
||||
files that 'configure' created (so you can compile the package for
|
||||
a different kind of computer), type 'make distclean'. There is
|
||||
also a 'make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
7. Often, you can also type 'make uninstall' to remove the installed
|
||||
files again. In practice, not all packages have tested that
|
||||
uninstallation works correctly, even though it is required by the
|
||||
GNU Coding Standards.
|
||||
|
||||
8. Some packages, particularly those that use Automake, provide 'make
|
||||
distcheck', which can by used by developers to test that all other
|
||||
targets like 'make install' and 'make uninstall' work correctly.
|
||||
This target is generally not run by end users.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the 'configure' script does not know about. Run './configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give 'configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here is
|
||||
an example:
|
||||
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU 'make'. 'cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the 'configure' script. 'configure' automatically checks for the source
|
||||
code in the directory that 'configure' is in and in '..'. This is known
|
||||
as a "VPATH" build.
|
||||
|
||||
With a non-GNU 'make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use 'make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
On MacOS X 10.5 and later systems, you can create libraries and
|
||||
executables that work on multiple system types--known as "fat" or
|
||||
"universal" binaries--by specifying multiple '-arch' options to the
|
||||
compiler but only a single '-arch' option to the preprocessor. Like
|
||||
this:
|
||||
|
||||
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CPP="gcc -E" CXXCPP="g++ -E"
|
||||
|
||||
This is not guaranteed to produce working output in all cases, you
|
||||
may have to build one architecture at a time and combine the results
|
||||
using the 'lipo' tool if you have problems.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, 'make install' installs the package's commands under
|
||||
'/usr/local/bin', include files under '/usr/local/include', etc. You
|
||||
can specify an installation prefix other than '/usr/local' by giving
|
||||
'configure' the option '--prefix=PREFIX', where PREFIX must be an
|
||||
absolute file name.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like '--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run 'configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them. In general, the default
|
||||
for these options is expressed in terms of '${prefix}', so that
|
||||
specifying just '--prefix' will affect all of the other directory
|
||||
specifications that were not explicitly provided.
|
||||
|
||||
The most portable way to affect installation locations is to pass the
|
||||
correct locations to 'configure'; however, many packages provide one or
|
||||
both of the following shortcuts of passing variable assignments to the
|
||||
'make install' command line to change installation locations without
|
||||
having to reconfigure or recompile.
|
||||
|
||||
The first method involves providing an override variable for each
|
||||
affected directory. For example, 'make install
|
||||
prefix=/alternate/directory' will choose an alternate location for all
|
||||
directory configuration variables that were expressed in terms of
|
||||
'${prefix}'. Any directories that were specified during 'configure',
|
||||
but not in terms of '${prefix}', must each be overridden at install time
|
||||
for the entire installation to be relocated. The approach of makefile
|
||||
variable overrides for each directory variable is required by the GNU
|
||||
Coding Standards, and ideally causes no recompilation. However, some
|
||||
platforms have known limitations with the semantics of shared libraries
|
||||
that end up requiring recompilation when using this method, particularly
|
||||
noticeable in packages that use GNU Libtool.
|
||||
|
||||
The second method involves providing the 'DESTDIR' variable. For
|
||||
example, 'make install DESTDIR=/alternate/directory' will prepend
|
||||
'/alternate/directory' before all installation names. The approach of
|
||||
'DESTDIR' overrides is not required by the GNU Coding Standards, and
|
||||
does not work on platforms that have drive letters. On the other hand,
|
||||
it does better at avoiding recompilation issues, and works well even
|
||||
when some directory options were not specified in terms of '${prefix}'
|
||||
at 'configure' time.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving 'configure' the
|
||||
option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
|
||||
|
||||
Some packages pay attention to '--enable-FEATURE' options to
|
||||
'configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to '--with-PACKAGE' options, where PACKAGE
|
||||
is something like 'gnu-as' or 'x' (for the X Window System). The
|
||||
'README' should mention any '--enable-' and '--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, 'configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the 'configure' options '--x-includes=DIR' and
|
||||
'--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Some packages offer the ability to configure how verbose the
|
||||
execution of 'make' will be. For these packages, running './configure
|
||||
--enable-silent-rules' sets the default to minimal output, which can be
|
||||
overridden with 'make V=1'; while running './configure
|
||||
--disable-silent-rules' sets the default to verbose, which can be
|
||||
overridden with 'make V=0'.
|
||||
|
||||
Particular systems
|
||||
==================
|
||||
|
||||
On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC
|
||||
is not installed, it is recommended to use the following options in
|
||||
order to use an ANSI C compiler:
|
||||
|
||||
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
|
||||
|
||||
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||
|
||||
HP-UX 'make' updates targets which have the same time stamps as their
|
||||
prerequisites, which makes it generally unusable when shipped generated
|
||||
files such as 'configure' are involved. Use GNU 'make' instead.
|
||||
|
||||
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||
parse its '<wchar.h>' header file. The option '-nodtk' can be used as a
|
||||
workaround. If GNU CC is not installed, it is therefore recommended to
|
||||
try
|
||||
|
||||
./configure CC="cc"
|
||||
|
||||
and if that doesn't work, try
|
||||
|
||||
./configure CC="cc -nodtk"
|
||||
|
||||
On Solaris, don't put '/usr/ucb' early in your 'PATH'. This
|
||||
directory contains several dysfunctional programs; working variants of
|
||||
these programs are available in '/usr/bin'. So, if you need '/usr/ucb'
|
||||
in your 'PATH', put it _after_ '/usr/bin'.
|
||||
|
||||
On Haiku, software installed for all users goes in '/boot/common',
|
||||
not '/usr/local'. It is recommended to use the following options:
|
||||
|
||||
./configure --prefix=/boot/common
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features 'configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, 'configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
'--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as 'sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS
|
||||
KERNEL-OS
|
||||
|
||||
See the file 'config.sub' for the possible values of each field. If
|
||||
'config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option '--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with '--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for 'configure' scripts to share,
|
||||
you can create a site shell script called 'config.site' that gives
|
||||
default values for variables like 'CC', 'cache_file', and 'prefix'.
|
||||
'configure' looks for 'PREFIX/share/config.site' if it exists, then
|
||||
'PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
'CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all 'configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to 'configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the 'configure' command line, using 'VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified 'gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
|
||||
Autoconf limitation. Until the limitation is lifted, you can use this
|
||||
workaround:
|
||||
|
||||
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
'configure' Invocation
|
||||
======================
|
||||
|
||||
'configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
'--help'
|
||||
'-h'
|
||||
Print a summary of all of the options to 'configure', and exit.
|
||||
|
||||
'--help=short'
|
||||
'--help=recursive'
|
||||
Print a summary of the options unique to this package's
|
||||
'configure', and exit. The 'short' variant lists options used only
|
||||
in the top level, while the 'recursive' variant lists options also
|
||||
present in any nested packages.
|
||||
|
||||
'--version'
|
||||
'-V'
|
||||
Print the version of Autoconf used to generate the 'configure'
|
||||
script, and exit.
|
||||
|
||||
'--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally 'config.cache'. FILE defaults to '/dev/null' to
|
||||
disable caching.
|
||||
|
||||
'--config-cache'
|
||||
'-C'
|
||||
Alias for '--cache-file=config.cache'.
|
||||
|
||||
'--quiet'
|
||||
'--silent'
|
||||
'-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to '/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
'--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
'configure' can determine that directory automatically.
|
||||
|
||||
'--prefix=DIR'
|
||||
Use DIR as the installation prefix. *note Installation Names:: for
|
||||
more details, including other options available for fine-tuning the
|
||||
installation locations.
|
||||
|
||||
'--no-create'
|
||||
'-n'
|
||||
Run the configure checks, but stop before creating any output
|
||||
files.
|
||||
|
||||
'configure' also accepts some other, not widely useful, options. Run
|
||||
'configure --help' for more details.
|
|
@ -0,0 +1,3 @@
|
|||
this is a modified version of FFTW for usage in Furnace.
|
||||
|
||||
it adds a `WITH_OUR_MALLOC` option to CMakeListst.txt, which was absent in the original release.
|
|
@ -0,0 +1,179 @@
|
|||
OPTIONS_AUTOMAKE=gnu
|
||||
lib_LTLIBRARIES = libfftw3@PREC_SUFFIX@.la
|
||||
|
||||
# pkgincludedir = $(includedir)/fftw3@PREC_SUFFIX@
|
||||
# nodist_pkginclude_HEADERS = config.h
|
||||
|
||||
# recompile genfft if maintainer mode is true
|
||||
if MAINTAINER_MODE
|
||||
GENFFT = genfft
|
||||
EXTRA_libfftw3@PREC_SUFFIX@_la_DEPENDENCIES = assert-shared-version-info
|
||||
else
|
||||
GENFFT =
|
||||
endif
|
||||
|
||||
ACLOCAL_AMFLAGS=-I m4
|
||||
|
||||
# when using combined thread libraries (necessary on Windows), we want
|
||||
# to build threads/ first, because libfftw3_threads is added to
|
||||
# libfftw3.
|
||||
#
|
||||
# Otherwise, we want to build libfftw3_threads after libfftw3
|
||||
# so that we can track the fact that libfftw3_threads depends upon
|
||||
# libfftw3.
|
||||
#
|
||||
# This is the inescapable result of combining three bad ideas
|
||||
# (threads, Windows, and shared libraries).
|
||||
#
|
||||
if COMBINED_THREADS
|
||||
CHICKEN_EGG=threads .
|
||||
else
|
||||
CHICKEN_EGG=. threads
|
||||
endif
|
||||
|
||||
# Only build in doc/ if not disabled by user (i.e. not all
|
||||
# tools are available, such as fig2dev in maintainer mode)
|
||||
if BUILD_DOC
|
||||
DOCDIR=doc
|
||||
else
|
||||
DOCDIR=
|
||||
endif
|
||||
|
||||
SUBDIRS=support $(GENFFT) kernel simd-support dft rdft reodft api \
|
||||
libbench2 $(CHICKEN_EGG) tests mpi $(DOCDIR) tools m4
|
||||
EXTRA_DIST=COPYRIGHT bootstrap.sh CONVENTIONS fftw.pc.in \
|
||||
CMakeLists.txt cmake.config.h.in FFTW3Config.cmake.in \
|
||||
FFTW3ConfigVersion.cmake.in README-perfcnt.md
|
||||
|
||||
SIMD_LIBS = simd-support/libsimd_support.la
|
||||
|
||||
if HAVE_SSE2
|
||||
SSE2_LIBS = dft/simd/sse2/libdft_sse2_codelets.la \
|
||||
rdft/simd/sse2/librdft_sse2_codelets.la
|
||||
endif
|
||||
|
||||
if HAVE_AVX
|
||||
AVX_LIBS = dft/simd/avx/libdft_avx_codelets.la \
|
||||
rdft/simd/avx/librdft_avx_codelets.la
|
||||
endif
|
||||
|
||||
if HAVE_AVX_128_FMA
|
||||
AVX_128_FMA_LIBS = dft/simd/avx-128-fma/libdft_avx_128_fma_codelets.la \
|
||||
rdft/simd/avx-128-fma/librdft_avx_128_fma_codelets.la
|
||||
endif
|
||||
|
||||
if HAVE_AVX2
|
||||
AVX2_LIBS = dft/simd/avx2/libdft_avx2_codelets.la \
|
||||
dft/simd/avx2-128/libdft_avx2_128_codelets.la \
|
||||
rdft/simd/avx2/librdft_avx2_codelets.la \
|
||||
rdft/simd/avx2-128/librdft_avx2_128_codelets.la
|
||||
endif
|
||||
|
||||
if HAVE_AVX512
|
||||
AVX512_LIBS = dft/simd/avx512/libdft_avx512_codelets.la \
|
||||
rdft/simd/avx512/librdft_avx512_codelets.la
|
||||
endif
|
||||
|
||||
if HAVE_KCVI
|
||||
KCVI_LIBS = dft/simd/kcvi/libdft_kcvi_codelets.la \
|
||||
rdft/simd/kcvi/librdft_kcvi_codelets.la
|
||||
endif
|
||||
|
||||
if HAVE_ALTIVEC
|
||||
ALTIVEC_LIBS = dft/simd/altivec/libdft_altivec_codelets.la \
|
||||
rdft/simd/altivec/librdft_altivec_codelets.la
|
||||
endif
|
||||
|
||||
if HAVE_VSX
|
||||
VSX_LIBS = dft/simd/vsx/libdft_vsx_codelets.la \
|
||||
rdft/simd/vsx/librdft_vsx_codelets.la
|
||||
endif
|
||||
|
||||
if HAVE_NEON
|
||||
NEON_LIBS = dft/simd/neon/libdft_neon_codelets.la \
|
||||
rdft/simd/neon/librdft_neon_codelets.la
|
||||
endif
|
||||
|
||||
if HAVE_GENERIC_SIMD128
|
||||
GENERIC_SIMD128_LIBS = dft/simd/generic-simd128/libdft_generic_simd128_codelets.la \
|
||||
rdft/simd/generic-simd128/librdft_generic_simd128_codelets.la
|
||||
endif
|
||||
|
||||
if HAVE_GENERIC_SIMD256
|
||||
GENERIC_SIMD256_LIBS = dft/simd/generic-simd256/libdft_generic_simd256_codelets.la \
|
||||
rdft/simd/generic-simd256/librdft_generic_simd256_codelets.la
|
||||
endif
|
||||
|
||||
if THREADS
|
||||
if COMBINED_THREADS
|
||||
COMBINED_THREADLIBS=threads/libfftw3@PREC_SUFFIX@_threads.la
|
||||
endif
|
||||
endif
|
||||
|
||||
libfftw3@PREC_SUFFIX@_la_SOURCES =
|
||||
|
||||
libfftw3@PREC_SUFFIX@_la_LIBADD = \
|
||||
kernel/libkernel.la \
|
||||
dft/libdft.la \
|
||||
dft/scalar/libdft_scalar.la \
|
||||
dft/scalar/codelets/libdft_scalar_codelets.la \
|
||||
rdft/librdft.la \
|
||||
rdft/scalar/librdft_scalar.la \
|
||||
rdft/scalar/r2cf/librdft_scalar_r2cf.la \
|
||||
rdft/scalar/r2cb/librdft_scalar_r2cb.la \
|
||||
rdft/scalar/r2r/librdft_scalar_r2r.la \
|
||||
reodft/libreodft.la \
|
||||
api/libapi.la \
|
||||
$(SIMD_LIBS) $(SSE2_LIBS) $(AVX_LIBS) $(AVX_128_FMA_LIBS) \
|
||||
$(AVX2_LIBS) $(ALTIVEC_LIBS) \
|
||||
$(VSX_LIBS) $(NEON_LIBS) $(KCVI_LIBS) $(AVX512_LIBS) \
|
||||
$(GENERIC_SIMD128_LIBS) $(GENERIC_SIMD256_LIBS) \
|
||||
$(COMBINED_THREADLIBS)
|
||||
|
||||
if QUAD
|
||||
# cannot use -no-undefined since dependent on libquadmath
|
||||
libfftw3@PREC_SUFFIX@_la_LDFLAGS = -version-info @SHARED_VERSION_INFO@ $(ENVIRONMENT_LIBFFTW3_LDFLAGS)
|
||||
else
|
||||
libfftw3@PREC_SUFFIX@_la_LDFLAGS = -no-undefined -version-info \
|
||||
@SHARED_VERSION_INFO@ $(ENVIRONMENT_LIBFFTW3_LDFLAGS)
|
||||
endif
|
||||
|
||||
fftw3@PREC_SUFFIX@.pc: fftw.pc
|
||||
cp -f fftw.pc fftw3@PREC_SUFFIX@.pc
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = fftw3@PREC_SUFFIX@.pc
|
||||
|
||||
FFTW3@PREC_SUFFIX@Config.cmake: $(top_srcdir)/FFTW3Config.cmake.in
|
||||
$(SED) \
|
||||
-e 's|[@]PREC_SUFFIX@|@PREC_SUFFIX@|g' \
|
||||
-e 's|[@]CMAKE_INSTALL_FULL_LIBDIR@|$(libdir)|g' \
|
||||
-e 's|[@]CMAKE_INSTALL_FULL_INCLUDEDIR@|$(includedir)|g' \
|
||||
$(top_srcdir)/FFTW3Config.cmake.in > $@
|
||||
FFTW3@PREC_SUFFIX@ConfigVersion.cmake: $(top_srcdir)/FFTW3ConfigVersion.cmake.in
|
||||
$(SED) \
|
||||
-e 's|[@]FFTW_VERSION@|@PACKAGE_VERSION@|g' \
|
||||
$(top_srcdir)/FFTW3ConfigVersion.cmake.in > $@
|
||||
cmakedir = $(libdir)/cmake/fftw3
|
||||
cmake_DATA = FFTW3@PREC_SUFFIX@Config.cmake FFTW3@PREC_SUFFIX@ConfigVersion.cmake
|
||||
|
||||
WISDOM_DIR = /etc/fftw
|
||||
WISDOM = wisdom@PREC_SUFFIX@
|
||||
|
||||
WISDOM_TIME=12 # default to 12-hour limit, i.e. overnight
|
||||
WISDOM_FLAGS=--verbose --canonical --time-limit=$(WISDOM_TIME)
|
||||
|
||||
wisdom:
|
||||
tools/fftw@PREC_SUFFIX@-wisdom -o $@ $(WISDOM_FLAGS)
|
||||
|
||||
install-wisdom: wisdom
|
||||
$(mkinstalldirs) $(WISDOM_DIR)
|
||||
$(INSTALL_DATA) wisdom $(WISDOM_DIR)/$(WISDOM)
|
||||
|
||||
if MAINTAINER_MODE
|
||||
assert-shared-version-info:
|
||||
current=`echo @SHARED_VERSION_INFO@ | cut -d: -f1`; \
|
||||
age=`echo @SHARED_VERSION_INFO@ | cut -d: -f3`; \
|
||||
major=3; \
|
||||
expected=`expr $$age + $$major`; \
|
||||
test $$current -eq $$expected
|
||||
endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,681 @@
|
|||
FFTW 3.3.10:
|
||||
|
||||
* Fix bug that would cause 2-way SIMD (notably SSE2 in double precision)
|
||||
to attempt unaligned accesses in certain obscure cases, causing
|
||||
segfaults.
|
||||
|
||||
The following test triggers the bug (SSE2, double precision):
|
||||
|
||||
./tests/bench -oexhaustive r4*2:5:3
|
||||
|
||||
This test computes a pair of length-4 real->complex transforms where
|
||||
the second input is 5 real numbers away from the first input. That
|
||||
is, there is a gap of one real number between the first and second
|
||||
input array. The -oexhaustive level allow FFTW to attempt to
|
||||
compute this transform by reducing it to a pair of complex
|
||||
transforms of length 2, but now the second input is not aligned to a
|
||||
complex-number boundary. The fact that 5 is odd is the problem.
|
||||
|
||||
The bug cannot occur in complex->complex transforms because the
|
||||
complex interface accepts strides in units of complex numbers, so
|
||||
strides are aligned by construction.
|
||||
|
||||
This bug has been around at least since fftw-3.1.2 (July 2006), and
|
||||
probably since fftw-3.0 (2003).
|
||||
|
||||
FFTW 3.3.9:
|
||||
|
||||
* New API fftw_planner_nthreads() returns the number of threads
|
||||
currently being used by the planner.
|
||||
|
||||
* Fix incorrect math in 128-bit generic SIMD
|
||||
|
||||
* Fix wisdom for avx512.
|
||||
|
||||
The avx512 alignment requirement was set to 64 bytes, but this is
|
||||
wrong. Alignment requirements are a property of the platform (e.g.,
|
||||
x86) and not of the instruction set (e.g., AVX). Among other
|
||||
things, this broke wisdom with avx512.
|
||||
|
||||
Note that avx512 support is still experimental because the FFTW
|
||||
authors have no avx512 hardware available for testing.
|
||||
|
||||
* fftw_threads_set_callback function to change the threading backend at runtime.
|
||||
|
||||
FFTW 3.3.8:
|
||||
|
||||
* Fixed AVX, AVX2 for gcc-8.
|
||||
|
||||
By default, FFTW 3.3.7 was broken with gcc-8. AVX and AVX2 code
|
||||
assumed that the compiler honors the distinction between +0 and -0,
|
||||
but gcc-8 -ffast-math does not. The default CFLAGS included -ffast-math.
|
||||
This release ensures that FFTW works with gcc-8 -ffast-math, and
|
||||
removes -ffast-math from the default CFLAGS for good measure.
|
||||
|
||||
FFTW 3.3.7:
|
||||
|
||||
* Experimental support for CMake.
|
||||
|
||||
The primary build mechanism for FFTW remains GNU autoconf/automake.
|
||||
CMake support is meant to offer an easy way to compile FFTW on
|
||||
Windows, and as such it does not cover all the features of the
|
||||
automake build system, such as exotic cycle counters,
|
||||
cross-compiling, or build of binaries for a mixture of ISA's
|
||||
(e.g., amd64 vs amd64+avx vs amd64+avx2). Patches are welcome.
|
||||
|
||||
* Fixes for armv7a cycle counter.
|
||||
* Official support for aarch64, now that we have hardware to test it.
|
||||
* Tweak usage of FMA instructions in a way that favors newer processors
|
||||
(Skylake and Ryzen) over older processors (Haswell).
|
||||
* tests/bench: use 64-bit precision to compute mflops.
|
||||
|
||||
FFTW 3.3.6-pl2:
|
||||
|
||||
* Bugfix: MPI Fortran-03 headers were missing in FFTW 3.3.6-pl1.
|
||||
|
||||
FFTW 3.3.6-pl1:
|
||||
|
||||
* Bugfix: FFTW 3.3.6 had the wrong libtool version number, and generated
|
||||
shared libraries of the form libfftw3.so.2.6.6 instead of
|
||||
libfftw3.so.3.*.
|
||||
|
||||
FFTW 3.3.6:
|
||||
|
||||
* The fftw_make_planner_thread_safe() API introduced in 3.3.5 didn't
|
||||
work, and this 3.3.6 fixes it. Sorry about that.
|
||||
* compilation fixes for IBM XLC
|
||||
* compilation fixes for threads on Windows
|
||||
* fix SIMD autodetection on amd64 when (_MSC_VER > 1500)
|
||||
|
||||
FFTW 3.3.5:
|
||||
|
||||
* New SIMD support:
|
||||
- Power8 VSX instructions in single and double precision.
|
||||
To use, add --enable-vsx to configure.
|
||||
- Support for AVX2 (256-bit FMA instructions).
|
||||
To use, add --enable-avx2 to configure.
|
||||
- Experimental support for AVX512 and KCVI. (--enable-avx512, --enable-kcvi)
|
||||
This code is expected to work but the FFTW maintainers do not have
|
||||
hardware to test it.
|
||||
- Support for AVX128/FMA (for some AMD machines) (--enable-avx128-fma)
|
||||
- Double precision Neon SIMD for aarch64.
|
||||
This code is expected to work but the FFTW maintainers do not have
|
||||
hardware to test it.
|
||||
- generic SIMD support using gcc vector intrinsics
|
||||
* Add fftw_make_planner_thread_safe() API
|
||||
* fix #18 (disable float128 for CUDACC)
|
||||
* fix #19: missing Fortran interface for fftwq_alloc_real
|
||||
* fix #21 (don't use float128 on Portland compilers, which pretend to be gcc)
|
||||
* fix: Avoid segfaults due to double free in MPI transpose
|
||||
|
||||
* Special note for distribution maintainers: Although FFTW supports a
|
||||
zillion SIMD instruction sets, enabling them all at the same time is
|
||||
a bad idea, because it increases the planning time for minimal gain.
|
||||
We recommend that general-purpose x86 distributions only enable SSE2
|
||||
and perhaps AVX. Users who care about the last ounce of performance
|
||||
should recompile FFTW themselves.
|
||||
|
||||
FFTW 3.3.4
|
||||
|
||||
* New functions fftw_alignment_of (to check whether two arrays are
|
||||
equally aligned for the purposes of applying a plan) and fftw_sprint_plan
|
||||
(to output a description of plan to a string).
|
||||
|
||||
* Bugfix in fftw-wisdom-to-conf; thanks to Florian Oppermann for the
|
||||
bug report.
|
||||
|
||||
* Fixed manual to work with texinfo-5.
|
||||
|
||||
* Increased timing interval on x86_64 to reduce timing errors.
|
||||
|
||||
* Default to Win32 threads, not pthreads, if both are present.
|
||||
|
||||
* Various build-script fixes.
|
||||
|
||||
FFTW 3.3.3
|
||||
|
||||
* Fix deadlock bug in MPI transforms (thanks to Michael Pippig for the
|
||||
bug report and patch, and to Graham Dennis for the bug report).
|
||||
|
||||
* Use 128-bit ARM NEON instructions instead of 64-bits. This change
|
||||
appears to speed up even ARM processors with a 64-bit NEON pipe.
|
||||
|
||||
* Speed improvements for single-precision AVX.
|
||||
|
||||
* Speed up planner on machines without "official" cycle counters, such as ARM.
|
||||
|
||||
FFTW 3.3.2
|
||||
|
||||
* Removed an archaic stack-alignment hack that was failing with
|
||||
gcc-4.7/i386.
|
||||
|
||||
* Added stack-alignment hack necessary for gcc on Windows/i386. We
|
||||
will regret this in ten years (see previous change).
|
||||
|
||||
* Fix incompatibility with Intel icc which pretends to be gcc
|
||||
but does not support quad precision.
|
||||
|
||||
* make libfftw{threads,mpi} depend upon libfftw when using libtool;
|
||||
this is consistent with most other libraries and simplifies the life
|
||||
of various distributors of GNU/Linux.
|
||||
|
||||
FFTW 3.3.1
|
||||
|
||||
* Changes since 3.3.1-beta1:
|
||||
|
||||
- Reduced planning time in estimate mode for sizes with large
|
||||
prime factors.
|
||||
|
||||
- Added AVX autodetection under Visual Studio. Thanks Carsten
|
||||
Steger for submitting the necessary code.
|
||||
|
||||
- Modern Fortran interface now uses a separate fftw3l.f03 interface
|
||||
file for the long double interface, which is not supported by
|
||||
some Fortran compilers. Provided new fftw3q.f03 interface file
|
||||
to access the quadruple-precision FFTW routines with recent
|
||||
versions of gcc/gfortran.
|
||||
|
||||
* Added support for the NEON extensions to the ARM ISA. (Note to beta
|
||||
users: an ARM cycle counter is not yet implemented; please contact
|
||||
fftw@fftw.org if you know how to do it right.)
|
||||
|
||||
* MPI code now compiles even if mpicc is a C++ compiler; thanks to
|
||||
Kyle Spyksma for the bug report.
|
||||
|
||||
FFTW 3.3
|
||||
|
||||
* Changes since 3.3-beta1:
|
||||
|
||||
- Compiling OpenMP support (--enable-openmp) now installs a
|
||||
fftw3_omp library, instead of fftw3_threads, so that OpenMP
|
||||
and POSIX threads (--enable-threads) libraries can be built
|
||||
and installed at the same time.
|
||||
|
||||
- Various minor compilation fixes, corrections of manual typos, and
|
||||
improvements to the benchmark test program.
|
||||
|
||||
* Add support for the AVX extensions to x86 and x86-64. The AVX code
|
||||
works with 16-byte alignment (as opposed to 32-byte alignment),
|
||||
so there is no ABI change compared to FFTW 3.2.2.
|
||||
|
||||
* Added Fortran 2003 interface, which should be usable on most modern
|
||||
Fortran compilers (e.g. gfortran) and provides type-checked access
|
||||
to the the C FFTW interface. (The legacy Fortran-77 interface is
|
||||
still included also.)
|
||||
|
||||
* Added MPI distributed-memory transforms. Compared to 3.3alpha,
|
||||
the major changes in the MPI transforms are:
|
||||
- Fixed some deadlock and crashing bugs.
|
||||
- Added Fortran 2003 interface.
|
||||
- Added new-array execute functions for MPI plans.
|
||||
- Eliminated use of large MPI tags, since Cray MPI requires tags < 2^24;
|
||||
thanks to Jonathan Bentz for the bug report.
|
||||
- Expanded documentation.
|
||||
- 'make check' now runs MPI tests
|
||||
- Some ABI changes - not binary-compatible with 3.3alpha MPI.
|
||||
|
||||
* Add support for quad-precision __float128 in gcc 4.6 or later (on x86.
|
||||
x86-64, and Itanium). The new routines use the fftwq_ prefix.
|
||||
|
||||
* Removed support for MIPS paired-single instructions due to lack of
|
||||
available hardware for testing. Users who want this functionality
|
||||
should continue using FFTW 3.2.x. (Note that FFTW 3.3 still works
|
||||
on MIPS; this only concerns special instructions available on some
|
||||
MIPS chips.)
|
||||
|
||||
* Removed support for the Cell Broadband Engine. Cell users should
|
||||
use FFTW 3.2.x.
|
||||
|
||||
* New convenience functions fftw_alloc_real and fftw_alloc_complex
|
||||
to use fftw_malloc for real and complex arrays without typecasts
|
||||
or sizeof.
|
||||
|
||||
* New convenience functions fftw_export_wisdom_to_filename and
|
||||
fftw_import_wisdom_from_filename that export/import wisdom
|
||||
to a file, which don't require you to open/close the file yourself.
|
||||
|
||||
* New function fftw_cost to return FFTW's internal cost metric for
|
||||
a given plan; thanks to Rhys Ulerich and Nathanael Schaeffer for the
|
||||
suggestion.
|
||||
|
||||
* The --enable-sse2 configure flag now works in both double and single
|
||||
precision (and is equivalent to --enable-sse in the latter case).
|
||||
|
||||
* Remove --enable-portable-binary flag: we new produce portable binaries
|
||||
by default.
|
||||
|
||||
* Remove the automatic detection of native architecture flag for gcc
|
||||
which was introduced in fftw-3.1, since new gcc supports -mtune=native.
|
||||
Remove the --with-gcc-arch flag; if you want to specify a particlar
|
||||
arch to configure, use ./configure CC="gcc -mtune=...".
|
||||
|
||||
* --with-our-malloc16 configure flag is now renamed --with-our-malloc.
|
||||
|
||||
* Fixed build problem failure when srand48 declaration is missing;
|
||||
thanks to Ralf Wildenhues for the bug report.
|
||||
|
||||
* Fixed bug in fftw_set_timelimit: ensure that a negative timelimit
|
||||
is equivalent to no timelimit in all cases. Thanks to William Andrew
|
||||
Burnson for the bug report.
|
||||
|
||||
* Fixed stack-overflow problem on OpenBSD caused by using alloca with
|
||||
too large a buffer.
|
||||
|
||||
FFTW 3.2.2
|
||||
|
||||
* Improve performance of some copy operations of complex arrays on
|
||||
x86 machines.
|
||||
|
||||
* Add configure flag to disable alloca(), which is broken in mingw64.
|
||||
|
||||
* Planning in FFTW_ESTIMATE mode for r2r transforms became slower
|
||||
between fftw-3.1.3 and 3.2. This regression has now been fixed.
|
||||
|
||||
FFTW 3.2.1
|
||||
|
||||
* Performance improvements for some multidimensional r2c/c2r transforms;
|
||||
thanks to Eugene Miloslavsky for his benchmark reports.
|
||||
|
||||
* Compile with icc on MacOS X, use better icc compiler flags.
|
||||
|
||||
* Compilation fixes for systems where snprintf is defined as a macro;
|
||||
thanks to Marcus Mae for the bug report.
|
||||
|
||||
* Fortran documentation now recommends not using dfftw_execute,
|
||||
because of reports of problems with various Fortran compilers;
|
||||
it is better to use dfftw_execute_dft etcetera.
|
||||
|
||||
* Some documentation clarifications, e.g. of fact that --enable-openmp
|
||||
and --enable-threads are mutually exclusive (thanks to Long To),
|
||||
and document slightly odd behavior of plan_guru_r2r in Fortran
|
||||
(thanks to Alexander Pozdneev).
|
||||
|
||||
* FAQ was accidentally omitted from 3.2 tarball.
|
||||
|
||||
* Remove some extraneous (harmless) files accidentally included in
|
||||
a subdirectory of the 3.2 tarball.
|
||||
|
||||
FFTW 3.2
|
||||
|
||||
* Worked around apparent glibc bug that leads to rare hangs when freeing
|
||||
semaphores.
|
||||
|
||||
* Fixed segfault due to unaligned access in certain obscure problems
|
||||
that use SSE and multiple threads.
|
||||
|
||||
* MPI transforms not included, as they are still in alpha; the alpha
|
||||
versions of the MPI transforms have been moved to FFTW 3.3alpha1.
|
||||
|
||||
FFTW 3.2alpha3
|
||||
|
||||
* Performance improvements for sizes with factors of 5 and 10.
|
||||
|
||||
* Documented FFTW_WISDOM_ONLY flag, at the suggestion of Mario
|
||||
Emmenlauer and Phil Dumont.
|
||||
|
||||
* Port Cell code to SDK2.1 (libspe2), as opposed to the old libspe1 code.
|
||||
|
||||
* Performance improvements in Cell code for N < 32k, thanks to Jan Wagner
|
||||
for the suggestions.
|
||||
|
||||
* Cycle counter for Sun x86_64 compiler, and compilation fix in cycle
|
||||
counter for AIX/xlc (thanks to Jeff Haferman for the bug report).
|
||||
|
||||
* Fixed incorrect type prefix in MPI code that prevented wisdom routines
|
||||
from working in single precision (thanks to Eric A. Borisch for the report).
|
||||
|
||||
* Added 'make check' for MPI code (which still fails in a couple corner
|
||||
cases, but should be much better than in alpha2).
|
||||
|
||||
* Many other small fixes.
|
||||
|
||||
FFTW 3.2alpha2
|
||||
|
||||
* Support for the Cell processor, donated by IBM Research; see README.Cell
|
||||
and the Cell section of the manual.
|
||||
|
||||
* New 64-bit API: for every "plan_guru" function there is a new "plan_guru64"
|
||||
function with the same semantics, but which takes fftw_iodim64 instead of
|
||||
fftw_iodim. fftw_iodim64 is the same as fftw_iodim, except that it takes
|
||||
ptrdiff_t integer types as parameters, which is a 64-bit type on
|
||||
64-bit machines. This is only useful for specifying very large transforms
|
||||
on 64-bit machines. (Internally, FFTW uses ptrdiff_t everywhere
|
||||
regardless of what API you choose.)
|
||||
|
||||
* Experimental MPI support. Complex one- and multi-dimensional FFTs,
|
||||
multi-dimensional r2r, multi-dimensional r2c/c2r transforms, and
|
||||
distributed transpose operations, with 1d block distributions.
|
||||
(This is an alpha preview: routines have not been exhaustively
|
||||
tested, documentation is incomplete, and some functionality is
|
||||
missing, e.g. Fortran support.) See mpi/README and also the MPI
|
||||
section of the manual.
|
||||
|
||||
* Significantly faster r2c/c2r transforms, especially on machines with SIMD.
|
||||
|
||||
* Rewritten multi-threaded support for better performance by
|
||||
re-using a fixed pool of threads rather than continually
|
||||
respawning and joining (which nowadays is much slower).
|
||||
|
||||
* Support for MIPS paired-single SIMD instructions, donated by
|
||||
Codesourcery.
|
||||
|
||||
* FFTW_WISDOM_ONLY planner flag, to create plan only if wisdom is
|
||||
available and return NULL otherwise.
|
||||
|
||||
* Removed k7 support, which only worked in 32-bit mode and is
|
||||
becoming obsolete. Use --enable-sse instead.
|
||||
|
||||
* Added --with-g77-wrappers configure option to force inclusion
|
||||
of g77 wrappers, in addition to whatever is needed for the
|
||||
detected Fortran compilers. This is mainly intended for GNU/Linux
|
||||
distros switching to gfortran that wish to include both
|
||||
gfortran and g77 support in FFTW.
|
||||
|
||||
* In manual, renamed "guru execute" functions to "new-array execute"
|
||||
functions, to reduce confusion with the guru planner interface.
|
||||
(The programming interface is unchanged.)
|
||||
|
||||
* Add missing __declspec attribute to threads API functions when compiling
|
||||
for Windows; thanks to Robert O. Morris for the bug report.
|
||||
|
||||
* Fixed missing return value from dfftw_init_threads in Fortran;
|
||||
thanks to Markus Wetzstein for the bug report.
|
||||
|
||||
FFTW 3.1.3
|
||||
|
||||
* Bug fix: FFTW computes incorrect results when the user plans both
|
||||
REDFT11 and RODFT11 transforms of certain sizes. The bug is caused
|
||||
by incorrect sharing of twiddle-factor tables between the two
|
||||
transforms, and only occurs when both are used. Thanks to Paul
|
||||
A. Valiant for the bug report.
|
||||
|
||||
FFTW 3.1.2
|
||||
|
||||
* Correct bug in configure script: --enable-portable-binary option was ignored!
|
||||
Thanks to Andrew Salamon for the bug report.
|
||||
|
||||
* Threads compilation fix on AIX: prefer xlc_r to cc_r, and don't use
|
||||
either if we are using gcc. Thanks to Guy Moebs for the bug report.
|
||||
|
||||
* Updated FAQ to note that Apple gcc 4.0.1 on MacOS/Intel is broken,
|
||||
and suggest a workaround. configure script now detects Core/Duo arch.
|
||||
|
||||
* Use -maltivec when checking for altivec.h. Fixes Gentoo bug #129304,
|
||||
thanks to Markus Dittrich.
|
||||
|
||||
FFTW 3.1.1
|
||||
|
||||
* Performance improvements for Intel EMT64.
|
||||
|
||||
* Performance improvements for large-size transforms with SIMD.
|
||||
|
||||
* Cycle counter support for Intel icc and Visual C++ on x86-64.
|
||||
|
||||
* In fftw-wisdom tool, replaced obsolete --impatient with --measure.
|
||||
|
||||
* Fixed compilation failure with AIX/xlc; thanks to Joseph Thomas.
|
||||
|
||||
* Windows DLL support for Fortran API (added missing __declspec(dllexport)).
|
||||
|
||||
* SSE/SSE2 code works properly (i.e. disables itself) on older 386 and 486
|
||||
CPUs lacking a CPUID instruction; thanks to Eric Korpela.
|
||||
|
||||
FFTW 3.1
|
||||
|
||||
* Faster FFTW_ESTIMATE planner.
|
||||
|
||||
* New (faster) algorithm for REDFT00/RODFT00 (type-I DCT/DST) of odd size.
|
||||
|
||||
* "4-step" algorithm for faster FFTs of very large sizes (> 2^18).
|
||||
|
||||
* Faster in-place real-data DFTs (for R2HC and HC2R r2r formats).
|
||||
|
||||
* Faster in-place non-square transpositions (FFTW uses these internally
|
||||
for in-place FFTs, and you can also perform them explicitly using
|
||||
the guru interface).
|
||||
|
||||
* Faster prime-size DFTs: implemented Bluestein's algorithm, as well
|
||||
as a zero-padded Rader variant to limit recursive use of Rader's algorithm.
|
||||
|
||||
* SIMD support for split complex arrays.
|
||||
|
||||
* Much faster Altivec/VMX performance.
|
||||
|
||||
* New fftw_set_timelimit function to specify a (rough) upper bound to the
|
||||
planning time (does not affect ESTIMATE mode).
|
||||
|
||||
* Removed --enable-3dnow support; use --enable-k7 instead.
|
||||
|
||||
* FMA (fused multiply-add) version is now included in "standard" FFTW,
|
||||
and is enabled with --enable-fma (the default on PowerPC and Itanium).
|
||||
|
||||
* Automatic detection of native architecture flag for gcc. New
|
||||
configure options: --enable-portable-binary and --with-gcc-arch=<arch>,
|
||||
for people distributing compiled binaries of FFTW (see manual).
|
||||
|
||||
* Automatic detection of Altivec under Linux with gcc 3.4 (so that
|
||||
same binary should work on both Altivec and non-Altivec PowerPCs).
|
||||
|
||||
* Compiler-specific tweaks/flags/workarounds for gcc 3.4, xlc, HP/UX,
|
||||
Solaris/Intel.
|
||||
|
||||
* Various documentation clarifications.
|
||||
|
||||
* 64-bit clean. (Fixes a bug affecting the split guru planner on
|
||||
64-bit machines, reported by David Necas.)
|
||||
|
||||
* Fixed Debian bug #259612: inadvertent use of SSE instructions on
|
||||
non-SSE machines (causing a crash) for --enable-sse binaries.
|
||||
|
||||
* Fixed bug that caused HC2R transforms to destroy the input in
|
||||
certain cases, even if the user specified FFTW_PRESERVE_INPUT.
|
||||
|
||||
* Fixed bug where wisdom would be lost under rare circumstances,
|
||||
causing excessive planning time.
|
||||
|
||||
* FAQ notes bug in gcc-3.4.[1-3] that causes FFTW to crash with SSE/SSE2.
|
||||
|
||||
* Fixed accidentally exported symbol that prohibited simultaneous
|
||||
linking to double/single multithreaded FFTW (thanks to Alessio Massaro).
|
||||
|
||||
* Support Win32 threads under MinGW (thanks to Alessio Massaro).
|
||||
|
||||
* Fixed problem with building DLL under Cygwin; thanks to Stephane Fillod.
|
||||
|
||||
* Fix build failure if no Fortran compiler is found (thanks to Charles
|
||||
Radley for the bug report).
|
||||
|
||||
* Fixed compilation failure with icc 8.0 and SSE/SSE2. Automatic
|
||||
detection of icc architecture flag (e.g. -xW).
|
||||
|
||||
* Fixed compilation with OpenMP on AIX (thanks to Greg Bauer).
|
||||
|
||||
* Fixed compilation failure on x86-64 with gcc (thanks to Orion Poplawski).
|
||||
|
||||
* Incorporated patch from FreeBSD ports (FreeBSD does not have memalign,
|
||||
but its malloc is 16-byte aligned).
|
||||
|
||||
* Cycle-counter compilation fixes for Itanium, Alpha, x86-64, Sparc,
|
||||
MacOS (thanks to Matt Boman, John Bowman, and James A. Treacy for
|
||||
reports/fixes). Added x86-64 cycle counter for PGI compilers,
|
||||
courtesy Cristiano Calonaci.
|
||||
|
||||
* Fix compilation problem in test program due to C99 conflict.
|
||||
|
||||
* Portability fix for import_system_wisdom with djgpp (thanks to Juan
|
||||
Manuel Guerrero).
|
||||
|
||||
* Fixed compilation failure on MacOS 10.3 due to getopt conflict.
|
||||
|
||||
* Work around Visual C++ (version 6/7) bug in SSE compilation;
|
||||
thanks to Eddie Yee for his detailed report.
|
||||
|
||||
Changes from FFTW 3.1 beta 2:
|
||||
|
||||
* Several minor compilation fixes.
|
||||
|
||||
* Eliminate FFTW_TIMELIMIT flag and replace fftw_timelimit global with
|
||||
fftw_set_timelimit function. Make wisdom work with time-limited plans.
|
||||
|
||||
Changes from FFTW 3.1 beta 1:
|
||||
|
||||
* Fixes for creating DLLs under Windows; thanks to John Pavel for his feedback.
|
||||
|
||||
* Fixed more 64-bit problems, thanks to John Pavel for the bug report.
|
||||
|
||||
* Further speed improvements for Altivec/VMX.
|
||||
|
||||
* Further speed improvements for non-square transpositions.
|
||||
|
||||
* Many minor tweaks.
|
||||
|
||||
FFTW 3.0.1
|
||||
|
||||
* Some speed improvements in SIMD code.
|
||||
|
||||
* --without-cycle-counter option is removed. If no cycle counter is found,
|
||||
then the estimator is always used. A --with-slow-timer option is provided
|
||||
to force the use of lower-resolution timers.
|
||||
|
||||
* Several fixes for compilation under Visual C++, with help from Stefane Ruel.
|
||||
|
||||
* Added x86 cycle counter for Visual C++, with help from Morten Nissov.
|
||||
|
||||
* Added S390 cycle counter, courtesy of James Treacy.
|
||||
|
||||
* Added missing static keyword that prevented simultaneous linkage
|
||||
of different-precision versions; thanks to Rasmus Larsen for the bug report.
|
||||
|
||||
* Corrected accidental omission of f77_wisdom.f file; thanks to Alan Watson.
|
||||
|
||||
* Support -xopenmp flag for SunOS; thanks to John Lou for the bug report.
|
||||
|
||||
* Compilation with HP/UX cc requires -Wp,-H128000 flag to increase
|
||||
preprocessor limits; thanks to Peter Vouras for the bug report.
|
||||
|
||||
* Removed non-portable use of 'tempfile' in fftw-wisdom-to-conf script;
|
||||
thanks to Nicolas Decoster for the patch.
|
||||
|
||||
* Added 'make smallcheck' target in tests/ directory, at the request of
|
||||
James Treacy.
|
||||
|
||||
FFTW 3.0
|
||||
|
||||
Major goals of this release:
|
||||
|
||||
* Speed: often 20% or more faster than FFTW 2.x, even without SIMD (see below).
|
||||
|
||||
* Complete rewrite, to make it easier to add new algorithms and transforms.
|
||||
|
||||
* New API, to support more general semantics.
|
||||
|
||||
Other enhancements:
|
||||
|
||||
* SIMD acceleration on supporting CPUs (SSE, SSE2, 3DNow!, and AltiVec).
|
||||
(With special thanks to Franz Franchetti for many experimental prototypes
|
||||
and to Stefan Kral for the vectorizing generator from fftwgel.)
|
||||
|
||||
* True in-place 1d transforms of large sizes (as well as compressed
|
||||
twiddle tables for additional memory/cache savings).
|
||||
|
||||
* More arbitrary placement of real & imaginary data, e.g. including
|
||||
interleaved (as in FFTW 2.x) as well as separate real/imag arrays.
|
||||
|
||||
* Efficient prime-size transforms of real data.
|
||||
|
||||
* Multidimensional transforms can operate on a subset of a larger matrix,
|
||||
and/or transform selected dimensions of a multidimensional array.
|
||||
|
||||
* By popular demand, simultaneous linking to double precision (fftw),
|
||||
single precision (fftwf), and long-double precision (fftwl) versions
|
||||
of FFTW is now supported.
|
||||
|
||||
* Cycle counters (on all modern CPUs) are exploited to speed planning.
|
||||
|
||||
* Efficient transforms of real even/odd arrays, a.k.a. discrete
|
||||
cosine/sine transforms (types I-IV). (Currently work via pre/post
|
||||
processing of real transforms, ala FFTPACK, so are not optimal.)
|
||||
|
||||
* DHTs (Discrete Hartley Transforms), again via post-processing
|
||||
of real transforms (and thus suboptimal, for now).
|
||||
|
||||
* Support for linking to just those parts of FFTW that you need,
|
||||
greatly reducing the size of statically linked programs when
|
||||
only a limited set of transform sizes/types are required.
|
||||
|
||||
* Canonical global wisdom file (/etc/fftw/wisdom) on Unix, along
|
||||
with a command-line tool (fftw-wisdom) to generate/update it.
|
||||
|
||||
* Fortran API can be used with both g77 and non-g77 compilers
|
||||
simultaneously.
|
||||
|
||||
* Multi-threaded version has optional OpenMP support.
|
||||
|
||||
* Authors' good looks have greatly improved with age.
|
||||
|
||||
Changes from 3.0beta3:
|
||||
|
||||
* Separate FMA distribution to better exploit fused multiply-add instructions
|
||||
on PowerPC (and possibly other) architectures.
|
||||
|
||||
* Performance improvements via some inlining tweaks.
|
||||
|
||||
* fftw_flops now returns double arguments, not int, to avoid overflows
|
||||
for large sizes.
|
||||
|
||||
* Workarounds for automake bugs.
|
||||
|
||||
Changes from 3.0beta2:
|
||||
|
||||
* The standard REDFT00/RODFT00 (DCT-I/DST-I) algorithm (used in
|
||||
FFTPACK, NR, etcetera) turns out to have poor numerical accuracy, so
|
||||
we replaced it with a slower routine that is more accurate.
|
||||
|
||||
* The guru planner and execute functions now have two variants, one that
|
||||
takes complex arguments and one that takes separate real/imag pointers.
|
||||
|
||||
* Execute and planner routines now automatically align the stack on x86,
|
||||
in case the calling program is misaligned.
|
||||
|
||||
* README file for test program.
|
||||
|
||||
* Fixed bugs in the combination of SIMD with multi-threaded transforms.
|
||||
|
||||
* Eliminated internal fftw_threads_init function, which some people were
|
||||
calling accidentally instead of the fftw_init_threads API function.
|
||||
|
||||
* Check for -openmp flag (Intel C compiler) when --enable-openmp is used.
|
||||
|
||||
* Support AMD x86-64 SIMD and cycle counter.
|
||||
|
||||
* Support SSE2 intrinsics in forthcoming gcc 3.3.
|
||||
|
||||
Changes from 3.0beta1:
|
||||
|
||||
* Faster in-place 1d transforms of non-power-of-two sizes.
|
||||
|
||||
* SIMD improvements for in-place, multi-dimensional, and/or non-FFTW_PATIENT
|
||||
transforms.
|
||||
|
||||
* Added support for hard-coded DCT/DST/DHT codelets of small sizes; the
|
||||
default distribution only includes hard-coded size-8 DCT-II/III, however.
|
||||
|
||||
* Many minor improvements to the manual. Added section on using the
|
||||
codelet generator to customize and enhance FFTW.
|
||||
|
||||
* The default 'make check' should now only take a few minutes; for more
|
||||
strenuous tests (which may take a day or so), do 'cd tests; make bigcheck'.
|
||||
|
||||
* fftw_print_plan is split into fftw_fprint_plan and fftw_print_plan, where
|
||||
the latter uses stdout.
|
||||
|
||||
* Fixed ability to compile with a C++ compiler.
|
||||
|
||||
* Fixed support for C99 complex type under glibc.
|
||||
|
||||
* Fixed problems with alloca under MinGW, AIX.
|
||||
|
||||
* Workaround for gcc/SPARC bug.
|
||||
|
||||
* Fixed multi-threaded initialization failure on IRIX due to lack of
|
||||
user-accessible PTHREAD_SCOPE_SYSTEM there.
|
|
@ -0,0 +1,65 @@
|
|||
FFTW is a free collection of fast C routines for computing the
|
||||
Discrete Fourier Transform in one or more dimensions. It includes
|
||||
complex, real, symmetric, and parallel transforms, and can handle
|
||||
arbitrary array sizes efficiently. FFTW is typically faster than
|
||||
other publically-available FFT implementations, and is even
|
||||
competitive with vendor-tuned libraries. (See our web page
|
||||
http://fftw.org/ for extensive benchmarks.) To achieve this
|
||||
performance, FFTW uses novel code-generation and runtime
|
||||
self-optimization techniques (along with many other tricks).
|
||||
|
||||
The doc/ directory contains the manual in texinfo, PDF, info, and HTML
|
||||
formats. Frequently asked questions and answers can be found in the
|
||||
doc/FAQ/ directory in ASCII and HTML.
|
||||
|
||||
For a quick introduction to calling FFTW, see the "Tutorial" section
|
||||
of the manual.
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
INSTALLATION FROM AN OFFICIAL RELEASE:
|
||||
|
||||
Please read chapter 10 "Installation and Customization" of the manual.
|
||||
In short:
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
INSTALLATION FROM THE GIT REPOSITORY:
|
||||
|
||||
First, install these programs:
|
||||
|
||||
ocaml, ocamlbuild, autoconf, automake, indent, and libtool.
|
||||
|
||||
You also need the ocaml Num library, which was standard in Ocaml but
|
||||
was removed without warning in OCaml 4.06.0 (3 Nov 2017). On Fedora
|
||||
30, try installing the ocaml-num-devel package.
|
||||
|
||||
Then, execute
|
||||
|
||||
sh bootstrap.sh
|
||||
make
|
||||
|
||||
The bootstrap.sh script runs configure directly, but if you need to
|
||||
re-run configure, you must pass the --enable-maintainer-mode flag:
|
||||
|
||||
./configure --enable-maintainer-mode [OTHER CONFIGURE FLAGS]
|
||||
|
||||
Alternatively, you can run
|
||||
|
||||
sh mkdist.sh
|
||||
|
||||
which will run the entire bootstrapping process and generate
|
||||
.tar.gz files similar to those for official releases.
|
||||
|
||||
CONTACTS
|
||||
--------
|
||||
|
||||
FFTW was written by Matteo Frigo and Steven G. Johnson. You can
|
||||
contact them at fftw@fftw.org. The latest version of FFTW,
|
||||
benchmarks, links, and other information can be found at the FFTW home
|
||||
page (http://www.fftw.org). You can also sign up to the fftw-announce
|
||||
Google group to receive (infrequent) updates and information about new
|
||||
releases.
|
|
@ -0,0 +1,93 @@
|
|||
Performance Counters
|
||||
====================
|
||||
|
||||
FFTW measures execution time in the planning stage, optionally taking advantage
|
||||
of hardware performance counters. This document describes the supported
|
||||
counters and additional steps needed to enable each on different architectures.
|
||||
|
||||
See `./configure --help` for flags for enabling each supported counter.
|
||||
See [kernel/cycle.h](kernel/cycle.h) for the code that accesses the counters.
|
||||
|
||||
ARMv7-A (armv7a)
|
||||
================
|
||||
|
||||
`CNTVCT`: Virtual Count Register in VMSA
|
||||
--------------------------------------
|
||||
|
||||
A 64-bit counter part of Virtual Memory System Architecture.
|
||||
Section B4.1.34 in ARM Architecture Reference Manual ARMv7-A/ARMv7-R
|
||||
|
||||
For access from user mode, requires `CNTKCTL.PL0VCTEN == 1`, which must
|
||||
be set in kernel mode on each CPU:
|
||||
|
||||
#define CNTKCTL_PL0VCTEN 0x2 /* B4.1.26 in ARM Architecture Rreference */
|
||||
uint32_t r;
|
||||
asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r"(r)); /* read */
|
||||
r |= CNTKCTL_PL0VCTEN;
|
||||
asm volatile("mcr p15, 0, %0, c14, c1, 0" :: "r"(r)); /* write */
|
||||
|
||||
Kernel module source *which can be patched with the above code* available at:
|
||||
https://github.com/thoughtpolice/enable_arm_pmu
|
||||
|
||||
`PMCCNTR`: Performance Monitors Cycle Count Register in VMSA
|
||||
----------------------------------------------------------
|
||||
|
||||
A 32-bit counter part of Virtual Memory System Architecture.
|
||||
Section B4.1.113 in ARM Architecture Reference Manual ARMv7-A/ARMv7-R
|
||||
|
||||
For access from user mode, requires user-mode access to PMU to be enabled
|
||||
(`PMUSERENR.EN == 1`), which must be done from kernel mode on each CPU:
|
||||
|
||||
#define PERF_DEF_OPTS (1 | 16)
|
||||
/* enable user-mode access to counters */
|
||||
asm volatile("mcr p15, 0, %0, c9, c14, 0" :: "r"(1));
|
||||
/* Program PMU and enable all counters */
|
||||
asm volatile("mcr p15, 0, %0, c9, c12, 0" :: "r"(PERF_DEF_OPTS));
|
||||
asm volatile("mcr p15, 0, %0, c9, c12, 1" :: "r"(0x8000000f));
|
||||
|
||||
Kernel module source with the above code available at:
|
||||
[GitHub thoughtpolice/enable\_arm\_pmu](https://github.com/thoughtpolice/enable_arm_pmu)
|
||||
|
||||
More information:
|
||||
http://neocontra.blogspot.com/2013/05/user-mode-performance-counters-for.html
|
||||
|
||||
ARMv8-A (aarch64)
|
||||
=================
|
||||
|
||||
`CNTVCT_EL0`: Counter-timer Virtual Count Register
|
||||
------------------------------------------------
|
||||
|
||||
A 64-bit counter, part of Generic Registers.
|
||||
Section D8.5.17 in ARM Architecture Reference Manual ARMv8-A
|
||||
|
||||
For user-mode access, requires `CNTKCTL_EL1.EL0VCTEN == 1`, which
|
||||
must be set from kernel mode for each CPU:
|
||||
|
||||
#define CNTKCTL_EL0VCTEN 0x2
|
||||
uint32_t r;
|
||||
asm volatile("mrs %0, CNTKCTL_EL1" : "=r"(r)); /* read */
|
||||
r |= CNTKCTL_EL0VCTEN;
|
||||
asm volatile("msr CNTKCTL_EL1, %0" :: "r"(r)); /* write */
|
||||
|
||||
*WARNING*: Above code was not tested.
|
||||
|
||||
`PMCCNTR_EL0`: Performance Monitors Cycle Count Register
|
||||
------------------------------------------------------
|
||||
|
||||
A 64-bit counter, part of Performance Monitors.
|
||||
Section D8.4.2 in ARM Architecture Reference Manual ARMv8-A
|
||||
|
||||
For access from user mode, requires user-mode access to PMU (`PMUSERENR_EL0.EN
|
||||
== 1`), which must be set from kernel mode for each CPU:
|
||||
|
||||
#define PERF_DEF_OPTS (1 | 16)
|
||||
/* enable user-mode access to counters */
|
||||
asm volatile("msr PMUSERENR_EL0, %0" :: "r"(1));
|
||||
/* Program PMU and enable all counters */
|
||||
asm volatile("msr PMCR_EL0, %0" :: "r"(PERF_DEF_OPTS));
|
||||
asm volatile("msr PMCNTENSET_EL0, %0" :: "r"(0x8000000f));
|
||||
asm volatile("msr PMCCFILTR_EL0, %0" :: "r"(0));
|
||||
|
||||
Kernel module source with the above code available at:
|
||||
[GitHub rdolbeau/enable\_arm\_pmu](https://github.com/rdolbeau/enable_arm_pmu)
|
||||
or in [Pull Request #2 at thoughtpolice/enable\_arm\_pmu](https://github.com/thoughtpolice/enable_arm_pmu/pull/2)
|
|
@ -0,0 +1,43 @@
|
|||
TODO before FFTW-$2\pi$:
|
||||
|
||||
* figure out how to autodetect NEON at runtime
|
||||
|
||||
* figure out the arm cycle counter business
|
||||
|
||||
* Wisdom: make it clear that it is specific to the exact fftw version
|
||||
and configuration. Report error codes when reading wisdom. Maybe
|
||||
have multiple system wisdom files, one per version?
|
||||
|
||||
* DCT/DST codelets? which kinds?
|
||||
|
||||
* investigate the addition-chain trig computation
|
||||
|
||||
* I can't believe that there isn't a closed form for the omega
|
||||
array in Rader.
|
||||
|
||||
* convolution problem type(s)
|
||||
|
||||
* Explore the idea of having n < 0 in tensors, possibly to mean
|
||||
inverse DFT.
|
||||
|
||||
* better estimator: possibly, let "other" cost be coef * n, where
|
||||
coef is a per-solver constant determined via some big numerical
|
||||
optimization/fit.
|
||||
|
||||
* vector radix, multidimensional codelets
|
||||
|
||||
* it may be a good idea to unify all those little loops that do
|
||||
copying, (X[i], X[n-i]) <- (X[i] + X[n-i], X[i] - X[n-i]),
|
||||
and multiplication of vectors by twiddle factors.
|
||||
|
||||
* Pruned FFTs (basically, a vecloop that skips zeros).
|
||||
|
||||
* Try FFTPACK-style back-and-forth (Stockham) FFT. (We tried this a
|
||||
few years ago and it was slower, but perhaps matters have changed.)
|
||||
|
||||
* Generate assembly directly for more processors, or maybe fork gcc. =)
|
||||
|
||||
* ensure that threaded solvers generate (block_size % 4 == 0)
|
||||
to allow SIMD to be used.
|
||||
|
||||
* memoize triggen.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,59 @@
|
|||
AM_CPPFLAGS = -I $(top_srcdir)
|
||||
AM_CFLAGS = $(STACK_ALIGN_CFLAGS)
|
||||
|
||||
EXTRA_DIST = f03api.sh genf03.pl fftw3.f03.in
|
||||
|
||||
include_HEADERS = fftw3.h fftw3.f fftw3l.f03 fftw3q.f03
|
||||
nodist_include_HEADERS = fftw3.f03
|
||||
noinst_LTLIBRARIES = libapi.la
|
||||
|
||||
libapi_la_SOURCES = apiplan.c configure.c execute-dft-c2r.c \
|
||||
execute-dft-r2c.c execute-dft.c execute-r2r.c execute-split-dft-c2r.c \
|
||||
execute-split-dft-r2c.c execute-split-dft.c execute.c \
|
||||
export-wisdom-to-file.c export-wisdom-to-string.c export-wisdom.c \
|
||||
f77api.c flops.c forget-wisdom.c import-system-wisdom.c \
|
||||
import-wisdom-from-file.c import-wisdom-from-string.c import-wisdom.c \
|
||||
malloc.c map-r2r-kind.c mapflags.c mkprinter-file.c mkprinter-str.c \
|
||||
mktensor-iodims.c mktensor-rowmajor.c plan-dft-1d.c plan-dft-2d.c \
|
||||
plan-dft-3d.c plan-dft-c2r-1d.c plan-dft-c2r-2d.c plan-dft-c2r-3d.c \
|
||||
plan-dft-c2r.c plan-dft-r2c-1d.c plan-dft-r2c-2d.c plan-dft-r2c-3d.c \
|
||||
plan-dft-r2c.c plan-dft.c plan-guru-dft-c2r.c plan-guru-dft-r2c.c \
|
||||
plan-guru-dft.c plan-guru-r2r.c plan-guru-split-dft-c2r.c \
|
||||
plan-guru-split-dft-r2c.c plan-guru-split-dft.c plan-many-dft-c2r.c \
|
||||
plan-many-dft-r2c.c plan-many-dft.c plan-many-r2r.c plan-r2r-1d.c \
|
||||
plan-r2r-2d.c plan-r2r-3d.c plan-r2r.c print-plan.c rdft2-pad.c \
|
||||
the-planner.c version.c api.h f77funcs.h fftw3.h x77.h guru.h \
|
||||
guru64.h mktensor-iodims.h plan-guru-dft-c2r.h plan-guru-dft-r2c.h \
|
||||
plan-guru-dft.h plan-guru-r2r.h plan-guru-split-dft-c2r.h \
|
||||
plan-guru-split-dft-r2c.h plan-guru-split-dft.h plan-guru64-dft-c2r.c \
|
||||
plan-guru64-dft-r2c.c plan-guru64-dft.c plan-guru64-r2r.c \
|
||||
plan-guru64-split-dft-c2r.c plan-guru64-split-dft-r2c.c \
|
||||
plan-guru64-split-dft.c mktensor-iodims64.c
|
||||
|
||||
BUILT_SOURCES = fftw3.f fftw3.f03.in fftw3.f03 fftw3l.f03 fftw3q.f03
|
||||
CLEANFILES = fftw3.f03
|
||||
|
||||
fftw3.f03: fftw3.f03.in
|
||||
(echo "! Generated automatically. DO NOT EDIT!"; echo; \
|
||||
echo " integer, parameter :: C_FFTW_R2R_KIND = @C_FFTW_R2R_KIND@"; \
|
||||
grep -v "Generated automatically" $(srcdir)/fftw3.f03.in) > $@
|
||||
|
||||
if MAINTAINER_MODE
|
||||
|
||||
# convert constants to F77 PARAMETER statements
|
||||
fftw3.f: fftw3.h
|
||||
rm -f $@
|
||||
perl -pe 's/([A-Z0-9_]+)=([+-]?[0-9]+)/\n INTEGER \1\n PARAMETER (\1=\2)\n/g' $< |egrep 'PARAMETER|INTEGER' > $@
|
||||
perl -pe 's/#define +([A-Z0-9_]+) +\(([+-]?[0-9]+)U?\)/\n INTEGER \1\n PARAMETER (\1=\2)\n/g' $< |egrep 'PARAMETER|INTEGER' >> $@
|
||||
perl -pe 'if (/#define +([A-Z0-9_]+) +\(([0-9]+)U? *<< *([0-9]+)\)/) { print "\n INTEGER $$1\n PARAMETER ($$1=",$$2 << $$3,")\n"; }' $< |egrep 'PARAMETER|INTEGER' >> $@
|
||||
|
||||
fftw3.f03.in: fftw3.h f03api.sh genf03.pl
|
||||
sh $(srcdir)/f03api.sh d f > $@
|
||||
|
||||
fftw3l.f03: fftw3.h f03api.sh genf03.pl
|
||||
sh $(srcdir)/f03api.sh l | grep -v parameter > $@
|
||||
|
||||
fftw3q.f03: fftw3.h f03api.sh genf03.pl
|
||||
sh $(srcdir)/f03api.sh q | grep -v parameter > $@
|
||||
|
||||
endif # MAINTAINER_MODE
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* internal API definitions */
|
||||
#ifndef __API_H__
|
||||
#define __API_H__
|
||||
|
||||
#ifndef CALLING_FFTW /* defined in hook.c, when calling internal functions */
|
||||
# define COMPILING_FFTW /* used for DLL symbol exporting in fftw3.h */
|
||||
#endif
|
||||
|
||||
/* When compiling with GNU libtool on Windows, DLL_EXPORT is #defined
|
||||
for compiling the shared-library code. In this case, we'll #define
|
||||
FFTW_DLL to add dllexport attributes to the specified functions in
|
||||
fftw3.h.
|
||||
|
||||
If we don't specify dllexport explicitly, then libtool
|
||||
automatically exports all symbols. However, if we specify
|
||||
dllexport explicitly for any functions, then libtool apparently
|
||||
doesn't do any automatic exporting. (Not documented, grrr, but
|
||||
this is the observed behavior with libtool 1.5.8.) Thus, using
|
||||
this forces us to correctly dllexport every exported symbol, or
|
||||
linking bench.exe will fail. This has the advantage of forcing
|
||||
us to mark things correctly, which is necessary for other compilers
|
||||
(such as MS VC++). */
|
||||
#ifdef DLL_EXPORT
|
||||
# define FFTW_DLL
|
||||
#endif
|
||||
|
||||
/* just in case: force <fftw3.h> not to use C99 complex numbers
|
||||
(we need this for IBM xlc because _Complex_I is treated specially
|
||||
and is defined even if <complex.h> is not included) */
|
||||
#define FFTW_NO_Complex
|
||||
|
||||
#include "api/fftw3.h"
|
||||
#include "kernel/ifftw.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* the API ``plan'' contains both the kernel plan and problem */
|
||||
struct X(plan_s) {
|
||||
plan *pln;
|
||||
problem *prb;
|
||||
int sign;
|
||||
};
|
||||
|
||||
/* shorthand */
|
||||
typedef struct X(plan_s) apiplan;
|
||||
|
||||
/* complex type for internal use */
|
||||
typedef R C[2];
|
||||
|
||||
#define EXTRACT_REIM(sign, c, r, i) X(extract_reim)(sign, (c)[0], r, i)
|
||||
|
||||
#define TAINT_UNALIGNED(p, flg) TAINT(p, ((flg) & FFTW_UNALIGNED) != 0)
|
||||
|
||||
tensor *X(mktensor_rowmajor)(int rnk, const int *n,
|
||||
const int *niphys, const int *nophys,
|
||||
int is, int os);
|
||||
|
||||
tensor *X(mktensor_iodims)(int rank, const X(iodim) *dims, int is, int os);
|
||||
tensor *X(mktensor_iodims64)(int rank, const X(iodim64) *dims, int is, int os);
|
||||
const int *X(rdft2_pad)(int rnk, const int *n, const int *nembed,
|
||||
int inplace, int cmplx, int **nfree);
|
||||
|
||||
int X(many_kosherp)(int rnk, const int *n, int howmany);
|
||||
int X(guru_kosherp)(int rank, const X(iodim) *dims,
|
||||
int howmany_rank, const X(iodim) *howmany_dims);
|
||||
int X(guru64_kosherp)(int rank, const X(iodim64) *dims,
|
||||
int howmany_rank, const X(iodim64) *howmany_dims);
|
||||
|
||||
/* Note: FFTW_EXTERN is used for "internal" functions used in tests/hook.c */
|
||||
|
||||
FFTW_EXTERN printer *X(mkprinter_file)(FILE *f);
|
||||
|
||||
printer *X(mkprinter_cnt)(size_t *cnt);
|
||||
printer *X(mkprinter_str)(char *s);
|
||||
|
||||
FFTW_EXTERN planner *X(the_planner)(void);
|
||||
void X(configure_planner)(planner *plnr);
|
||||
|
||||
void X(mapflags)(planner *, unsigned);
|
||||
|
||||
apiplan *X(mkapiplan)(int sign, unsigned flags, problem *prb);
|
||||
|
||||
rdft_kind *X(map_r2r_kind)(int rank, const X(r2r_kind) * kind);
|
||||
|
||||
typedef void (*planner_hook_t)(void);
|
||||
|
||||
void X(set_planner_hooks)(planner_hook_t before, planner_hook_t after);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __API_H__ */
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
static planner_hook_t before_planner_hook = 0, after_planner_hook = 0;
|
||||
|
||||
void X(set_planner_hooks)(planner_hook_t before, planner_hook_t after)
|
||||
{
|
||||
before_planner_hook = before;
|
||||
after_planner_hook = after;
|
||||
}
|
||||
|
||||
static plan *mkplan0(planner *plnr, unsigned flags,
|
||||
const problem *prb, unsigned hash_info,
|
||||
wisdom_state_t wisdom_state)
|
||||
{
|
||||
/* map API flags into FFTW flags */
|
||||
X(mapflags)(plnr, flags);
|
||||
|
||||
plnr->flags.hash_info = hash_info;
|
||||
plnr->wisdom_state = wisdom_state;
|
||||
|
||||
/* create plan */
|
||||
return plnr->adt->mkplan(plnr, prb);
|
||||
}
|
||||
|
||||
static unsigned force_estimator(unsigned flags)
|
||||
{
|
||||
flags &= ~(FFTW_MEASURE | FFTW_PATIENT | FFTW_EXHAUSTIVE);
|
||||
return (flags | FFTW_ESTIMATE);
|
||||
}
|
||||
|
||||
static plan *mkplan(planner *plnr, unsigned flags,
|
||||
const problem *prb, unsigned hash_info)
|
||||
{
|
||||
plan *pln;
|
||||
|
||||
pln = mkplan0(plnr, flags, prb, hash_info, WISDOM_NORMAL);
|
||||
|
||||
if (plnr->wisdom_state == WISDOM_NORMAL && !pln) {
|
||||
/* maybe the planner failed because of inconsistent wisdom;
|
||||
plan again ignoring infeasible wisdom */
|
||||
pln = mkplan0(plnr, force_estimator(flags), prb,
|
||||
hash_info, WISDOM_IGNORE_INFEASIBLE);
|
||||
}
|
||||
|
||||
if (plnr->wisdom_state == WISDOM_IS_BOGUS) {
|
||||
/* if the planner detected a wisdom inconsistency,
|
||||
forget all wisdom and plan again */
|
||||
plnr->adt->forget(plnr, FORGET_EVERYTHING);
|
||||
|
||||
A(!pln);
|
||||
pln = mkplan0(plnr, flags, prb, hash_info, WISDOM_NORMAL);
|
||||
|
||||
if (plnr->wisdom_state == WISDOM_IS_BOGUS) {
|
||||
/* if it still fails, plan without wisdom */
|
||||
plnr->adt->forget(plnr, FORGET_EVERYTHING);
|
||||
|
||||
A(!pln);
|
||||
pln = mkplan0(plnr, force_estimator(flags),
|
||||
prb, hash_info, WISDOM_IGNORE_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
return pln;
|
||||
}
|
||||
|
||||
apiplan *X(mkapiplan)(int sign, unsigned flags, problem *prb)
|
||||
{
|
||||
apiplan *p = 0;
|
||||
plan *pln;
|
||||
unsigned flags_used_for_planning;
|
||||
planner *plnr;
|
||||
static const unsigned int pats[] = {FFTW_ESTIMATE, FFTW_MEASURE,
|
||||
FFTW_PATIENT, FFTW_EXHAUSTIVE};
|
||||
int pat, pat_max;
|
||||
double pcost = 0;
|
||||
|
||||
if (before_planner_hook)
|
||||
before_planner_hook();
|
||||
|
||||
plnr = X(the_planner)();
|
||||
|
||||
if (flags & FFTW_WISDOM_ONLY) {
|
||||
/* Special mode that returns a plan only if wisdom is present,
|
||||
and returns 0 otherwise. This is now documented in the manual,
|
||||
as a way to detect whether wisdom is available for a problem. */
|
||||
flags_used_for_planning = flags;
|
||||
pln = mkplan0(plnr, flags, prb, 0, WISDOM_ONLY);
|
||||
} else {
|
||||
pat_max = flags & FFTW_ESTIMATE ? 0 :
|
||||
(flags & FFTW_EXHAUSTIVE ? 3 :
|
||||
(flags & FFTW_PATIENT ? 2 : 1));
|
||||
pat = plnr->timelimit >= 0 ? 0 : pat_max;
|
||||
|
||||
flags &= ~(FFTW_ESTIMATE | FFTW_MEASURE |
|
||||
FFTW_PATIENT | FFTW_EXHAUSTIVE);
|
||||
|
||||
plnr->start_time = X(get_crude_time)();
|
||||
|
||||
/* plan at incrementally increasing patience until we run
|
||||
out of time */
|
||||
for (pln = 0, flags_used_for_planning = 0; pat <= pat_max; ++pat) {
|
||||
plan *pln1;
|
||||
unsigned tmpflags = flags | pats[pat];
|
||||
pln1 = mkplan(plnr, tmpflags, prb, 0u);
|
||||
|
||||
if (!pln1) {
|
||||
/* don't bother continuing if planner failed or timed out */
|
||||
A(!pln || plnr->timed_out);
|
||||
break;
|
||||
}
|
||||
|
||||
X(plan_destroy_internal)(pln);
|
||||
pln = pln1;
|
||||
flags_used_for_planning = tmpflags;
|
||||
pcost = pln->pcost;
|
||||
}
|
||||
}
|
||||
|
||||
if (pln) {
|
||||
/* build apiplan */
|
||||
p = (apiplan *) MALLOC(sizeof(apiplan), PLANS);
|
||||
p->prb = prb;
|
||||
p->sign = sign; /* cache for execute_dft */
|
||||
|
||||
/* re-create plan from wisdom, adding blessing */
|
||||
p->pln = mkplan(plnr, flags_used_for_planning, prb, BLESSING);
|
||||
|
||||
/* record pcost from most recent measurement for use in X(cost) */
|
||||
p->pln->pcost = pcost;
|
||||
|
||||
if (sizeof(trigreal) > sizeof(R)) {
|
||||
/* this is probably faster, and we have enough trigreal
|
||||
bits to maintain accuracy */
|
||||
X(plan_awake)(p->pln, AWAKE_SQRTN_TABLE);
|
||||
} else {
|
||||
/* more accurate */
|
||||
X(plan_awake)(p->pln, AWAKE_SINCOS);
|
||||
}
|
||||
|
||||
/* we don't use pln for p->pln, above, since by re-creating the
|
||||
plan we might use more patient wisdom from a timed-out mkplan */
|
||||
X(plan_destroy_internal)(pln);
|
||||
} else
|
||||
X(problem_destroy)(prb);
|
||||
|
||||
/* discard all information not necessary to reconstruct the plan */
|
||||
plnr->adt->forget(plnr, FORGET_ACCURSED);
|
||||
|
||||
#ifdef FFTW_RANDOM_ESTIMATOR
|
||||
X(random_estimate_seed)++; /* subsequent "random" plans are distinct */
|
||||
#endif
|
||||
|
||||
if (after_planner_hook)
|
||||
after_planner_hook();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void X(destroy_plan)(X(plan) p)
|
||||
{
|
||||
if (p) {
|
||||
if (before_planner_hook)
|
||||
before_planner_hook();
|
||||
|
||||
X(plan_awake)(p->pln, SLEEPY);
|
||||
X(plan_destroy_internal)(p->pln);
|
||||
X(problem_destroy)(p->prb);
|
||||
X(ifree)(p);
|
||||
|
||||
if (after_planner_hook)
|
||||
after_planner_hook();
|
||||
}
|
||||
}
|
||||
|
||||
int X(alignment_of)(R *p)
|
||||
{
|
||||
return X(ialignment_of(p));
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "dft/dft.h"
|
||||
#include "rdft/rdft.h"
|
||||
#include "reodft/reodft.h"
|
||||
|
||||
void X(configure_planner)(planner *plnr)
|
||||
{
|
||||
X(dft_conf_standard)(plnr);
|
||||
X(rdft_conf_standard)(plnr);
|
||||
X(reodft_conf_standard)(plnr);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
/* guru interface: requires care in alignment, r - i, etcetera. */
|
||||
void X(execute_dft_c2r)(const X(plan) p, C *in, R *out)
|
||||
{
|
||||
plan_rdft2 *pln = (plan_rdft2 *) p->pln;
|
||||
problem_rdft2 *prb = (problem_rdft2 *) p->prb;
|
||||
pln->apply((plan *) pln, out, out + (prb->r1 - prb->r0), in[0], in[0]+1);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
/* guru interface: requires care in alignment, r - i, etcetera. */
|
||||
void X(execute_dft_r2c)(const X(plan) p, R *in, C *out)
|
||||
{
|
||||
plan_rdft2 *pln = (plan_rdft2 *) p->pln;
|
||||
problem_rdft2 *prb = (problem_rdft2 *) p->prb;
|
||||
pln->apply((plan *) pln, in, in + (prb->r1 - prb->r0), out[0], out[0]+1);
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "dft/dft.h"
|
||||
|
||||
/* guru interface: requires care in alignment etcetera. */
|
||||
void X(execute_dft)(const X(plan) p, C *in, C *out)
|
||||
{
|
||||
plan_dft *pln = (plan_dft *) p->pln;
|
||||
if (p->sign == FFT_SIGN)
|
||||
pln->apply((plan *) pln, in[0], in[0]+1, out[0], out[0]+1);
|
||||
else
|
||||
pln->apply((plan *) pln, in[0]+1, in[0], out[0]+1, out[0]);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
/* guru interface: requires care in alignment, etcetera. */
|
||||
void X(execute_r2r)(const X(plan) p, R *in, R *out)
|
||||
{
|
||||
plan_rdft *pln = (plan_rdft *) p->pln;
|
||||
pln->apply((plan *) pln, in, out);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
/* guru interface: requires care in alignment, r - i, etcetera. */
|
||||
void X(execute_split_dft_c2r)(const X(plan) p, R *ri, R *ii, R *out)
|
||||
{
|
||||
plan_rdft2 *pln = (plan_rdft2 *) p->pln;
|
||||
problem_rdft2 *prb = (problem_rdft2 *) p->prb;
|
||||
pln->apply((plan *) pln, out, out + (prb->r1 - prb->r0), ri, ii);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
/* guru interface: requires care in alignment, r - i, etcetera. */
|
||||
void X(execute_split_dft_r2c)(const X(plan) p, R *in, R *ro, R *io)
|
||||
{
|
||||
plan_rdft2 *pln = (plan_rdft2 *) p->pln;
|
||||
problem_rdft2 *prb = (problem_rdft2 *) p->prb;
|
||||
pln->apply((plan *) pln, in, in + (prb->r1 - prb->r0), ro, io);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "dft/dft.h"
|
||||
|
||||
/* guru interface: requires care in alignment, r - i, etcetera. */
|
||||
void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, R *ro, R *io)
|
||||
{
|
||||
plan_dft *pln = (plan_dft *) p->pln;
|
||||
pln->apply((plan *) pln, ri, ii, ro, io);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
void X(execute)(const X(plan) p)
|
||||
{
|
||||
plan *pln = p->pln;
|
||||
pln->adt->solve(pln, p->prb);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
void X(export_wisdom_to_file)(FILE *output_file)
|
||||
{
|
||||
printer *p = X(mkprinter_file)(output_file);
|
||||
planner *plnr = X(the_planner)();
|
||||
plnr->adt->exprt(plnr, p);
|
||||
X(printer_destroy)(p);
|
||||
}
|
||||
|
||||
int X(export_wisdom_to_filename)(const char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "w");
|
||||
int ret;
|
||||
if (!f) return 0; /* error opening file */
|
||||
X(export_wisdom_to_file)(f);
|
||||
ret = !ferror(f);
|
||||
if (fclose(f)) ret = 0; /* error closing file */
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
char *X(export_wisdom_to_string)(void)
|
||||
{
|
||||
printer *p;
|
||||
planner *plnr = X(the_planner)();
|
||||
size_t cnt;
|
||||
char *s;
|
||||
|
||||
p = X(mkprinter_cnt)(&cnt);
|
||||
plnr->adt->exprt(plnr, p);
|
||||
X(printer_destroy)(p);
|
||||
|
||||
s = (char *) malloc(sizeof(char) * (cnt + 1));
|
||||
if (s) {
|
||||
p = X(mkprinter_str)(s);
|
||||
plnr->adt->exprt(plnr, p);
|
||||
X(printer_destroy)(p);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
typedef struct {
|
||||
printer super;
|
||||
void (*write_char)(char c, void *);
|
||||
void *data;
|
||||
} P;
|
||||
|
||||
static void putchr_generic(printer * p_, char c)
|
||||
{
|
||||
P *p = (P *) p_;
|
||||
(p->write_char)(c, p->data);
|
||||
}
|
||||
|
||||
void X(export_wisdom)(void (*write_char)(char c, void *), void *data)
|
||||
{
|
||||
P *p = (P *) X(mkprinter)(sizeof(P), putchr_generic, 0);
|
||||
planner *plnr = X(the_planner)();
|
||||
|
||||
p->write_char = write_char;
|
||||
p->data = data;
|
||||
plnr->adt->exprt(plnr, (printer *) p);
|
||||
X(printer_destroy)((printer *) p);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#! /bin/sh
|
||||
|
||||
# Script to generate Fortran 2003 interface declarations for FFTW from
|
||||
# the fftw3.h header file.
|
||||
|
||||
# This is designed so that the Fortran caller can do:
|
||||
# use, intrinsic :: iso_c_binding
|
||||
# implicit none
|
||||
# include 'fftw3.f03'
|
||||
# and then call the C FFTW functions directly, with type checking.
|
||||
|
||||
echo "! Generated automatically. DO NOT EDIT!"
|
||||
echo
|
||||
|
||||
# C_FFTW_R2R_KIND is determined by configure and inserted by the Makefile
|
||||
# echo " integer, parameter :: C_FFTW_R2R_KIND = @C_FFTW_R2R_KIND@"
|
||||
|
||||
# Extract constants
|
||||
perl -pe 's/([A-Z0-9_]+)=([+-]?[0-9]+)/\n integer\(C_INT\), parameter :: \1 = \2\n/g' < fftw3.h | grep 'integer(C_INT)'
|
||||
perl -pe 's/#define +([A-Z0-9_]+) +\(([+-]?[0-9]+)U?\)/\n integer\(C_INT\), parameter :: \1 = \2\n/g' < fftw3.h | grep 'integer(C_INT)'
|
||||
perl -pe 'if (/#define +([A-Z0-9_]+) +\(([0-9]+)U? *<< *([0-9]+)\)/) { print "\n integer\(C_INT\), parameter :: $1 = ",$2 << $3,"\n"; }' < fftw3.h | grep 'integer(C_INT)'
|
||||
|
||||
# Extract function declarations
|
||||
for p in $*; do
|
||||
if test "$p" = "d"; then p=""; fi
|
||||
|
||||
echo
|
||||
cat <<EOF
|
||||
type, bind(C) :: fftw${p}_iodim
|
||||
integer(C_INT) n, is, os
|
||||
end type fftw${p}_iodim
|
||||
type, bind(C) :: fftw${p}_iodim64
|
||||
integer(C_INTPTR_T) n, is, os
|
||||
end type fftw${p}_iodim64
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo " interface"
|
||||
gcc -D__GNUC__=5 -D__i386__ -E fftw3.h |grep "fftw${p}_plan_dft" |tr ';' '\n' | grep -v "fftw${p}_execute(" | perl genf03.pl
|
||||
echo " end interface"
|
||||
|
||||
done
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "dft/dft.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
#include "api/x77.h"
|
||||
|
||||
/* if F77_FUNC is not defined, then we don't know how to mangle identifiers
|
||||
for the Fortran linker, and we must omit the f77 API. */
|
||||
#if defined(F77_FUNC) || defined(WINDOWS_F77_MANGLING)
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* some internal functions used by the f77 api */
|
||||
|
||||
/* in fortran, the natural array ordering is column-major, which
|
||||
corresponds to reversing the dimensions relative to C's row-major */
|
||||
static int *reverse_n(int rnk, const int *n)
|
||||
{
|
||||
int *nrev;
|
||||
int i;
|
||||
A(FINITE_RNK(rnk));
|
||||
nrev = (int *) MALLOC(sizeof(int) * (unsigned)rnk, PROBLEMS);
|
||||
for (i = 0; i < rnk; ++i)
|
||||
nrev[rnk - i - 1] = n[i];
|
||||
return nrev;
|
||||
}
|
||||
|
||||
/* f77 doesn't have data structures, so we have to pass iodims as
|
||||
parallel arrays */
|
||||
static X(iodim) *make_dims(int rnk, const int *n,
|
||||
const int *is, const int *os)
|
||||
{
|
||||
X(iodim) *dims;
|
||||
int i;
|
||||
A(FINITE_RNK(rnk));
|
||||
dims = (X(iodim) *) MALLOC(sizeof(X(iodim)) * (unsigned)rnk, PROBLEMS);
|
||||
for (i = 0; i < rnk; ++i) {
|
||||
dims[i].n = n[i];
|
||||
dims[i].is = is[i];
|
||||
dims[i].os = os[i];
|
||||
}
|
||||
return dims;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
void (*f77_write_char)(char *, void *);
|
||||
void *data;
|
||||
} write_char_data;
|
||||
|
||||
static void write_char(char c, void *d)
|
||||
{
|
||||
write_char_data *ad = (write_char_data *) d;
|
||||
ad->f77_write_char(&c, ad->data);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
void (*f77_read_char)(int *, void *);
|
||||
void *data;
|
||||
} read_char_data;
|
||||
|
||||
static int read_char(void *d)
|
||||
{
|
||||
read_char_data *ed = (read_char_data *) d;
|
||||
int c;
|
||||
ed->f77_read_char(&c, ed->data);
|
||||
return (c < 0 ? EOF : c);
|
||||
}
|
||||
|
||||
static X(r2r_kind) *ints2kinds(int rnk, const int *ik)
|
||||
{
|
||||
if (!FINITE_RNK(rnk) || rnk == 0)
|
||||
return 0;
|
||||
else {
|
||||
int i;
|
||||
X(r2r_kind) *k;
|
||||
|
||||
k = (X(r2r_kind) *) MALLOC(sizeof(X(r2r_kind)) * (unsigned)rnk, PROBLEMS);
|
||||
/* reverse order for Fortran -> C */
|
||||
for (i = 0; i < rnk; ++i)
|
||||
k[i] = (X(r2r_kind)) ik[rnk - 1 - i];
|
||||
return k;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#define F77(a, A) F77x(x77(a), X77(A))
|
||||
|
||||
#ifndef WINDOWS_F77_MANGLING
|
||||
|
||||
#if defined(F77_FUNC)
|
||||
# define F77x(a, A) F77_FUNC(a, A)
|
||||
# include "f77funcs.h"
|
||||
#endif
|
||||
|
||||
/* If identifiers with underscores are mangled differently than those
|
||||
without underscores, then we include *both* mangling versions. The
|
||||
reason is that the only Fortran compiler that does such differing
|
||||
mangling is currently g77 (which adds an extra underscore to names
|
||||
with underscores), whereas other compilers running on the same
|
||||
machine are likely to use non-underscored mangling. (I'm sick
|
||||
of users complaining that FFTW works with g77 but not with e.g.
|
||||
pgf77 or ifc on the same machine.) Note that all FFTW identifiers
|
||||
contain underscores, and configure picks g77 by default. */
|
||||
#if defined(F77_FUNC_) && !defined(F77_FUNC_EQUIV)
|
||||
# undef F77x
|
||||
# define F77x(a, A) F77_FUNC_(a, A)
|
||||
# include "f77funcs.h"
|
||||
#endif
|
||||
|
||||
#else /* WINDOWS_F77_MANGLING */
|
||||
|
||||
/* Various mangling conventions common (?) under Windows. */
|
||||
|
||||
/* g77 */
|
||||
# define WINDOWS_F77_FUNC(a, A) a ## __
|
||||
# define F77x(a, A) WINDOWS_F77_FUNC(a, A)
|
||||
# include "f77funcs.h"
|
||||
|
||||
/* Intel, etc. */
|
||||
# undef WINDOWS_F77_FUNC
|
||||
# define WINDOWS_F77_FUNC(a, A) a ## _
|
||||
# include "f77funcs.h"
|
||||
|
||||
/* Digital/Compaq/HP Visual Fortran, Intel Fortran. stdcall attribute
|
||||
is apparently required to adjust for calling conventions (callee
|
||||
pops stack in stdcall). See also:
|
||||
http://msdn.microsoft.com/library/en-us/vccore98/html/_core_mixed.2d.language_programming.3a_.overview.asp
|
||||
*/
|
||||
# undef WINDOWS_F77_FUNC
|
||||
# if defined(__GNUC__)
|
||||
# define WINDOWS_F77_FUNC(a, A) __attribute__((stdcall)) A
|
||||
# elif defined(_MSC_VER) || defined(_ICC) || defined(_STDCALL_SUPPORTED)
|
||||
# define WINDOWS_F77_FUNC(a, A) __stdcall A
|
||||
# else
|
||||
# define WINDOWS_F77_FUNC(a, A) A /* oh well */
|
||||
# endif
|
||||
# include "f77funcs.h"
|
||||
|
||||
#endif /* WINDOWS_F77_MANGLING */
|
||||
|
||||
#endif /* F77_FUNC */
|
|
@ -0,0 +1,458 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* Functions in the FFTW Fortran API, mangled according to the
|
||||
F77(...) macro. This file is designed to be #included by
|
||||
f77api.c, possibly multiple times in order to support multiple
|
||||
compiler manglings (via redefinition of F77). */
|
||||
|
||||
FFTW_VOIDFUNC F77(execute, EXECUTE)(X(plan) * const p)
|
||||
{
|
||||
plan *pln = (*p)->pln;
|
||||
pln->adt->solve(pln, (*p)->prb);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(destroy_plan, DESTROY_PLAN)(X(plan) *p)
|
||||
{
|
||||
X(destroy_plan)(*p);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(cleanup, CLEANUP)(void)
|
||||
{
|
||||
X(cleanup)();
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(forget_wisdom, FORGET_WISDOM)(void)
|
||||
{
|
||||
X(forget_wisdom)();
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(export_wisdom, EXPORT_WISDOM)(void (*f77_write_char)(char *, void *),
|
||||
void *data)
|
||||
{
|
||||
write_char_data ad;
|
||||
ad.f77_write_char = f77_write_char;
|
||||
ad.data = data;
|
||||
X(export_wisdom)(write_char, (void *) &ad);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(import_wisdom, IMPORT_WISDOM)(int *isuccess,
|
||||
void (*f77_read_char)(int *, void *),
|
||||
void *data)
|
||||
{
|
||||
read_char_data ed;
|
||||
ed.f77_read_char = f77_read_char;
|
||||
ed.data = data;
|
||||
*isuccess = X(import_wisdom)(read_char, (void *) &ed);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(import_system_wisdom, IMPORT_SYSTEM_WISDOM)(int *isuccess)
|
||||
{
|
||||
*isuccess = X(import_system_wisdom)();
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(print_plan, PRINT_PLAN)(X(plan) * const p)
|
||||
{
|
||||
X(print_plan)(*p);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(flops,FLOPS)(X(plan) *p, double *add, double *mul, double *fma)
|
||||
{
|
||||
X(flops)(*p, add, mul, fma);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(estimate_cost,ESTIMATE_COST)(double *cost, X(plan) * const p)
|
||||
{
|
||||
*cost = X(estimate_cost)(*p);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(cost,COST)(double *cost, X(plan) * const p)
|
||||
{
|
||||
*cost = X(cost)(*p);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(set_timelimit,SET_TIMELIMIT)(double *t)
|
||||
{
|
||||
X(set_timelimit)(*t);
|
||||
}
|
||||
|
||||
/******************************** DFT ***********************************/
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft, PLAN_DFT)(X(plan) *p, int *rank, const int *n,
|
||||
C *in, C *out, int *sign, int *flags)
|
||||
{
|
||||
int *nrev = reverse_n(*rank, n);
|
||||
*p = X(plan_dft)(*rank, nrev, in, out, *sign, *flags);
|
||||
X(ifree0)(nrev);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft_1d, PLAN_DFT_1D)(X(plan) *p, int *n, C *in, C *out,
|
||||
int *sign, int *flags)
|
||||
{
|
||||
*p = X(plan_dft_1d)(*n, in, out, *sign, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft_2d, PLAN_DFT_2D)(X(plan) *p, int *nx, int *ny,
|
||||
C *in, C *out, int *sign, int *flags)
|
||||
{
|
||||
*p = X(plan_dft_2d)(*ny, *nx, in, out, *sign, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft_3d, PLAN_DFT_3D)(X(plan) *p, int *nx, int *ny, int *nz,
|
||||
C *in, C *out,
|
||||
int *sign, int *flags)
|
||||
{
|
||||
*p = X(plan_dft_3d)(*nz, *ny, *nx, in, out, *sign, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_many_dft, PLAN_MANY_DFT)(X(plan) *p, int *rank, const int *n,
|
||||
int *howmany,
|
||||
C *in, const int *inembed,
|
||||
int *istride, int *idist,
|
||||
C *out, const int *onembed,
|
||||
int *ostride, int *odist,
|
||||
int *sign, int *flags)
|
||||
{
|
||||
int *nrev = reverse_n(*rank, n);
|
||||
int *inembedrev = reverse_n(*rank, inembed);
|
||||
int *onembedrev = reverse_n(*rank, onembed);
|
||||
*p = X(plan_many_dft)(*rank, nrev, *howmany,
|
||||
in, inembedrev, *istride, *idist,
|
||||
out, onembedrev, *ostride, *odist,
|
||||
*sign, *flags);
|
||||
X(ifree0)(onembedrev);
|
||||
X(ifree0)(inembedrev);
|
||||
X(ifree0)(nrev);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_guru_dft, PLAN_GURU_DFT)(X(plan) *p, int *rank, const int *n,
|
||||
const int *is, const int *os,
|
||||
int *howmany_rank, const int *h_n,
|
||||
const int *h_is, const int *h_os,
|
||||
C *in, C *out, int *sign, int *flags)
|
||||
{
|
||||
X(iodim) *dims = make_dims(*rank, n, is, os);
|
||||
X(iodim) *howmany_dims = make_dims(*howmany_rank, h_n, h_is, h_os);
|
||||
*p = X(plan_guru_dft)(*rank, dims, *howmany_rank, howmany_dims,
|
||||
in, out, *sign, *flags);
|
||||
X(ifree0)(howmany_dims);
|
||||
X(ifree0)(dims);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_guru_split_dft, PLAN_GURU_SPLIT_DFT)(X(plan) *p, int *rank, const int *n,
|
||||
const int *is, const int *os,
|
||||
int *howmany_rank, const int *h_n,
|
||||
const int *h_is, const int *h_os,
|
||||
R *ri, R *ii, R *ro, R *io, int *flags)
|
||||
{
|
||||
X(iodim) *dims = make_dims(*rank, n, is, os);
|
||||
X(iodim) *howmany_dims = make_dims(*howmany_rank, h_n, h_is, h_os);
|
||||
*p = X(plan_guru_split_dft)(*rank, dims, *howmany_rank, howmany_dims,
|
||||
ri, ii, ro, io, *flags);
|
||||
X(ifree0)(howmany_dims);
|
||||
X(ifree0)(dims);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(execute_dft, EXECUTE_DFT)(X(plan) * const p, C *in, C *out)
|
||||
{
|
||||
plan_dft *pln = (plan_dft *) (*p)->pln;
|
||||
if ((*p)->sign == FFT_SIGN)
|
||||
pln->apply((plan *) pln, in[0], in[0]+1, out[0], out[0]+1);
|
||||
else
|
||||
pln->apply((plan *) pln, in[0]+1, in[0], out[0]+1, out[0]);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(execute_split_dft, EXECUTE_SPLIT_DFT)(X(plan) * const p,
|
||||
R *ri, R *ii, R *ro, R *io)
|
||||
{
|
||||
plan_dft *pln = (plan_dft *) (*p)->pln;
|
||||
pln->apply((plan *) pln, ri, ii, ro, io);
|
||||
}
|
||||
|
||||
/****************************** DFT r2c *********************************/
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft_r2c, PLAN_DFT_R2C)(X(plan) *p, int *rank, const int *n,
|
||||
R *in, C *out, int *flags)
|
||||
{
|
||||
int *nrev = reverse_n(*rank, n);
|
||||
*p = X(plan_dft_r2c)(*rank, nrev, in, out, *flags);
|
||||
X(ifree0)(nrev);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft_r2c_1d, PLAN_DFT_R2C_1D)(X(plan) *p, int *n, R *in, C *out,
|
||||
int *flags)
|
||||
{
|
||||
*p = X(plan_dft_r2c_1d)(*n, in, out, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft_r2c_2d, PLAN_DFT_R2C_2D)(X(plan) *p, int *nx, int *ny,
|
||||
R *in, C *out, int *flags)
|
||||
{
|
||||
*p = X(plan_dft_r2c_2d)(*ny, *nx, in, out, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft_r2c_3d, PLAN_DFT_R2C_3D)(X(plan) *p,
|
||||
int *nx, int *ny, int *nz,
|
||||
R *in, C *out,
|
||||
int *flags)
|
||||
{
|
||||
*p = X(plan_dft_r2c_3d)(*nz, *ny, *nx, in, out, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_many_dft_r2c, PLAN_MANY_DFT_R2C)(
|
||||
X(plan) *p, int *rank, const int *n,
|
||||
int *howmany,
|
||||
R *in, const int *inembed, int *istride, int *idist,
|
||||
C *out, const int *onembed, int *ostride, int *odist,
|
||||
int *flags)
|
||||
{
|
||||
int *nrev = reverse_n(*rank, n);
|
||||
int *inembedrev = reverse_n(*rank, inembed);
|
||||
int *onembedrev = reverse_n(*rank, onembed);
|
||||
*p = X(plan_many_dft_r2c)(*rank, nrev, *howmany,
|
||||
in, inembedrev, *istride, *idist,
|
||||
out, onembedrev, *ostride, *odist,
|
||||
*flags);
|
||||
X(ifree0)(onembedrev);
|
||||
X(ifree0)(inembedrev);
|
||||
X(ifree0)(nrev);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_guru_dft_r2c, PLAN_GURU_DFT_R2C)(
|
||||
X(plan) *p, int *rank, const int *n,
|
||||
const int *is, const int *os,
|
||||
int *howmany_rank, const int *h_n,
|
||||
const int *h_is, const int *h_os,
|
||||
R *in, C *out, int *flags)
|
||||
{
|
||||
X(iodim) *dims = make_dims(*rank, n, is, os);
|
||||
X(iodim) *howmany_dims = make_dims(*howmany_rank, h_n, h_is, h_os);
|
||||
*p = X(plan_guru_dft_r2c)(*rank, dims, *howmany_rank, howmany_dims,
|
||||
in, out, *flags);
|
||||
X(ifree0)(howmany_dims);
|
||||
X(ifree0)(dims);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_guru_split_dft_r2c, PLAN_GURU_SPLIT_DFT_R2C)(
|
||||
X(plan) *p, int *rank, const int *n,
|
||||
const int *is, const int *os,
|
||||
int *howmany_rank, const int *h_n,
|
||||
const int *h_is, const int *h_os,
|
||||
R *in, R *ro, R *io, int *flags)
|
||||
{
|
||||
X(iodim) *dims = make_dims(*rank, n, is, os);
|
||||
X(iodim) *howmany_dims = make_dims(*howmany_rank, h_n, h_is, h_os);
|
||||
*p = X(plan_guru_split_dft_r2c)(*rank, dims, *howmany_rank, howmany_dims,
|
||||
in, ro, io, *flags);
|
||||
X(ifree0)(howmany_dims);
|
||||
X(ifree0)(dims);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(execute_dft_r2c, EXECUTE_DFT_R2C)(X(plan) * const p, R *in, C *out)
|
||||
{
|
||||
plan_rdft2 *pln = (plan_rdft2 *) (*p)->pln;
|
||||
problem_rdft2 *prb = (problem_rdft2 *) (*p)->prb;
|
||||
pln->apply((plan *) pln, in, in + (prb->r1 - prb->r0), out[0], out[0]+1);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(execute_split_dft_r2c, EXECUTE_SPLIT_DFT_R2C)(X(plan) * const p,
|
||||
R *in, R *ro, R *io)
|
||||
{
|
||||
plan_rdft2 *pln = (plan_rdft2 *) (*p)->pln;
|
||||
problem_rdft2 *prb = (problem_rdft2 *) (*p)->prb;
|
||||
pln->apply((plan *) pln, in, in + (prb->r1 - prb->r0), ro, io);
|
||||
}
|
||||
|
||||
/****************************** DFT c2r *********************************/
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft_c2r, PLAN_DFT_C2R)(X(plan) *p, int *rank, const int *n,
|
||||
C *in, R *out, int *flags)
|
||||
{
|
||||
int *nrev = reverse_n(*rank, n);
|
||||
*p = X(plan_dft_c2r)(*rank, nrev, in, out, *flags);
|
||||
X(ifree0)(nrev);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft_c2r_1d, PLAN_DFT_C2R_1D)(X(plan) *p, int *n, C *in, R *out,
|
||||
int *flags)
|
||||
{
|
||||
*p = X(plan_dft_c2r_1d)(*n, in, out, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft_c2r_2d, PLAN_DFT_C2R_2D)(X(plan) *p, int *nx, int *ny,
|
||||
C *in, R *out, int *flags)
|
||||
{
|
||||
*p = X(plan_dft_c2r_2d)(*ny, *nx, in, out, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_dft_c2r_3d, PLAN_DFT_C2R_3D)(X(plan) *p,
|
||||
int *nx, int *ny, int *nz,
|
||||
C *in, R *out,
|
||||
int *flags)
|
||||
{
|
||||
*p = X(plan_dft_c2r_3d)(*nz, *ny, *nx, in, out, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_many_dft_c2r, PLAN_MANY_DFT_C2R)(
|
||||
X(plan) *p, int *rank, const int *n,
|
||||
int *howmany,
|
||||
C *in, const int *inembed, int *istride, int *idist,
|
||||
R *out, const int *onembed, int *ostride, int *odist,
|
||||
int *flags)
|
||||
{
|
||||
int *nrev = reverse_n(*rank, n);
|
||||
int *inembedrev = reverse_n(*rank, inembed);
|
||||
int *onembedrev = reverse_n(*rank, onembed);
|
||||
*p = X(plan_many_dft_c2r)(*rank, nrev, *howmany,
|
||||
in, inembedrev, *istride, *idist,
|
||||
out, onembedrev, *ostride, *odist,
|
||||
*flags);
|
||||
X(ifree0)(onembedrev);
|
||||
X(ifree0)(inembedrev);
|
||||
X(ifree0)(nrev);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_guru_dft_c2r, PLAN_GURU_DFT_C2R)(
|
||||
X(plan) *p, int *rank, const int *n,
|
||||
const int *is, const int *os,
|
||||
int *howmany_rank, const int *h_n,
|
||||
const int *h_is, const int *h_os,
|
||||
C *in, R *out, int *flags)
|
||||
{
|
||||
X(iodim) *dims = make_dims(*rank, n, is, os);
|
||||
X(iodim) *howmany_dims = make_dims(*howmany_rank, h_n, h_is, h_os);
|
||||
*p = X(plan_guru_dft_c2r)(*rank, dims, *howmany_rank, howmany_dims,
|
||||
in, out, *flags);
|
||||
X(ifree0)(howmany_dims);
|
||||
X(ifree0)(dims);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_guru_split_dft_c2r, PLAN_GURU_SPLIT_DFT_C2R)(
|
||||
X(plan) *p, int *rank, const int *n,
|
||||
const int *is, const int *os,
|
||||
int *howmany_rank, const int *h_n,
|
||||
const int *h_is, const int *h_os,
|
||||
R *ri, R *ii, R *out, int *flags)
|
||||
{
|
||||
X(iodim) *dims = make_dims(*rank, n, is, os);
|
||||
X(iodim) *howmany_dims = make_dims(*howmany_rank, h_n, h_is, h_os);
|
||||
*p = X(plan_guru_split_dft_c2r)(*rank, dims, *howmany_rank, howmany_dims,
|
||||
ri, ii, out, *flags);
|
||||
X(ifree0)(howmany_dims);
|
||||
X(ifree0)(dims);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(execute_dft_c2r, EXECUTE_DFT_C2R)(X(plan) * const p, C *in, R *out)
|
||||
{
|
||||
plan_rdft2 *pln = (plan_rdft2 *) (*p)->pln;
|
||||
problem_rdft2 *prb = (problem_rdft2 *) (*p)->prb;
|
||||
pln->apply((plan *) pln, out, out + (prb->r1 - prb->r0), in[0], in[0]+1);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(execute_split_dft_c2r, EXECUTE_SPLIT_DFT_C2R)(X(plan) * const p,
|
||||
R *ri, R *ii, R *out)
|
||||
{
|
||||
plan_rdft2 *pln = (plan_rdft2 *) (*p)->pln;
|
||||
problem_rdft2 *prb = (problem_rdft2 *) (*p)->prb;
|
||||
pln->apply((plan *) pln, out, out + (prb->r1 - prb->r0), ri, ii);
|
||||
}
|
||||
|
||||
/****************************** r2r *********************************/
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_r2r, PLAN_R2R)(X(plan) *p, int *rank, const int *n,
|
||||
R *in, R *out,
|
||||
int *kind, int *flags)
|
||||
{
|
||||
int *nrev = reverse_n(*rank, n);
|
||||
X(r2r_kind) *k = ints2kinds(*rank, kind);
|
||||
*p = X(plan_r2r)(*rank, nrev, in, out, k, *flags);
|
||||
X(ifree0)(k);
|
||||
X(ifree0)(nrev);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_r2r_1d, PLAN_R2R_1D)(X(plan) *p, int *n, R *in, R *out,
|
||||
int *kind, int *flags)
|
||||
{
|
||||
*p = X(plan_r2r_1d)(*n, in, out, (X(r2r_kind)) *kind, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_r2r_2d, PLAN_R2R_2D)(X(plan) *p, int *nx, int *ny,
|
||||
R *in, R *out,
|
||||
int *kindx, int *kindy, int *flags)
|
||||
{
|
||||
*p = X(plan_r2r_2d)(*ny, *nx, in, out,
|
||||
(X(r2r_kind)) *kindy, (X(r2r_kind)) *kindx, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_r2r_3d, PLAN_R2R_3D)(X(plan) *p,
|
||||
int *nx, int *ny, int *nz,
|
||||
R *in, R *out,
|
||||
int *kindx, int *kindy, int *kindz,
|
||||
int *flags)
|
||||
{
|
||||
*p = X(plan_r2r_3d)(*nz, *ny, *nx, in, out,
|
||||
(X(r2r_kind)) *kindz, (X(r2r_kind)) *kindy,
|
||||
(X(r2r_kind)) *kindx, *flags);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_many_r2r, PLAN_MANY_R2R)(
|
||||
X(plan) *p, int *rank, const int *n,
|
||||
int *howmany,
|
||||
R *in, const int *inembed, int *istride, int *idist,
|
||||
R *out, const int *onembed, int *ostride, int *odist,
|
||||
int *kind, int *flags)
|
||||
{
|
||||
int *nrev = reverse_n(*rank, n);
|
||||
int *inembedrev = reverse_n(*rank, inembed);
|
||||
int *onembedrev = reverse_n(*rank, onembed);
|
||||
X(r2r_kind) *k = ints2kinds(*rank, kind);
|
||||
*p = X(plan_many_r2r)(*rank, nrev, *howmany,
|
||||
in, inembedrev, *istride, *idist,
|
||||
out, onembedrev, *ostride, *odist,
|
||||
k, *flags);
|
||||
X(ifree0)(k);
|
||||
X(ifree0)(onembedrev);
|
||||
X(ifree0)(inembedrev);
|
||||
X(ifree0)(nrev);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(plan_guru_r2r, PLAN_GURU_R2R)(
|
||||
X(plan) *p, int *rank, const int *n,
|
||||
const int *is, const int *os,
|
||||
int *howmany_rank, const int *h_n,
|
||||
const int *h_is, const int *h_os,
|
||||
R *in, R *out, int *kind, int *flags)
|
||||
{
|
||||
X(iodim) *dims = make_dims(*rank, n, is, os);
|
||||
X(iodim) *howmany_dims = make_dims(*howmany_rank, h_n, h_is, h_os);
|
||||
X(r2r_kind) *k = ints2kinds(*rank, kind);
|
||||
*p = X(plan_guru_r2r)(*rank, dims, *howmany_rank, howmany_dims,
|
||||
in, out, k, *flags);
|
||||
X(ifree0)(k);
|
||||
X(ifree0)(howmany_dims);
|
||||
X(ifree0)(dims);
|
||||
}
|
||||
|
||||
FFTW_VOIDFUNC F77(execute_r2r, EXECUTE_R2R)(X(plan) * const p, R *in, R *out)
|
||||
{
|
||||
plan_rdft *pln = (plan_rdft *) (*p)->pln;
|
||||
pln->apply((plan *) pln, in, out);
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
INTEGER FFTW_R2HC
|
||||
PARAMETER (FFTW_R2HC=0)
|
||||
INTEGER FFTW_HC2R
|
||||
PARAMETER (FFTW_HC2R=1)
|
||||
INTEGER FFTW_DHT
|
||||
PARAMETER (FFTW_DHT=2)
|
||||
INTEGER FFTW_REDFT00
|
||||
PARAMETER (FFTW_REDFT00=3)
|
||||
INTEGER FFTW_REDFT01
|
||||
PARAMETER (FFTW_REDFT01=4)
|
||||
INTEGER FFTW_REDFT10
|
||||
PARAMETER (FFTW_REDFT10=5)
|
||||
INTEGER FFTW_REDFT11
|
||||
PARAMETER (FFTW_REDFT11=6)
|
||||
INTEGER FFTW_RODFT00
|
||||
PARAMETER (FFTW_RODFT00=7)
|
||||
INTEGER FFTW_RODFT01
|
||||
PARAMETER (FFTW_RODFT01=8)
|
||||
INTEGER FFTW_RODFT10
|
||||
PARAMETER (FFTW_RODFT10=9)
|
||||
INTEGER FFTW_RODFT11
|
||||
PARAMETER (FFTW_RODFT11=10)
|
||||
INTEGER FFTW_FORWARD
|
||||
PARAMETER (FFTW_FORWARD=-1)
|
||||
INTEGER FFTW_BACKWARD
|
||||
PARAMETER (FFTW_BACKWARD=+1)
|
||||
INTEGER FFTW_MEASURE
|
||||
PARAMETER (FFTW_MEASURE=0)
|
||||
INTEGER FFTW_DESTROY_INPUT
|
||||
PARAMETER (FFTW_DESTROY_INPUT=1)
|
||||
INTEGER FFTW_UNALIGNED
|
||||
PARAMETER (FFTW_UNALIGNED=2)
|
||||
INTEGER FFTW_CONSERVE_MEMORY
|
||||
PARAMETER (FFTW_CONSERVE_MEMORY=4)
|
||||
INTEGER FFTW_EXHAUSTIVE
|
||||
PARAMETER (FFTW_EXHAUSTIVE=8)
|
||||
INTEGER FFTW_PRESERVE_INPUT
|
||||
PARAMETER (FFTW_PRESERVE_INPUT=16)
|
||||
INTEGER FFTW_PATIENT
|
||||
PARAMETER (FFTW_PATIENT=32)
|
||||
INTEGER FFTW_ESTIMATE
|
||||
PARAMETER (FFTW_ESTIMATE=64)
|
||||
INTEGER FFTW_WISDOM_ONLY
|
||||
PARAMETER (FFTW_WISDOM_ONLY=2097152)
|
||||
INTEGER FFTW_ESTIMATE_PATIENT
|
||||
PARAMETER (FFTW_ESTIMATE_PATIENT=128)
|
||||
INTEGER FFTW_BELIEVE_PCOST
|
||||
PARAMETER (FFTW_BELIEVE_PCOST=256)
|
||||
INTEGER FFTW_NO_DFT_R2HC
|
||||
PARAMETER (FFTW_NO_DFT_R2HC=512)
|
||||
INTEGER FFTW_NO_NONTHREADED
|
||||
PARAMETER (FFTW_NO_NONTHREADED=1024)
|
||||
INTEGER FFTW_NO_BUFFERING
|
||||
PARAMETER (FFTW_NO_BUFFERING=2048)
|
||||
INTEGER FFTW_NO_INDIRECT_OP
|
||||
PARAMETER (FFTW_NO_INDIRECT_OP=4096)
|
||||
INTEGER FFTW_ALLOW_LARGE_GENERIC
|
||||
PARAMETER (FFTW_ALLOW_LARGE_GENERIC=8192)
|
||||
INTEGER FFTW_NO_RANK_SPLITS
|
||||
PARAMETER (FFTW_NO_RANK_SPLITS=16384)
|
||||
INTEGER FFTW_NO_VRANK_SPLITS
|
||||
PARAMETER (FFTW_NO_VRANK_SPLITS=32768)
|
||||
INTEGER FFTW_NO_VRECURSE
|
||||
PARAMETER (FFTW_NO_VRECURSE=65536)
|
||||
INTEGER FFTW_NO_SIMD
|
||||
PARAMETER (FFTW_NO_SIMD=131072)
|
||||
INTEGER FFTW_NO_SLOW
|
||||
PARAMETER (FFTW_NO_SLOW=262144)
|
||||
INTEGER FFTW_NO_FIXED_RADIX_LARGE_N
|
||||
PARAMETER (FFTW_NO_FIXED_RADIX_LARGE_N=524288)
|
||||
INTEGER FFTW_ALLOW_PRUNING
|
||||
PARAMETER (FFTW_ALLOW_PRUNING=1048576)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,522 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* The following statement of license applies *only* to this header file,
|
||||
* and *not* to the other files distributed with FFTW or derived therefrom:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/***************************** NOTE TO USERS *********************************
|
||||
*
|
||||
* THIS IS A HEADER FILE, NOT A MANUAL
|
||||
*
|
||||
* If you want to know how to use FFTW, please read the manual,
|
||||
* online at http://www.fftw.org/doc/ and also included with FFTW.
|
||||
* For a quick start, see the manual's tutorial section.
|
||||
*
|
||||
* (Reading header files to learn how to use a library is a habit
|
||||
* stemming from code lacking a proper manual. Arguably, it's a
|
||||
* *bad* habit in most cases, because header files can contain
|
||||
* interfaces that are not part of the public, stable API.)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef FFTW3_H
|
||||
#define FFTW3_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* If <complex.h> is included, use the C99 complex type. Otherwise
|
||||
define a type bit-compatible with C99 complex */
|
||||
#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
|
||||
# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
|
||||
#else
|
||||
# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
|
||||
#endif
|
||||
|
||||
#define FFTW_CONCAT(prefix, name) prefix ## name
|
||||
#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name)
|
||||
#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name)
|
||||
#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name)
|
||||
#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name)
|
||||
|
||||
/* IMPORTANT: for Windows compilers, you should add a line
|
||||
#define FFTW_DLL
|
||||
here and in kernel/ifftw.h if you are compiling/using FFTW as a
|
||||
DLL, in order to do the proper importing/exporting, or
|
||||
alternatively compile with -DFFTW_DLL or the equivalent
|
||||
command-line flag. This is not necessary under MinGW/Cygwin, where
|
||||
libtool does the imports/exports automatically. */
|
||||
#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__))
|
||||
/* annoying Windows syntax for shared-library declarations */
|
||||
# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */
|
||||
# define FFTW_EXTERN extern __declspec(dllexport)
|
||||
# else /* user is calling FFTW; import symbol */
|
||||
# define FFTW_EXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define FFTW_EXTERN extern
|
||||
#endif
|
||||
|
||||
/* specify calling convention (Windows only) */
|
||||
#if defined(_WIN32) || defined(__WIN32__)
|
||||
# define FFTW_CDECL __cdecl
|
||||
#else
|
||||
# define FFTW_CDECL
|
||||
#endif
|
||||
|
||||
enum fftw_r2r_kind_do_not_use_me {
|
||||
FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2,
|
||||
FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6,
|
||||
FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10
|
||||
};
|
||||
|
||||
struct fftw_iodim_do_not_use_me {
|
||||
int n; /* dimension size */
|
||||
int is; /* input stride */
|
||||
int os; /* output stride */
|
||||
};
|
||||
|
||||
#include <stddef.h> /* for ptrdiff_t */
|
||||
struct fftw_iodim64_do_not_use_me {
|
||||
ptrdiff_t n; /* dimension size */
|
||||
ptrdiff_t is; /* input stride */
|
||||
ptrdiff_t os; /* output stride */
|
||||
};
|
||||
|
||||
typedef void (FFTW_CDECL *fftw_write_char_func_do_not_use_me)(char c, void *);
|
||||
typedef int (FFTW_CDECL *fftw_read_char_func_do_not_use_me)(void *);
|
||||
|
||||
/*
|
||||
huge second-order macro that defines prototypes for all API
|
||||
functions. We expand this macro for each supported precision
|
||||
|
||||
X: name-mangling macro
|
||||
R: real data type
|
||||
C: complex data type
|
||||
*/
|
||||
|
||||
#define FFTW_DEFINE_API(X, R, C) \
|
||||
\
|
||||
FFTW_DEFINE_COMPLEX(R, C); \
|
||||
\
|
||||
typedef struct X(plan_s) *X(plan); \
|
||||
\
|
||||
typedef struct fftw_iodim_do_not_use_me X(iodim); \
|
||||
typedef struct fftw_iodim64_do_not_use_me X(iodim64); \
|
||||
\
|
||||
typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \
|
||||
\
|
||||
typedef fftw_write_char_func_do_not_use_me X(write_char_func); \
|
||||
typedef fftw_read_char_func_do_not_use_me X(read_char_func); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(execute)(const X(plan) p); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft)(int rank, const int *n, \
|
||||
C *in, C *out, int sign, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft_1d)(int n, C *in, C *out, int sign, \
|
||||
unsigned flags); \
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft_2d)(int n0, int n1, \
|
||||
C *in, C *out, int sign, unsigned flags); \
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft_3d)(int n0, int n1, int n2, \
|
||||
C *in, C *out, int sign, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_many_dft)(int rank, const int *n, \
|
||||
int howmany, \
|
||||
C *in, const int *inembed, \
|
||||
int istride, int idist, \
|
||||
C *out, const int *onembed, \
|
||||
int ostride, int odist, \
|
||||
int sign, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru_dft)(int rank, const X(iodim) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim) *howmany_dims, \
|
||||
C *in, C *out, \
|
||||
int sign, unsigned flags); \
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim) *howmany_dims, \
|
||||
R *ri, R *ii, R *ro, R *io, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru64_dft)(int rank, \
|
||||
const X(iodim64) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim64) *howmany_dims, \
|
||||
C *in, C *out, \
|
||||
int sign, unsigned flags); \
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru64_split_dft)(int rank, \
|
||||
const X(iodim64) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim64) *howmany_dims, \
|
||||
R *ri, R *ii, R *ro, R *io, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(execute_dft)(const X(plan) p, C *in, C *out); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \
|
||||
R *ro, R *io); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_many_dft_r2c)(int rank, const int *n, \
|
||||
int howmany, \
|
||||
R *in, const int *inembed, \
|
||||
int istride, int idist, \
|
||||
C *out, const int *onembed, \
|
||||
int ostride, int odist, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft_r2c)(int rank, const int *n, \
|
||||
R *in, C *out, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft_r2c_2d)(int n0, int n1, \
|
||||
R *in, C *out, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft_r2c_3d)(int n0, int n1, \
|
||||
int n2, \
|
||||
R *in, C *out, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_many_dft_c2r)(int rank, const int *n, \
|
||||
int howmany, \
|
||||
C *in, const int *inembed, \
|
||||
int istride, int idist, \
|
||||
R *out, const int *onembed, \
|
||||
int ostride, int odist, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft_c2r)(int rank, const int *n, \
|
||||
C *in, R *out, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft_c2r_2d)(int n0, int n1, \
|
||||
C *in, R *out, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_dft_c2r_3d)(int n0, int n1, \
|
||||
int n2, \
|
||||
C *in, R *out, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim) *howmany_dims, \
|
||||
R *in, C *out, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim) *howmany_dims, \
|
||||
C *in, R *out, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru_split_dft_r2c)(int rank, const X(iodim) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim) *howmany_dims, \
|
||||
R *in, R *ro, R *io, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru_split_dft_c2r)(int rank, const X(iodim) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim) *howmany_dims, \
|
||||
R *ri, R *ii, R *out, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru64_dft_r2c)(int rank, \
|
||||
const X(iodim64) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim64) *howmany_dims, \
|
||||
R *in, C *out, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru64_dft_c2r)(int rank, \
|
||||
const X(iodim64) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim64) *howmany_dims, \
|
||||
C *in, R *out, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru64_split_dft_r2c)(int rank, const X(iodim64) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim64) *howmany_dims, \
|
||||
R *in, R *ro, R *io, \
|
||||
unsigned flags); \
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru64_split_dft_c2r)(int rank, const X(iodim64) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim64) *howmany_dims, \
|
||||
R *ri, R *ii, R *out, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(execute_split_dft_r2c)(const X(plan) p, \
|
||||
R *in, R *ro, R *io); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(execute_split_dft_c2r)(const X(plan) p, \
|
||||
R *ri, R *ii, R *out); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_many_r2r)(int rank, const int *n, \
|
||||
int howmany, \
|
||||
R *in, const int *inembed, \
|
||||
int istride, int idist, \
|
||||
R *out, const int *onembed, \
|
||||
int ostride, int odist, \
|
||||
const X(r2r_kind) *kind, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_r2r)(int rank, const int *n, R *in, R *out, \
|
||||
const X(r2r_kind) *kind, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_r2r_1d)(int n, R *in, R *out, \
|
||||
X(r2r_kind) kind, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \
|
||||
X(r2r_kind) kind0, X(r2r_kind) kind1, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_r2r_3d)(int n0, int n1, int n2, \
|
||||
R *in, R *out, X(r2r_kind) kind0, \
|
||||
X(r2r_kind) kind1, X(r2r_kind) kind2, \
|
||||
unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru_r2r)(int rank, const X(iodim) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim) *howmany_dims, \
|
||||
R *in, R *out, \
|
||||
const X(r2r_kind) *kind, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN X(plan) \
|
||||
FFTW_CDECL X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \
|
||||
int howmany_rank, \
|
||||
const X(iodim64) *howmany_dims, \
|
||||
R *in, R *out, \
|
||||
const X(r2r_kind) *kind, unsigned flags); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(execute_r2r)(const X(plan) p, R *in, R *out); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(destroy_plan)(X(plan) p); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(forget_wisdom)(void); \
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(cleanup)(void); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(set_timelimit)(double t); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(plan_with_nthreads)(int nthreads); \
|
||||
\
|
||||
FFTW_EXTERN int \
|
||||
FFTW_CDECL X(planner_nthreads)(void); \
|
||||
\
|
||||
FFTW_EXTERN int \
|
||||
FFTW_CDECL X(init_threads)(void); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(cleanup_threads)(void); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(threads_set_callback)( \
|
||||
void (*parallel_loop)(void *(*work)(char *), \
|
||||
char *jobdata, size_t elsize, int njobs, void *data), void *data); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(make_planner_thread_safe)(void); \
|
||||
\
|
||||
FFTW_EXTERN int \
|
||||
FFTW_CDECL X(export_wisdom_to_filename)(const char *filename); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(export_wisdom_to_file)(FILE *output_file); \
|
||||
\
|
||||
FFTW_EXTERN char * \
|
||||
FFTW_CDECL X(export_wisdom_to_string)(void); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(export_wisdom)(X(write_char_func) write_char, \
|
||||
void *data); \
|
||||
FFTW_EXTERN int \
|
||||
FFTW_CDECL X(import_system_wisdom)(void); \
|
||||
\
|
||||
FFTW_EXTERN int \
|
||||
FFTW_CDECL X(import_wisdom_from_filename)(const char *filename); \
|
||||
\
|
||||
FFTW_EXTERN int \
|
||||
FFTW_CDECL X(import_wisdom_from_file)(FILE *input_file); \
|
||||
\
|
||||
FFTW_EXTERN int \
|
||||
FFTW_CDECL X(import_wisdom_from_string)(const char *input_string); \
|
||||
\
|
||||
FFTW_EXTERN int \
|
||||
FFTW_CDECL X(import_wisdom)(X(read_char_func) read_char, void *data); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(fprint_plan)(const X(plan) p, FILE *output_file); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(print_plan)(const X(plan) p); \
|
||||
\
|
||||
FFTW_EXTERN char * \
|
||||
FFTW_CDECL X(sprint_plan)(const X(plan) p); \
|
||||
\
|
||||
FFTW_EXTERN void * \
|
||||
FFTW_CDECL X(malloc)(size_t n); \
|
||||
\
|
||||
FFTW_EXTERN R * \
|
||||
FFTW_CDECL X(alloc_real)(size_t n); \
|
||||
FFTW_EXTERN C * \
|
||||
FFTW_CDECL X(alloc_complex)(size_t n); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(free)(void *p); \
|
||||
\
|
||||
FFTW_EXTERN void \
|
||||
FFTW_CDECL X(flops)(const X(plan) p, \
|
||||
double *add, double *mul, double *fmas); \
|
||||
FFTW_EXTERN double \
|
||||
FFTW_CDECL X(estimate_cost)(const X(plan) p); \
|
||||
\
|
||||
FFTW_EXTERN double \
|
||||
FFTW_CDECL X(cost)(const X(plan) p); \
|
||||
\
|
||||
FFTW_EXTERN int \
|
||||
FFTW_CDECL X(alignment_of)(R *p); \
|
||||
\
|
||||
FFTW_EXTERN const char X(version)[]; \
|
||||
FFTW_EXTERN const char X(cc)[]; \
|
||||
FFTW_EXTERN const char X(codelet_optim)[];
|
||||
|
||||
|
||||
/* end of FFTW_DEFINE_API macro */
|
||||
|
||||
FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
|
||||
FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
|
||||
FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
|
||||
|
||||
/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64
|
||||
for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */
|
||||
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \
|
||||
&& !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \
|
||||
&& (defined(__i386__) || defined(__x86_64__) || defined(__ia64__))
|
||||
# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
|
||||
/* note: __float128 is a typedef, which is not supported with the _Complex
|
||||
keyword in gcc, so instead we use this ugly __attribute__ version.
|
||||
However, we can't simply pass the __attribute__ version to
|
||||
FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer
|
||||
types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */
|
||||
# undef FFTW_DEFINE_COMPLEX
|
||||
# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C
|
||||
# endif
|
||||
FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex)
|
||||
#endif
|
||||
|
||||
#define FFTW_FORWARD (-1)
|
||||
#define FFTW_BACKWARD (+1)
|
||||
|
||||
#define FFTW_NO_TIMELIMIT (-1.0)
|
||||
|
||||
/* documented flags */
|
||||
#define FFTW_MEASURE (0U)
|
||||
#define FFTW_DESTROY_INPUT (1U << 0)
|
||||
#define FFTW_UNALIGNED (1U << 1)
|
||||
#define FFTW_CONSERVE_MEMORY (1U << 2)
|
||||
#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */
|
||||
#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */
|
||||
#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */
|
||||
#define FFTW_ESTIMATE (1U << 6)
|
||||
#define FFTW_WISDOM_ONLY (1U << 21)
|
||||
|
||||
/* undocumented beyond-guru flags */
|
||||
#define FFTW_ESTIMATE_PATIENT (1U << 7)
|
||||
#define FFTW_BELIEVE_PCOST (1U << 8)
|
||||
#define FFTW_NO_DFT_R2HC (1U << 9)
|
||||
#define FFTW_NO_NONTHREADED (1U << 10)
|
||||
#define FFTW_NO_BUFFERING (1U << 11)
|
||||
#define FFTW_NO_INDIRECT_OP (1U << 12)
|
||||
#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */
|
||||
#define FFTW_NO_RANK_SPLITS (1U << 14)
|
||||
#define FFTW_NO_VRANK_SPLITS (1U << 15)
|
||||
#define FFTW_NO_VRECURSE (1U << 16)
|
||||
#define FFTW_NO_SIMD (1U << 17)
|
||||
#define FFTW_NO_SLOW (1U << 18)
|
||||
#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19)
|
||||
#define FFTW_ALLOW_PRUNING (1U << 20)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* FFTW3_H */
|
|
@ -0,0 +1,614 @@
|
|||
! Generated automatically. DO NOT EDIT!
|
||||
|
||||
|
||||
type, bind(C) :: fftwl_iodim
|
||||
integer(C_INT) n, is, os
|
||||
end type fftwl_iodim
|
||||
type, bind(C) :: fftwl_iodim64
|
||||
integer(C_INTPTR_T) n, is, os
|
||||
end type fftwl_iodim64
|
||||
|
||||
interface
|
||||
type(C_PTR) function fftwl_plan_dft(rank,n,in,out,sign,flags) bind(C, name='fftwl_plan_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft
|
||||
|
||||
type(C_PTR) function fftwl_plan_dft_1d(n,in,out,sign,flags) bind(C, name='fftwl_plan_dft_1d')
|
||||
import
|
||||
integer(C_INT), value :: n
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft_1d
|
||||
|
||||
type(C_PTR) function fftwl_plan_dft_2d(n0,n1,in,out,sign,flags) bind(C, name='fftwl_plan_dft_2d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft_2d
|
||||
|
||||
type(C_PTR) function fftwl_plan_dft_3d(n0,n1,n2,in,out,sign,flags) bind(C, name='fftwl_plan_dft_3d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
integer(C_INT), value :: n2
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft_3d
|
||||
|
||||
type(C_PTR) function fftwl_plan_many_dft(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,sign,flags) &
|
||||
bind(C, name='fftwl_plan_many_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
integer(C_INT), value :: howmany
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
integer(C_INT), dimension(*), intent(in) :: inembed
|
||||
integer(C_INT), value :: istride
|
||||
integer(C_INT), value :: idist
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), dimension(*), intent(in) :: onembed
|
||||
integer(C_INT), value :: ostride
|
||||
integer(C_INT), value :: odist
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_many_dft
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru_dft(rank,dims,howmany_rank,howmany_dims,in,out,sign,flags) &
|
||||
bind(C, name='fftwl_plan_guru_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru_dft
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru_split_dft(rank,dims,howmany_rank,howmany_dims,ri,ii,ro,io,flags) &
|
||||
bind(C, name='fftwl_plan_guru_split_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ri
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ii
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ro
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: io
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru_split_dft
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru64_dft(rank,dims,howmany_rank,howmany_dims,in,out,sign,flags) &
|
||||
bind(C, name='fftwl_plan_guru64_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru64_dft
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru64_split_dft(rank,dims,howmany_rank,howmany_dims,ri,ii,ro,io,flags) &
|
||||
bind(C, name='fftwl_plan_guru64_split_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ri
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ii
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ro
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: io
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru64_split_dft
|
||||
|
||||
subroutine fftwl_execute_dft(p,in,out) bind(C, name='fftwl_execute_dft')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(inout) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
end subroutine fftwl_execute_dft
|
||||
|
||||
subroutine fftwl_execute_split_dft(p,ri,ii,ro,io) bind(C, name='fftwl_execute_split_dft')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(inout) :: ri
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(inout) :: ii
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ro
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: io
|
||||
end subroutine fftwl_execute_split_dft
|
||||
|
||||
type(C_PTR) function fftwl_plan_many_dft_r2c(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,flags) &
|
||||
bind(C, name='fftwl_plan_many_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
integer(C_INT), value :: howmany
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
integer(C_INT), dimension(*), intent(in) :: inembed
|
||||
integer(C_INT), value :: istride
|
||||
integer(C_INT), value :: idist
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), dimension(*), intent(in) :: onembed
|
||||
integer(C_INT), value :: ostride
|
||||
integer(C_INT), value :: odist
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_many_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwl_plan_dft_r2c(rank,n,in,out,flags) bind(C, name='fftwl_plan_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwl_plan_dft_r2c_1d(n,in,out,flags) bind(C, name='fftwl_plan_dft_r2c_1d')
|
||||
import
|
||||
integer(C_INT), value :: n
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft_r2c_1d
|
||||
|
||||
type(C_PTR) function fftwl_plan_dft_r2c_2d(n0,n1,in,out,flags) bind(C, name='fftwl_plan_dft_r2c_2d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft_r2c_2d
|
||||
|
||||
type(C_PTR) function fftwl_plan_dft_r2c_3d(n0,n1,n2,in,out,flags) bind(C, name='fftwl_plan_dft_r2c_3d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
integer(C_INT), value :: n2
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft_r2c_3d
|
||||
|
||||
type(C_PTR) function fftwl_plan_many_dft_c2r(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,flags) &
|
||||
bind(C, name='fftwl_plan_many_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
integer(C_INT), value :: howmany
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
integer(C_INT), dimension(*), intent(in) :: inembed
|
||||
integer(C_INT), value :: istride
|
||||
integer(C_INT), value :: idist
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_INT), dimension(*), intent(in) :: onembed
|
||||
integer(C_INT), value :: ostride
|
||||
integer(C_INT), value :: odist
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_many_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwl_plan_dft_c2r(rank,n,in,out,flags) bind(C, name='fftwl_plan_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwl_plan_dft_c2r_1d(n,in,out,flags) bind(C, name='fftwl_plan_dft_c2r_1d')
|
||||
import
|
||||
integer(C_INT), value :: n
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft_c2r_1d
|
||||
|
||||
type(C_PTR) function fftwl_plan_dft_c2r_2d(n0,n1,in,out,flags) bind(C, name='fftwl_plan_dft_c2r_2d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft_c2r_2d
|
||||
|
||||
type(C_PTR) function fftwl_plan_dft_c2r_3d(n0,n1,n2,in,out,flags) bind(C, name='fftwl_plan_dft_c2r_3d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
integer(C_INT), value :: n2
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_dft_c2r_3d
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru_dft_r2c(rank,dims,howmany_rank,howmany_dims,in,out,flags) &
|
||||
bind(C, name='fftwl_plan_guru_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru_dft_c2r(rank,dims,howmany_rank,howmany_dims,in,out,flags) &
|
||||
bind(C, name='fftwl_plan_guru_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru_split_dft_r2c(rank,dims,howmany_rank,howmany_dims,in,ro,io,flags) &
|
||||
bind(C, name='fftwl_plan_guru_split_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ro
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: io
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru_split_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru_split_dft_c2r(rank,dims,howmany_rank,howmany_dims,ri,ii,out,flags) &
|
||||
bind(C, name='fftwl_plan_guru_split_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ri
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ii
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru_split_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru64_dft_r2c(rank,dims,howmany_rank,howmany_dims,in,out,flags) &
|
||||
bind(C, name='fftwl_plan_guru64_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru64_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru64_dft_c2r(rank,dims,howmany_rank,howmany_dims,in,out,flags) &
|
||||
bind(C, name='fftwl_plan_guru64_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru64_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru64_split_dft_r2c(rank,dims,howmany_rank,howmany_dims,in,ro,io,flags) &
|
||||
bind(C, name='fftwl_plan_guru64_split_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ro
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: io
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru64_split_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru64_split_dft_c2r(rank,dims,howmany_rank,howmany_dims,ri,ii,out,flags) &
|
||||
bind(C, name='fftwl_plan_guru64_split_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ri
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ii
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru64_split_dft_c2r
|
||||
|
||||
subroutine fftwl_execute_dft_r2c(p,in,out) bind(C, name='fftwl_execute_dft_r2c')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(inout) :: in
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out) :: out
|
||||
end subroutine fftwl_execute_dft_r2c
|
||||
|
||||
subroutine fftwl_execute_dft_c2r(p,in,out) bind(C, name='fftwl_execute_dft_c2r')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(inout) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
end subroutine fftwl_execute_dft_c2r
|
||||
|
||||
subroutine fftwl_execute_split_dft_r2c(p,in,ro,io) bind(C, name='fftwl_execute_split_dft_r2c')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(inout) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: ro
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: io
|
||||
end subroutine fftwl_execute_split_dft_r2c
|
||||
|
||||
subroutine fftwl_execute_split_dft_c2r(p,ri,ii,out) bind(C, name='fftwl_execute_split_dft_c2r')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(inout) :: ri
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(inout) :: ii
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
end subroutine fftwl_execute_split_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwl_plan_many_r2r(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,kind,flags) &
|
||||
bind(C, name='fftwl_plan_many_r2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
integer(C_INT), value :: howmany
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
integer(C_INT), dimension(*), intent(in) :: inembed
|
||||
integer(C_INT), value :: istride
|
||||
integer(C_INT), value :: idist
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_INT), dimension(*), intent(in) :: onembed
|
||||
integer(C_INT), value :: ostride
|
||||
integer(C_INT), value :: odist
|
||||
integer(C_FFTW_R2R_KIND), dimension(*), intent(in) :: kind
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_many_r2r
|
||||
|
||||
type(C_PTR) function fftwl_plan_r2r(rank,n,in,out,kind,flags) bind(C, name='fftwl_plan_r2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), dimension(*), intent(in) :: kind
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_r2r
|
||||
|
||||
type(C_PTR) function fftwl_plan_r2r_1d(n,in,out,kind,flags) bind(C, name='fftwl_plan_r2r_1d')
|
||||
import
|
||||
integer(C_INT), value :: n
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), value :: kind
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_r2r_1d
|
||||
|
||||
type(C_PTR) function fftwl_plan_r2r_2d(n0,n1,in,out,kind0,kind1,flags) bind(C, name='fftwl_plan_r2r_2d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), value :: kind0
|
||||
integer(C_FFTW_R2R_KIND), value :: kind1
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_r2r_2d
|
||||
|
||||
type(C_PTR) function fftwl_plan_r2r_3d(n0,n1,n2,in,out,kind0,kind1,kind2,flags) bind(C, name='fftwl_plan_r2r_3d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
integer(C_INT), value :: n2
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), value :: kind0
|
||||
integer(C_FFTW_R2R_KIND), value :: kind1
|
||||
integer(C_FFTW_R2R_KIND), value :: kind2
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_r2r_3d
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru_r2r(rank,dims,howmany_rank,howmany_dims,in,out,kind,flags) &
|
||||
bind(C, name='fftwl_plan_guru_r2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), dimension(*), intent(in) :: kind
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru_r2r
|
||||
|
||||
type(C_PTR) function fftwl_plan_guru64_r2r(rank,dims,howmany_rank,howmany_dims,in,out,kind,flags) &
|
||||
bind(C, name='fftwl_plan_guru64_r2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwl_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), dimension(*), intent(in) :: kind
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwl_plan_guru64_r2r
|
||||
|
||||
subroutine fftwl_execute_r2r(p,in,out) bind(C, name='fftwl_execute_r2r')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(inout) :: in
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: out
|
||||
end subroutine fftwl_execute_r2r
|
||||
|
||||
subroutine fftwl_destroy_plan(p) bind(C, name='fftwl_destroy_plan')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end subroutine fftwl_destroy_plan
|
||||
|
||||
subroutine fftwl_forget_wisdom() bind(C, name='fftwl_forget_wisdom')
|
||||
import
|
||||
end subroutine fftwl_forget_wisdom
|
||||
|
||||
subroutine fftwl_cleanup() bind(C, name='fftwl_cleanup')
|
||||
import
|
||||
end subroutine fftwl_cleanup
|
||||
|
||||
subroutine fftwl_set_timelimit(t) bind(C, name='fftwl_set_timelimit')
|
||||
import
|
||||
real(C_DOUBLE), value :: t
|
||||
end subroutine fftwl_set_timelimit
|
||||
|
||||
subroutine fftwl_plan_with_nthreads(nthreads) bind(C, name='fftwl_plan_with_nthreads')
|
||||
import
|
||||
integer(C_INT), value :: nthreads
|
||||
end subroutine fftwl_plan_with_nthreads
|
||||
|
||||
integer(C_INT) function fftwl_planner_nthreads() bind(C, name='fftwl_planner_nthreads')
|
||||
import
|
||||
end function fftwl_planner_nthreads
|
||||
|
||||
integer(C_INT) function fftwl_init_threads() bind(C, name='fftwl_init_threads')
|
||||
import
|
||||
end function fftwl_init_threads
|
||||
|
||||
subroutine fftwl_cleanup_threads() bind(C, name='fftwl_cleanup_threads')
|
||||
import
|
||||
end subroutine fftwl_cleanup_threads
|
||||
|
||||
! Unable to generate Fortran interface for fftwl_threads_set_callback
|
||||
subroutine fftwl_make_planner_thread_safe() bind(C, name='fftwl_make_planner_thread_safe')
|
||||
import
|
||||
end subroutine fftwl_make_planner_thread_safe
|
||||
|
||||
integer(C_INT) function fftwl_export_wisdom_to_filename(filename) bind(C, name='fftwl_export_wisdom_to_filename')
|
||||
import
|
||||
character(C_CHAR), dimension(*), intent(in) :: filename
|
||||
end function fftwl_export_wisdom_to_filename
|
||||
|
||||
subroutine fftwl_export_wisdom_to_file(output_file) bind(C, name='fftwl_export_wisdom_to_file')
|
||||
import
|
||||
type(C_PTR), value :: output_file
|
||||
end subroutine fftwl_export_wisdom_to_file
|
||||
|
||||
type(C_PTR) function fftwl_export_wisdom_to_string() bind(C, name='fftwl_export_wisdom_to_string')
|
||||
import
|
||||
end function fftwl_export_wisdom_to_string
|
||||
|
||||
subroutine fftwl_export_wisdom(write_char,data) bind(C, name='fftwl_export_wisdom')
|
||||
import
|
||||
type(C_FUNPTR), value :: write_char
|
||||
type(C_PTR), value :: data
|
||||
end subroutine fftwl_export_wisdom
|
||||
|
||||
integer(C_INT) function fftwl_import_system_wisdom() bind(C, name='fftwl_import_system_wisdom')
|
||||
import
|
||||
end function fftwl_import_system_wisdom
|
||||
|
||||
integer(C_INT) function fftwl_import_wisdom_from_filename(filename) bind(C, name='fftwl_import_wisdom_from_filename')
|
||||
import
|
||||
character(C_CHAR), dimension(*), intent(in) :: filename
|
||||
end function fftwl_import_wisdom_from_filename
|
||||
|
||||
integer(C_INT) function fftwl_import_wisdom_from_file(input_file) bind(C, name='fftwl_import_wisdom_from_file')
|
||||
import
|
||||
type(C_PTR), value :: input_file
|
||||
end function fftwl_import_wisdom_from_file
|
||||
|
||||
integer(C_INT) function fftwl_import_wisdom_from_string(input_string) bind(C, name='fftwl_import_wisdom_from_string')
|
||||
import
|
||||
character(C_CHAR), dimension(*), intent(in) :: input_string
|
||||
end function fftwl_import_wisdom_from_string
|
||||
|
||||
integer(C_INT) function fftwl_import_wisdom(read_char,data) bind(C, name='fftwl_import_wisdom')
|
||||
import
|
||||
type(C_FUNPTR), value :: read_char
|
||||
type(C_PTR), value :: data
|
||||
end function fftwl_import_wisdom
|
||||
|
||||
subroutine fftwl_fprint_plan(p,output_file) bind(C, name='fftwl_fprint_plan')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
type(C_PTR), value :: output_file
|
||||
end subroutine fftwl_fprint_plan
|
||||
|
||||
subroutine fftwl_print_plan(p) bind(C, name='fftwl_print_plan')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end subroutine fftwl_print_plan
|
||||
|
||||
type(C_PTR) function fftwl_sprint_plan(p) bind(C, name='fftwl_sprint_plan')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end function fftwl_sprint_plan
|
||||
|
||||
type(C_PTR) function fftwl_malloc(n) bind(C, name='fftwl_malloc')
|
||||
import
|
||||
integer(C_SIZE_T), value :: n
|
||||
end function fftwl_malloc
|
||||
|
||||
type(C_PTR) function fftwl_alloc_real(n) bind(C, name='fftwl_alloc_real')
|
||||
import
|
||||
integer(C_SIZE_T), value :: n
|
||||
end function fftwl_alloc_real
|
||||
|
||||
type(C_PTR) function fftwl_alloc_complex(n) bind(C, name='fftwl_alloc_complex')
|
||||
import
|
||||
integer(C_SIZE_T), value :: n
|
||||
end function fftwl_alloc_complex
|
||||
|
||||
subroutine fftwl_free(p) bind(C, name='fftwl_free')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end subroutine fftwl_free
|
||||
|
||||
subroutine fftwl_flops(p,add,mul,fmas) bind(C, name='fftwl_flops')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(C_DOUBLE), intent(out) :: add
|
||||
real(C_DOUBLE), intent(out) :: mul
|
||||
real(C_DOUBLE), intent(out) :: fmas
|
||||
end subroutine fftwl_flops
|
||||
|
||||
real(C_DOUBLE) function fftwl_estimate_cost(p) bind(C, name='fftwl_estimate_cost')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end function fftwl_estimate_cost
|
||||
|
||||
real(C_DOUBLE) function fftwl_cost(p) bind(C, name='fftwl_cost')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end function fftwl_cost
|
||||
|
||||
integer(C_INT) function fftwl_alignment_of(p) bind(C, name='fftwl_alignment_of')
|
||||
import
|
||||
real(C_LONG_DOUBLE), dimension(*), intent(out) :: p
|
||||
end function fftwl_alignment_of
|
||||
|
||||
end interface
|
|
@ -0,0 +1,614 @@
|
|||
! Generated automatically. DO NOT EDIT!
|
||||
|
||||
|
||||
type, bind(C) :: fftwq_iodim
|
||||
integer(C_INT) n, is, os
|
||||
end type fftwq_iodim
|
||||
type, bind(C) :: fftwq_iodim64
|
||||
integer(C_INTPTR_T) n, is, os
|
||||
end type fftwq_iodim64
|
||||
|
||||
interface
|
||||
type(C_PTR) function fftwq_plan_dft(rank,n,in,out,sign,flags) bind(C, name='fftwq_plan_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft
|
||||
|
||||
type(C_PTR) function fftwq_plan_dft_1d(n,in,out,sign,flags) bind(C, name='fftwq_plan_dft_1d')
|
||||
import
|
||||
integer(C_INT), value :: n
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft_1d
|
||||
|
||||
type(C_PTR) function fftwq_plan_dft_2d(n0,n1,in,out,sign,flags) bind(C, name='fftwq_plan_dft_2d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft_2d
|
||||
|
||||
type(C_PTR) function fftwq_plan_dft_3d(n0,n1,n2,in,out,sign,flags) bind(C, name='fftwq_plan_dft_3d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
integer(C_INT), value :: n2
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft_3d
|
||||
|
||||
type(C_PTR) function fftwq_plan_many_dft(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,sign,flags) &
|
||||
bind(C, name='fftwq_plan_many_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
integer(C_INT), value :: howmany
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
integer(C_INT), dimension(*), intent(in) :: inembed
|
||||
integer(C_INT), value :: istride
|
||||
integer(C_INT), value :: idist
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), dimension(*), intent(in) :: onembed
|
||||
integer(C_INT), value :: ostride
|
||||
integer(C_INT), value :: odist
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_many_dft
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru_dft(rank,dims,howmany_rank,howmany_dims,in,out,sign,flags) &
|
||||
bind(C, name='fftwq_plan_guru_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru_dft
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru_split_dft(rank,dims,howmany_rank,howmany_dims,ri,ii,ro,io,flags) &
|
||||
bind(C, name='fftwq_plan_guru_split_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
real(16), dimension(*), intent(out) :: ri
|
||||
real(16), dimension(*), intent(out) :: ii
|
||||
real(16), dimension(*), intent(out) :: ro
|
||||
real(16), dimension(*), intent(out) :: io
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru_split_dft
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru64_dft(rank,dims,howmany_rank,howmany_dims,in,out,sign,flags) &
|
||||
bind(C, name='fftwq_plan_guru64_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: sign
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru64_dft
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru64_split_dft(rank,dims,howmany_rank,howmany_dims,ri,ii,ro,io,flags) &
|
||||
bind(C, name='fftwq_plan_guru64_split_dft')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
real(16), dimension(*), intent(out) :: ri
|
||||
real(16), dimension(*), intent(out) :: ii
|
||||
real(16), dimension(*), intent(out) :: ro
|
||||
real(16), dimension(*), intent(out) :: io
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru64_split_dft
|
||||
|
||||
subroutine fftwq_execute_dft(p,in,out) bind(C, name='fftwq_execute_dft')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
complex(16), dimension(*), intent(inout) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
end subroutine fftwq_execute_dft
|
||||
|
||||
subroutine fftwq_execute_split_dft(p,ri,ii,ro,io) bind(C, name='fftwq_execute_split_dft')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(16), dimension(*), intent(inout) :: ri
|
||||
real(16), dimension(*), intent(inout) :: ii
|
||||
real(16), dimension(*), intent(out) :: ro
|
||||
real(16), dimension(*), intent(out) :: io
|
||||
end subroutine fftwq_execute_split_dft
|
||||
|
||||
type(C_PTR) function fftwq_plan_many_dft_r2c(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,flags) &
|
||||
bind(C, name='fftwq_plan_many_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
integer(C_INT), value :: howmany
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
integer(C_INT), dimension(*), intent(in) :: inembed
|
||||
integer(C_INT), value :: istride
|
||||
integer(C_INT), value :: idist
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), dimension(*), intent(in) :: onembed
|
||||
integer(C_INT), value :: ostride
|
||||
integer(C_INT), value :: odist
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_many_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwq_plan_dft_r2c(rank,n,in,out,flags) bind(C, name='fftwq_plan_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwq_plan_dft_r2c_1d(n,in,out,flags) bind(C, name='fftwq_plan_dft_r2c_1d')
|
||||
import
|
||||
integer(C_INT), value :: n
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft_r2c_1d
|
||||
|
||||
type(C_PTR) function fftwq_plan_dft_r2c_2d(n0,n1,in,out,flags) bind(C, name='fftwq_plan_dft_r2c_2d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft_r2c_2d
|
||||
|
||||
type(C_PTR) function fftwq_plan_dft_r2c_3d(n0,n1,n2,in,out,flags) bind(C, name='fftwq_plan_dft_r2c_3d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
integer(C_INT), value :: n2
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft_r2c_3d
|
||||
|
||||
type(C_PTR) function fftwq_plan_many_dft_c2r(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,flags) &
|
||||
bind(C, name='fftwq_plan_many_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
integer(C_INT), value :: howmany
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
integer(C_INT), dimension(*), intent(in) :: inembed
|
||||
integer(C_INT), value :: istride
|
||||
integer(C_INT), value :: idist
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), dimension(*), intent(in) :: onembed
|
||||
integer(C_INT), value :: ostride
|
||||
integer(C_INT), value :: odist
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_many_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwq_plan_dft_c2r(rank,n,in,out,flags) bind(C, name='fftwq_plan_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwq_plan_dft_c2r_1d(n,in,out,flags) bind(C, name='fftwq_plan_dft_c2r_1d')
|
||||
import
|
||||
integer(C_INT), value :: n
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft_c2r_1d
|
||||
|
||||
type(C_PTR) function fftwq_plan_dft_c2r_2d(n0,n1,in,out,flags) bind(C, name='fftwq_plan_dft_c2r_2d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft_c2r_2d
|
||||
|
||||
type(C_PTR) function fftwq_plan_dft_c2r_3d(n0,n1,n2,in,out,flags) bind(C, name='fftwq_plan_dft_c2r_3d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
integer(C_INT), value :: n2
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_dft_c2r_3d
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru_dft_r2c(rank,dims,howmany_rank,howmany_dims,in,out,flags) &
|
||||
bind(C, name='fftwq_plan_guru_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru_dft_c2r(rank,dims,howmany_rank,howmany_dims,in,out,flags) &
|
||||
bind(C, name='fftwq_plan_guru_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru_split_dft_r2c(rank,dims,howmany_rank,howmany_dims,in,ro,io,flags) &
|
||||
bind(C, name='fftwq_plan_guru_split_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: ro
|
||||
real(16), dimension(*), intent(out) :: io
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru_split_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru_split_dft_c2r(rank,dims,howmany_rank,howmany_dims,ri,ii,out,flags) &
|
||||
bind(C, name='fftwq_plan_guru_split_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
real(16), dimension(*), intent(out) :: ri
|
||||
real(16), dimension(*), intent(out) :: ii
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru_split_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru64_dft_r2c(rank,dims,howmany_rank,howmany_dims,in,out,flags) &
|
||||
bind(C, name='fftwq_plan_guru64_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru64_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru64_dft_c2r(rank,dims,howmany_rank,howmany_dims,in,out,flags) &
|
||||
bind(C, name='fftwq_plan_guru64_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
complex(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru64_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru64_split_dft_r2c(rank,dims,howmany_rank,howmany_dims,in,ro,io,flags) &
|
||||
bind(C, name='fftwq_plan_guru64_split_dft_r2c')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: ro
|
||||
real(16), dimension(*), intent(out) :: io
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru64_split_dft_r2c
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru64_split_dft_c2r(rank,dims,howmany_rank,howmany_dims,ri,ii,out,flags) &
|
||||
bind(C, name='fftwq_plan_guru64_split_dft_c2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
real(16), dimension(*), intent(out) :: ri
|
||||
real(16), dimension(*), intent(out) :: ii
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru64_split_dft_c2r
|
||||
|
||||
subroutine fftwq_execute_dft_r2c(p,in,out) bind(C, name='fftwq_execute_dft_r2c')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(16), dimension(*), intent(inout) :: in
|
||||
complex(16), dimension(*), intent(out) :: out
|
||||
end subroutine fftwq_execute_dft_r2c
|
||||
|
||||
subroutine fftwq_execute_dft_c2r(p,in,out) bind(C, name='fftwq_execute_dft_c2r')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
complex(16), dimension(*), intent(inout) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
end subroutine fftwq_execute_dft_c2r
|
||||
|
||||
subroutine fftwq_execute_split_dft_r2c(p,in,ro,io) bind(C, name='fftwq_execute_split_dft_r2c')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(16), dimension(*), intent(inout) :: in
|
||||
real(16), dimension(*), intent(out) :: ro
|
||||
real(16), dimension(*), intent(out) :: io
|
||||
end subroutine fftwq_execute_split_dft_r2c
|
||||
|
||||
subroutine fftwq_execute_split_dft_c2r(p,ri,ii,out) bind(C, name='fftwq_execute_split_dft_c2r')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(16), dimension(*), intent(inout) :: ri
|
||||
real(16), dimension(*), intent(inout) :: ii
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
end subroutine fftwq_execute_split_dft_c2r
|
||||
|
||||
type(C_PTR) function fftwq_plan_many_r2r(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,kind,flags) &
|
||||
bind(C, name='fftwq_plan_many_r2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
integer(C_INT), value :: howmany
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
integer(C_INT), dimension(*), intent(in) :: inembed
|
||||
integer(C_INT), value :: istride
|
||||
integer(C_INT), value :: idist
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_INT), dimension(*), intent(in) :: onembed
|
||||
integer(C_INT), value :: ostride
|
||||
integer(C_INT), value :: odist
|
||||
integer(C_FFTW_R2R_KIND), dimension(*), intent(in) :: kind
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_many_r2r
|
||||
|
||||
type(C_PTR) function fftwq_plan_r2r(rank,n,in,out,kind,flags) bind(C, name='fftwq_plan_r2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
integer(C_INT), dimension(*), intent(in) :: n
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), dimension(*), intent(in) :: kind
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_r2r
|
||||
|
||||
type(C_PTR) function fftwq_plan_r2r_1d(n,in,out,kind,flags) bind(C, name='fftwq_plan_r2r_1d')
|
||||
import
|
||||
integer(C_INT), value :: n
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), value :: kind
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_r2r_1d
|
||||
|
||||
type(C_PTR) function fftwq_plan_r2r_2d(n0,n1,in,out,kind0,kind1,flags) bind(C, name='fftwq_plan_r2r_2d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), value :: kind0
|
||||
integer(C_FFTW_R2R_KIND), value :: kind1
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_r2r_2d
|
||||
|
||||
type(C_PTR) function fftwq_plan_r2r_3d(n0,n1,n2,in,out,kind0,kind1,kind2,flags) bind(C, name='fftwq_plan_r2r_3d')
|
||||
import
|
||||
integer(C_INT), value :: n0
|
||||
integer(C_INT), value :: n1
|
||||
integer(C_INT), value :: n2
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), value :: kind0
|
||||
integer(C_FFTW_R2R_KIND), value :: kind1
|
||||
integer(C_FFTW_R2R_KIND), value :: kind2
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_r2r_3d
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru_r2r(rank,dims,howmany_rank,howmany_dims,in,out,kind,flags) &
|
||||
bind(C, name='fftwq_plan_guru_r2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim), dimension(*), intent(in) :: howmany_dims
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), dimension(*), intent(in) :: kind
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru_r2r
|
||||
|
||||
type(C_PTR) function fftwq_plan_guru64_r2r(rank,dims,howmany_rank,howmany_dims,in,out,kind,flags) &
|
||||
bind(C, name='fftwq_plan_guru64_r2r')
|
||||
import
|
||||
integer(C_INT), value :: rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: dims
|
||||
integer(C_INT), value :: howmany_rank
|
||||
type(fftwq_iodim64), dimension(*), intent(in) :: howmany_dims
|
||||
real(16), dimension(*), intent(out) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
integer(C_FFTW_R2R_KIND), dimension(*), intent(in) :: kind
|
||||
integer(C_INT), value :: flags
|
||||
end function fftwq_plan_guru64_r2r
|
||||
|
||||
subroutine fftwq_execute_r2r(p,in,out) bind(C, name='fftwq_execute_r2r')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(16), dimension(*), intent(inout) :: in
|
||||
real(16), dimension(*), intent(out) :: out
|
||||
end subroutine fftwq_execute_r2r
|
||||
|
||||
subroutine fftwq_destroy_plan(p) bind(C, name='fftwq_destroy_plan')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end subroutine fftwq_destroy_plan
|
||||
|
||||
subroutine fftwq_forget_wisdom() bind(C, name='fftwq_forget_wisdom')
|
||||
import
|
||||
end subroutine fftwq_forget_wisdom
|
||||
|
||||
subroutine fftwq_cleanup() bind(C, name='fftwq_cleanup')
|
||||
import
|
||||
end subroutine fftwq_cleanup
|
||||
|
||||
subroutine fftwq_set_timelimit(t) bind(C, name='fftwq_set_timelimit')
|
||||
import
|
||||
real(C_DOUBLE), value :: t
|
||||
end subroutine fftwq_set_timelimit
|
||||
|
||||
subroutine fftwq_plan_with_nthreads(nthreads) bind(C, name='fftwq_plan_with_nthreads')
|
||||
import
|
||||
integer(C_INT), value :: nthreads
|
||||
end subroutine fftwq_plan_with_nthreads
|
||||
|
||||
integer(C_INT) function fftwq_planner_nthreads() bind(C, name='fftwq_planner_nthreads')
|
||||
import
|
||||
end function fftwq_planner_nthreads
|
||||
|
||||
integer(C_INT) function fftwq_init_threads() bind(C, name='fftwq_init_threads')
|
||||
import
|
||||
end function fftwq_init_threads
|
||||
|
||||
subroutine fftwq_cleanup_threads() bind(C, name='fftwq_cleanup_threads')
|
||||
import
|
||||
end subroutine fftwq_cleanup_threads
|
||||
|
||||
! Unable to generate Fortran interface for fftwq_threads_set_callback
|
||||
subroutine fftwq_make_planner_thread_safe() bind(C, name='fftwq_make_planner_thread_safe')
|
||||
import
|
||||
end subroutine fftwq_make_planner_thread_safe
|
||||
|
||||
integer(C_INT) function fftwq_export_wisdom_to_filename(filename) bind(C, name='fftwq_export_wisdom_to_filename')
|
||||
import
|
||||
character(C_CHAR), dimension(*), intent(in) :: filename
|
||||
end function fftwq_export_wisdom_to_filename
|
||||
|
||||
subroutine fftwq_export_wisdom_to_file(output_file) bind(C, name='fftwq_export_wisdom_to_file')
|
||||
import
|
||||
type(C_PTR), value :: output_file
|
||||
end subroutine fftwq_export_wisdom_to_file
|
||||
|
||||
type(C_PTR) function fftwq_export_wisdom_to_string() bind(C, name='fftwq_export_wisdom_to_string')
|
||||
import
|
||||
end function fftwq_export_wisdom_to_string
|
||||
|
||||
subroutine fftwq_export_wisdom(write_char,data) bind(C, name='fftwq_export_wisdom')
|
||||
import
|
||||
type(C_FUNPTR), value :: write_char
|
||||
type(C_PTR), value :: data
|
||||
end subroutine fftwq_export_wisdom
|
||||
|
||||
integer(C_INT) function fftwq_import_system_wisdom() bind(C, name='fftwq_import_system_wisdom')
|
||||
import
|
||||
end function fftwq_import_system_wisdom
|
||||
|
||||
integer(C_INT) function fftwq_import_wisdom_from_filename(filename) bind(C, name='fftwq_import_wisdom_from_filename')
|
||||
import
|
||||
character(C_CHAR), dimension(*), intent(in) :: filename
|
||||
end function fftwq_import_wisdom_from_filename
|
||||
|
||||
integer(C_INT) function fftwq_import_wisdom_from_file(input_file) bind(C, name='fftwq_import_wisdom_from_file')
|
||||
import
|
||||
type(C_PTR), value :: input_file
|
||||
end function fftwq_import_wisdom_from_file
|
||||
|
||||
integer(C_INT) function fftwq_import_wisdom_from_string(input_string) bind(C, name='fftwq_import_wisdom_from_string')
|
||||
import
|
||||
character(C_CHAR), dimension(*), intent(in) :: input_string
|
||||
end function fftwq_import_wisdom_from_string
|
||||
|
||||
integer(C_INT) function fftwq_import_wisdom(read_char,data) bind(C, name='fftwq_import_wisdom')
|
||||
import
|
||||
type(C_FUNPTR), value :: read_char
|
||||
type(C_PTR), value :: data
|
||||
end function fftwq_import_wisdom
|
||||
|
||||
subroutine fftwq_fprint_plan(p,output_file) bind(C, name='fftwq_fprint_plan')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
type(C_PTR), value :: output_file
|
||||
end subroutine fftwq_fprint_plan
|
||||
|
||||
subroutine fftwq_print_plan(p) bind(C, name='fftwq_print_plan')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end subroutine fftwq_print_plan
|
||||
|
||||
type(C_PTR) function fftwq_sprint_plan(p) bind(C, name='fftwq_sprint_plan')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end function fftwq_sprint_plan
|
||||
|
||||
type(C_PTR) function fftwq_malloc(n) bind(C, name='fftwq_malloc')
|
||||
import
|
||||
integer(C_SIZE_T), value :: n
|
||||
end function fftwq_malloc
|
||||
|
||||
type(C_PTR) function fftwq_alloc_real(n) bind(C, name='fftwq_alloc_real')
|
||||
import
|
||||
integer(C_SIZE_T), value :: n
|
||||
end function fftwq_alloc_real
|
||||
|
||||
type(C_PTR) function fftwq_alloc_complex(n) bind(C, name='fftwq_alloc_complex')
|
||||
import
|
||||
integer(C_SIZE_T), value :: n
|
||||
end function fftwq_alloc_complex
|
||||
|
||||
subroutine fftwq_free(p) bind(C, name='fftwq_free')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end subroutine fftwq_free
|
||||
|
||||
subroutine fftwq_flops(p,add,mul,fmas) bind(C, name='fftwq_flops')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
real(C_DOUBLE), intent(out) :: add
|
||||
real(C_DOUBLE), intent(out) :: mul
|
||||
real(C_DOUBLE), intent(out) :: fmas
|
||||
end subroutine fftwq_flops
|
||||
|
||||
real(C_DOUBLE) function fftwq_estimate_cost(p) bind(C, name='fftwq_estimate_cost')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end function fftwq_estimate_cost
|
||||
|
||||
real(C_DOUBLE) function fftwq_cost(p) bind(C, name='fftwq_cost')
|
||||
import
|
||||
type(C_PTR), value :: p
|
||||
end function fftwq_cost
|
||||
|
||||
integer(C_INT) function fftwq_alignment_of(p) bind(C, name='fftwq_alignment_of')
|
||||
import
|
||||
real(16), dimension(*), intent(out) :: p
|
||||
end function fftwq_alignment_of
|
||||
|
||||
end interface
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
void X(flops)(const X(plan) p, double *add, double *mul, double *fma)
|
||||
{
|
||||
planner *plnr = X(the_planner)();
|
||||
opcnt *o = &p->pln->ops;
|
||||
*add = o->add; *mul = o->mul; *fma = o->fma;
|
||||
if (plnr->cost_hook) {
|
||||
*add = plnr->cost_hook(p->prb, *add, COST_SUM);
|
||||
*mul = plnr->cost_hook(p->prb, *mul, COST_SUM);
|
||||
*fma = plnr->cost_hook(p->prb, *fma, COST_SUM);
|
||||
}
|
||||
}
|
||||
|
||||
double X(estimate_cost)(const X(plan) p)
|
||||
{
|
||||
return X(iestimate_cost)(X(the_planner)(), p->pln, p->prb);
|
||||
}
|
||||
|
||||
double X(cost)(const X(plan) p)
|
||||
{
|
||||
return p->pln->pcost;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
void X(forget_wisdom)(void)
|
||||
{
|
||||
planner *plnr = X(the_planner)();
|
||||
plnr->adt->forget(plnr, FORGET_EVERYTHING);
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
#!/usr/bin/perl -w
|
||||
# Generate Fortran 2003 interfaces from a sequence of C function declarations
|
||||
# of the form (one per line):
|
||||
# extern <type> <name>(...args...)
|
||||
# extern <type> <name>(...args...)
|
||||
# ...
|
||||
# with no line breaks within a given function. (It's too much work to
|
||||
# write a general parser, since we just have to handle FFTW's header files.)
|
||||
|
||||
sub canonicalize_type {
|
||||
my($type);
|
||||
($type) = @_;
|
||||
$type =~ s/ +/ /g;
|
||||
$type =~ s/^ //;
|
||||
$type =~ s/ $//;
|
||||
$type =~ s/([^\* ])\*/$1 \*/g;
|
||||
return $type;
|
||||
}
|
||||
|
||||
# C->Fortran map of supported return types
|
||||
%return_types = (
|
||||
"int" => "integer(C_INT)",
|
||||
"ptrdiff_t" => "integer(C_INTPTR_T)",
|
||||
"size_t" => "integer(C_SIZE_T)",
|
||||
"double" => "real(C_DOUBLE)",
|
||||
"float" => "real(C_FLOAT)",
|
||||
"long double" => "real(C_LONG_DOUBLE)",
|
||||
"__float128" => "real(16)",
|
||||
"fftw_plan" => "type(C_PTR)",
|
||||
"fftwf_plan" => "type(C_PTR)",
|
||||
"fftwl_plan" => "type(C_PTR)",
|
||||
"fftwq_plan" => "type(C_PTR)",
|
||||
"void *" => "type(C_PTR)",
|
||||
"char *" => "type(C_PTR)",
|
||||
"double *" => "type(C_PTR)",
|
||||
"float *" => "type(C_PTR)",
|
||||
"long double *" => "type(C_PTR)",
|
||||
"__float128 *" => "type(C_PTR)",
|
||||
"fftw_complex *" => "type(C_PTR)",
|
||||
"fftwf_complex *" => "type(C_PTR)",
|
||||
"fftwl_complex *" => "type(C_PTR)",
|
||||
"fftwq_complex *" => "type(C_PTR)",
|
||||
);
|
||||
|
||||
# C->Fortran map of supported argument types
|
||||
%arg_types = (
|
||||
"int" => "integer(C_INT), value",
|
||||
"unsigned" => "integer(C_INT), value",
|
||||
"size_t" => "integer(C_SIZE_T), value",
|
||||
"ptrdiff_t" => "integer(C_INTPTR_T), value",
|
||||
|
||||
"fftw_r2r_kind" => "integer(C_FFTW_R2R_KIND), value",
|
||||
"fftwf_r2r_kind" => "integer(C_FFTW_R2R_KIND), value",
|
||||
"fftwl_r2r_kind" => "integer(C_FFTW_R2R_KIND), value",
|
||||
"fftwq_r2r_kind" => "integer(C_FFTW_R2R_KIND), value",
|
||||
|
||||
"double" => "real(C_DOUBLE), value",
|
||||
"float" => "real(C_FLOAT), value",
|
||||
"long double" => "real(C_LONG_DOUBLE), value",
|
||||
"__float128" => "real(16), value",
|
||||
|
||||
"fftw_complex" => "complex(C_DOUBLE_COMPLEX), value",
|
||||
"fftwf_complex" => "complex(C_DOUBLE_COMPLEX), value",
|
||||
"fftwl_complex" => "complex(C_LONG_DOUBLE), value",
|
||||
"fftwq_complex" => "complex(16), value",
|
||||
|
||||
"fftw_plan" => "type(C_PTR), value",
|
||||
"fftwf_plan" => "type(C_PTR), value",
|
||||
"fftwl_plan" => "type(C_PTR), value",
|
||||
"fftwq_plan" => "type(C_PTR), value",
|
||||
"const fftw_plan" => "type(C_PTR), value",
|
||||
"const fftwf_plan" => "type(C_PTR), value",
|
||||
"const fftwl_plan" => "type(C_PTR), value",
|
||||
"const fftwq_plan" => "type(C_PTR), value",
|
||||
|
||||
"const int *" => "integer(C_INT), dimension(*), intent(in)",
|
||||
"ptrdiff_t *" => "integer(C_INTPTR_T), intent(out)",
|
||||
"const ptrdiff_t *" => "integer(C_INTPTR_T), dimension(*), intent(in)",
|
||||
|
||||
"const fftw_r2r_kind *" => "integer(C_FFTW_R2R_KIND), dimension(*), intent(in)",
|
||||
"const fftwf_r2r_kind *" => "integer(C_FFTW_R2R_KIND), dimension(*), intent(in)",
|
||||
"const fftwl_r2r_kind *" => "integer(C_FFTW_R2R_KIND), dimension(*), intent(in)",
|
||||
"const fftwq_r2r_kind *" => "integer(C_FFTW_R2R_KIND), dimension(*), intent(in)",
|
||||
|
||||
"double *" => "real(C_DOUBLE), dimension(*), intent(out)",
|
||||
"float *" => "real(C_FLOAT), dimension(*), intent(out)",
|
||||
"long double *" => "real(C_LONG_DOUBLE), dimension(*), intent(out)",
|
||||
"__float128 *" => "real(16), dimension(*), intent(out)",
|
||||
|
||||
"fftw_complex *" => "complex(C_DOUBLE_COMPLEX), dimension(*), intent(out)",
|
||||
"fftwf_complex *" => "complex(C_FLOAT_COMPLEX), dimension(*), intent(out)",
|
||||
"fftwl_complex *" => "complex(C_LONG_DOUBLE_COMPLEX), dimension(*), intent(out)",
|
||||
"fftwq_complex *" => "complex(16), dimension(*), intent(out)",
|
||||
|
||||
"const fftw_iodim *" => "type(fftw_iodim), dimension(*), intent(in)",
|
||||
"const fftwf_iodim *" => "type(fftwf_iodim), dimension(*), intent(in)",
|
||||
"const fftwl_iodim *" => "type(fftwl_iodim), dimension(*), intent(in)",
|
||||
"const fftwq_iodim *" => "type(fftwq_iodim), dimension(*), intent(in)",
|
||||
|
||||
"const fftw_iodim64 *" => "type(fftw_iodim64), dimension(*), intent(in)",
|
||||
"const fftwf_iodim64 *" => "type(fftwf_iodim64), dimension(*), intent(in)",
|
||||
"const fftwl_iodim64 *" => "type(fftwl_iodim64), dimension(*), intent(in)",
|
||||
"const fftwq_iodim64 *" => "type(fftwq_iodim64), dimension(*), intent(in)",
|
||||
|
||||
"void *" => "type(C_PTR), value",
|
||||
"FILE *" => "type(C_PTR), value",
|
||||
|
||||
"const char *" => "character(C_CHAR), dimension(*), intent(in)",
|
||||
|
||||
"fftw_write_char_func" => "type(C_FUNPTR), value",
|
||||
"fftwf_write_char_func" => "type(C_FUNPTR), value",
|
||||
"fftwl_write_char_func" => "type(C_FUNPTR), value",
|
||||
"fftwq_write_char_func" => "type(C_FUNPTR), value",
|
||||
"fftw_read_char_func" => "type(C_FUNPTR), value",
|
||||
"fftwf_read_char_func" => "type(C_FUNPTR), value",
|
||||
"fftwl_read_char_func" => "type(C_FUNPTR), value",
|
||||
"fftwq_read_char_func" => "type(C_FUNPTR), value",
|
||||
|
||||
# Although the MPI standard defines this type as simply "integer",
|
||||
# if we use integer without a 'C_' kind in a bind(C) interface then
|
||||
# gfortran complains. Instead, since MPI also requires the C type
|
||||
# MPI_Fint to match Fortran integers, we use the size of this type
|
||||
# (extracted by configure and substituted by the Makefile).
|
||||
"MPI_Comm" => "integer(C_MPI_FINT), value"
|
||||
);
|
||||
|
||||
while (<>) {
|
||||
next if /^ *$/;
|
||||
if (/^ *extern +([a-zA-Z_0-9 ]+[ \*]) *([a-zA-Z_0-9]+) *\((.*)\) *$/) {
|
||||
$ret = &canonicalize_type($1);
|
||||
$name = $2;
|
||||
|
||||
$args = $3;
|
||||
$args =~ s/^ *void *$//;
|
||||
|
||||
$bad = ($ret ne "void") && !exists($return_types{$ret});
|
||||
foreach $arg (split(/ *, */, $args)) {
|
||||
$arg =~ /^([a-zA-Z_0-9 ]+[ \*]) *([a-zA-Z_0-9]+) *$/;
|
||||
$argtype = &canonicalize_type($1);
|
||||
$bad = 1 if !exists($arg_types{$argtype});
|
||||
}
|
||||
if ($bad) {
|
||||
print "! Unable to generate Fortran interface for $name\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# any function taking an MPI_Comm arg needs a C wrapper (grr).
|
||||
if ($args =~ /MPI_Comm/) {
|
||||
$cname = $name . "_f03";
|
||||
}
|
||||
else {
|
||||
$cname = $name;
|
||||
}
|
||||
|
||||
# Fortran has a 132-character line-length limit by default (grr)
|
||||
$len = 0;
|
||||
|
||||
print " "; $len = $len + length(" ");
|
||||
if ($ret eq "void") {
|
||||
$kind = "subroutine"
|
||||
}
|
||||
else {
|
||||
print "$return_types{$ret} ";
|
||||
$len = $len + length("$return_types{$ret} ");
|
||||
$kind = "function"
|
||||
}
|
||||
print "$kind $name("; $len = $len + length("$kind $name(");
|
||||
$len0 = $len;
|
||||
|
||||
$argnames = $args;
|
||||
$argnames =~ s/([a-zA-Z_0-9 ]+[ \*]) *([a-zA-Z_0-9]+) */$2/g;
|
||||
$comma = "";
|
||||
foreach $argname (split(/ *, */, $argnames)) {
|
||||
if ($len + length("$comma$argname") + 3 > 132) {
|
||||
printf ", &\n%*s", $len0, "";
|
||||
$len = $len0;
|
||||
$comma = "";
|
||||
}
|
||||
print "$comma$argname";
|
||||
$len = $len + length("$comma$argname");
|
||||
$comma = ",";
|
||||
}
|
||||
print ") "; $len = $len + 2;
|
||||
|
||||
if ($len + length("bind(C, name='$cname')") > 132) {
|
||||
printf "&\n%*s", $len0 - length("$name("), "";
|
||||
}
|
||||
print "bind(C, name='$cname')\n";
|
||||
|
||||
print " import\n";
|
||||
foreach $arg (split(/ *, */, $args)) {
|
||||
$arg =~ /^([a-zA-Z_0-9 ]+[ \*]) *([a-zA-Z_0-9]+) *$/;
|
||||
$argtype = &canonicalize_type($1);
|
||||
$argname = $2;
|
||||
$ftype = $arg_types{$argtype};
|
||||
|
||||
# Various special cases for argument types:
|
||||
if ($name =~ /_flops$/ && $argtype eq "double *") {
|
||||
$ftype = "real(C_DOUBLE), intent(out)"
|
||||
}
|
||||
if ($name =~ /_execute/ && ($argname eq "ri" ||
|
||||
$argname eq "ii" ||
|
||||
$argname eq "in")) {
|
||||
$ftype =~ s/intent\(out\)/intent(inout)/;
|
||||
}
|
||||
|
||||
print " $ftype :: $argname\n"
|
||||
}
|
||||
|
||||
print " end $kind $name\n";
|
||||
print " \n";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#define XGURU(name) X(plan_guru_ ## name)
|
||||
#define IODIM X(iodim)
|
||||
#define MKTENSOR_IODIMS X(mktensor_iodims)
|
||||
#define GURU_KOSHERP X(guru_kosherp)
|
|
@ -0,0 +1,4 @@
|
|||
#define XGURU(name) X(plan_guru64_ ## name)
|
||||
#define IODIM X(iodim64)
|
||||
#define MKTENSOR_IODIMS X(mktensor_iodims64)
|
||||
#define GURU_KOSHERP X(guru64_kosherp)
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
#if defined(FFTW_SINGLE)
|
||||
# define WISDOM_NAME "wisdomf"
|
||||
#elif defined(FFTW_LDOUBLE)
|
||||
# define WISDOM_NAME "wisdoml"
|
||||
#else
|
||||
# define WISDOM_NAME "wisdom"
|
||||
#endif
|
||||
|
||||
/* OS-specific configuration-file directory */
|
||||
#if defined(__DJGPP__)
|
||||
# define WISDOM_DIR "/dev/env/DJDIR/etc/fftw/"
|
||||
#else
|
||||
# define WISDOM_DIR "/etc/fftw/"
|
||||
#endif
|
||||
|
||||
int X(import_system_wisdom)(void)
|
||||
{
|
||||
#if defined(__WIN32__) || defined(WIN32) || defined(_WINDOWS)
|
||||
return 0; /* TODO? */
|
||||
#else
|
||||
|
||||
FILE *f;
|
||||
f = fopen(WISDOM_DIR WISDOM_NAME, "r");
|
||||
if (f) {
|
||||
int ret = X(import_wisdom_from_file)(f);
|
||||
fclose(f);
|
||||
return ret;
|
||||
} else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* getc()/putc() are *unbelievably* slow on linux. Looks like glibc
|
||||
is grabbing a lock for each call to getc()/putc(), or something
|
||||
like that. You pay the price for these idiotic posix threads
|
||||
whether you use them or not.
|
||||
|
||||
So, we do our own buffering. This completely defeats the purpose
|
||||
of having stdio in the first place, of course.
|
||||
*/
|
||||
|
||||
#define BUFSZ 256
|
||||
|
||||
typedef struct {
|
||||
scanner super;
|
||||
FILE *f;
|
||||
char buf[BUFSZ];
|
||||
char *bufr, *bufw;
|
||||
} S;
|
||||
|
||||
static int getchr_file(scanner * sc_)
|
||||
{
|
||||
S *sc = (S *) sc_;
|
||||
|
||||
if (sc->bufr >= sc->bufw) {
|
||||
sc->bufr = sc->buf;
|
||||
sc->bufw = sc->buf + fread(sc->buf, 1, BUFSZ, sc->f);
|
||||
if (sc->bufr >= sc->bufw)
|
||||
return EOF;
|
||||
}
|
||||
|
||||
return *(sc->bufr++);
|
||||
}
|
||||
|
||||
static scanner *mkscanner_file(FILE *f)
|
||||
{
|
||||
S *sc = (S *) X(mkscanner)(sizeof(S), getchr_file);
|
||||
sc->f = f;
|
||||
sc->bufr = sc->bufw = sc->buf;
|
||||
return &sc->super;
|
||||
}
|
||||
|
||||
int X(import_wisdom_from_file)(FILE *input_file)
|
||||
{
|
||||
scanner *s = mkscanner_file(input_file);
|
||||
planner *plnr = X(the_planner)();
|
||||
int ret = plnr->adt->imprt(plnr, s);
|
||||
X(scanner_destroy)(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int X(import_wisdom_from_filename)(const char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "r");
|
||||
int ret;
|
||||
if (!f) return 0; /* error opening file */
|
||||
ret = X(import_wisdom_from_file)(f);
|
||||
if (fclose(f)) ret = 0; /* error closing file */
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
typedef struct {
|
||||
scanner super;
|
||||
const char *s;
|
||||
} S_str;
|
||||
|
||||
static int getchr_str(scanner * sc_)
|
||||
{
|
||||
S_str *sc = (S_str *) sc_;
|
||||
if (!*sc->s)
|
||||
return EOF;
|
||||
return *sc->s++;
|
||||
}
|
||||
|
||||
static scanner *mkscanner_str(const char *s)
|
||||
{
|
||||
S_str *sc = (S_str *) X(mkscanner)(sizeof(S_str), getchr_str);
|
||||
sc->s = s;
|
||||
return &sc->super;
|
||||
}
|
||||
|
||||
int X(import_wisdom_from_string)(const char *input_string)
|
||||
{
|
||||
scanner *s = mkscanner_str(input_string);
|
||||
planner *plnr = X(the_planner)();
|
||||
int ret = plnr->adt->imprt(plnr, s);
|
||||
X(scanner_destroy)(s);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
typedef struct {
|
||||
scanner super;
|
||||
int (*read_char)(void *);
|
||||
void *data;
|
||||
} S;
|
||||
|
||||
static int getchr_generic(scanner * s_)
|
||||
{
|
||||
S *s = (S *) s_;
|
||||
return (s->read_char)(s->data);
|
||||
}
|
||||
|
||||
int X(import_wisdom)(int (*read_char)(void *), void *data)
|
||||
{
|
||||
S *s = (S *) X(mkscanner)(sizeof(S), getchr_generic);
|
||||
planner *plnr = X(the_planner)();
|
||||
int ret;
|
||||
|
||||
s->read_char = read_char;
|
||||
s->data = data;
|
||||
ret = plnr->adt->imprt(plnr, (scanner *) s);
|
||||
X(scanner_destroy)((scanner *) s);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
|
||||
void *X(malloc)(size_t n)
|
||||
{
|
||||
return X(kernel_malloc)(n);
|
||||
}
|
||||
|
||||
void X(free)(void *p)
|
||||
{
|
||||
X(kernel_free)(p);
|
||||
}
|
||||
|
||||
/* The following two routines are mainly for the convenience of
|
||||
the Fortran 2003 API, although C users may find them convienent
|
||||
as well. The problem is that, although Fortran 2003 has a
|
||||
c_sizeof intrinsic that is equivalent to sizeof, it is broken
|
||||
in some gfortran versions, and in any case is a bit unnatural
|
||||
in a Fortran context. So we provide routines to allocate real
|
||||
and complex arrays, which are all that are really needed by FFTW. */
|
||||
|
||||
R *X(alloc_real)(size_t n)
|
||||
{
|
||||
return (R *) X(malloc)(sizeof(R) * n);
|
||||
}
|
||||
|
||||
C *X(alloc_complex)(size_t n)
|
||||
{
|
||||
return (C *) X(malloc)(sizeof(C) * n);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
rdft_kind *X(map_r2r_kind)(int rank, const X(r2r_kind) * kind)
|
||||
{
|
||||
int i;
|
||||
rdft_kind *k;
|
||||
|
||||
A(FINITE_RNK(rank));
|
||||
k = (rdft_kind *) MALLOC((unsigned)rank * sizeof(rdft_kind), PROBLEMS);
|
||||
for (i = 0; i < rank; ++i) {
|
||||
rdft_kind m;
|
||||
switch (kind[i]) {
|
||||
case FFTW_R2HC: m = R2HC; break;
|
||||
case FFTW_HC2R: m = HC2R; break;
|
||||
case FFTW_DHT: m = DHT; break;
|
||||
case FFTW_REDFT00: m = REDFT00; break;
|
||||
case FFTW_REDFT01: m = REDFT01; break;
|
||||
case FFTW_REDFT10: m = REDFT10; break;
|
||||
case FFTW_REDFT11: m = REDFT11; break;
|
||||
case FFTW_RODFT00: m = RODFT00; break;
|
||||
case FFTW_RODFT01: m = RODFT01; break;
|
||||
case FFTW_RODFT10: m = RODFT10; break;
|
||||
case FFTW_RODFT11: m = RODFT11; break;
|
||||
default: m = R2HC; A(0);
|
||||
}
|
||||
k[i] = m;
|
||||
}
|
||||
return k;
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include <math.h>
|
||||
|
||||
/* a flag operation: x is either a flag, in which case xm == 0, or
|
||||
a mask, in which case xm == x; using this we can compactly code
|
||||
the various bit operations via (flags & x) ^ xm or (flags | x) ^ xm. */
|
||||
typedef struct {
|
||||
unsigned x, xm;
|
||||
} flagmask;
|
||||
|
||||
typedef struct {
|
||||
flagmask flag;
|
||||
flagmask op;
|
||||
} flagop;
|
||||
|
||||
#define FLAGP(f, msk)(((f) & (msk).x) ^ (msk).xm)
|
||||
#define OP(f, msk)(((f) | (msk).x) ^ (msk).xm)
|
||||
|
||||
#define YES(x) {x, 0}
|
||||
#define NO(x) {x, x}
|
||||
#define IMPLIES(predicate, consequence) { predicate, consequence }
|
||||
#define EQV(a, b) IMPLIES(YES(a), YES(b)), IMPLIES(NO(a), NO(b))
|
||||
#define NEQV(a, b) IMPLIES(YES(a), NO(b)), IMPLIES(NO(a), YES(b))
|
||||
|
||||
static void map_flags(unsigned *iflags, unsigned *oflags,
|
||||
const flagop flagmap[], size_t nmap)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < nmap; ++i)
|
||||
if (FLAGP(*iflags, flagmap[i].flag))
|
||||
*oflags = OP(*oflags, flagmap[i].op);
|
||||
}
|
||||
|
||||
/* encoding of the planner timelimit into a BITS_FOR_TIMELIMIT-bits
|
||||
nonnegative integer, such that we can still view the integer as
|
||||
``impatience'': higher means *lower* time limit, and 0 is the
|
||||
highest possible value (about 1 year of calendar time) */
|
||||
static unsigned timelimit_to_flags(double timelimit)
|
||||
{
|
||||
const double tmax = 365 * 24 * 3600;
|
||||
const double tstep = 1.05;
|
||||
const int nsteps = (1 << BITS_FOR_TIMELIMIT);
|
||||
int x;
|
||||
|
||||
if (timelimit < 0 || timelimit >= tmax)
|
||||
return 0;
|
||||
if (timelimit <= 1.0e-10)
|
||||
return nsteps - 1;
|
||||
|
||||
x = (int) (0.5 + (log(tmax / timelimit) / log(tstep)));
|
||||
|
||||
if (x < 0) x = 0;
|
||||
if (x >= nsteps) x = nsteps - 1;
|
||||
return x;
|
||||
}
|
||||
|
||||
void X(mapflags)(planner *plnr, unsigned flags)
|
||||
{
|
||||
unsigned l, u, t;
|
||||
|
||||
/* map of api flags -> api flags, to implement consistency rules
|
||||
and combination flags */
|
||||
const flagop self_flagmap[] = {
|
||||
/* in some cases (notably for halfcomplex->real transforms),
|
||||
DESTROY_INPUT is the default, so we need to support
|
||||
an inverse flag to disable it.
|
||||
|
||||
(PRESERVE, DESTROY) -> (PRESERVE, DESTROY)
|
||||
(0, 0) (1, 0)
|
||||
(0, 1) (0, 1)
|
||||
(1, 0) (1, 0)
|
||||
(1, 1) (1, 0)
|
||||
*/
|
||||
IMPLIES(YES(FFTW_PRESERVE_INPUT), NO(FFTW_DESTROY_INPUT)),
|
||||
IMPLIES(NO(FFTW_DESTROY_INPUT), YES(FFTW_PRESERVE_INPUT)),
|
||||
|
||||
IMPLIES(YES(FFTW_EXHAUSTIVE), YES(FFTW_PATIENT)),
|
||||
|
||||
IMPLIES(YES(FFTW_ESTIMATE), NO(FFTW_PATIENT)),
|
||||
IMPLIES(YES(FFTW_ESTIMATE),
|
||||
YES(FFTW_ESTIMATE_PATIENT
|
||||
| FFTW_NO_INDIRECT_OP
|
||||
| FFTW_ALLOW_PRUNING)),
|
||||
|
||||
IMPLIES(NO(FFTW_EXHAUSTIVE),
|
||||
YES(FFTW_NO_SLOW)),
|
||||
|
||||
/* a canonical set of fftw2-like impatience flags */
|
||||
IMPLIES(NO(FFTW_PATIENT),
|
||||
YES(FFTW_NO_VRECURSE
|
||||
| FFTW_NO_RANK_SPLITS
|
||||
| FFTW_NO_VRANK_SPLITS
|
||||
| FFTW_NO_NONTHREADED
|
||||
| FFTW_NO_DFT_R2HC
|
||||
| FFTW_NO_FIXED_RADIX_LARGE_N
|
||||
| FFTW_BELIEVE_PCOST))
|
||||
};
|
||||
|
||||
/* map of (processed) api flags to internal problem/planner flags */
|
||||
const flagop l_flagmap[] = {
|
||||
EQV(FFTW_PRESERVE_INPUT, NO_DESTROY_INPUT),
|
||||
EQV(FFTW_NO_SIMD, NO_SIMD),
|
||||
EQV(FFTW_CONSERVE_MEMORY, CONSERVE_MEMORY),
|
||||
EQV(FFTW_NO_BUFFERING, NO_BUFFERING),
|
||||
NEQV(FFTW_ALLOW_LARGE_GENERIC, NO_LARGE_GENERIC)
|
||||
};
|
||||
|
||||
const flagop u_flagmap[] = {
|
||||
IMPLIES(YES(FFTW_EXHAUSTIVE), NO(0xFFFFFFFF)),
|
||||
IMPLIES(NO(FFTW_EXHAUSTIVE), YES(NO_UGLY)),
|
||||
|
||||
/* the following are undocumented, "beyond-guru" flags that
|
||||
require some understanding of FFTW internals */
|
||||
EQV(FFTW_ESTIMATE_PATIENT, ESTIMATE),
|
||||
EQV(FFTW_ALLOW_PRUNING, ALLOW_PRUNING),
|
||||
EQV(FFTW_BELIEVE_PCOST, BELIEVE_PCOST),
|
||||
EQV(FFTW_NO_DFT_R2HC, NO_DFT_R2HC),
|
||||
EQV(FFTW_NO_NONTHREADED, NO_NONTHREADED),
|
||||
EQV(FFTW_NO_INDIRECT_OP, NO_INDIRECT_OP),
|
||||
EQV(FFTW_NO_RANK_SPLITS, NO_RANK_SPLITS),
|
||||
EQV(FFTW_NO_VRANK_SPLITS, NO_VRANK_SPLITS),
|
||||
EQV(FFTW_NO_VRECURSE, NO_VRECURSE),
|
||||
EQV(FFTW_NO_SLOW, NO_SLOW),
|
||||
EQV(FFTW_NO_FIXED_RADIX_LARGE_N, NO_FIXED_RADIX_LARGE_N)
|
||||
};
|
||||
|
||||
map_flags(&flags, &flags, self_flagmap, NELEM(self_flagmap));
|
||||
|
||||
l = u = 0;
|
||||
map_flags(&flags, &l, l_flagmap, NELEM(l_flagmap));
|
||||
map_flags(&flags, &u, u_flagmap, NELEM(u_flagmap));
|
||||
|
||||
/* enforce l <= u */
|
||||
PLNR_L(plnr) = l;
|
||||
PLNR_U(plnr) = u | l;
|
||||
|
||||
/* assert that the conversion didn't lose bits */
|
||||
A(PLNR_L(plnr) == l);
|
||||
A(PLNR_U(plnr) == (u | l));
|
||||
|
||||
/* compute flags representation of the timelimit */
|
||||
t = timelimit_to_flags(plnr->timelimit);
|
||||
|
||||
PLNR_TIMELIMIT_IMPATIENCE(plnr) = t;
|
||||
A(PLNR_TIMELIMIT_IMPATIENCE(plnr) == t);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define BUFSZ 256
|
||||
|
||||
typedef struct {
|
||||
printer super;
|
||||
FILE *f;
|
||||
char buf[BUFSZ];
|
||||
char *bufw;
|
||||
} P;
|
||||
|
||||
static void myflush(P *p)
|
||||
{
|
||||
fwrite(p->buf, 1, p->bufw - p->buf, p->f);
|
||||
p->bufw = p->buf;
|
||||
}
|
||||
|
||||
static void myputchr(printer *p_, char c)
|
||||
{
|
||||
P *p = (P *) p_;
|
||||
if (p->bufw >= p->buf + BUFSZ)
|
||||
myflush(p);
|
||||
*p->bufw++ = c;
|
||||
}
|
||||
|
||||
static void mycleanup(printer *p_)
|
||||
{
|
||||
P *p = (P *) p_;
|
||||
myflush(p);
|
||||
}
|
||||
|
||||
printer *X(mkprinter_file)(FILE *f)
|
||||
{
|
||||
P *p = (P *) X(mkprinter)(sizeof(P), myputchr, mycleanup);
|
||||
p->f = f;
|
||||
p->bufw = p->buf;
|
||||
return &p->super;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
typedef struct {
|
||||
printer super;
|
||||
size_t *cnt;
|
||||
} P_cnt;
|
||||
|
||||
static void putchr_cnt(printer * p_, char c)
|
||||
{
|
||||
P_cnt *p = (P_cnt *) p_;
|
||||
UNUSED(c);
|
||||
++*p->cnt;
|
||||
}
|
||||
|
||||
printer *X(mkprinter_cnt)(size_t *cnt)
|
||||
{
|
||||
P_cnt *p = (P_cnt *) X(mkprinter)(sizeof(P_cnt), putchr_cnt, 0);
|
||||
p->cnt = cnt;
|
||||
*cnt = 0;
|
||||
return &p->super;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
printer super;
|
||||
char *s;
|
||||
} P_str;
|
||||
|
||||
static void putchr_str(printer * p_, char c)
|
||||
{
|
||||
P_str *p = (P_str *) p_;
|
||||
*p->s++ = c;
|
||||
*p->s = 0;
|
||||
}
|
||||
|
||||
printer *X(mkprinter_str)(char *s)
|
||||
{
|
||||
P_str *p = (P_str *) X(mkprinter)(sizeof(P_str), putchr_str, 0);
|
||||
p->s = s;
|
||||
*s = 0;
|
||||
return &p->super;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru.h"
|
||||
#include "mktensor-iodims.h"
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
tensor *MKTENSOR_IODIMS(int rank, const IODIM *dims, int is, int os)
|
||||
{
|
||||
int i;
|
||||
tensor *x = X(mktensor)(rank);
|
||||
|
||||
if (FINITE_RNK(rank)) {
|
||||
for (i = 0; i < rank; ++i) {
|
||||
x->dims[i].n = dims[i].n;
|
||||
x->dims[i].is = dims[i].is * is;
|
||||
x->dims[i].os = dims[i].os * os;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static int iodims_kosherp(int rank, const IODIM *dims, int allow_minfty)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (rank < 0) return 0;
|
||||
|
||||
if (allow_minfty) {
|
||||
if (!FINITE_RNK(rank)) return 1;
|
||||
for (i = 0; i < rank; ++i)
|
||||
if (dims[i].n < 0) return 0;
|
||||
} else {
|
||||
if (!FINITE_RNK(rank)) return 0;
|
||||
for (i = 0; i < rank; ++i)
|
||||
if (dims[i].n <= 0) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int GURU_KOSHERP(int rank, const IODIM *dims,
|
||||
int howmany_rank, const IODIM *howmany_dims)
|
||||
{
|
||||
return (iodims_kosherp(rank, dims, 0) &&
|
||||
iodims_kosherp(howmany_rank, howmany_dims, 1));
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru64.h"
|
||||
#include "mktensor-iodims.h"
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
tensor *X(mktensor_rowmajor)(int rnk, const int *n,
|
||||
const int *niphys, const int *nophys,
|
||||
int is, int os)
|
||||
{
|
||||
tensor *x = X(mktensor)(rnk);
|
||||
|
||||
if (FINITE_RNK(rnk) && rnk > 0) {
|
||||
int i;
|
||||
|
||||
A(n && niphys && nophys);
|
||||
x->dims[rnk - 1].is = is;
|
||||
x->dims[rnk - 1].os = os;
|
||||
x->dims[rnk - 1].n = n[rnk - 1];
|
||||
for (i = rnk - 1; i > 0; --i) {
|
||||
x->dims[i - 1].is = x->dims[i].is * niphys[i];
|
||||
x->dims[i - 1].os = x->dims[i].os * nophys[i];
|
||||
x->dims[i - 1].n = n[i - 1];
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static int rowmajor_kosherp(int rnk, const int *n)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!FINITE_RNK(rnk)) return 0;
|
||||
if (rnk < 0) return 0;
|
||||
|
||||
for (i = 0; i < rnk; ++i)
|
||||
if (n[i] <= 0) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int X(many_kosherp)(int rnk, const int *n, int howmany)
|
||||
{
|
||||
return (howmany >= 0) && rowmajor_kosherp(rnk, n);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "dft/dft.h"
|
||||
|
||||
X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, unsigned flags)
|
||||
{
|
||||
return X(plan_dft)(1, &n, in, out, sign, flags);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "dft/dft.h"
|
||||
|
||||
X(plan) X(plan_dft_2d)(int nx, int ny, C *in, C *out, int sign, unsigned flags)
|
||||
{
|
||||
int n[2];
|
||||
n[0] = nx;
|
||||
n[1] = ny;
|
||||
return X(plan_dft)(2, n, in, out, sign, flags);
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "dft/dft.h"
|
||||
|
||||
X(plan) X(plan_dft_3d)(int nx, int ny, int nz,
|
||||
C *in, C *out, int sign, unsigned flags)
|
||||
{
|
||||
int n[3];
|
||||
n[0] = nx;
|
||||
n[1] = ny;
|
||||
n[2] = nz;
|
||||
return X(plan_dft)(3, n, in, out, sign, flags);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
X(plan) X(plan_dft_c2r_1d)(int n, C *in, R *out, unsigned flags)
|
||||
{
|
||||
return X(plan_dft_c2r)(1, &n, in, out, flags);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
X(plan) X(plan_dft_c2r_2d)(int nx, int ny, C *in, R *out, unsigned flags)
|
||||
{
|
||||
int n[2];
|
||||
n[0] = nx;
|
||||
n[1] = ny;
|
||||
return X(plan_dft_c2r)(2, n, in, out, flags);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
X(plan) X(plan_dft_c2r_3d)(int nx, int ny, int nz,
|
||||
C *in, R *out, unsigned flags)
|
||||
{
|
||||
int n[3];
|
||||
n[0] = nx;
|
||||
n[1] = ny;
|
||||
n[2] = nz;
|
||||
return X(plan_dft_c2r)(3, n, in, out, flags);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
X(plan) X(plan_dft_c2r)(int rank, const int *n, C *in, R *out, unsigned flags)
|
||||
{
|
||||
return X(plan_many_dft_c2r)(rank, n, 1,
|
||||
in, 0, 1, 1, out, 0, 1, 1, flags);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
X(plan) X(plan_dft_r2c_1d)(int n, R *in, C *out, unsigned flags)
|
||||
{
|
||||
return X(plan_dft_r2c)(1, &n, in, out, flags);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
X(plan) X(plan_dft_r2c_2d)(int nx, int ny, R *in, C *out, unsigned flags)
|
||||
{
|
||||
int n[2];
|
||||
n[0] = nx;
|
||||
n[1] = ny;
|
||||
return X(plan_dft_r2c)(2, n, in, out, flags);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
X(plan) X(plan_dft_r2c_3d)(int nx, int ny, int nz,
|
||||
R *in, C *out, unsigned flags)
|
||||
{
|
||||
int n[3];
|
||||
n[0] = nx;
|
||||
n[1] = ny;
|
||||
n[2] = nz;
|
||||
return X(plan_dft_r2c)(3, n, in, out, flags);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
X(plan) X(plan_dft_r2c)(int rank, const int *n, R *in, C *out, unsigned flags)
|
||||
{
|
||||
return X(plan_many_dft_r2c)(rank, n, 1,
|
||||
in, 0, 1, 1,
|
||||
out, 0, 1, 1,
|
||||
flags);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
|
||||
X(plan) X(plan_dft)(int rank, const int *n,
|
||||
C *in, C *out, int sign, unsigned flags)
|
||||
{
|
||||
return X(plan_many_dft)(rank, n, 1,
|
||||
in, 0, 1, 1,
|
||||
out, 0, 1, 1,
|
||||
sign, flags);
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru.h"
|
||||
#include "plan-guru-dft-c2r.h"
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
X(plan) XGURU(dft_c2r)(int rank, const IODIM *dims,
|
||||
int howmany_rank, const IODIM *howmany_dims,
|
||||
C *in, R *out, unsigned flags)
|
||||
{
|
||||
R *ri, *ii;
|
||||
|
||||
if (!GURU_KOSHERP(rank, dims, howmany_rank, howmany_dims)) return 0;
|
||||
|
||||
EXTRACT_REIM(FFT_SIGN, in, &ri, &ii);
|
||||
|
||||
if (out != ri)
|
||||
flags |= FFTW_DESTROY_INPUT;
|
||||
return X(mkapiplan)(
|
||||
0, flags,
|
||||
X(mkproblem_rdft2_d_3pointers)(
|
||||
MKTENSOR_IODIMS(rank, dims, 2, 1),
|
||||
MKTENSOR_IODIMS(howmany_rank, howmany_dims, 2, 1),
|
||||
TAINT_UNALIGNED(out, flags),
|
||||
TAINT_UNALIGNED(ri, flags),
|
||||
TAINT_UNALIGNED(ii, flags), HC2R));
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru.h"
|
||||
#include "plan-guru-dft-r2c.h"
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
X(plan) XGURU(dft_r2c)(int rank, const IODIM *dims,
|
||||
int howmany_rank,
|
||||
const IODIM *howmany_dims,
|
||||
R *in, C *out, unsigned flags)
|
||||
{
|
||||
R *ro, *io;
|
||||
|
||||
if (!GURU_KOSHERP(rank, dims, howmany_rank, howmany_dims)) return 0;
|
||||
|
||||
EXTRACT_REIM(FFT_SIGN, out, &ro, &io);
|
||||
|
||||
return X(mkapiplan)(
|
||||
0, flags,
|
||||
X(mkproblem_rdft2_d_3pointers)(
|
||||
MKTENSOR_IODIMS(rank, dims, 1, 2),
|
||||
MKTENSOR_IODIMS(howmany_rank, howmany_dims, 1, 2),
|
||||
TAINT_UNALIGNED(in, flags),
|
||||
TAINT_UNALIGNED(ro, flags),
|
||||
TAINT_UNALIGNED(io, flags), R2HC));
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru.h"
|
||||
#include "plan-guru-dft.h"
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "dft/dft.h"
|
||||
|
||||
X(plan) XGURU(dft)(int rank, const IODIM *dims,
|
||||
int howmany_rank, const IODIM *howmany_dims,
|
||||
C *in, C *out, int sign, unsigned flags)
|
||||
{
|
||||
R *ri, *ii, *ro, *io;
|
||||
|
||||
if (!GURU_KOSHERP(rank, dims, howmany_rank, howmany_dims)) return 0;
|
||||
|
||||
EXTRACT_REIM(sign, in, &ri, &ii);
|
||||
EXTRACT_REIM(sign, out, &ro, &io);
|
||||
|
||||
return X(mkapiplan)(
|
||||
sign, flags,
|
||||
X(mkproblem_dft_d)(MKTENSOR_IODIMS(rank, dims, 2, 2),
|
||||
MKTENSOR_IODIMS(howmany_rank, howmany_dims,
|
||||
2, 2),
|
||||
TAINT_UNALIGNED(ri, flags),
|
||||
TAINT_UNALIGNED(ii, flags),
|
||||
TAINT_UNALIGNED(ro, flags),
|
||||
TAINT_UNALIGNED(io, flags)));
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru.h"
|
||||
#include "plan-guru-r2r.h"
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
X(plan) XGURU(r2r)(int rank, const IODIM *dims,
|
||||
int howmany_rank,
|
||||
const IODIM *howmany_dims,
|
||||
R *in, R *out,
|
||||
const X(r2r_kind) * kind, unsigned flags)
|
||||
{
|
||||
X(plan) p;
|
||||
rdft_kind *k;
|
||||
|
||||
if (!GURU_KOSHERP(rank, dims, howmany_rank, howmany_dims)) return 0;
|
||||
|
||||
k = X(map_r2r_kind)(rank, kind);
|
||||
p = X(mkapiplan)(
|
||||
0, flags,
|
||||
X(mkproblem_rdft_d)(MKTENSOR_IODIMS(rank, dims, 1, 1),
|
||||
MKTENSOR_IODIMS(howmany_rank, howmany_dims,
|
||||
1, 1),
|
||||
TAINT_UNALIGNED(in, flags),
|
||||
TAINT_UNALIGNED(out, flags), k));
|
||||
X(ifree0)(k);
|
||||
return p;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru.h"
|
||||
#include "plan-guru-split-dft-c2r.h"
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
X(plan) XGURU(split_dft_c2r)(int rank, const IODIM *dims,
|
||||
int howmany_rank, const IODIM *howmany_dims,
|
||||
R *ri, R *ii, R *out, unsigned flags)
|
||||
{
|
||||
if (!GURU_KOSHERP(rank, dims, howmany_rank, howmany_dims)) return 0;
|
||||
|
||||
if (out != ri)
|
||||
flags |= FFTW_DESTROY_INPUT;
|
||||
return X(mkapiplan)(
|
||||
0, flags,
|
||||
X(mkproblem_rdft2_d_3pointers)(
|
||||
MKTENSOR_IODIMS(rank, dims, 1, 1),
|
||||
MKTENSOR_IODIMS(howmany_rank, howmany_dims, 1, 1),
|
||||
TAINT_UNALIGNED(out, flags),
|
||||
TAINT_UNALIGNED(ri, flags),
|
||||
TAINT_UNALIGNED(ii, flags), HC2R));
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru.h"
|
||||
#include "plan-guru-split-dft-r2c.h"
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
X(plan) XGURU(split_dft_r2c)(int rank, const IODIM *dims,
|
||||
int howmany_rank,
|
||||
const IODIM *howmany_dims,
|
||||
R *in, R *ro, R *io, unsigned flags)
|
||||
{
|
||||
if (!GURU_KOSHERP(rank, dims, howmany_rank, howmany_dims)) return 0;
|
||||
|
||||
return X(mkapiplan)(
|
||||
0, flags,
|
||||
X(mkproblem_rdft2_d_3pointers)(
|
||||
MKTENSOR_IODIMS(rank, dims, 1, 1),
|
||||
MKTENSOR_IODIMS(howmany_rank, howmany_dims, 1, 1),
|
||||
TAINT_UNALIGNED(in, flags),
|
||||
TAINT_UNALIGNED(ro, flags),
|
||||
TAINT_UNALIGNED(io, flags), R2HC));
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru.h"
|
||||
#include "plan-guru-split-dft.h"
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "dft/dft.h"
|
||||
|
||||
X(plan) XGURU(split_dft)(int rank, const IODIM *dims,
|
||||
int howmany_rank, const IODIM *howmany_dims,
|
||||
R *ri, R *ii, R *ro, R *io, unsigned flags)
|
||||
{
|
||||
if (!GURU_KOSHERP(rank, dims, howmany_rank, howmany_dims)) return 0;
|
||||
|
||||
return X(mkapiplan)(
|
||||
ii - ri == 1 && io - ro == 1 ? FFT_SIGN : -FFT_SIGN, flags,
|
||||
X(mkproblem_dft_d)(MKTENSOR_IODIMS(rank, dims, 1, 1),
|
||||
MKTENSOR_IODIMS(howmany_rank, howmany_dims,
|
||||
1, 1),
|
||||
TAINT_UNALIGNED(ri, flags),
|
||||
TAINT_UNALIGNED(ii, flags),
|
||||
TAINT_UNALIGNED(ro, flags),
|
||||
TAINT_UNALIGNED(io, flags)));
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru64.h"
|
||||
#include "plan-guru-dft-c2r.h"
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru64.h"
|
||||
#include "plan-guru-dft-r2c.h"
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru64.h"
|
||||
#include "plan-guru-dft.h"
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru64.h"
|
||||
#include "plan-guru-r2r.h"
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru64.h"
|
||||
#include "plan-guru-split-dft-c2r.h"
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru64.h"
|
||||
#include "plan-guru-split-dft-r2c.h"
|
|
@ -0,0 +1,2 @@
|
|||
#include "guru64.h"
|
||||
#include "plan-guru-split-dft.h"
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
X(plan) X(plan_many_dft_c2r)(int rank, const int *n,
|
||||
int howmany,
|
||||
C *in, const int *inembed,
|
||||
int istride, int idist,
|
||||
R *out, const int *onembed,
|
||||
int ostride, int odist, unsigned flags)
|
||||
{
|
||||
R *ri, *ii;
|
||||
int *nfi, *nfo;
|
||||
int inplace;
|
||||
X(plan) p;
|
||||
|
||||
if (!X(many_kosherp)(rank, n, howmany)) return 0;
|
||||
|
||||
EXTRACT_REIM(FFT_SIGN, in, &ri, &ii);
|
||||
inplace = out == ri;
|
||||
|
||||
if (!inplace)
|
||||
flags |= FFTW_DESTROY_INPUT;
|
||||
p = X(mkapiplan)(
|
||||
0, flags,
|
||||
X(mkproblem_rdft2_d_3pointers)(
|
||||
X(mktensor_rowmajor)(
|
||||
rank, n,
|
||||
X(rdft2_pad)(rank, n, inembed, inplace, 1, &nfi),
|
||||
X(rdft2_pad)(rank, n, onembed, inplace, 0, &nfo),
|
||||
2 * istride, ostride),
|
||||
X(mktensor_1d)(howmany, 2 * idist, odist),
|
||||
TAINT_UNALIGNED(out, flags),
|
||||
TAINT_UNALIGNED(ri, flags), TAINT_UNALIGNED(ii, flags),
|
||||
HC2R));
|
||||
|
||||
X(ifree0)(nfi);
|
||||
X(ifree0)(nfo);
|
||||
return p;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "api/api.h"
|
||||
#include "rdft/rdft.h"
|
||||
|
||||
X(plan) X(plan_many_dft_r2c)(int rank, const int *n,
|
||||
int howmany,
|
||||
R *in, const int *inembed,
|
||||
int istride, int idist,
|
||||
C *out, const int *onembed,
|
||||
int ostride, int odist, unsigned flags)
|
||||
{
|
||||
R *ro, *io;
|
||||
int *nfi, *nfo;
|
||||
int inplace;
|
||||
X(plan) p;
|
||||
|
||||
if (!X(many_kosherp)(rank, n, howmany)) return 0;
|
||||
|
||||
EXTRACT_REIM(FFT_SIGN, out, &ro, &io);
|
||||
inplace = in == ro;
|
||||
|
||||
p = X(mkapiplan)(
|
||||
0, flags,
|
||||
X(mkproblem_rdft2_d_3pointers)(
|
||||
X(mktensor_rowmajor)(
|
||||
rank, n,
|
||||
X(rdft2_pad)(rank, n, inembed, inplace, 0, &nfi),
|
||||
X(rdft2_pad)(rank, n, onembed, inplace, 1, &nfo),
|
||||
istride, 2 * ostride),
|
||||
X(mktensor_1d)(howmany, idist, 2 * odist),
|
||||
TAINT_UNALIGNED(in, flags),
|
||||
TAINT_UNALIGNED(ro, flags), TAINT_UNALIGNED(io, flags),
|
||||
R2HC));
|
||||
|
||||
X(ifree0)(nfi);
|
||||
X(ifree0)(nfo);
|
||||
return p;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue