{"id":17113058,"url":"https://github.com/emmt/xfft","last_synced_at":"2025-10-24T19:09:29.915Z","repository":{"id":71510268,"uuid":"37706969","full_name":"emmt/XFFT","owner":"emmt","description":"Enhanced and uniformized support for FFTW2 and FFTW3 in Yorick.","archived":false,"fork":false,"pushed_at":"2022-03-16T10:40:31.000Z","size":69,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-05T08:10:49.565Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emmt.png","metadata":{"files":{"readme":"README.md","changelog":"NEWS.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-06-19T06:59:41.000Z","updated_at":"2022-03-16T10:40:34.000Z","dependencies_parsed_at":"2023-04-07T12:47:03.272Z","dependency_job_id":null,"html_url":"https://github.com/emmt/XFFT","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/emmt/XFFT","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emmt%2FXFFT","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emmt%2FXFFT/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emmt%2FXFFT/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emmt%2FXFFT/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emmt","download_url":"https://codeload.github.com/emmt/XFFT/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emmt%2FXFFT/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280850528,"owners_count":26401982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-24T02:00:06.418Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T17:02:40.526Z","updated_at":"2025-10-24T19:09:29.910Z","avatar_url":"https://github.com/emmt.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"XFFT: eXtended support for the Fast Fourier Transform in Yorick\n===============================================================\n\nDescription\n-----------\n\n**XFFT** (for *eXtended Fast Fourier Transform*) is a\n[Yorick](http://github.com/LLNL/yorick/) extension to uniformely interface\nbetween various implementations of FFT (notably\n[FFTW](http://www.fftw.org), the Fastest Fourier Transform in the West,\nand, in the future, CFFT based on Swarztrauber routines) and benefit from\nmulti-threading, complex-to-real and real-to-complex transforms, etc.\n\nThe idea is to simplify the use of FFT transforms (XFFT provides direct,\ninverse, complex-to-real and real-to-complex transforms) and write the\nsame code whatever the particular FFT implementation used at runtime.\n\nNote that, for the moment, the ability of Yorick's FFT to compute the\nforward or backward transform along some (not all) directions of the input\narray are not supported by XFFT.\n\n\nInstallation\n------------\n\nIn short, building and installing the plug-in can be as quick as:\n````{.sh}\ncd $BUILD_DIR\n$SRC_DIR/configure\nmake\nmake install\n````\nwhere `$BUILD_DIR` is the build directory (at your convenience) and\n`$SRC_DIR` is the source directory of the plug-in code.  The build and\nsource directories can be the same in which case, call `./configure` to\nconfigure for building.\n\nIf the plug-in has been properly installed, it is sufficient to use any\nof its functions (like `xfft_new`) to automatically load the plug-in.\nYou may force the loading of the plug-in by something like:\n````{.cpp}\n#include \"xfft.i\"\n````\nor\n````{.cpp}\nrequire, \"xfft.i\";\n````\nin your code.\n\nMore detailled installation explanations are given below.\n\n\n0. You must have [Yorick](http://github.com/LLNL/yorick/) installed on your\n   machine and the various FFT libraries.\n\n1. Unpack the plug-in code somewhere.\n\n2. Configure for compilation.  There are two possibilities:\n\n   * For an **in-place build**, go to the source directory of the plug-in \n     code and run the configuration script:\n     ````{.sh}\n     cd $SRC_DIR\n     ./configure\n     ````\n     To see the configuration options, call:\n     ````{.sh}\n     ./configure --help\n     ````\n\t See below for more informations about the options.\n\n   * To compile in a **different build directory**, say `$BUILD_DIR`, create\n     the build directory, go to the build directory and run the\n     configuration script:\n     ````{.sh}\n     mkdir -p $BUILD_DIR\n     cd $BUILD_DIR\n     $SRC_DIR/configure\n     ````\n     where `$SRC_DIR` is the path to the source directory of the plug-in code.\n     To see the configuration options, call:\n     ````{.sh}\n     $SRC_DIR/configure --help\n     ````\n\t See below for more informations about the options.\n\n3. Compile the code:\n   ````{.sh}\n   make clean\n   make\n   ````\n\n4. Install the plug-in in Yorick directories:\n   ````{.sh}\n   make install\n   ````\n\n\nConfiguration Options\n---------------------\n\nThe configuration is the opportunity to specify which implementation(s) of\nFFT you want to use and the corresponding compilation flags and libraries.\nYou may specify as many implementations as you want (this will result in\nseveral different plugins) providing you have the corresponding libraries\n(and header files).  The possibilities are:\n```\n    fftw2           - FFTW version 2\n    fftw2-threads   - FFTW version 2 with multi-threading\n    fftw3           - FFTW version 3\n    fftw3-threads   - FFTW version 3 with multi-threading\n```\nIn the future, the following front-ends will be implemented:\n```\n    cfft            - Swarztrauber FFT routines\n    mkl             - FFTW from the Math kernel Library with multi-threading\n    mkl-threads     - FFTW from the Math kernel Library with multi-threading\n```\nCFFT implementation uses Swarztrauber FFT routines already compiled in Yorick\nso this one should be always available.\n\nFor each specific implementation, say `IMPL`, the configuration can be done\nvia options of the `configure` script:\n\n* `--with-IMPL` or `--with-IMPL=yes` to compile support for `IMPL`.\n\n* `--without-IMPL` or `--with-IMPL=no` to not compile support for `IMPL`.\n\n* `--IMPL-cflags=...` for additional compiler (or preprocessor) flags.\n\n* `--IMPL-ldflags=...` for additional linker flags.\n\n* `--IMPL-deplibs=...` for additional libraries.\n\nFor instance, the default configuration settings correspond to:\n```sh\n    configure \\\n      --with-fftw2=yes \\\n      --fftw2-cflags=\"\" \\\n      --fftw2-ldflags=\"\" \\\n      --fftw2-deplibs=\"-lrfftw -lfftw\" \\\n      --with-fftw2-threads=yes \\\n      --fftw2-threads-cflags=\"\" \\\n\t  --fftw2-threads-ldflags=\"\" \\\n      --fftw2-threads-deplibs=\"-lrfftw_threads -lfftw_threads -lrfftw -lfftw -lpthread\" \\\n      --with-fftw3=yes \\\n      --fftw3-cflags=\"\" \\\n      --fftw3-ldflags=\"\" \\\n      --fftw3-deplibs=\"-lfftw3\" \\\n      --with-fftw3-threads=yes \\\n      --fftw3-threads-cflags=\"\" \\\n      --fftw3-threads-ldflags=\"\" \\\n      --fftw3-threads-deplibs=\"-lfftw3_threads -lfftw3 -lpthread\"\n```\n\n\nImplementation\n--------------\n\nFFT transforms are implemented by XFFT in Yorick as special objects which\nbehave as functions to compute the forward or backward transforms and which\ntake care themself of all the housekeeping with (de-)allocation of required\nFFTW plans and workspaces.  These ressources are only allocated once and only\nwhen required.  That is, assuming you have compiled XFFT to use FFTW to\ncompute the transforms, if you create an XFFT object and only compute forward\nFFT with it, it will never create a FFTW plan for backward transform.  The\ndrawback of this hiding is that an XFFT object can only be used for a given\ndimension list of the arrays to transform, similarly XFFT objects for\nreal-complex and complex-complex transforms must be different (even if they\napply to arrays of same dimensions).  However the same XFFT object can be used\nfor forward and backward transform.  For instance:\n```\n    f = xfft_new();          // create a new XFFT object with default options\n    z = f(a);                // compute the forward transform of A\n    z = f(a, XFFT_FORWARD);  // idem\n    b = f(z, XFFT_BACKWARD); // compute the backward transform of Z\n    f, a, job;               // in-place transform, optional job is\n                             // XFFT_FORWARD, or XFFT_BACKWARD, etc.\n    f = [];                  // destroys the XFFT object (and release\n                             // ressources)\n```\nThe main difference between FFTW2 and FFTW3 is that FFTW3 makes use of\nworkspaces that are properly aligned to boost the performances (e.g., by\nusing\n[SIMD]'https://fr.wikipedia.org/wiki/Single_instruction_multiple_data)\ninstructions).  Each FFTW3 plan is aware of its input and output workspaces\n(which can be the same for an in-place transform).  This is why each FFTW\nobject owns its workspaces (though they are the same for the forward and\nbackward plans of complex transforms).  In the interfacing with Yorick,\ninput array must be copied into the input workspace, then the FFT is\ncomputed, then the output workspace is copied into the output Yorick array.\nThese copy operations have a slight impact on the performances but\ndestroying the contents of the input workspace in FFTW transform is not an\nissue.  For 1-D transforms, the out-of-place transform is slighlty faster\nthan the in-place one.  For N-D transforms (N \u003e 1), the performances are\nvery similar or better for the in-place transforms.  To save memory without\nsacrificing performances, FFTW objects use out-of-place transform for 1-D\ndata and in-place transform otherwise.\n\nC2R destroys its input even for out-of-place transform (unless in 1D and if\nflag `FFTW_PRESERVE_INPUT` is set, but this yields to some sacrifice of\nperformance, therefore I always consider that input is not preserved).\n\nThe same interface is implemented for FFTW2 and FFTW3 (and will perhaps be\nimplemented for Swarztrauber's FFT which is built into Yorick).  However,\nbecause some symbols have the same names in the two libraries, the two plugins\ncannot be loaded in the same Yorick session.  The recommended way to load FFTW\nplugin is:\n```C\n   #include \"xfft.i\"\n```\nwhich will load FFTW3 if possible and FFTW2 otherwise, *etc.*  Thanks to the\n`autoload` comman of Yorick, this should be automatically done as soon as\nyou use one of the XFFT functions.  To explicitly use FFTW2:\n```C\n   #include \"xfft_fftw2.i\"\n```\nand to explicitly use FFTW3 with threads:\n```C\n   #include \"xfft_fftw3_threads.i\"\n```\n\nExample of use:\n```C\n   f = xfft_new();\n   input = array(double, f.dims);\n   if (f.real) {\n      // Real-complex transform.\n      dims = f.dims;\n      dims(2) = dims(2)/2 + 1;\n   } else {\n      // Complex-complex transform.\n      dims = f.dims;\n   }\n   output = array(complex, dims);\n```\n\n\nDimension List\n--------------\n\n\u003e Following Yorick conventions, dimensions are given here in column major\n\u003e format, the first array index varies most rapidly; however beware that\n\u003e FFTW documentation is for row major format.\n\nFor complex-complex transforms, input and output arrays have the same\ndimensions whether the transform is done in-place or not.  Input and\noutput workspaces can be the same that is array(s) of `N1 x N2 x ... x Nd`\ncomplex values.\n\nFor real-complex transforms, the real array is `N1 x N2 x ... x Nd` whereas\nthe complex array is Hermitian and of size `(N1/2 + 1) x N2 x ... x Nd`.  For\nout-of-place transforms, the workspace for the real array must be at least\n`N1 x N2 x ... x Nd` real data, the workspace for the complex array must be\nat least `(N1/2 + 1) x N2 x ... x Nd` complex data.  For in-place transforms,\nthe single workspace must be large enough to store the real or the complex\narray, that is: `2*(N1/2 + 1) x N2 x ... x Nd` real data.\n\n\nChoosing a Specific Implementation\n----------------------------------\n\nIf you want to use a specific FFT implementation, directly include the\ncorresponding library file, for instance:\n```C\n    #include \"xfft_fftw2_threads.i\"\n```\nto use FFTW (version 2) with multi-threading.  By default, when you include\n\"xfft.i\" the first time, it tries to load a multi-threaded version and by\nprefrence FFTW (version 3).  Thus the order of preference is:\n```C\n    mkl_threads     - FFTW from the Math kernel Library with multi-threading\n    fftw3_threads   - FFTW version 3 with multi-threading\n    fftw2_threads   - FFTW version 2 with multi-threading\n    mkl             - FFTW from the Math kernel Library with multi-threading\n    fftw3           - FFTW version 3\n    fftw2           - FFTW version 2\n    cfft            - Swarztrauber FFT routines\n```\nSome provisions have been made to allow for different implementations of the\nFFT to co-exist in a Yorick session but this is not always possible.  For\ninstance, FFTW 2 and 3 cannot be safely loaded at the same time.\n\nIf multiple implementations are loaded, `fftw_new` will create an FFT transform\nobject which uses the last implementation that have nee loaded.  To choose a\nspecific implementation, then use:\n```C\n    op = _xfft_IMPL_new(...)\n```\nwith `IMPL` the name of the implementation (e.g., `fftw2_threads`) to create an\nobject which uses FFTW (version 2) with multi-threading.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femmt%2Fxfft","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femmt%2Fxfft","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femmt%2Fxfft/lists"}