CINXE.COM
cuFFT
<!DOCTYPE html> <html class="writer-html5" lang="en" > <head> <meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" /> <meta content="The API reference guide for cuFFT, the CUDA Fast Fourier Transform library." name="description" /> <meta content="CUDA cuFFT, CUDA cuFFT features, CUDA cuFFT data, CUDA cuFFT layout, CUDA cuFFT performance, CUDA cuFFT API, CUDA cuFFT library, CUDA cuFFT example, CUDA cuFFT transforms, CUDA cuFFT multidimensional transforms" name="keywords" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>cuFFT</title> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <link rel="stylesheet" href="../_static/css/theme.css" type="text/css" /> <link rel="stylesheet" href="../_static/copybutton.css" type="text/css" /> <link rel="stylesheet" href="../_static/design-style.b7bb847fb20b106c3d81b95245e65545.min.css" type="text/css" /> <link rel="stylesheet" href="../_static/omni-style.css" type="text/css" /> <link rel="stylesheet" href="../_static/api-styles.css" type="text/css" /> <link rel="shortcut icon" href="../_static/favicon.ico"/> <!--[if lt IE 9]> <script src="../_static/js/html5shiv.min.js"></script> <![endif]--> <script data-url_root="./" id="documentation_options" src="../_static/documentation_options.js"></script> <script src="../_static/jquery.js"></script> <script src="../_static/underscore.js"></script> <script src="../_static/doctools.js"></script> <script src="../_static/mermaid-init.js"></script> <script src="../_static/clipboard.min.js"></script> <script src="../_static/copybutton.js"></script> <script src="../_static/design-tabs.js"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="../_static/geoip/geoip.js"></script> <script src="../_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> <link rel="prev" title="Contents" href="contents.html" /> <script src="//assets.adobedtm.com/5d4962a43b79/c1061d2c5e7b/launch-191c2462b890.min.js"></script> </head> <body class="wy-body-for-nav"> <div class="wy-grid-for-nav"> <nav data-toggle="wy-nav-shift" class="wy-nav-side"> <div class="wy-side-scroll"> <div class="wy-side-nav-search" > <a href="contents.html"> <img src="../_static/Logo_and_CUDA.png" class="logo" alt="Logo"/> </a> <div role="search"> <form id="rtd-search-form" class="wy-form" action="search.html" method="get"> <input type="text" name="q" placeholder="Search docs" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> <ul class="current"> <li class="toctree-l1 current"><a class="current reference internal" href="#">1. Introduction</a></li> <li class="toctree-l1"><a class="reference internal" href="#using-the-cufft-api">2. Using the cuFFT API</a><ul> <li class="toctree-l2"><a class="reference internal" href="#accessing-cufft">2.1. Accessing cuFFT</a></li> <li class="toctree-l2"><a class="reference internal" href="#fourier-transform-setup">2.2. Fourier Transform Setup</a><ul> <li class="toctree-l3"><a class="reference internal" href="#free-memory-requirement">2.2.1. Free Memory Requirement</a></li> <li class="toctree-l3"><a class="reference internal" href="#plan-initialization-time">2.2.2. Plan Initialization Time</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#fourier-transform-types">2.3. Fourier Transform Types</a><ul> <li class="toctree-l3"><a class="reference internal" href="#half-precision-cufft-transforms">2.3.1. Half-precision cuFFT Transforms</a></li> <li class="toctree-l3"><a class="reference internal" href="#bfloat16-precision-cufft-transforms">2.3.2. Bfloat16-precision cuFFT Transforms</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#data-layout">2.4. Data Layout</a></li> <li class="toctree-l2"><a class="reference internal" href="#multidimensional-transforms">2.5. Multidimensional Transforms</a></li> <li class="toctree-l2"><a class="reference internal" href="#advanced-data-layout">2.6. Advanced Data Layout</a></li> <li class="toctree-l2"><a class="reference internal" href="#streamed-cufft-transforms">2.7. Streamed cuFFT Transforms</a></li> <li class="toctree-l2"><a class="reference internal" href="#multiple-gpu-cufft-transforms">2.8. Multiple GPU cuFFT Transforms</a><ul> <li class="toctree-l3"><a class="reference internal" href="#plan-specification-and-work-areas">2.8.1. Plan Specification and Work Areas</a></li> <li class="toctree-l3"><a class="reference internal" href="#helper-functions">2.8.2. Helper Functions</a></li> <li class="toctree-l3"><a class="reference internal" href="#multiple-gpu-2d-and-3d-transforms-on-permuted-input">2.8.3. Multiple GPU 2D and 3D Transforms on Permuted Input</a></li> <li class="toctree-l3"><a class="reference internal" href="#supported-functionality">2.8.4. Supported Functionality</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#cufft-callback-routines">2.9. cuFFT Callback Routines</a><ul> <li class="toctree-l3"><a class="reference internal" href="#overview-of-the-cufft-callback-routine-feature">2.9.1. Overview of the cuFFT Callback Routine Feature</a></li> <li class="toctree-l3"><a class="reference internal" href="#lto-load-and-store-callback-routines">2.9.2. LTO Load and Store Callback Routines</a><ul> <li class="toctree-l4"><a class="reference internal" href="#specifying-lto-load-and-store-callback-routines">2.9.2.1. Specifying LTO Load and Store Callback Routines</a></li> <li class="toctree-l4"><a class="reference internal" href="#lto-callback-routine-function-details">2.9.2.2. LTO Callback Routine Function Details</a></li> </ul> </li> <li class="toctree-l3"><a class="reference internal" href="#legacy-load-and-store-callback-routines">2.9.3. Legacy Load and Store Callback Routines</a><ul> <li class="toctree-l4"><a class="reference internal" href="#specifying-legacy-load-and-store-callback-routines">2.9.3.1. Specifying Legacy Load and Store Callback Routines</a></li> <li class="toctree-l4"><a class="reference internal" href="#legacy-callback-routine-function-details">2.9.3.2. Legacy Callback Routine Function Details</a></li> </ul> </li> <li class="toctree-l3"><a class="reference internal" href="#coding-considerations-for-the-cufft-callback-routine-feature">2.9.4. Coding Considerations for the cuFFT Callback Routine Feature</a><ul> <li class="toctree-l4"><a class="reference internal" href="#coding-considerations-for-lto-callback-routines">2.9.4.1. Coding Considerations for LTO Callback Routines</a></li> <li class="toctree-l4"><a class="reference internal" href="#coding-considerations-for-legacy-callback-routines">2.9.4.2. Coding Considerations for Legacy Callback Routines</a></li> </ul> </li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#thread-safety">2.10. Thread Safety</a></li> <li class="toctree-l2"><a class="reference internal" href="#cuda-graphs-support">2.11. CUDA Graphs Support</a></li> <li class="toctree-l2"><a class="reference internal" href="#static-library-and-callback-support">2.12. Static Library and Callback Support</a><ul> <li class="toctree-l3"><a class="reference internal" href="#static-library-without-legacy-callback-support">2.12.1. Static library without legacy callback support</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#accuracy-and-performance">2.13. Accuracy and Performance</a></li> <li class="toctree-l2"><a class="reference internal" href="#caller-allocated-work-area-support">2.14. Caller Allocated Work Area Support</a></li> <li class="toctree-l2"><a class="reference internal" href="#cufft-link-time-optimized-kernels">2.15. cuFFT Link-Time Optimized Kernels</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="#cufft-api-reference">3. cuFFT API Reference</a><ul> <li class="toctree-l2"><a class="reference internal" href="#return-value-cufftresult">3.1. Return value cufftResult</a></li> <li class="toctree-l2"><a class="reference internal" href="#cufft-basic-plans">3.2. cuFFT Basic Plans</a><ul> <li class="toctree-l3"><a class="reference internal" href="#cufftplan1d">3.2.1. cufftPlan1d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftplan2d">3.2.2. cufftPlan2d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftplan3d">3.2.3. cufftPlan3d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftplanmany">3.2.4. cufftPlanMany()</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#cufft-extensible-plans">3.3. cuFFT Extensible Plans</a><ul> <li class="toctree-l3"><a class="reference internal" href="#cufftcreate">3.3.1. cufftCreate()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftdestroy">3.3.2. cufftDestroy()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftmakeplan1d">3.3.3. cufftMakePlan1d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftmakeplan2d">3.3.4. cufftMakePlan2d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftmakeplan3d">3.3.5. cufftMakePlan3d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftmakeplanmany">3.3.6. cufftMakePlanMany()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftmakeplanmany64">3.3.7. cufftMakePlanMany64()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftxtmakeplanmany">3.3.8. cufftXtMakePlanMany()</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#cufft-plan-properties">3.4. cuFFT Plan Properties</a><ul> <li class="toctree-l3"><a class="reference internal" href="#cufftsetplanpropertyint64">3.4.1. cufftSetPlanPropertyInt64()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftgetplanpropertyint64">3.4.2. cufftGetPlanPropertyInt64()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftresetplanproperty">3.4.3. cufftResetPlanProperty()</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#cufft-estimated-size-of-work-area">3.5. cuFFT Estimated Size of Work Area</a><ul> <li class="toctree-l3"><a class="reference internal" href="#cufftestimate1d">3.5.1. cufftEstimate1d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftestimate2d">3.5.2. cufftEstimate2d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftestimate3d">3.5.3. cufftEstimate3d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftestimatemany">3.5.4. cufftEstimateMany()</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#cufft-refined-estimated-size-of-work-area">3.6. cuFFT Refined Estimated Size of Work Area</a><ul> <li class="toctree-l3"><a class="reference internal" href="#cufftgetsize1d">3.6.1. cufftGetSize1d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftgetsize2d">3.6.2. cufftGetSize2d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftgetsize3d">3.6.3. cufftGetSize3d()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftgetsizemany">3.6.4. cufftGetSizeMany()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftgetsizemany64">3.6.5. cufftGetSizeMany64()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftxtgetsizemany">3.6.6. cufftXtGetSizeMany()</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#cufftgetsize">3.7. cufftGetSize()</a></li> <li class="toctree-l2"><a class="reference internal" href="#cufft-caller-allocated-work-area-support">3.8. cuFFT Caller Allocated Work Area Support</a><ul> <li class="toctree-l3"><a class="reference internal" href="#cufftsetautoallocation">3.8.1. cufftSetAutoAllocation()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftsetworkarea">3.8.2. cufftSetWorkArea()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftxtsetworkareapolicy">3.8.3. cufftXtSetWorkAreaPolicy()</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#cufft-execution">3.9. cuFFT Execution</a><ul> <li class="toctree-l3"><a class="reference internal" href="#cufftexecc2c-and-cufftexecz2z">3.9.1. cufftExecC2C() and cufftExecZ2Z()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftexecr2c-and-cufftexecd2z">3.9.2. cufftExecR2C() and cufftExecD2Z()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftexecc2r-and-cufftexecz2d">3.9.3. cufftExecC2R() and cufftExecZ2D()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftxtexec">3.9.4. cufftXtExec()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftxtexecdescriptor">3.9.5. cufftXtExecDescriptor()</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#cufft-and-multiple-gpus">3.10. cuFFT and Multiple GPUs</a><ul> <li class="toctree-l3"><a class="reference internal" href="#cufftxtsetgpus">3.10.1. cufftXtSetGPUs()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftxtsetworkarea">3.10.2. cufftXtSetWorkArea()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufft-multiple-gpu-execution">3.10.3. cuFFT Multiple GPU Execution</a><ul> <li class="toctree-l4"><a class="reference internal" href="#cufftxtexecdescriptorc2c-and-cufftxtexecdescriptorz2z">3.10.3.1. cufftXtExecDescriptorC2C() and cufftXtExecDescriptorZ2Z()</a></li> <li class="toctree-l4"><a class="reference internal" href="#cufftxtexecdescriptorr2c-and-cufftxtexecdescriptord2z">3.10.3.2. cufftXtExecDescriptorR2C() and cufftXtExecDescriptorD2Z()</a></li> <li class="toctree-l4"><a class="reference internal" href="#cufftxtexecdescriptorc2r-and-cufftxtexecdescriptorz2d">3.10.3.3. cufftXtExecDescriptorC2R() and cufftXtExecDescriptorZ2D()</a></li> </ul> </li> <li class="toctree-l3"><a class="reference internal" href="#memory-allocation-and-data-movement-functions">3.10.4. Memory Allocation and Data Movement Functions</a><ul> <li class="toctree-l4"><a class="reference internal" href="#cufftxtmalloc">3.10.4.1. cufftXtMalloc()</a><ul> <li class="toctree-l5"><a class="reference internal" href="#parameter-cufftxtsubformat">3.10.4.1.1. Parameter cufftXtSubFormat</a></li> </ul> </li> <li class="toctree-l4"><a class="reference internal" href="#cufftxtfree">3.10.4.2. cufftXtFree()</a></li> <li class="toctree-l4"><a class="reference internal" href="#cufftxtmemcpy">3.10.4.3. cufftXtMemcpy()</a><ul> <li class="toctree-l5"><a class="reference internal" href="#parameter-cufftxtcopytype">3.10.4.3.1. Parameter cufftXtCopyType</a></li> </ul> </li> </ul> </li> <li class="toctree-l3"><a class="reference internal" href="#general-multiple-gpu-descriptor-types">3.10.5. General Multiple GPU Descriptor Types</a><ul> <li class="toctree-l4"><a class="reference internal" href="#cudaxtdesc">3.10.5.1. cudaXtDesc</a></li> <li class="toctree-l4"><a class="reference internal" href="#cudalibxtdesc">3.10.5.2. cudaLibXtDesc</a></li> </ul> </li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#cufft-callbacks">3.11. cuFFT Callbacks</a><ul> <li class="toctree-l3"><a class="reference internal" href="#cufftxtsetjitcallback">3.11.1. cufftXtSetJITCallback()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftxtsetcallback">3.11.2. cufftXtSetCallback()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftxtclearcallback">3.11.3. cufftXtClearCallback()</a></li> <li class="toctree-l3"><a class="reference internal" href="#cufftxtsetcallbacksharedsize">3.11.4. cufftXtSetCallbackSharedSize()</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#cufftsetstream">3.12. cufftSetStream()</a></li> <li class="toctree-l2"><a class="reference internal" href="#cufftgetversion">3.13. cufftGetVersion()</a></li> <li class="toctree-l2"><a class="reference internal" href="#cufftgetproperty">3.14. cufftGetProperty()</a></li> <li class="toctree-l2"><a class="reference internal" href="#cufft-types">3.15. cuFFT Types</a><ul> <li class="toctree-l3"><a class="reference internal" href="#parameter-cuffttype">3.15.1. Parameter cufftType</a></li> <li class="toctree-l3"><a class="reference internal" href="#parameters-for-transform-direction">3.15.2. Parameters for Transform Direction</a></li> <li class="toctree-l3"><a class="reference internal" href="#type-definitions-for-callbacks">3.15.3. Type definitions for callbacks</a><ul> <li class="toctree-l4"><a class="reference internal" href="#type-definitions-for-lto-callbacks">3.15.3.1. Type definitions for LTO callbacks</a></li> <li class="toctree-l4"><a class="reference internal" href="#type-definitions-for-legacy-callbacks">3.15.3.2. Type definitions for legacy callbacks</a></li> </ul> </li> <li class="toctree-l3"><a class="reference internal" href="#other-cufft-types">3.15.4. Other cuFFT Types</a><ul> <li class="toctree-l4"><a class="reference internal" href="#cuffthandle">3.15.4.1. cufftHandle</a></li> <li class="toctree-l4"><a class="reference internal" href="#cufftreal">3.15.4.2. cufftReal</a></li> <li class="toctree-l4"><a class="reference internal" href="#cufftdoublereal">3.15.4.3. cufftDoubleReal</a></li> <li class="toctree-l4"><a class="reference internal" href="#cufftcomplex">3.15.4.4. cufftComplex</a></li> <li class="toctree-l4"><a class="reference internal" href="#cufftdoublecomplex">3.15.4.5. cufftDoubleComplex</a></li> </ul> </li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#common-types">3.16. Common types</a><ul> <li class="toctree-l3"><a class="reference internal" href="#cudadatatype">3.16.1. cudaDataType</a></li> <li class="toctree-l3"><a class="reference internal" href="#librarypropertytype">3.16.2. libraryPropertyType</a></li> </ul> </li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="#multiple-gpu-data-organization">4. Multiple GPU Data Organization</a><ul> <li class="toctree-l2"><a class="reference internal" href="#multiple-gpu-data-organization-for-batched-transforms">4.1. Multiple GPU Data Organization for Batched Transforms</a></li> <li class="toctree-l2"><a class="reference internal" href="#multiple-gpu-data-organization-for-single-2d-and-3d-transforms">4.2. Multiple GPU Data Organization for Single 2D and 3D Transforms</a></li> <li class="toctree-l2"><a class="reference internal" href="#multiple-gpu-data-organization-for-single-1d-transforms">4.3. Multiple-GPU Data Organization for Single 1D Transforms</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="#fftw-conversion-guide">5. FFTW Conversion Guide</a></li> <li class="toctree-l1"><a class="reference internal" href="#fftw-interface-to-cufft">6. FFTW Interface to cuFFT</a></li> <li class="toctree-l1"><a class="reference internal" href="#deprecated-functionality">7. Deprecated Functionality</a></li> <li class="toctree-l1"><a class="reference internal" href="#notices">8. Notices</a><ul> <li class="toctree-l2"><a class="reference internal" href="#notice">8.1. Notice</a></li> <li class="toctree-l2"><a class="reference internal" href="#opencl">8.2. OpenCL</a></li> <li class="toctree-l2"><a class="reference internal" href="#trademarks">8.3. Trademarks</a></li> </ul> </li> </ul> </div> </div> </nav> <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > <i data-toggle="wy-nav-top" class="fa fa-bars"></i> <a href="contents.html">cuFFT</a> </nav> <div class="wy-nav-content"> <div class="rst-content"> <div role="navigation" aria-label="Page navigation"> <ul class="wy-breadcrumbs"> <li><a href="../index.html" class="icon icon-home"></a> »</li> <li><span class="section-number">1. </span>Introduction</li> <li class="wy-breadcrumbs-aside"> </li> <li class="wy-breadcrumbs-aside"> <span>v12.6 |</span> <a href="../pdf/CUFFT_Library.pdf" class="reference external">PDF</a> <span>|</span> <a href="https://developer.nvidia.com/cuda-toolkit-archive" class="reference external">Archive</a> <span> </span> </li> </ul> <hr/> </div> <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> <div itemprop="articleBody"> <p class="rubric-h1 rubric">cuFFT API Reference</p> <p>The API reference guide for cuFFT, the CUDA Fast Fourier Transform library.</p> <section id="introduction"> <h1><span class="section-number">1. </span>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h1> <p><strong>cuFFT Release Notes</strong>: <a class="reference external" href="https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cufft-library">CUDA Toolkit Release Notes</a></p> <p><strong>cuFFT GitHub Samples</strong>: <a class="reference external" href="https://github.com/NVIDIA/CUDALibrarySamples/tree/master/cuFFT">CUDA Library Samples</a></p> <p><strong>Nvidia Developer Forum</strong>: <a class="reference external" href="https://forums.developer.nvidia.com/c/accelerated-computing/gpu-accelerated-libraries/">GPU-Accelerated Libraries</a></p> <p><strong>Provide Feedback</strong>: <a class="reference external" href="mailto:Math-Libs-Feedback%40nvidia.com?subject=cuFFT-Feedback">Math-Libs-Feedback<span>@</span>nvidia<span>.</span>com</a></p> <p><strong>Related FFT Libraries</strong>:</p> <ul class="simple"> <li><p><a class="reference external" href="https://docs.nvidia.com/hpc-sdk/cufftmp/">cuFFTMP</a></p></li> <li><p><a class="reference external" href="https://docs.nvidia.com/cuda/cufftdx/index.html">cuFFTDx</a></p></li> <li><p><a class="reference external" href="https://docs.nvidia.com/cuda/cufft/ltoea/index.html">cuFFT LTO EA (DEPRECATED)</a></p></li> <li><p><a class="reference external" href="https://docs.nvidia.com/nvpl/_static/fft/index.html">NVPL FFT</a></p></li> </ul> <p><strong>Relevant cuFFT Blog Posts and GTC presentations</strong>:</p> <ul class="simple"> <li><p><a class="reference external" href="https://developer.nvidia.com/blog/accelerating-gpu-applications-with-nvidia-math-libraries/">Accelerating GPU Applications with NVIDIA Math Libraries</a></p></li> <li><p><a class="reference external" href="https://developer.nvidia.com/blog/multinode-multi-gpu-using-nvidia-cufftmp-ffts-at-scale/">Multinode Multi-GPU: Using NVIDIA cuFFTMp FFTs at Scale</a></p></li> <li><p><a class="reference external" href="https://developer.nvidia.com/blog/building-high-performance-applications-in-the-era-of-accelerated-computing/">New Asynchronous Programming Model Library Now Available with NVIDIA HPC SDK v22.11</a></p></li> <li><p><a class="reference external" href="https://www.nvidia.com/en-us/on-demand/session/gtcfall21-a31155/?playlistId=playList-ead11304-9931-4e91-9d5a-fb0e1ef27014">Just-In-Time Link-Time Optimization Adoption in cuSPARSE/cuFFT: Use Case Overview</a></p></li> </ul> <p>This document describes cuFFT, the NVIDIA® CUDA® Fast Fourier Transform (FFT) product. It consists of two separate libraries: cuFFT and cuFFTW. The cuFFT library is designed to provide high performance on NVIDIA GPUs. The cuFFTW library is provided as a porting tool to enable users of FFTW to start using NVIDIA GPUs with a minimum amount of effort.</p> <p>The FFT is a divide-and-conquer algorithm for efficiently computing discrete Fourier transforms of complex or real-valued data sets. It is one of the most important and widely used numerical algorithms in computational physics and general signal processing. The cuFFT library provides a simple interface for computing FFTs on an NVIDIA GPU, which allows users to quickly leverage the floating-point power and parallelism of the GPU in a highly optimized and tested FFT library.</p> <p>The cuFFT product supports a wide range of FFT inputs and options efficiently on NVIDIA GPUs. This version of the cuFFT library supports the following features:</p> <ul class="simple"> <li><p>Algorithms highly optimized for input sizes that can be written in the form <span class="math notranslate nohighlight">\(2^{a} \times 3^{b} \times 5^{c} \times 7^{d}\)</span>. In general the smaller the prime factor, the better the performance, i.e., powers of two are fastest.</p></li> <li><p>An <span class="math notranslate nohighlight">\(O\left( n\log n \right)\)</span> algorithm for every input data size</p></li> <li><p>Half-precision (16-bit floating point), single-precision (32-bit floating point) and double-precision (64-bit floating point). Transforms of lower precision have higher performance.</p></li> <li><p>Complex and real-valued input and output. Real valued input or output require less computations and data than complex values and often have faster time to solution. Types supported are:</p> <ul> <li><p>C2C - Complex input to complex output</p></li> <li><p>R2C - Real input to complex output</p></li> <li><p>C2R - Symmetric complex input to real output</p></li> </ul> </li> <li><p>1D, 2D and 3D transforms</p></li> <li><p>Execution of multiple 1D, 2D and 3D transforms simultaneously. These batched transforms have higher performance than single transforms.</p></li> <li><p>In-place and out-of-place transforms</p></li> <li><p>Arbitrary intra- and inter-dimension element strides (strided layout)</p></li> <li><p>FFTW compatible data layout</p></li> <li><p>Execution of transforms across multiple GPUs</p></li> <li><p>Streamed execution, enabling asynchronous computation and data movement</p></li> </ul> <p>The cuFFTW library provides the FFTW3 API to facilitate porting of existing FFTW applications.</p> <p>Please note that starting from CUDA 11.0, the minimum supported GPU architecture is SM35. See <a class="reference external" href="index.html#deprecated-functionality">Deprecated Functionality</a>.</p> <blockquote> <div></div></blockquote> </section> <section id="using-the-cufft-api"> <h1><span class="section-number">2. </span>Using the cuFFT API<a class="headerlink" href="#using-the-cufft-api" title="Permalink to this headline"></a></h1> <p>This chapter provides a general overview of the cuFFT library API. For more complete information on specific functions, see <a class="reference external" href="index.html#cufft-api-reference">cuFFT API Reference</a>. Users are encouraged to read this chapter before continuing with more detailed descriptions.</p> <p>The Discrete Fourier transform (DFT) maps a complex-valued vector <span class="math notranslate nohighlight">\(x_{k}\)</span> (<em>time domain</em>) into its <em>frequency domain representation</em> given by:</p> <table class="table-no-stripes docutils align-default"> <colgroup> <col style="width: 100%" /> </colgroup> <tbody> <tr class="row-odd"><td><p><span class="math notranslate nohighlight">\(X_{k} = \sum\limits_{n = 0}^{N - 1}x_{n}e^{-2\pi i\frac{kn}{N}}\)</span></p></td> </tr> </tbody> </table> <p>where <span class="math notranslate nohighlight">\(X_{k}\)</span> is a complex-valued vector of the same size. This is known as a <em>forward</em> DFT. If the sign on the exponent of e is changed to be positive, the transform is an <em>inverse</em> transform. Depending on <span class="math notranslate nohighlight">\(N\)</span>, different algorithms are deployed for the best performance.</p> <p>The cuFFT API is modeled after <a class="reference external" href="http://www.fftw.org">FFTW</a>, which is one of the most popular and efficient CPU-based FFT libraries. cuFFT provides a simple configuration mechanism called a <em>plan</em> that uses internal building blocks to optimize the transform for the given configuration and the particular GPU hardware selected. Then, when the <em>execution</em> function is called, the actual transform takes place following the plan of execution. The advantage of this approach is that once the user creates a plan, the library retains whatever state is needed to execute the plan multiple times without recalculation of the configuration. This model works well for cuFFT because different kinds of FFTs require different thread configurations and GPU resources, and the plan interface provides a simple way of reusing configurations.</p> <p>Computing a number <code class="docutils literal notranslate"><span class="pre">BATCH</span></code> of one-dimensional DFTs of size <code class="docutils literal notranslate"><span class="pre">NX</span></code> using cuFFT will typically look like this:</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cp">#define NX 256</span> <span class="cp">#define BATCH 10</span> <span class="cp">#define RANK 1</span> <span class="p">...</span><span class="w"></span> <span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">cufftHandle</span><span class="w"> </span><span class="n">plan</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">cufftComplex</span><span class="w"> </span><span class="o">*</span><span class="n">data</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">...</span><span class="w"></span> <span class="w"> </span><span class="n">cudaMalloc</span><span class="p">((</span><span class="kt">void</span><span class="o">**</span><span class="p">)</span><span class="o">&</span><span class="n">data</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">cufftComplex</span><span class="p">)</span><span class="o">*</span><span class="n">NX</span><span class="o">*</span><span class="n">BATCH</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="n">cufftPlanMany</span><span class="p">(</span><span class="o">&</span><span class="n">plan</span><span class="p">,</span><span class="w"> </span><span class="n">RANK</span><span class="p">,</span><span class="w"> </span><span class="n">NX</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">iembed</span><span class="p">,</span><span class="w"> </span><span class="n">istride</span><span class="p">,</span><span class="w"> </span><span class="n">idist</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="o">&</span><span class="n">oembed</span><span class="p">,</span><span class="w"> </span><span class="n">ostride</span><span class="p">,</span><span class="w"> </span><span class="n">odist</span><span class="p">,</span><span class="w"> </span><span class="n">CUFFT_C2C</span><span class="p">,</span><span class="w"> </span><span class="n">BATCH</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="p">...</span><span class="w"></span> <span class="w"> </span><span class="n">cufftExecC2C</span><span class="p">(</span><span class="n">plan</span><span class="p">,</span><span class="w"> </span><span class="n">data</span><span class="p">,</span><span class="w"> </span><span class="n">data</span><span class="p">,</span><span class="w"> </span><span class="n">CUFFT_FORWARD</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="n">cudaDeviceSynchronize</span><span class="p">();</span><span class="w"></span> <span class="w"> </span><span class="p">...</span><span class="w"></span> <span class="w"> </span><span class="n">cufftDestroy</span><span class="p">(</span><span class="n">plan</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="n">cudaFree</span><span class="p">(</span><span class="n">data</span><span class="p">);</span><span class="w"></span> <span class="p">}</span><span class="w"></span> </pre></div> </div> <section id="accessing-cufft"> <h2><span class="section-number">2.1. </span>Accessing cuFFT<a class="headerlink" href="#accessing-cufft" title="Permalink to this headline"></a></h2> <p>The cuFFT and cuFFTW libraries are available as shared libraries. They consist of compiled programs ready for users to incorporate into applications with the compiler and linker. cuFFT can be downloaded from <a class="reference external" href="https://developer.nvidia.com/cufft">https://developer.nvidia.com/cufft</a>. By selecting <strong>Download CUDA Production Release</strong> users are all able to install the package containing the CUDA Toolkit, SDK code samples and development drivers. The CUDA Toolkit contains cuFFT and the samples include <code class="docutils literal notranslate"><span class="pre">simplecuFFT</span></code>.</p> <p>The Linux release for <code class="docutils literal notranslate"><span class="pre">simplecuFFT</span></code> assumes that the root install directory is <code class="docutils literal notranslate"><span class="pre">/usr/local/cuda</span></code> and that the locations of the products are contained there as follows. Modify the Makefile as appropriate for your system.</p> <table class="table-no-stripes docutils align-default"> <colgroup> <col style="width: 45%" /> <col style="width: 34%" /> <col style="width: 21%" /> </colgroup> <thead> <tr class="row-odd"><th class="head"><p>Product</p></th> <th class="head"><p>Location and name</p></th> <th class="head"><p>Include file</p></th> </tr> </thead> <tbody> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">nvcc</span></code> compiler</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">/bin/nvcc</span></code></p></td> <td></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">cuFFT</span></code> library</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">{lib,</span> <span class="pre">lib64}/libcufft.so</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">inc/cufft.h</span></code></p></td> </tr> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">cuFFT</span></code> library with Xt functionality</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">{lib,</span> <span class="pre">lib64}/libcufft.so</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">inc/cufftXt.h</span></code></p></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">cuFFTW</span></code> library</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">{lib,</span> <span class="pre">lib64}/libcufftw.so</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">inc/cufftw.h</span></code></p></td> </tr> </tbody> </table> <p>The most common case is for developers to modify an existing CUDA routine (for example, <code class="docutils literal notranslate"><span class="pre">filename.cu</span></code>) to call cuFFT routines. In this case the include file <code class="docutils literal notranslate"><span class="pre">cufft.h</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftXt.h</span></code> should be inserted into <code class="docutils literal notranslate"><span class="pre">filename.cu</span></code> file and the library included in the link line. A single compile and link line might appear as</p> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">/usr/local/cuda/bin/nvcc</span> <span class="pre">[options]</span> <span class="pre">filename.cu</span> <span class="pre">…</span> <span class="pre">-I/usr/local/cuda/inc</span> <span class="pre">-L/usr/local/cuda/lib</span> <span class="pre">-lcufft</span></code></p></li> </ul> <p>Of course there will typically be many compile lines and the compiler <code class="docutils literal notranslate"><span class="pre">g++</span></code> may be used for linking so long as the library path is set correctly.</p> <p>Users of the FFTW interface (see <a class="reference external" href="index.html#fftw-supported-interface">FFTW Interface to cuFFT</a>) should include <code class="docutils literal notranslate"><span class="pre">cufftw.h</span></code> and link with both cuFFT and cuFFTW libraries.</p> <p>Functions in the cuFFT and cuFFTW library assume that the data is in GPU visible memory. This means any memory allocated by <code class="docutils literal notranslate"><span class="pre">cudaMalloc</span></code>, <code class="docutils literal notranslate"><span class="pre">cudaMallocHost</span></code> and <code class="docutils literal notranslate"><span class="pre">cudaMallocManaged</span></code> or registered with <code class="docutils literal notranslate"><span class="pre">cudaHostRegister</span></code> can be used as input, output or plan work area with cuFFT and cuFFTW functions. For the best performance input data, output data and plan work area should reside in device memory.</p> <p>cuFFTW library also supports input data and output data that is not GPU visible.</p> </section> <section id="fourier-transform-setup"> <h2><span class="section-number">2.2. </span>Fourier Transform Setup<a class="headerlink" href="#fourier-transform-setup" title="Permalink to this headline"></a></h2> <p>The first step in using the cuFFT Library is to create a plan using one of the following:</p> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">cufftPlan1D()</span> <span class="pre">/</span> <span class="pre">cufftPlan2D()</span> <span class="pre">/</span> <span class="pre">cufftPlan3D()</span></code> - Create a simple plan for a 1D/2D/3D transform respectively.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftPlanMany()</span></code> - Creates a plan supporting batched input and strided data layouts.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtMakePlanMany()</span></code> - Creates a plan supporting batched input and strided data layouts for any supported precision.</p></li> </ul> <p>Among the plan creation functions, <code class="docutils literal notranslate"><span class="pre">cufftPlanMany()</span></code> allows use of more complicated data layouts and batched executions. Execution of a transform of a particular size and type may take several stages of processing. When a plan for the transform is generated, cuFFT derives the internal steps that need to be taken. These steps may include multiple kernel launches, memory copies, and so on. In addition, all the intermediate buffer allocations (on CPU/GPU memory) take place during planning. These buffers are released when the plan is destroyed. In the worst case, the cuFFT Library allocates space for <code class="docutils literal notranslate"><span class="pre">8*batch*n[0]*..*n[rank-1]</span> <span class="pre">cufftComplex</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftDoubleComplex</span></code> elements (where <code class="docutils literal notranslate"><span class="pre">batch</span></code> denotes the number of transforms that will be executed in parallel, <code class="docutils literal notranslate"><span class="pre">rank</span></code> is the number of dimensions of the input data (see <a class="reference external" href="index.html#multi-dimensional">Multidimensional Transforms</a>) and <code class="docutils literal notranslate"><span class="pre">n[]</span></code> is the array of transform dimensions) for single and double-precision transforms respectively. Depending on the configuration of the plan, less memory may be used. In some specific cases, the temporary space allocations can be as low as <code class="docutils literal notranslate"><span class="pre">1*batch*n[0]*..*n[rank-1]</span> <span class="pre">cufftComplex</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftDoubleComplex</span></code> elements. This temporary space is allocated separately for each individual plan when it is created (i.e., temporary space is not shared between the plans).</p> <p>The next step in using the library is to call an execution function such as <code class="docutils literal notranslate"><span class="pre">cufftExecC2C()</span></code> (see <a class="reference external" href="index.html#cufft-transform-types">Parameter cufftType</a>) which will perform the transform with the specifications defined at planning.</p> <p>One can create a cuFFT plan and perform multiple transforms on different data sets by providing different input and output pointers. Once the plan is no longer needed, the <code class="docutils literal notranslate"><span class="pre">cufftDestroy()</span></code> function should be called to release the resources allocated for the plan.</p> <section id="free-memory-requirement"> <h3><span class="section-number">2.2.1. </span>Free Memory Requirement<a class="headerlink" href="#free-memory-requirement" title="Permalink to this headline"></a></h3> <p>The first program call to any cuFFT function causes the initialization of the cuFFT kernels. This can fail if there is not enough free memory on the GPU. It is advisable to initialize cufft first (e.g. by creating a plan) and then allocating memory.</p> </section> <section id="plan-initialization-time"> <h3><span class="section-number">2.2.2. </span>Plan Initialization Time<a class="headerlink" href="#plan-initialization-time" title="Permalink to this headline"></a></h3> <p>During plan initialization, cuFFT conducts a series of steps, including heuristics to determine which kernels to be used as well as kernel module loads. Starting from CUDA 12.0, cuFFT delivers a larger portion of kernels using the CUDA Parallel Thread eXecution assembly form (PTX code), instead of the binary form (cubin object). The PTX code of cuFFT kernels are loaded and compiled further to the binary code by the CUDA device driver at runtime when a cuFFT plan is initialized. This is called <a class="reference external" href="https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#just-in-time-compilation">just-in-time (JIT) compilation</a>.</p> <p>JIT compilation slightly increases cuFFT plan initialization time, depending on the transform size and the speed of the host CPU (see <a class="reference external" href="https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#module">Module load driver API</a>) . But the JIT overhead occurs only when a binary code is generated for the first time during plan initialization using one of the <a class="reference external" href="https://docs.nvidia.com/cuda/cufft/index.html#cufft-setup">plan creation functions</a>. The device driver automatically caches a copy of the generated binary code to avoid repeating the compilation in subsequent invocations. If necessary, <code class="docutils literal notranslate"><span class="pre">CUDA_CACHE_PATH</span></code> or <code class="docutils literal notranslate"><span class="pre">CUDA_CACHE_MAXSIZE</span></code> can be customized to set the cache folder and max size (see detail in <a class="reference external" href="https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#env-vars">CUDA Environmental Variables</a>), but the default settings are fine in general.</p> </section> </section> <section id="fourier-transform-types"> <h2><span class="section-number">2.3. </span>Fourier Transform Types<a class="headerlink" href="#fourier-transform-types" title="Permalink to this headline"></a></h2> <p>Apart from the general complex-to-complex (C2C) transform, cuFFT implements efficiently two other types: real-to-complex (R2C) and complex-to-real (C2R). In many practical applications the input vector is real-valued. It can be easily shown that in this case the output satisfies Hermitian symmetry ( <span class="math notranslate nohighlight">\(X_{k} = X_{N - k}^{\ast}\)</span>, where the star denotes complex conjugation). The converse is also true: for complex-Hermitian input the inverse transform will be purely real-valued. cuFFT takes advantage of this redundancy and works only on the first half of the Hermitian vector.</p> <p>Transform execution functions for single and double-precision are defined separately as:</p> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">cufftExecC2C()</span> <span class="pre">/</span> <span class="pre">cufftExecZ2Z()</span></code> - complex-to-complex transforms for single/double precision.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftExecR2C()</span> <span class="pre">/</span> <span class="pre">cufftExecD2Z()</span></code> - real-to-complex forward transform for single/double precision.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftExecC2R()</span> <span class="pre">/</span> <span class="pre">cufftExecZ2D()</span></code> - complex-to-real inverse transform for single/double precision.</p></li> </ul> <p>Each of those functions demands different input data layout (see <a class="reference external" href="index.html#data-layout">Data Layout</a> for details).</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Complex-to-real (C2R) transforms accept complex-Hermitian input. For one-dimensional signals, this requires the 0th element (and the <span class="math notranslate nohighlight">\(\frac{N}{2}\)</span>th input if N is even) to be real-valued, i.e. its imaginary part should be zero. For d-dimension signals, this means <span class="math notranslate nohighlight">\(x_{(n_{1},n_{2},\ldots,n_{d})} = x_{(N_{1} - n_{1},N_{2} - n_{2},\ldots,N_{d} - n_{d})}^{\ast}\)</span>. Otherwise, the behavior of the transform is undefined. Also see <a class="reference external" href="index.html#multidimensional-transforms">Multidimensional Transforms</a>.</p> </div> <p>Functions <code class="docutils literal notranslate"><span class="pre">cufftXtExec()</span></code> and <code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptor()</span></code> can perform transforms on any of the supported types.</p> <section id="half-precision-cufft-transforms"> <h3><span class="section-number">2.3.1. </span>Half-precision cuFFT Transforms<a class="headerlink" href="#half-precision-cufft-transforms" title="Permalink to this headline"></a></h3> <p>Half-precision transforms have the following limitations:</p> <ul class="simple"> <li><p>Minimum GPU architecture is SM_53</p></li> <li><p>Sizes are restricted to powers of two only</p></li> <li><p>Strides on the real part of real-to-complex and complex-to-real transforms are not supported</p></li> <li><p>More than one GPU is not supported</p></li> <li><p>Transforms spanning more than 4 billion elements are not supported</p></li> </ul> <p>Please refer to <code class="docutils literal notranslate"><span class="pre">cufftXtMakePlanMany</span></code> function for plan creation details.</p> <p>The CUDA Toolkit provides the <code class="docutils literal notranslate"><span class="pre">cuda_fp16.h</span></code> header with types and intrinsic functions for handling half-precision arithmetic.</p> </section> <section id="bfloat16-precision-cufft-transforms"> <h3><span class="section-number">2.3.2. </span>Bfloat16-precision cuFFT Transforms<a class="headerlink" href="#bfloat16-precision-cufft-transforms" title="Permalink to this headline"></a></h3> <p>cuFFT supports bfloat16 precision using the <code class="docutils literal notranslate"><span class="pre">nv_bfloat16</span></code> data type. Please note that cuFFT utilizes a combination of single- and bfloat16-precision arithmetic operations when computing the FFT in bfloat16 precision. Bfloat16-precision transforms have similar limitations to half-precision transforms:</p> <ul class="simple"> <li><p>Minimum GPU architecture is SM_80</p></li> <li><p>Sizes are restricted to powers of two only</p></li> <li><p>Strides on the real part of real-to-complex and complex-to-real transforms are not supported</p></li> <li><p>More than one GPU is not supported</p></li> <li><p>Transforms spanning more than 4 billion elements are not supported</p></li> </ul> <p>Please refer to <code class="docutils literal notranslate"><span class="pre">cufftXtMakePlanMany</span></code> function for plan creation details.</p> <p>The CUDA Toolkit provides the <code class="docutils literal notranslate"><span class="pre">cuda_bf16.h</span></code> header with types and intrinsic functions for handling bfloat16-precision arithmetic.</p> </section> </section> <section id="data-layout"> <h2><span class="section-number">2.4. </span>Data Layout<a class="headerlink" href="#data-layout" title="Permalink to this headline"></a></h2> <p>In the cuFFT Library, data layout depends strictly on the configuration and the transform type. In the case of general complex-to-complex transform both the input and output data shall be a <code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code>/<code class="docutils literal notranslate"><span class="pre">cufftDoubleComplex</span></code> array in single- and double-precision modes respectively. In C2R mode an input array <span class="math notranslate nohighlight">\((x_{1},x_{2},\ldots,x_{\lfloor\frac{N}{2}\rfloor + 1})\)</span> of only non-redundant complex elements is required. The output array <span class="math notranslate nohighlight">\((X_{1},X_{2},\ldots,X_{N})\)</span> consists of <code class="docutils literal notranslate"><span class="pre">cufftReal</span></code>/<code class="docutils literal notranslate"><span class="pre">cufftDouble</span></code> elements in this mode. Finally, R2C demands an input array <span class="math notranslate nohighlight">\((X_{1},X_{2},\ldots,X_{N})\)</span> of real values and returns an array <span class="math notranslate nohighlight">\((x_{1},x_{2},\ldots,x_{\lfloor\frac{N}{2}\rfloor + 1})\)</span> of non-redundant complex elements.</p> <p>In real-to-complex and complex-to-real transforms the size of input data and the size of output data differ. For out-of-place transforms a separate array of appropriate size is created. For in-place transforms the user should use <code class="docutils literal notranslate"><span class="pre">padded</span></code> data layout. This layout is FFTW compatibile.</p> <p>In the <code class="docutils literal notranslate"><span class="pre">padded</span></code> layout output signals begin at the same memory addresses as the input data. Therefore input data for real-to-complex and output data for complex-to-real must be padded.</p> <p>Expected sizes of input/output data for 1-d transforms are summarized in the table below:</p> <table class="table-no-stripes docutils align-default"> <colgroup> <col style="width: 7%" /> <col style="width: 47%" /> <col style="width: 47%" /> </colgroup> <thead> <tr class="row-odd"><th class="head"><p>FFT type</p></th> <th class="head"><p>input data size</p></th> <th class="head"><p>output data size</p></th> </tr> </thead> <tbody> <tr class="row-even"><td><p>C2C</p></td> <td><p><span class="math notranslate nohighlight">\(x\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(x\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> </tr> <tr class="row-odd"><td><p>C2R</p></td> <td><p><span class="math notranslate nohighlight">\(\left\lfloor \frac{x}{2} \right\rfloor + 1\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(x\)</span><code class="docutils literal notranslate"><span class="pre">cufftReal</span></code></p></td> </tr> <tr class="row-even"><td><p>R2C*</p></td> <td><p><span class="math notranslate nohighlight">\(x\)</span><code class="docutils literal notranslate"><span class="pre">cufftReal</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(\left\lfloor \frac{x}{2} \right\rfloor + 1\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> </tr> </tbody> </table> <p>The real-to-complex transform is implicitly a forward transform. For an in-place real-to-complex transform where FFTW compatible output is desired, the input size must be padded to <span class="math notranslate nohighlight">\(\left( {\lfloor\frac{N}{2}\rfloor + 1} \right)\)</span> complex elements. For out-of-place transforms, input and output sizes match the logical transform size <span class="math notranslate nohighlight">\(N\)</span> and the non-redundant size <span class="math notranslate nohighlight">\(\lfloor\frac{N}{2}\rfloor + 1\)</span>, respectively.</p> <p>The complex-to-real transform is implicitly inverse. For in-place complex-to-real FFTs where FFTW compatible output is selected (default padding mode), the input size is assumed to be <span class="math notranslate nohighlight">\(\lfloor\frac{N}{2}\rfloor + 1\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code> elements. Note that in-place complex-to-real FFTs may <strong>overwrite</strong> arbitrary imaginary input point values when non-unit input and output strides are chosen. Out-of-place complex-to-real FFT will always <strong>overwrite</strong> input buffer. For out-of-place transforms, input and output sizes match the logical transform non-redundant size <span class="math notranslate nohighlight">\(\lfloor\frac{N}{2}\rfloor + 1\)</span> and size <span class="math notranslate nohighlight">\(N\)</span>, respectively.</p> </section> <section id="multidimensional-transforms"> <h2><span class="section-number">2.5. </span>Multidimensional Transforms<a class="headerlink" href="#multidimensional-transforms" title="Permalink to this headline"></a></h2> <p>Multidimensional DFT map a <span class="math notranslate nohighlight">\(d\)</span>-dimensional array <span class="math notranslate nohighlight">\(x_{\mathbf{n}}\)</span>, where <span class="math notranslate nohighlight">\(\mathbf{n} = (n_{1},n_{2},\ldots,n_{d})\)</span> into its frequency domain array given by:</p> <table class="table-no-stripes docutils align-default"> <colgroup> <col style="width: 100%" /> </colgroup> <tbody> <tr class="row-odd"><td><p><span class="math notranslate nohighlight">\(X_{\mathbf{k}} = \sum\limits_{n = 0}^{N - 1}x_{\mathbf{n}}e^{-2\pi i\frac{\mathbf{k}\mathbf{n}}{\mathbf{N}}}\)</span></p></td> </tr> </tbody> </table> <p>where <span class="math notranslate nohighlight">\(\frac{\mathbf{n}}{\mathbf{N}} = (\frac{n_{1}}{N_{1}},\frac{n_{2}}{N_{2}},\ldots,\frac{n_{d}}{N_{d}})\)</span>, and the summation denotes the set of nested summations</p> <table class="table-no-stripes docutils align-default"> <colgroup> <col style="width: 100%" /> </colgroup> <tbody> <tr class="row-odd"><td><p><span class="math notranslate nohighlight">\(\sum\limits_{n_{1} = 0}^{N_{1} - 1}\sum\limits_{n_{2} = 0}^{N_{2} - 1}\ldots\sum\limits_{n_{d} = 0}^{N_{d} - 1}\)</span></p></td> </tr> </tbody> </table> <p>cuFFT supports one-dimensional, two-dimensional and three-dimensional transforms, which can all be called by the same <code class="docutils literal notranslate"><span class="pre">cufftExec*</span></code> functions (see <a class="reference external" href="index.html#fft-types">Fourier Transform Types</a>).</p> <p>Similar to the one-dimensional case, the frequency domain representation of real-valued input data satisfies Hermitian symmetry, defined as: <span class="math notranslate nohighlight">\(x_{(n_{1},n_{2},\ldots,n_{d})} = x_{(N_{1} - n_{1},N_{2} - n_{2},\ldots,N_{d} - n_{d})}^{\ast}\)</span>.</p> <p>C2R and R2C algorithms take advantage of this fact by operating only on half of the elements of signal array, namely on: <span class="math notranslate nohighlight">\(x_{\mathbf{n}}\)</span> for <span class="math notranslate nohighlight">\(\mathbf{n} \in \{ 1,\ldots,N_{1}\} \times \ldots \times \{ 1,\ldots,N_{d - 1}\} \times \{ 1,\ldots,\lfloor\frac{N_{d}}{2}\rfloor + 1\}\)</span>.</p> <p>The general rules of data alignment described in <a class="reference external" href="index.html#data-layout">Data Layout</a> apply to higher-dimensional transforms. The following table summarizes input and output data sizes for multidimensional DFTs:</p> <table class="table-no-stripes docutils align-default"> <colgroup> <col style="width: 3%" /> <col style="width: 5%" /> <col style="width: 46%" /> <col style="width: 46%" /> </colgroup> <thead> <tr class="row-odd"><th class="head"><p>Dims</p></th> <th class="head"><p>FFT type</p></th> <th class="head"><p>Input data size</p></th> <th class="head"><p>Output data size</p></th> </tr> </thead> <tbody> <tr class="row-even"><td><p>1D</p></td> <td><p>C2C</p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> </tr> <tr class="row-odd"><td><p>1D</p></td> <td><p>C2R</p></td> <td><p><span class="math notranslate nohighlight">\(\lfloor\frac{\mathbf{N}_{1}}{2}\rfloor + 1\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\)</span><code class="docutils literal notranslate"><span class="pre">cufftReal</span></code></p></td> </tr> <tr class="row-even"><td><p>1D</p></td> <td><p>R2C</p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\)</span><code class="docutils literal notranslate"><span class="pre">cufftReal</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(\lfloor\frac{\mathbf{N}_{1}}{2}\rfloor + 1\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> </tr> <tr class="row-odd"><td><p>2D</p></td> <td><p>C2C</p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\mathbf{N}_{2}\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\mathbf{N}_{2}\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> </tr> <tr class="row-even"><td><p>2D</p></td> <td><p>C2R</p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}(\lfloor\frac{\mathbf{N}_{2}}{2}\rfloor + 1)\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\mathbf{N}_{2}\)</span><code class="docutils literal notranslate"><span class="pre">cufftReal</span></code></p></td> </tr> <tr class="row-odd"><td><p>2D</p></td> <td><p>R2C</p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\mathbf{N}_{2}\)</span><code class="docutils literal notranslate"><span class="pre">cufftReal</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}(\lfloor\frac{\mathbf{N}_{2}}{2}\rfloor + 1)\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> </tr> <tr class="row-even"><td><p>3D</p></td> <td><p>C2C</p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\mathbf{N}_{2}\mathbf{N}_{3}\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\mathbf{N}_{2}\mathbf{N}_{3}\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> </tr> <tr class="row-odd"><td><p>3D</p></td> <td><p>C2R</p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\mathbf{N}_{2}(\lfloor\frac{\mathbf{N}_{3}}{2}\rfloor + 1)\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\mathbf{N}_{2}\mathbf{N}_{3}\)</span><code class="docutils literal notranslate"><span class="pre">cufftReal</span></code></p></td> </tr> <tr class="row-even"><td><p>3D</p></td> <td><p>R2C</p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\mathbf{N}_{2}\mathbf{N}_{3}\)</span><code class="docutils literal notranslate"><span class="pre">cufftReal</span></code></p></td> <td><p><span class="math notranslate nohighlight">\(\mathbf{N}_{1}\mathbf{N}_{2}(\lfloor\frac{\mathbf{N}_{3}}{2}\rfloor + 1)\)</span><code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code></p></td> </tr> </tbody> </table> <p>For example, static declaration of a three-dimensional array for the output of an out-of-place real-to-complex transform will look like this:</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">cufftComplex</span><span class="w"> </span><span class="n">odata</span><span class="p">[</span><span class="n">N1</span><span class="p">][</span><span class="n">N2</span><span class="p">][</span><span class="n">N3</span><span class="o">/</span><span class="mi">2</span><span class="o">+</span><span class="mi">1</span><span class="p">];</span><span class="w"></span> </pre></div> </div> </section> <section id="advanced-data-layout"> <h2><span class="section-number">2.6. </span>Advanced Data Layout<a class="headerlink" href="#advanced-data-layout" title="Permalink to this headline"></a></h2> <p>The advanced data layout feature allows transforming only a subset of an input array, or outputting to only a portion of a larger data structure. It can be set by calling function:</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">cufftResult</span><span class="w"> </span><span class="nf">cufftPlanMany</span><span class="p">(</span><span class="n">cufftHandle</span><span class="w"> </span><span class="o">*</span><span class="n">plan</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rank</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="n">inembed</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">istride</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">idist</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="n">onembed</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">ostride</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">odist</span><span class="p">,</span><span class="w"> </span><span class="n">cufftType</span><span class="w"> </span><span class="n">type</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">batch</span><span class="p">);</span><span class="w"></span> </pre></div> </div> <p>Passing <code class="docutils literal notranslate"><span class="pre">inembed</span></code> or <code class="docutils literal notranslate"><span class="pre">onembed</span></code> set to <code class="docutils literal notranslate"><span class="pre">NULL</span></code> is a special case and is equivalent to passing <code class="docutils literal notranslate"><span class="pre">n</span></code> for each. This is same as the basic data layout and other advanced parameters such as <code class="docutils literal notranslate"><span class="pre">istride</span></code> are ignored.</p> <p>If the advanced parameters are to be used, then all of the advanced interface parameters must be specified correctly. Advanced parameters are defined in units of the relevant data type (<code class="docutils literal notranslate"><span class="pre">cufftReal</span></code>, <code class="docutils literal notranslate"><span class="pre">cufftDoubleReal</span></code>, <code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code>, or <code class="docutils literal notranslate"><span class="pre">cufftDoubleComplex</span></code>).</p> <p>Advanced layout can be perceived as an additional layer of abstraction above the access to input/output data arrays. An element of coordinates <code class="docutils literal notranslate"><span class="pre">[z][y][x]</span></code> in signal number <code class="docutils literal notranslate"><span class="pre">b</span></code> in the batch will be associated with the following addresses in the memory:</p> <ul> <li><p>1D</p> <p><code class="docutils literal notranslate"><span class="pre">input[</span> <span class="pre">b</span> <span class="pre">*</span> <span class="pre">idist</span> <span class="pre">+</span> <span class="pre">x</span> <span class="pre">*</span> <span class="pre">istride</span> <span class="pre">]</span></code></p> <p><code class="docutils literal notranslate"><span class="pre">output[</span> <span class="pre">b</span> <span class="pre">*</span> <span class="pre">odist</span> <span class="pre">+</span> <span class="pre">x</span> <span class="pre">*</span> <span class="pre">ostride</span> <span class="pre">]</span></code></p> </li> <li><p>2D</p> <p><code class="docutils literal notranslate"><span class="pre">input[</span> <span class="pre">b</span> <span class="pre">*</span> <span class="pre">idist`</span> <span class="pre">+</span> <span class="pre">(x</span> <span class="pre">*</span> <span class="pre">inembed[1]</span> <span class="pre">+</span> <span class="pre">y)</span> <span class="pre">*</span> <span class="pre">istride</span> <span class="pre">]</span></code></p> <p><code class="docutils literal notranslate"><span class="pre">output[</span> <span class="pre">b</span> <span class="pre">*</span> <span class="pre">odist</span> <span class="pre">+</span> <span class="pre">(x</span> <span class="pre">*</span> <span class="pre">onembed[1]</span> <span class="pre">+</span> <span class="pre">y)</span> <span class="pre">*</span> <span class="pre">ostride</span> <span class="pre">]</span></code></p> </li> <li><p>3D</p> <p><code class="docutils literal notranslate"><span class="pre">input[</span> <span class="pre">b</span> <span class="pre">*</span> <span class="pre">idist</span> <span class="pre">+</span> <span class="pre">((x</span> <span class="pre">*</span> <span class="pre">inembed[1]</span> <span class="pre">+</span> <span class="pre">y)</span> <span class="pre">*</span> <span class="pre">inembed[2]</span> <span class="pre">+</span> <span class="pre">z)</span> <span class="pre">*</span> <span class="pre">istride</span> <span class="pre">]</span></code></p> <p><code class="docutils literal notranslate"><span class="pre">output[</span> <span class="pre">b</span> <span class="pre">*</span> <span class="pre">odist</span> <span class="pre">+</span> <span class="pre">((x</span> <span class="pre">*</span> <span class="pre">onembed[1]</span> <span class="pre">+</span> <span class="pre">y)</span> <span class="pre">*</span> <span class="pre">onembed[2]</span> <span class="pre">+</span> <span class="pre">z)</span> <span class="pre">*</span> <span class="pre">ostride</span> <span class="pre">]</span></code></p> </li> </ul> <p>The <code class="docutils literal notranslate"><span class="pre">istride</span></code> and <code class="docutils literal notranslate"><span class="pre">ostride</span></code> parameters denote the distance between two successive input and output elements in the least significant (that is, the innermost) dimension respectively. In a single 1D transform, if every input element is to be used in the transform, <code class="docutils literal notranslate"><span class="pre">istride</span></code> should be set to <span class="math notranslate nohighlight">\(1\)</span>; if every other input element is to be used in the transform, then <code class="docutils literal notranslate"><span class="pre">istride</span></code> should be set to <span class="math notranslate nohighlight">\(2\)</span>. Similarly, in a single 1D transform, if it is desired to output final elements one after another compactly, <code class="docutils literal notranslate"><span class="pre">ostride</span></code> should be set to <span class="math notranslate nohighlight">\(1\)</span>; if spacing is desired between the least significant dimension output data, <code class="docutils literal notranslate"><span class="pre">ostride</span></code> should be set to the distance between the elements.</p> <p>The <code class="docutils literal notranslate"><span class="pre">inembed</span></code> and <code class="docutils literal notranslate"><span class="pre">onembed</span></code> parameters define the number of elements in each dimension in the input array and the output array respectively. The <code class="docutils literal notranslate"><span class="pre">inembed[rank-1]</span></code> contains the number of elements in the least significant (innermost) dimension of the input data excluding the <code class="docutils literal notranslate"><span class="pre">istride</span></code> elements; the number of total elements in the least significant dimension of the input array is then <code class="docutils literal notranslate"><span class="pre">istride*inembed[rank-1]</span></code>. The <code class="docutils literal notranslate"><span class="pre">inembed[0]</span></code> or <code class="docutils literal notranslate"><span class="pre">onembed[0]</span></code> corresponds to the most significant (that is, the outermost) dimension and is effectively ignored since the <code class="docutils literal notranslate"><span class="pre">idist</span></code> or <code class="docutils literal notranslate"><span class="pre">odist</span></code> parameter provides this information instead. Note that the size of each dimension of the transform should be less than or equal to the <code class="docutils literal notranslate"><span class="pre">inembed</span></code> and <code class="docutils literal notranslate"><span class="pre">onembed</span></code> values for the corresponding dimension, that is <code class="docutils literal notranslate"><span class="pre">n[i]</span></code> ≤ <code class="docutils literal notranslate"><span class="pre">inembed[i]</span></code>, <code class="docutils literal notranslate"><span class="pre">n[i]</span></code> ≤ <code class="docutils literal notranslate"><span class="pre">onembed[i]</span></code>, where <span class="math notranslate nohighlight">\(i \in \{ 0,\ldots,rank - 1\}\)</span>.</p> <p>The <code class="docutils literal notranslate"><span class="pre">idist</span></code> and <code class="docutils literal notranslate"><span class="pre">odist</span></code> parameters indicate the distance between the first element of two consecutive batches in the input and output data.</p> </section> <section id="streamed-cufft-transforms"> <h2><span class="section-number">2.7. </span>Streamed cuFFT Transforms<a class="headerlink" href="#streamed-cufft-transforms" title="Permalink to this headline"></a></h2> <p>Every cuFFT plan may be associated with a CUDA stream. Once so associated, all launches of the internal stages of that plan take place through the specified stream. Streaming of cuFFT execution allows for potential overlap between transforms and memory copies. (See the <em>NVIDIA CUDA Programming Guide</em> for more information on streams.) If no stream is associated with a plan, launches take place in <code class="docutils literal notranslate"><span class="pre">stream(0)</span></code>, the default CUDA stream. Note that many plan executions require multiple kernel launches.</p> <p>cuFFT uses private streams internally to sort operations, including event syncrhonization. cuFFT does not guarantee ordering of internal operations, and the order is only preserved with respect to the streams set by the user.</p> <p>As of CUDA 11.2 (cuFFT 10.4.0), <code class="docutils literal notranslate"><span class="pre">cufftSetStream()</span></code> is supported in multiple GPU cases. However, calls to <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> are still synchronous across multiple GPUs when using streams. In previous versions of cuFFT, <code class="docutils literal notranslate"><span class="pre">cufftSetStream()</span></code> returns an error in the multiple GPU case. Likewise, calling certain multi-GPU functions such as <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallback()</span></code> after setting a stream with <code class="docutils literal notranslate"><span class="pre">cufftSetStream()</span></code> will result in an error (see API functions for more details).</p> <p>Please note that in order to overlap plans using single plan handle user needs to manage work area buffers. Each concurrent plan execution needs it’s exclusive work area. Work area can be set by <code class="docutils literal notranslate"><span class="pre">cufftSetWorkArea</span></code> function.</p> </section> <section id="multiple-gpu-cufft-transforms"> <h2><span class="section-number">2.8. </span>Multiple GPU cuFFT Transforms<a class="headerlink" href="#multiple-gpu-cufft-transforms" title="Permalink to this headline"></a></h2> <p>cuFFT supports using up to sixteen GPUs connected to a CPU to perform Fourier Transforms whose calculations are distributed across the GPUs. An API has been defined to allow users to write new code or modify existing code to use this functionality.</p> <p>Some existing functions such as the creation of a plan using <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> also apply in the multiple GPU case. Multiple GPU routines contain <code class="docutils literal notranslate"><span class="pre">Xt</span></code> in their name.</p> <p>The memory on the GPUs is managed by helper functions <code class="docutils literal notranslate"><span class="pre">cufftXtMalloc()/cufftXtFree()</span></code> and <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> using the <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span></code> descriptor.</p> <p>Performance is a function of the bandwidth between the GPUs, the computational ability of the individual GPUs, and the type and number of FFT to be performed. The highest performance is obtained using NVLink interconnect (<a class="reference external" href="https://www.nvidia.com/object/nvlink.html">https://www.nvidia.com/object/nvlink.html</a>). The second best option is using PCI Express 3.0 between the GPUs and ensuring that both GPUs are on the same switch. Note that multiple GPU execution is not guaranteed to solve a given size problem in a shorter time than single GPU execution.</p> <p>The multiple GPU extensions to cuFFT are built on the extensible cuFFT API. The general steps in defining and executing a transform with this API are:</p> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> - create an empty plan, as in the single GPU case</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> - define which GPUs are to be used</p></li> <li><p>Optional: <code class="docutils literal notranslate"><span class="pre">cufftEstimate{1d,2d,3d,Many}()</span></code> - estimate the sizes of the work areas required. These are the same functions used in the single GPU case although the definition of the argument <code class="docutils literal notranslate"><span class="pre">workSize</span></code> reflects the number of GPUs used.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftMakePlan{1d,2d,3d,Many}()</span></code> - create the plan. These are the same functions used in the single GPU case although the definition of the argument <code class="docutils literal notranslate"><span class="pre">workSize</span></code> reflects the number of GPUs used.</p></li> <li><p>Optional: <code class="docutils literal notranslate"><span class="pre">cufftGetSize{1d,2d,3d,Many}()</span></code> - refined estimate of the sizes of the work areas required. These are the same functions used in the single GPU case although the definition of the argument <code class="docutils literal notranslate"><span class="pre">workSize</span></code> reflects the number of GPUs used.</p></li> <li><p>Optional: <code class="docutils literal notranslate"><span class="pre">cufftGetSize()</span></code> - check workspace size. This is the same function used in the single GPU case although the definition of the argument <code class="docutils literal notranslate"><span class="pre">workSize</span></code> reflects the number of GPUs used.</p></li> <li><p>Optional: <code class="docutils literal notranslate"><span class="pre">cufftXtSetWorkArea()</span></code> - do your own workspace allocation.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtMalloc()</span></code> - allocate descriptor and data on the GPUs</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> - copy data to the GPUs</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptorC2C()/cufftXtExecDescriptorZ2Z()</span></code> - execute the plan</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> - copy data from the GPUs</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtFree()</span></code> - free any memory allocated with <code class="docutils literal notranslate"><span class="pre">cufftXtMalloc()</span></code></p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftDestroy()</span></code> - free cuFFT plan resources</p></li> </ul> <section id="plan-specification-and-work-areas"> <h3><span class="section-number">2.8.1. </span>Plan Specification and Work Areas<a class="headerlink" href="#plan-specification-and-work-areas" title="Permalink to this headline"></a></h3> <p>In the single GPU case a plan is created by a call to <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> followed by a call to <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code>. For multiple GPUs, the GPUs to use for execution are identified by a call to <code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> and this must occur after the call to <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> and prior to the call to <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code>.</p> <p>Note that when <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code> is called for a single GPU, the work area is on that GPU. In a multiple GPU plan, the returned work area has multiple entries; one value per GPU. That is <code class="docutils literal notranslate"><span class="pre">workSize</span></code> points to a <code class="docutils literal notranslate"><span class="pre">size_t</span></code> array, one entry per GPU. Also the strides and batches apply to the entire plan across all GPUs associated with the plan.</p> <p>Once a plan is locked by a call to <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code>, different descriptors may be specified in calls to <code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptor*()</span></code> to execute the plan on different data sets, but the new descriptors must use the same GPUs in the same order.</p> <p>As in the single GPU case, <code class="docutils literal notranslate"><span class="pre">cufftEstimateSize{Many,1d,2d,3d}()</span></code> and <code class="docutils literal notranslate"><span class="pre">cufftGetSize{Many,1d,2d,3d}()</span></code> give estimates of the work area sizes required for a multiple GPU plan and in this case <code class="docutils literal notranslate"><span class="pre">workSize</span></code> points to a <code class="docutils literal notranslate"><span class="pre">size_t</span></code> array, one entry per GPU.</p> <p>Similarly the actual work size returned by <code class="docutils literal notranslate"><span class="pre">cufftGetSize()</span></code> is a <code class="docutils literal notranslate"><span class="pre">size_t</span></code> array, one entry per GPU in the multiple GPU case.</p> </section> <section id="helper-functions"> <h3><span class="section-number">2.8.2. </span>Helper Functions<a class="headerlink" href="#helper-functions" title="Permalink to this headline"></a></h3> <p>Multiple GPU cuFFT execution functions assume a certain data layout in terms of what input data has been copied to which GPUs prior to execution, and what output data resides in which GPUs post execution. cuFFT provides functions to assist users in manipulating data on multiple GPUs. These must be called after the call to <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code>.</p> <p>On a single GPU users may call <code class="docutils literal notranslate"><span class="pre">cudaMalloc()</span></code> and <code class="docutils literal notranslate"><span class="pre">cudaFree()</span></code> to allocate and free GPU memory. To provide similar functionality in the multiple GPU case, cuFFT includes <code class="docutils literal notranslate"><span class="pre">cufftXtMalloc()</span></code> and <code class="docutils literal notranslate"><span class="pre">cufftXtFree()</span></code> functions. The function <code class="docutils literal notranslate"><span class="pre">cufftXtMalloc()</span></code> returns a descriptor which specifies the location of these memories.</p> <p>On a single GPU users may call <code class="docutils literal notranslate"><span class="pre">cudaMemcpy()</span></code> to transfer data between host and GPU memory. To provide similar functionality in the multiple GPU case, cuFFT includes <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> which allows users to copy between host and multiple GPU memories or even between the GPU memories.</p> <p>All single GPU cuFFT FFTs return output the data in natural order, that is the ordering of the result is the same as if a DFT had been performed on the data. Some Fast Fourier Transforms produce intermediate results where the data is left in a permutation of the natural output. When batch is one, data is left in the GPU memory in a permutation of the natural output.</p> <p>When <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> is used to copy data from GPU memory back to host memory, the results are in natural order regardless of whether the data on the GPUs is in natural order or permuted. Using <code class="docutils literal notranslate"><span class="pre">CUFFT_COPY_DEVICE_TO_DEVICE</span></code> allows users to copy data from the permuted data format produced after a single transform to the natural order on GPUs.</p> </section> <section id="multiple-gpu-2d-and-3d-transforms-on-permuted-input"> <h3><span class="section-number">2.8.3. </span>Multiple GPU 2D and 3D Transforms on Permuted Input<a class="headerlink" href="#multiple-gpu-2d-and-3d-transforms-on-permuted-input" title="Permalink to this headline"></a></h3> <p>For single 2D or 3D transforms on multiple GPUs, when <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> distributes the data to the GPUs, the array is divided on the X axis. E.G. for two GPUs half of the X dimenson points, for all Y (and Z) values, are copied to each of the GPUs. When the transform is computed, the data are permuted such that they are divided on the Y axis. I.E. half of the Y dimension points, for all X (and Z) values are on each of the GPUs.</p> <p>When cuFFT creates a 2D or 3D plan for a single transform on multiple GPUs, it actually creates two plans. One plan expects input to be divided on the X axis. The other plan expects data to be divided on the Y axis. This is done because many algorithms compute a forward FFT, then perform some point-wise operation on the result, and then compute the inverse FFT. A memory copy to restore the data to the original order would be expensive. To avoid this, <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy</span></code> and <code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptor()</span></code> keep track of the data ordering so that the correct operation is used.</p> <p>The ability of cuFFT to process data in either order makes the following sequence possible.</p> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> - create an empty plan, as in the single GPU case</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> - define which GPUs are to be used</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftMakePlan{1d,2d,3d,Many}()</span></code> - create the plan.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtMalloc()</span></code> - allocate descriptor and data on the GPUs</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> - copy data to the GPUs</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptorC2C()/cufftXtExecDescriptorZ2Z()</span></code> - compute the forward FFT</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">userFunction()</span></code> - modify the data in the frequency domain</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptorC2C()/cufftXtExecDescriptorZ2Z()</span></code> - compute the inverse FFT</p></li> <li><p>Note that it was not necessary to copy/permute the data between execute calls</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> - copy data to the host</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtFree()</span></code> - free any memory allocated with <code class="docutils literal notranslate"><span class="pre">cufftXtMalloc()</span></code></p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftDestroy()</span></code> - free cuFFT plan resources</p></li> </ul> </section> <section id="supported-functionality"> <h3><span class="section-number">2.8.4. </span>Supported Functionality<a class="headerlink" href="#supported-functionality" title="Permalink to this headline"></a></h3> <p>Starting with cuFFT version 7.0, a subset of single GPU functionality is supported for multiple GPU execution.</p> <p>Requirements and limitations:</p> <ul class="simple"> <li><p>All GPUs must have the same CUDA architecture level and support Unified Virtual Address Space.</p></li> <li><p>On Windows, the GPU boards must be operating in Tesla Compute Cluster (TCC) mode.</p></li> <li><p>For an application that uses the CUDA Driver API, running cuFFT on multiple GPUs is only compatible with applications using the primary context on each GPU.</p></li> <li><p>Strided input and output are not supported.</p></li> <li><p>Running cuFFT on more than 8 GPUs (16 GPUs is max) is supported on machines with NVLink only.</p></li> </ul> <p>While transforms with batch count greater than one do not impose additional constraints, those with a single batch have some restrictions. Single-batch FFTs support only in-place mode, and have additional constraints depending on the FFT type. This behavior is summarized in the following table:</p> <table class="table-no-stripes longtable docutils align-default"> <colgroup> <col style="width: 11%" /> <col style="width: 25%" /> <col style="width: 53%" /> <col style="width: 11%" /> </colgroup> <thead> <tr class="row-odd"><th class="head"><p>batch=1</p></th> <th class="head"><p>1D</p></th> <th class="head"><p>2D</p></th> <th class="head"><p>3D</p></th> </tr> </thead> <tbody> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">C2C</span></code>/<code class="docutils literal notranslate"><span class="pre">Z2Z</span></code></p></td> <td><ul class="simple"> <li><p>2,4,8,16 GPUs</p></li> <li><p>power of 2 sizes only</p></li> <li><p>Minimum size for 2-4 GPUs is 64</p></li> <li><p>Minimum size for 8 GPUs is 128</p></li> <li><p>Minimum size for 16 GPUs is 1024</p></li> </ul> </td> <td colspan="2"><ul class="simple"> <li><p>2-16 GPUs</p></li> <li><p>One of the following conditions is met for each dimension:</p> <ul> <li><p>Dimension must factor into primes less than or equal to 127</p></li> <li><p>Maximum dimension size is 4096 for single precision</p></li> <li><p>Maximum dimension size is 2048 for double precision</p></li> </ul> </li> <li><p>Minimum size is 32</p></li> <li><p>No LTO callback support</p></li> </ul> </td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">R2C</span></code>/<code class="docutils literal notranslate"><span class="pre">D2Z</span></code></p></td> <td><p>not supported</p></td> <td colspan="2"><ul class="simple"> <li><p>2-16 GPUs</p></li> <li><p>One of the following conditions is met for each dimension:</p> <ul> <li><p>Dimension must factor into primes less than or equal to 127</p></li> <li><p>Maximum dimension size is 4096 for single precision</p></li> <li><p>Maximum dimension size is 2048 for double precision</p></li> </ul> </li> <li><p>Minimum size is 32</p></li> <li><p>Fastest changing dimension size needs to be even</p></li> <li><p>Supports only <code class="docutils literal notranslate"><span class="pre">CUFFT_XT_FORMAT_INPLACE</span></code> input descriptor format</p></li> <li><p>No legacy callback / LTO callback support</p></li> </ul> </td> </tr> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">C2R</span></code>/<code class="docutils literal notranslate"><span class="pre">Z2D</span></code></p></td> <td><p>not supported</p></td> <td colspan="2"><ul class="simple"> <li><p>2-16 GPUs</p></li> <li><p>One of the following conditions is met for each dimension:</p> <ul> <li><p>Dimension must factor into primes less than or equal to 127</p></li> <li><p>Maximum dimension size is 4096 for single precision</p></li> <li><p>Maximum dimension size is 2048 for double precision</p></li> </ul> </li> <li><p>Minimum size is 32</p></li> <li><p>Fastest changing dimension size needs to be even</p></li> <li><p>Supports only <code class="docutils literal notranslate"><span class="pre">CUFFT_XT_FORMAT_INPLACE_SHUFFLED</span></code> input descriptor format</p></li> <li><p>No legacy callback / LTO callback support</p></li> </ul> </td> </tr> </tbody> </table> <p>General guidelines are:</p> <ul class="simple"> <li><p>Parameter <code class="docutils literal notranslate"><span class="pre">whichGPUs</span></code> of <code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> function determines ordering of the GPUs with respect to data decomposition (first data chunk is placed on GPU denoted by first element of <code class="docutils literal notranslate"><span class="pre">whichGPUs</span></code>)</p></li> <li><p>The data for the entire transform must fit within the memory of the GPUs assigned to it.</p></li> <li><p>For batch size <code class="docutils literal notranslate"><span class="pre">m</span></code> on <code class="docutils literal notranslate"><span class="pre">n</span></code> GPUs :</p> <ul> <li><p>The first <code class="docutils literal notranslate"><span class="pre">m</span> <span class="pre">%</span> <span class="pre">n</span></code> GPUs execute <span class="math notranslate nohighlight">\(\left\lfloor \frac{m}{n} \right\rfloor+\ 1\)</span> transforms.</p></li> <li><p>The remaining GPUs execute <span class="math notranslate nohighlight">\(\left\lfloor \frac{m}{n} \right\rfloor\)</span> transforms.</p></li> </ul> </li> </ul> <p>Batch size output differences:</p> <p>Single GPU cuFFT results are always returned in natural order. When multiple GPUs are used to perform more than one transform, the results are also returned in natural order. When multiple GPUs are used to perform a single transform the results are returned in a permutation of the normal results to reduce communication time. This behavior is summarized in the following table:</p> <table class="table-no-stripes docutils align-default"> <colgroup> <col style="width: 23%" /> <col style="width: 43%" /> <col style="width: 33%" /> </colgroup> <thead> <tr class="row-odd"><th class="head"><p>Number of GPUs</p></th> <th class="head"><p>Number of transforms</p></th> <th class="head"><p>Output Order on GPUs</p></th> </tr> </thead> <tbody> <tr class="row-even"><td><p>One</p></td> <td><p>One or multiple transforms</p></td> <td><p>Natural order</p></td> </tr> <tr class="row-odd"><td><p>Multiple</p></td> <td><p>One</p></td> <td><p>Permuted results</p></td> </tr> <tr class="row-even"><td><p>Multiple</p></td> <td><p>Multiple</p></td> <td><p>Natural order</p></td> </tr> </tbody> </table> <p>To produce natural order results in GPU memory for multi-GPU runs in the 1D single transform case, requires calling <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> with <code class="docutils literal notranslate"><span class="pre">CUFFT_COPY_DEVICE_TO_DEVICE</span></code>.</p> <p>2D and 3D multi-GPU transforms support execution of a transform given permuted order results as input. After execution in this case, the output will be in natural order. It is also possible to use <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> with <code class="docutils literal notranslate"><span class="pre">CUFFT_COPY_DEVICE_TO_DEVICE</span></code> to return 2D or 3D data to natural order.</p> <p>See the cuFFT Code Examples section for single GPU and multiple GPU examples.</p> </section> </section> <section id="cufft-callback-routines"> <h2><span class="section-number">2.9. </span>cuFFT Callback Routines<a class="headerlink" href="#cufft-callback-routines" title="Permalink to this headline"></a></h2> <p>Callback routines are user-supplied kernel routines that cuFFT will call when loading or storing data. They allow the user to do data pre- or post- processing without additional kernel calls.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>In CUDA 12.6 Update 2, we introduced support for Link-Time Optimized (LTO) callbacks as a replacement for the deprecated (legacy) callbacks. See more in <a class="reference external" href="index.html#lto-load-and-store-callback-routines">LTO Load and Store Callback Routines</a>.</p> <p>Starting from CUDA 11.4, support for callback functionality using separately compiled device code (i.e. legacy callbacks) is deprecated on all GPU architectures. Callback functionality will continue to be supported for all GPU architectures.</p> </div> <section id="overview-of-the-cufft-callback-routine-feature"> <h3><span class="section-number">2.9.1. </span>Overview of the cuFFT Callback Routine Feature<a class="headerlink" href="#overview-of-the-cufft-callback-routine-feature" title="Permalink to this headline"></a></h3> <p>cuFFT provides a set of APIs that allow the cuFFT user to provide CUDA functions that re-direct or manipulate the data as it is loaded prior to processing the FFT, or stored once the FFT has been done. For the load callback, cuFFT calls the callback routine the address of the input data and the offset to the value to be loaded from device memory, and the callback routine returns the value it wishes cuFFT to use instead. For the store callback, cuFFT calls the callback routine the value it has computed, along with the address of the output data and the offset to the value to be written to device memory, and the callback routine modifies the value and stores the modified result.</p> <p>In order to provide a callback to cuFFT, a plan is created using the extensible plan APIs. After the call to <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>, the user may associate a load callback routine, or a store callback routine, or both, with the plan, by:</p> <ul class="simple"> <li><p>Calling <code class="docutils literal notranslate"><span class="pre">cufftXtSetJITCallback</span></code> before <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code>, for LTO callbacks</p></li> <li><p>Calling <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallback</span></code> after <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code>, for legacy callbacks</p></li> </ul> <p>The caller also has the option to specify a device pointer to an opaque structure they wish to associate with the plan. This pointer will be passed to the callback routine by the cuFFT library. The caller may use this structure to remember plan dimensions and strides, or have a pointer to auxiliary data, etc.</p> <p>With some restrictions, the callback routine is allowed to request shared memory for its own use. If the requested amount of shared memory is available, cufft will pass a pointer to it when it calls the callback routine.</p> <p>CUFFT allows for 8 types of callback routines, one for each possible combination of: load or store, real or complex, single precision or double:</p> <ul class="simple"> <li><p>For LTO callbacks, the user must provide an LTO routine that matches the function prototype for the type of routine specified. Otherwise, the planning function <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code> <strong>will fail</strong>.</p></li> <li><p>For legacy callbacks, it is the caller’s responsibility to provide a routine that matches the function prototype for the type of routine specified.</p></li> </ul> <p>If there is already a callback of the specified type associated with the plan handle, the set callback functions will replace it with the new one.</p> <p>The callback routine extensions to cuFFT are built on the extensible cuFFT API. The general steps in defining and executing a transform with callbacks are:</p> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> - create an empty plan, as in the single GPU case.</p></li> <li><p>(For <strong>LTO</strong> callbacks) <code class="docutils literal notranslate"><span class="pre">cufftXtSetJITCallback()</span></code> - set a load and/or store LTO callback for this plan.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftMakePlan{1d,2d,3d,Many}()</span></code> - create the plan. These are the same functions used in the single GPU case.</p></li> <li><p>(For <strong>legacy</strong> callbacks) <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallback()</span></code> - set a load and/or store legacy callback for this plan.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftExecC2C()</span> <span class="pre">etc.</span></code> - execute the plan.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftDestroy()</span></code> - free cuFFT plan resources.</p></li> </ul> <p>Callback functions are not supported on transforms with a dimension size that does not factor into primes smaller than 127. Callback functions on plans whose dimensions’ prime factors are limited to 2, 3, 5, and 7 can safely call <code class="docutils literal notranslate"><span class="pre">__syncthreads()</span></code>. On other plans, results are not defined.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>The LTO callback API is available in the dynamic and static cuFFT libraries on 64 bit Windows and LINUX operating systems. The LTO callback API requires compatible nvJitLink and NVRTC libraries present in the dynamic library path. See more details in <a class="reference external" href="index.html#lto-load-and-store-callback-routines">LTO Load and Store Callback Routines</a>.</p> <p>The legacy callback API is available only in the static cuFFT library on 64 bit LINUX operating systems.</p> </div> </section> <section id="lto-load-and-store-callback-routines"> <h3><span class="section-number">2.9.2. </span>LTO Load and Store Callback Routines<a class="headerlink" href="#lto-load-and-store-callback-routines" title="Permalink to this headline"></a></h3> <p>LTO callbacks in cuFFT for a given toolkit version require using the <a class="reference external" href="https://docs.nvidia.com/cuda/nvjitlink/index.html">nvJitLink library</a> from the same toolkit or greater, but within the same toolkit major.</p> <p>Additionally, in order to specify custom names for the LTO callback routines, cuFFT requires using the <a class="reference external" href="https://docs.nvidia.com/cuda/nvrtc/index.html">NVRTC library</a>. cuFFT uses NVRTC to compile a minimal wrapper around the user callback with custom symbol name. The custom symbol name provided to the cuFFT API must be a valid, null-terminated C-string containing the unmangled name; currently, keywords that alter the scope of the symbol name (such as <code class="docutils literal notranslate"><span class="pre">namespace</span></code>) or the mangling (such as <code class="docutils literal notranslate"><span class="pre">extern</span> <span class="pre">"C"</span></code>) are not supported.</p> <p>The NVRTC library used must be from a toolkit that is either the same version or older than the nvJitLink library, and both must be from the same toolkit major.</p> <p>For example, in toolkit version 12.6 cuFFT requires nvJitLink to be from toolkit version 12.X, where <code class="docutils literal notranslate"><span class="pre">X</span> <span class="pre">>=</span> <span class="pre">6</span></code>, and NVRTC to be from toolkit version 12.Y, where <code class="docutils literal notranslate"><span class="pre">0</span> <span class="pre"><=</span> <span class="pre">Y</span> <span class="pre"><=</span> <span class="pre">X</span></code>.</p> <p>Both the nvJitLink and the NVRTC libraries are loaded dynamically, and should be present in the system’s dynamic linking path (e.g. <code class="docutils literal notranslate"><span class="pre">LD_LIBRARY_PATH</span></code> on Unix systems, or <code class="docutils literal notranslate"><span class="pre">PATH</span></code> on Windows systems).</p> <p>Code samples for LTO callbacks are available in the public <a class="reference external" href="https://github.com/NVIDIA/CUDALibrarySamples/tree/master/cuFFT">CUDA Library Samples github repository</a>.</p> <section id="specifying-lto-load-and-store-callback-routines"> <h4><span class="section-number">2.9.2.1. </span>Specifying LTO Load and Store Callback Routines<a class="headerlink" href="#specifying-lto-load-and-store-callback-routines" title="Permalink to this headline"></a></h4> <p>Usage of LTO callbacks in cuFFT is divided in two parts:</p> <ul class="simple"> <li><p>Generating the LTO callback (i.e. compiling the callback routine to LTO-IR).</p></li> <li><p>Associating the LTO callback with the cuFFT plan.</p></li> </ul> <p><strong>To generate</strong> the LTO callback, users can compile the callback device function to LTO-IR using nvcc with any of the supported flags (such as <code class="docutils literal notranslate"><span class="pre">-dlto</span></code> or <code class="docutils literal notranslate"><span class="pre">-gencode=arch=compute_XX,code=lto_XX</span></code>, with <code class="docutils literal notranslate"><span class="pre">XX</span></code> indicating the target GPU architecture); alternatively, users can generate the LTO callback using NVRTC to do runtime compilation via the <code class="docutils literal notranslate"><span class="pre">-dlto</span></code> flag.</p> <p>Notice that PTX JIT is part of the JIT LTO kernel finalization trajectory, so architectures older than the current system architecture are supported; users can compile their callback function to LTO-IR for target arch <code class="docutils literal notranslate"><span class="pre">XX</span></code> and and execute plans which use the callback functions on GPUs with arch <code class="docutils literal notranslate"><span class="pre">YY</span></code>, where <code class="docutils literal notranslate"><span class="pre">XX</span> <span class="pre"><=</span> <span class="pre">YY</span></code>. Please see <a class="reference external" href="https://developer.nvidia.com/blog/cuda-12-0-compiler-support-for-runtime-lto-using-nvjitlink-library/">Compiler Support for Runtime LTO Using nvJitLink Library</a> and <a class="reference external" href="https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#just-in-time-compilation">Just-in-Time (JIT) Compilation</a> for more details.</p> <p>As an example, if a user wants to specify a load callback for a R2C transform, they could write the following code</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">__device__</span><span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="n">myOwnLTOCallback</span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPtr</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">// use offset, dataIn, and optionally callerInfo to</span> <span class="w"> </span><span class="c1">// compute the return value</span> <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span><span class="w"></span> <span class="p">}</span><span class="w"></span> </pre></div> </div> <p>To compile the callback to LTO-IR, the user could do</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cp"># Compile the code to SM60 LTO-IR into a fatbin file</span> <span class="n">nvcc</span><span class="w"> </span><span class="o">-</span><span class="n">gencode</span><span class="o">=</span><span class="n">arch</span><span class="o">=</span><span class="n">compute_60</span><span class="p">,</span><span class="n">code</span><span class="o">=</span><span class="n">lto_60</span><span class="w"> </span><span class="o">-</span><span class="n">dc</span><span class="w"> </span><span class="o">-</span><span class="n">fatbin</span><span class="w"> </span><span class="n">callback</span><span class="p">.</span><span class="n">cu</span><span class="w"> </span><span class="o">-</span><span class="n">o</span><span class="w"> </span><span class="n">callback</span><span class="p">.</span><span class="n">fatbin</span><span class="w"></span> <span class="cp">#Turn the fatbin data into a C array inside a header, for easy inclusion in host code</span> <span class="n">bin2c</span><span class="w"> </span><span class="o">--</span><span class="n">name</span><span class="w"> </span><span class="n">my_lto_callback_fatbin</span><span class="w"> </span><span class="o">--</span><span class="n">type</span><span class="w"> </span><span class="n">longlong</span><span class="w"> </span><span class="n">callback</span><span class="p">.</span><span class="n">fatbin</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">callback_fatbin</span><span class="p">.</span><span class="n">h</span><span class="w"></span> </pre></div> </div> <p><strong>To associate</strong> the LTO callback with the cuFFT plan, users can leverage the new API call <code class="docutils literal notranslate"><span class="pre">cufftXtSetJITCallback()</span></code>, which works similarly to <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallback()</span></code>, with a few caveats.</p> <p>First, <code class="docutils literal notranslate"><span class="pre">cufftXtSetJITCallback()</span></code> must be called after plan creation with <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code>, and before calling the plan initialization function with <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code> and similar routines.</p> <p>Second, removing the LTO callback from the plan (using <code class="docutils literal notranslate"><span class="pre">cufftXtClearCallback()</span></code>) is currently not supported. A new plan must be created.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><cufftXt.h></span><span class="cp"></span> <span class="cp">#include</span><span class="w"> </span><span class="cpf">"callback_fatbin.h"</span><span class="cp"></span> <span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">cufftResult</span><span class="w"> </span><span class="n">status</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">cufftHandle</span><span class="w"> </span><span class="n">fft_plan</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">...</span><span class="w"></span> <span class="w"> </span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cufftCreate</span><span class="p">(</span><span class="o">&</span><span class="n">fft_plan</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="c1">// NOTE: LTO callbacks must be set before plan creation and cannot be unset (yet)</span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">lto_callback_fatbin_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">my_lto_callback_fatbin</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cufftXtSetJITCallback</span><span class="p">(</span><span class="n">fft_plan</span><span class="p">,</span><span class="w"> </span><span class="s">"myOwnLTOCallback"</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="n">my_lto_callback_fatbin</span><span class="p">,</span><span class="w"> </span><span class="n">lto_callback_fatbin_size</span><span class="p">,</span><span class="w"> </span><span class="n">CUFFT_CB_LD_REAL</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">**</span><span class="p">)</span><span class="o">&</span><span class="n">device_params</span><span class="p">));</span><span class="w"></span> <span class="w"> </span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cufftMakePlan1d</span><span class="p">(</span><span class="n">fft_plan</span><span class="p">,</span><span class="w"> </span><span class="n">signal_size</span><span class="p">,</span><span class="w"> </span><span class="n">CUFFT_C2R</span><span class="p">,</span><span class="w"> </span><span class="n">batches</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">work_size</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="p">...</span><span class="w"></span> <span class="p">}</span><span class="w"></span> </pre></div> </div> </section> <section id="lto-callback-routine-function-details"> <h4><span class="section-number">2.9.2.2. </span>LTO Callback Routine Function Details<a class="headerlink" href="#lto-callback-routine-function-details" title="Permalink to this headline"></a></h4> <p>Below are the function prototypes for the user-supplied LTO callback routines that cuFFT calls to load data prior to the transform.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="n">cufftComplex</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackLoadC</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftDoubleComplex</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackLoadZ</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackLoadR</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftDoubleReal</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackLoadD</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> </pre></div> </div> <p>Parameters for all of the LTO load callbacks are defined as below:</p> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">offset</span></code>: offset of the input element from the start of input data. This is not a byte offset, rather it is the number of elements from start of data.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">dataIn</span></code>: device pointer to the start of the input array that was passed in the <code class="docutils literal notranslate"><span class="pre">cufftExecute</span></code> call.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">callerInfo</span></code>: device pointer to the optional caller specified data passed in the <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallback</span></code> call.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">sharedPointer</span></code>: pointer to shared memory, valid only if the user has called <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallbackSharedSize()</span></code>.</p></li> </ul> <p>Below are the function prototypes, and typedefs for pointers to the user supplied LTO callback routines that cuFFT calls to store data after completion of the transform. Note that the store callback functions do not return a value. This is because a store callback function is responsible not only for transforming the data as desired, but also for writing the data to the desired location. This allows the store callback to rearrange the data, for example to shift the zero frequency result to the center of the ouput.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackStoreC</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">cufftComplex</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackStoreZ</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">cufftDoubleComplex</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackStoreR</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackStoreD</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">cufftDoubleReal</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> </pre></div> </div> <p>Parameters for all of the LTO store callbacks are defined as below:</p> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">offset</span></code>: offset of the output element from the start of output data. This is not a byte offset, rather it is the number of elements from start of data.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">dataOut</span></code>: device pointer to the start of the output array that was passed in the <code class="docutils literal notranslate"><span class="pre">cufftExecute</span></code> call.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">element</span></code>: the real or complex result computed by CUFFT for the element specified by the offset argument.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">callerInfo</span></code>: device pointer to the optional caller specified data passed in the <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallback</span></code> call.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">sharedPointer</span></code>: pointer to shared memory, valid only if the user has called <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallbackSharedSize()</span></code>.</p></li> </ul> </section> </section> <section id="legacy-load-and-store-callback-routines"> <h3><span class="section-number">2.9.3. </span>Legacy Load and Store Callback Routines<a class="headerlink" href="#legacy-load-and-store-callback-routines" title="Permalink to this headline"></a></h3> <section id="specifying-legacy-load-and-store-callback-routines"> <h4><span class="section-number">2.9.3.1. </span>Specifying Legacy Load and Store Callback Routines<a class="headerlink" href="#specifying-legacy-load-and-store-callback-routines" title="Permalink to this headline"></a></h4> <p>In order to associate a legacy callback routine with a plan, it is necessary to obtain a device pointer to the callback routine.</p> <p>As an example, if the user wants to specify a load callback for an R2C transform, they would write the device code for the callback function, and define a global device variable that contains a pointer to the function:</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">__device__</span><span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="n">myOwnCallback</span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPtr</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">// use offset, dataIn, and optionally callerInfo to</span> <span class="w"> </span><span class="c1">// compute the return value</span> <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span><span class="w"></span> <span class="p">}</span><span class="w"></span> <span class="n">__device__</span><span class="w"> </span><span class="n">cufftCallbackLoadR</span><span class="w"> </span><span class="n">myOwnCallbackPtr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">myOwnCallback</span><span class="p">;</span><span class="w"></span> </pre></div> </div> <p>From the host side, the user then has to get the address of the legacy callback routine, which is stored in <code class="docutils literal notranslate"><span class="pre">myOwnCallbackPtr</span></code>. This is done with <code class="docutils literal notranslate"><span class="pre">cudaMemcpyFromSymbol</span></code>, as follows:</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">cufftCallbackLoadR</span><span class="w"> </span><span class="n">hostCopyOfCallbackPtr</span><span class="p">;</span><span class="w"></span> <span class="n">cudaMemcpyFromSymbol</span><span class="p">(</span><span class="o">&</span><span class="n">hostCopyOfCallbackPtr</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">myOwnCallbackPtr</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">hostCopyOfCallbackPtr</span><span class="p">));</span><span class="w"></span> </pre></div> </div> <p><code class="docutils literal notranslate"><span class="pre">hostCopyOfCallbackPtr</span></code> then contains the device address of the callback routine, that should be passed to <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallback</span></code>. Note that, for multi-GPU transforms, <code class="docutils literal notranslate"><span class="pre">hostCopyOfCallbackPtr</span></code> will need to be an array of pointers, and the <code class="docutils literal notranslate"><span class="pre">cudaMemcpyFromSymbol</span></code> will have to be invoked for each GPU. Please note that <code class="docutils literal notranslate"><span class="pre">__managed__</span></code> variables are not suitable to pass to <code class="docutils literal notranslate"><span class="pre">cufftSetCallback</span></code> due to restrictions on variable usage (See the <em>NVIDIA CUDA Programming Guide</em> for more information about <code class="docutils literal notranslate"><span class="pre">__managed__</span></code> variables).</p> </section> <section id="legacy-callback-routine-function-details"> <h4><span class="section-number">2.9.3.2. </span>Legacy Callback Routine Function Details<a class="headerlink" href="#legacy-callback-routine-function-details" title="Permalink to this headline"></a></h4> <p>Below are the function prototypes, and typedefs for pointers to the user supplied legacy callback routines that cuFFT calls to load data prior to the transform.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="n">cufftComplex</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackLoadC</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftDoubleComplex</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackLoadZ</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackLoadR</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftDoubleReal</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackLoadD</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> </pre></div> </div> <p>Parameters for all of the legacy load callbacks are defined as below:</p> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">offset</span></code>: offset of the input element from the start of input data. This is not a byte offset, rather it is the number of elements from start of data.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">dataIn</span></code>: device pointer to the start of the input array that was passed in the <code class="docutils literal notranslate"><span class="pre">cufftExecute</span></code> call.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">callerInfo</span></code>: device pointer to the optional caller specified data passed in the <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallback</span></code> call.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">sharedPointer</span></code>: pointer to shared memory, valid only if the user has called <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallbackSharedSize()</span></code>.</p></li> </ul> <p>Below are the function prototypes, and typedefs for pointers to the user supplied legacy callback routines that cuFFT calls to store data after completion of the transform. Note that the store callback functions do not return a value. This is because a store callback function is responsible not only for transforming the data as desired, but also for writing the data to the desired location. This allows the store callback to rearrange the data, for example to shift the zero frequency result to the center of the ouput.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackStoreC</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">cufftComplex</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackStoreZ</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">cufftDoubleComplex</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackStoreR</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackStoreD</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">cufftDoubleReal</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> </pre></div> </div> <p>Parameters for all of the legacy store callbacks are defined as below:</p> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">offset</span></code>: offset of the output element from the start of output data. This is not a byte offset, rather it is the number of elements from start of data.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">dataOut</span></code>: device pointer to the start of the output array that was passed in the <code class="docutils literal notranslate"><span class="pre">cufftExecute</span></code> call.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">element</span></code>: the real or complex result computed by CUFFT for the element specified by the offset argument.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">callerInfo</span></code>: device pointer to the optional caller specified data passed in the <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallback</span></code> call.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">sharedPointer</span></code>: pointer to shared memory, valid only if the user has called <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallbackSharedSize()</span></code>.</p></li> </ul> </section> </section> <section id="coding-considerations-for-the-cufft-callback-routine-feature"> <h3><span class="section-number">2.9.4. </span>Coding Considerations for the cuFFT Callback Routine Feature<a class="headerlink" href="#coding-considerations-for-the-cufft-callback-routine-feature" title="Permalink to this headline"></a></h3> <p>cuFFT supports callbacks on all types of transforms, dimension, batch, or stride between elements. Callbacks are supported for transforms of single and double precision.</p> <p>cuFFT supports a wide range of parameters, and based on those for a given plan, it attempts to optimize performance. The number of kernels launched, and for each of those, the number of blocks launched and the number of threads per block, will vary depending on how cuFFT decomposes the transform. For some configurations, cuFFT will load or store (and process) multiple inputs or outputs per thread. For some configurations, threads may load or store inputs or outputs in any order, and cuFFT does not guarantee that the inputs or outputs handled by a given thread will be contiguous. These characteristics may vary with transform size, transform type (e.g. C2C vs C2R), number of dimensions, and GPU architecture. These variations may also change from one library version to the next.</p> <p>When more than one kernel are used to implement a transform, the thread and block structure of the first kernel (the one that does the load) is often different from the thread and block structure of the last kernel (the one that does the store).</p> <p>One common use of callbacks is to reduce the amount of data read or written to memory, either by selective filtering or via type conversions. When more than one kernel are used to implement a transform, cuFFT alternates using the workspace and the output buffer to write intermediate results. This means that the output buffer must always be large enough to accommodate the entire transform.</p> <p>For transforms whose dimensions can be factored into powers of 2, 3, 5, or 7, cuFFT guarantees that it will call the load and store callback routines from points in the kernel where it is safe to call the <code class="docutils literal notranslate"><span class="pre">__syncthreads</span></code> function from within the callback routine. The caller is responsible for guaranteeing that the callback routine is at a point where the callback code has converged, to avoid deadlock. For plans whose dimensions are factored into higher primes, results of a callback routine calling <code class="docutils literal notranslate"><span class="pre">__syncthreads</span></code> are not defined.</p> <p>Note that there are no guarantees on the relative order of execution of blocks within a grid. As such, callbacks should not rely on any particular ordering within a kernel. For instance, reordering data (such as an FFT-shift) could rely on the order of execution of the blocks. Results in this case would be undefined.</p> <section id="coding-considerations-for-lto-callback-routines"> <h4><span class="section-number">2.9.4.1. </span>Coding Considerations for LTO Callback Routines<a class="headerlink" href="#coding-considerations-for-lto-callback-routines" title="Permalink to this headline"></a></h4> <p>cuFFT will call the LTO load callback routine, for each point in the input, once and only once for real-to-complex (<code class="docutils literal notranslate"><span class="pre">R2C</span></code>, <code class="docutils literal notranslate"><span class="pre">D2Z</span></code>) and complex-to-complex (<code class="docutils literal notranslate"><span class="pre">C2C</span></code>, <code class="docutils literal notranslate"><span class="pre">Z2Z</span></code>) transforms. Unlike with legacy callbacks, <strong>LTO load callbacks may be called more than once per element for complex-to-real</strong> (<code class="docutils literal notranslate"><span class="pre">C2R</span></code>, <code class="docutils literal notranslate"><span class="pre">Z2D</span></code>) transforms. The input value will not be updated twice (i.e. the transformed value will be stored in register and not memory, even for in-place transforms), but users should not rely on the amount of calls per element in their callback device functions.</p> <p>Similarly to legacy callbacks, LTO store callbacks will be called once and only once for each point in the output. If the transform is being done in-place (i.e. the input and output data are in the same memory location) the store callback for a given element cannot overwrite other elements. It can either overwrite the given element, or write in a completely distinct output buffer.</p> <p>cuFFT does not support LTO callbacks for multi-GPU transforms (yet).</p> </section> <section id="coding-considerations-for-legacy-callback-routines"> <h4><span class="section-number">2.9.4.2. </span>Coding Considerations for Legacy Callback Routines<a class="headerlink" href="#coding-considerations-for-legacy-callback-routines" title="Permalink to this headline"></a></h4> <p>cuFFT supports legacy callbacks on any number of GPUs.</p> <p>cuFFT will call the load callback routine, for each point in the input, once and only once. Similarly it will call the store callback routine, for each point in the output, once and only once. If the transform is being done in-place (i.e. the input and output data are in the same memory location) the store callback for a given element cannot overwrite other elements. It can either overwrite the given element, or write in a completely distinct output buffer.</p> <p>For multi-GPU transforms, the index passed to the callback routine is the element index from the start of data <em>on that GPU</em>, not from the start of the entire input or output data array.</p> </section> </section> </section> <section id="thread-safety"> <h2><span class="section-number">2.10. </span>Thread Safety<a class="headerlink" href="#thread-safety" title="Permalink to this headline"></a></h2> <p>cuFFT APIs are thread safe as long as different host threads execute FFTs using different plans and the output data are disjoint.</p> </section> <section id="cuda-graphs-support"> <h2><span class="section-number">2.11. </span>CUDA Graphs Support<a class="headerlink" href="#cuda-graphs-support" title="Permalink to this headline"></a></h2> <p>Using <a class="reference external" href="https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#cuda-graphs">CUDA Graphs</a> with cuFFT is supported on single GPU plans. It is also supported on multiple GPU plans starting with cuFFT version 10.4.0. The stream associated with a cuFFT plan must meet the requirements stated in <a class="reference external" href="https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#creating-a-graph-using-stream-capture">Creating a Graph Using Stream Capture</a>.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Starting from CUDA 11.8 (including CUDA 12.0 onward), CUDA Graphs are no longer supported for legacy callback routines that load data in out-of-place mode transforms. Starting from CUDA 12.6 Update 2, LTO callbacks can be used as a replacement for legacy callbacks without this limitation. cuFFT deprecated callback functionality based on separate compiled device code (legacy callbacks) in cuFFT 11.4.</p> </div> </section> <section id="static-library-and-callback-support"> <h2><span class="section-number">2.12. </span>Static Library and Callback Support<a class="headerlink" href="#static-library-and-callback-support" title="Permalink to this headline"></a></h2> <p>Starting with release 6.5, the cuFFT libraries are also delivered in a static form as libcufft_static.a and libcufftw_static.a on Linux and Mac. Static libraries are not supported on Windows. The static cufft and cufftw libraries depend on thread abstraction layer library <code class="docutils literal notranslate"><span class="pre">libculibos.a</span></code>.</p> <p>For example, on linux, to compile a small application using cuFFT against the dynamic library, the following command can be used:</p> <div class="highlight-text notranslate"><div class="highlight"><pre><span></span>nvcc mCufftApp.c -lcufft -o myCufftApp </pre></div> </div> <p>For cufftw on Linux, to compile a small application against the dynamic library, the following command can be used:</p> <div class="highlight-text notranslate"><div class="highlight"><pre><span></span>nvcc mCufftwApp.c -lcufftw -lcufft -o myCufftwApp </pre></div> </div> <p>Whereas to compile against the static cuFFT library, extra steps need to be taken. The library needs to be device linked. It may happen during building and linking of a simple program, or as a separate step. The entire process is described in <a class="reference external" href="https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#using-separate-compilation-in-cuda">Using Separarate Compilation in CUDA</a>.</p> <p>For cuFFT and cufftw in version 9.0 or later any supported architecture can be used to do the device linking:</p> <p>Static cuFFT compilation command:</p> <div class="highlight-text notranslate"><div class="highlight"><pre><span></span>nvcc mCufftApp.c -lcufft_static -lculibos -o myCufftApp </pre></div> </div> <p>Static cufftw compilation command:</p> <div class="highlight-text notranslate"><div class="highlight"><pre><span></span>nvcc mCufftwApp.c -lcufftw_static -lcufft_static -lculibos -o myCufftwApp </pre></div> </div> <p>Prior to version 9.0 proper linking required specifying a subset of supported architectures, as shown in the following commands:</p> <p>Static cuFFT compilation command:</p> <div class="highlight-text notranslate"><div class="highlight"><pre><span></span>nvcc mCufftApp.c -lcufft_static -lculibos -o myCufftApp\ -gencode arch=compute_20,\"code=sm_20\"\ -gencode arch=compute_30,\"code=sm_30\"\ -gencode arch=compute_35,\"code=sm_35\"\ -gencode arch=compute_50,\"code=sm_50\"\ -gencode arch=compute_60,\"code=sm_60\"\ -gencode arch=compute_60,\"code=compute_60\" </pre></div> </div> <p>Static cufftw compilation command:</p> <div class="highlight-text notranslate"><div class="highlight"><pre><span></span>nvcc mCufftwApp.c -lcufftw_static -lcufft_static -lculibos -o myCufftwApp\ -gencode arch=compute_20,\"code=sm_20\"\ -gencode arch=compute_30,\"code=sm_30\"\ -gencode arch=compute_35,\"code=sm_35\"\ -gencode arch=compute_50,\"code=sm_50\"\ -gencode arch=compute_60,\"code=sm_60\"\ -gencode arch=compute_60,\"code=compute_60\" </pre></div> </div> <p>Please note that the cuFFT library might not contain code for certain architectures as long as there is code for a lower architecture that is binary compatibile (e.g. SM52, SM61). This is reflected in link commands above and significant when using versions prior r9.0. To determine if a specific SM is included in the cuFFT library, one may use <code class="docutils literal notranslate"><span class="pre">cuobjdump</span></code> utility. For example, if you wish to know if SM_50 is included, the command to run is <code class="docutils literal notranslate"><span class="pre">cuobjdump</span> <span class="pre">-arch</span> <span class="pre">sm_50</span> <span class="pre">libcufft_static.a</span></code>. Some kernels are built only on select architectures (e.g. kernels with half precision arithmetics are present only for SM53 and above). This can cause warnings at link time that architectures are missing from these kernels. These warnings can be safely ignored.</p> <p>It is also possible to use the native Host C++ compiler and perform device link as a separate step. Please consult NVCC documentation for more details. Depending on the Host Operating system, some additional libraries like <code class="docutils literal notranslate"><span class="pre">pthread</span></code> or <code class="docutils literal notranslate"><span class="pre">dl</span></code> might be needed on the linking line.</p> <p>Note that in this case, the library <code class="docutils literal notranslate"><span class="pre">cuda</span></code> is not needed. The CUDA Runtime will try to open explicitly the <code class="docutils literal notranslate"><span class="pre">cuda</span></code> library if needed. In the case of a system which does not have the CUDA driver installed, this allows the application to gracefully manage this issue and potentially run if a CPU-only path is available.</p> <p>The cuFFT static library supports user supplied legacy callback routines. The legacy callback routines are CUDA device code, and must be separately compiled with NVCC and linked with the cuFFT library. Please refer to the NVCC documentation regarding separate compilation for details. If you specify an SM when compiling your callback functions, you must specify one of the SM’s cuFFT includes.</p> <section id="static-library-without-legacy-callback-support"> <h3><span class="section-number">2.12.1. </span>Static library without legacy callback support<a class="headerlink" href="#static-library-without-legacy-callback-support" title="Permalink to this headline"></a></h3> <p>Starting with cuFFT version 9.2, a new variant of the cuFTT static library, <code class="docutils literal notranslate"><span class="pre">libcufft_static_nocallback.a</span></code>, was added. This new version does not contain legacy callback functionality and can be linked using the host compiler only.</p> </section> </section> <section id="accuracy-and-performance"> <h2><span class="section-number">2.13. </span>Accuracy and Performance<a class="headerlink" href="#accuracy-and-performance" title="Permalink to this headline"></a></h2> <p>A DFT can be implemented as a matrix vector multiplication that requires <span class="math notranslate nohighlight">\(O(N^{2})\)</span> operations. However, the cuFFT Library employs the <a class="reference external" href="http://en.wikipedia.org/wiki/Cooley-Tukey_FFT_algorithm">Cooley-Tukey algorithm</a> to reduce the number of required operations to optimize the performance of particular transform sizes. This algorithm expresses the DFT matrix as a product of sparse building block matrices. The cuFFT Library implements the following building blocks: radix-2, radix-3, radix-5, and radix-7. Hence the performance of any transform size that can be factored as <span class="math notranslate nohighlight">\(2^{a} \times 3^{b} \times 5^{c} \times 7^{d}\)</span> (where <em>a</em>, <em>b</em>, <em>c</em>, and <em>d</em> are non-negative integers) is optimized in the cuFFT library. There are also radix-m building blocks for other primes, m, whose value is < 128. When the length cannot be decomposed as multiples of powers of primes from 2 to 127, <a class="reference external" href="http://en.wikipedia.org/wiki/Bluestein's_FFT_algorithm">Bluestein’s algorithm</a> is used. Since the Bluestein implementation requires more computations per output point than the Cooley-Tukey implementation, the accuracy of the Cooley-Tukey algorithm is better. The pure Cooley-Tukey implementation has excellent accuracy, with the relative error growing proportionally to <span class="math notranslate nohighlight">\(\log_{2}(N)\)</span> , where <span class="math notranslate nohighlight">\(N\)</span> is the transform size in points.</p> <p>For sizes handled by the Cooley-Tukey code path, the most efficient implementation is obtained by applying the following constraints (listed in order from the most generic to the most specialized constraint, with each subsequent constraint providing the potential of an additional performance improvement).</p> <p>Half precision transforms might not be suitable for all kinds of problems due to limited range represented by half precision floating point arithmetics. Please note that the first element of FFT result is the sum of all input elements and it is likely to overflow for certain inputs.</p> <p>Results produced by the cuFFT library are deterministic (ie, bitwise reproducible) as long as the following are kept constant between runs: plan input parameters, cuFFT version, and GPU model.</p> <p>cuFFT batched plans require that input data includes valid signal for all batches. Performance optimizations in batched mode can combine signal from different batches for processing. Optimizations used in cuFFT can vary from version to version.</p> <table class="table-no-stripes docutils align-default"> <colgroup> <col style="width: 14%" /> <col style="width: 38%" /> <col style="width: 49%" /> </colgroup> <thead> <tr class="row-odd"><th class="head"><p>Applies to</p></th> <th class="head"><p>Recommendation</p></th> <th class="head"><p>Comment</p></th> </tr> </thead> <tbody> <tr class="row-even"><td><p>All</p></td> <td><p>Use single precision transforms.</p></td> <td><p>Single precision transforms require less bandwidth per computation than double precision transforms.</p></td> </tr> <tr class="row-odd"><td><p>All</p></td> <td><p>Restrict the size along all dimensions to be representable as <span class="math notranslate nohighlight">\(2^{a} \times 3^{b} \times 5^{c} \times 7^{d}\)</span>.</p></td> <td><p>The cuFFT library has highly optimized kernels for transforms whose dimensions have these prime factors. In general the best performance occurs when using powers of 2, followed by powers of 3, then 5, 7.</p></td> </tr> <tr class="row-even"><td><p>All</p></td> <td><p>Restrict the size along each dimension to use fewer distinct prime factors.</p></td> <td><p>A transform of size <span class="math notranslate nohighlight">\(2^{n}\)</span> or <span class="math notranslate nohighlight">\(3^{n}\)</span> will usually be faster than one of size <span class="math notranslate nohighlight">\(2^{i} \times 3^{j}\)</span> even if the latter is slightly smaller, due to the composition of specialized paths.</p></td> </tr> <tr class="row-odd"><td><p>All</p></td> <td><p>Restrict the data to be contiguous in memory when performing a single transform. When performing multiple transforms make the individual datasets contiguous</p></td> <td><p>The cuFFT library has been optimized for this data layout.</p></td> </tr> <tr class="row-even"><td><p>All</p></td> <td><p>Perform multiple (i.e., batched) transforms.</p></td> <td><p>Additional optimizations are performed in batched mode.</p></td> </tr> <tr class="row-odd"><td><p>real-to-complex transforms or complex-to-real transforms</p></td> <td><p>Ensure problem size of x dimension is a multiple of 4.</p></td> <td><p>This scheme uses more efficient kernels to implement conjugate symmetry property.</p></td> </tr> <tr class="row-even"><td><p>real-to-complex transforms or complex-to-real transforms</p></td> <td><p>Use <code class="docutils literal notranslate"><span class="pre">out-of-place</span></code> mode.</p></td> <td><p>This scheme uses more efficient kernels than <code class="docutils literal notranslate"><span class="pre">in-place</span></code> mode.</p></td> </tr> <tr class="row-odd"><td><p>Multiple GPU transforms</p></td> <td><p>Use PCI Express 3.0 between GPUs and ensure the GPUs are on the same switch.</p></td> <td><p>The faster the interconnect between the GPUs, the faster the performance.</p></td> </tr> </tbody> </table> </section> <section id="caller-allocated-work-area-support"> <h2><span class="section-number">2.14. </span>Caller Allocated Work Area Support<a class="headerlink" href="#caller-allocated-work-area-support" title="Permalink to this headline"></a></h2> <p>cuFFT plans may use additional memory to store intermediate results. The cuFFT library offers several functions to manage this temporary memory utilization behavior:</p> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">cufftSetAutoAllocation</span></code></p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftEstimate1d</span></code>, <code class="docutils literal notranslate"><span class="pre">cufftEstimate2d</span></code>, <code class="docutils literal notranslate"><span class="pre">cufftEstimate3d</span></code> and <code class="docutils literal notranslate"><span class="pre">cufftEstimateMany</span></code></p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftGetSize</span></code></p></li> <li><p><code class="docutils literal notranslate"><span class="pre">cufftXtSetWorkAreaPolicy</span></code></p></li> </ul> <p>The first two functions manage allocation and ownership of temporary memory. By default cuFFT always allocates its own work area in GPU memory. Each cuFFT handle allocates data separately. If multiple cuFFT plans are to be launched sequentially it is possible to assign the same memory chunk as work area to all those plans and reduce memory overhead.</p> <p>The memory assigned as work area needs to be GPU visible. In addition to the regular memory acquired with <code class="docutils literal notranslate"><span class="pre">cudaMalloc</span></code>, usage of CUDA Unified Virtual Addressing enables cuFFT to use the following types of memory as work area memory: pinned host memory, managed memory, memory on GPU other than the one performing the calculations. While this provides flexibility, it comes with a performance penalty whose magnitude depends on the available memory bandwidth.</p> <p>The <code class="docutils literal notranslate"><span class="pre">cufftEstimateNd</span></code>, <code class="docutils literal notranslate"><span class="pre">cufftEstimateMany</span></code>, and <code class="docutils literal notranslate"><span class="pre">cufftGetSize</span></code> functions provide information about the required memory size for cases where the user is allocating the work space buffer.</p> <div class="line-block"> <div class="line">In version 9.2 cuFFT also introduced the <code class="docutils literal notranslate"><span class="pre">cufftXtSetWorkAreaPolicy</span></code> function. This function allows fine tuning of work area memory usage.</div> <div class="line">cuFFT 9.2 version supports only the <code class="docutils literal notranslate"><span class="pre">CUFFT_WORKAREA_MINIMAL</span></code> policy, which instructs cuFFT to re-plan the existing plan without the need to use work area memory.</div> </div> <p>Also as of cuFFT 9.2, supported FFT transforms that allow for <code class="docutils literal notranslate"><span class="pre">CUFFT_WORKAREA_MINIMAL</span></code> policy are as follows:</p> <ul class="simple"> <li><p>Transforms of type <code class="docutils literal notranslate"><span class="pre">C2C</span></code> are supported with sizes up to 4096 in any dimension.</p></li> <li><p>Transforms of type <code class="docutils literal notranslate"><span class="pre">Z2Z</span></code> are supported with sizes up to 2048 in any dimension.</p></li> <li><p>Only single GPU transforms are supported.</p></li> </ul> <p>Depending on the FFT transform size, a different FFT algorithm may be used when the <code class="docutils literal notranslate"><span class="pre">CUFFT_WORKAREA_MINIMAL</span></code> policy is set.</p> </section> <section id="cufft-link-time-optimized-kernels"> <h2><span class="section-number">2.15. </span>cuFFT Link-Time Optimized Kernels<a class="headerlink" href="#cufft-link-time-optimized-kernels" title="Permalink to this headline"></a></h2> <p>Starting from CUDA 12.4, cuFFT ships Link-Time Optimized (LTO) kernels. These kernels are linked and finalized at runtime as part of the cuFFT planning routines. This enables the cuFFT library to generate kernels optimized for the underlying architecture and the specific problem to solve.</p> <p>The current LTO kernel coverage includes:</p> <ul class="simple"> <li><p>Kernels for 64-bit addressing (with FFTs spanning addresses greater than 2^(32)-1 elements).</p></li> <li><p>Some single- and double-precision R2C and C2R sizes.</p></li> </ul> <p>The number and coverage of LTO kernels will grow with future releases of cuFFT. We encourage our users to test whether LTO kernels improve the performance for their use case.</p> <p>Users can opt-in into LTO kernels by setting the <code class="docutils literal notranslate"><span class="pre">NVFFT_PLAN_PROPERTY_INT64_PATIENT_JIT</span></code> plan property using the <code class="docutils literal notranslate"><span class="pre">cufftSetPlanProperty</span></code> routine.</p> <p>In order to finalize LTO kernels, cuFFT relies on the nvJitLink library that ships as part of the CUDA Toolkit. Finalizing the kernels at runtime can cause an <strong>increase in planning time</strong> (which could be in the order of hundreds of milliseconds, depending on the cuFFT plan and hardware characteristics of the host system), in exchange for faster execution time of the optimized kernels. Note that nvJitLink caches kernels linked at runtime to speed-up subsequent kernel finalizations in repeated planning routines.</p> <p>If for any reason the runtime linking of the kernel fails, cuFFT will fall back to offline-compiled kernels to compute the FFT.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>cuFFT LTO kernels for a given toolkit version require using the nvJitLink library from the same toolkit or greater, but within the same toolkit major. For example, cuFFT in 12.4 requires nvJitLink to be from a CUDA Toolkit 12.X, with <code class="docutils literal notranslate"><span class="pre">X</span> <span class="pre">>=</span> <span class="pre">4</span></code>.</p> <p>The nvJitLink library is loaded dynamically, and should be present in the system’s dynamic linking path (e.g. <code class="docutils literal notranslate"><span class="pre">LD_LIBRARY_PATH</span></code> on Unix systems, or <code class="docutils literal notranslate"><span class="pre">PATH</span></code> on Windows systems).</p> </div> </section> </section> <section id="cufft-api-reference"> <h1><span class="section-number">3. </span>cuFFT API Reference<a class="headerlink" href="#cufft-api-reference" title="Permalink to this headline"></a></h1> <p>This chapter specifies the behavior of the cuFFT library functions by describing their input/output parameters, data types, and error codes. The cuFFT library is initialized upon the first invocation of an API function, and cuFFT shuts down automatically when all user-created FFT plans are destroyed.</p> <section id="return-value-cufftresult"> <h2><span class="section-number">3.1. </span>Return value cufftResult<a class="headerlink" href="#return-value-cufftresult" title="Permalink to this headline"></a></h2> <p>All cuFFT Library return values except for <code class="docutils literal notranslate"><span class="pre">CUFFT_SUCCESS</span></code> indicate that the current API call failed and the user should reconfigure to correct the problem. The possible return values are defined as follows:</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">enum</span><span class="w"> </span><span class="nc">cufftResult_t</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_SUCCESS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="c1">// The cuFFT operation was successful</span> <span class="w"> </span><span class="n">CUFFT_INVALID_PLAN</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="c1">// cuFFT was passed an invalid plan handle</span> <span class="w"> </span><span class="n">CUFFT_ALLOC_FAILED</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="c1">// cuFFT failed to allocate GPU or CPU memory</span> <span class="w"> </span><span class="n">CUFFT_INVALID_TYPE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="c1">// No longer used</span> <span class="w"> </span><span class="n">CUFFT_INVALID_VALUE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="c1">// User specified an invalid pointer or parameter</span> <span class="w"> </span><span class="n">CUFFT_INTERNAL_ERROR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="w"> </span><span class="c1">// Driver or internal cuFFT library error</span> <span class="w"> </span><span class="n">CUFFT_EXEC_FAILED</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">6</span><span class="p">,</span><span class="w"> </span><span class="c1">// Failed to execute an FFT on the GPU</span> <span class="w"> </span><span class="n">CUFFT_SETUP_FAILED</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">7</span><span class="p">,</span><span class="w"> </span><span class="c1">// The cuFFT library failed to initialize</span> <span class="w"> </span><span class="n">CUFFT_INVALID_SIZE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">8</span><span class="p">,</span><span class="w"> </span><span class="c1">// User specified an invalid transform size</span> <span class="w"> </span><span class="n">CUFFT_UNALIGNED_DATA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">9</span><span class="p">,</span><span class="w"> </span><span class="c1">// No longer used</span> <span class="w"> </span><span class="n">CUFFT_INCOMPLETE_PARAMETER_LIST</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="c1">// Missing parameters in call</span> <span class="w"> </span><span class="n">CUFFT_INVALID_DEVICE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">11</span><span class="p">,</span><span class="w"> </span><span class="c1">// Execution of a plan was on different GPU than plan creation</span> <span class="w"> </span><span class="n">CUFFT_PARSE_ERROR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">12</span><span class="p">,</span><span class="w"> </span><span class="c1">// Internal plan database error</span> <span class="w"> </span><span class="n">CUFFT_NO_WORKSPACE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">13</span><span class="w"> </span><span class="c1">// No workspace has been provided prior to plan execution</span> <span class="w"> </span><span class="n">CUFFT_NOT_IMPLEMENTED</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">14</span><span class="p">,</span><span class="w"> </span><span class="c1">// Function does not implement functionality for parameters given.</span> <span class="w"> </span><span class="n">CUFFT_LICENSE_ERROR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">15</span><span class="p">,</span><span class="w"> </span><span class="c1">// Used in previous versions.</span> <span class="w"> </span><span class="n">CUFFT_NOT_SUPPORTED</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">16</span><span class="w"> </span><span class="c1">// Operation is not supported for parameters given.</span> <span class="p">}</span><span class="w"> </span><span class="n">cufftResult</span><span class="p">;</span><span class="w"></span> </pre></div> </div> <p>Users are encouraged to check return values from cuFFT functions for errors as shown in <a class="reference external" href="index.html#cufft-code-examples">cuFFT Code Examples</a>.</p> </section> <section id="cufft-basic-plans"> <h2><span class="section-number">3.2. </span>cuFFT Basic Plans<a class="headerlink" href="#cufft-basic-plans" title="Permalink to this headline"></a></h2> <p>These API routines take care of initializing the cufftHandle. Any already-initialized handle attributes passed to the planning functions will be ignored.</p> <section id="cufftplan1d"> <h3><span class="section-number">3.2.1. </span>cufftPlan1d()<a class="headerlink" href="#cufftplan1d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftPlan1d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftPlan1d</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftPlan1d" title="Permalink to this definition"></a><br /></dt> <dd><p>Creates a 1D FFT plan configuration for a specified signal size and data type. The <code class="docutils literal notranslate"><span class="pre">batch</span></code> input parameter tells cuFFT how many 1D transforms to configure.</p> <p>This call can only be used once for a given handle. It will fail and return <code class="docutils literal notranslate"><span class="pre">CUFFT_INVALID_PLAN</span></code> if the plan is locked, i.e. the handle was previously used with a different <code class="docutils literal notranslate"><span class="pre">cufftPlan</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code> call.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – Pointer to an uninitialized <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> object.</p></li> <li><p><strong>nx[In]</strong> – The transform size (e.g. 256 for a 256-point FFT).</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_C2C</span></code> for single precision complex to complex).</p></li> <li><p><strong>batch[In]</strong> – Number of transforms of size <code class="docutils literal notranslate"><span class="pre">nx</span></code>. Please consider using <code class="docutils literal notranslate"><span class="pre">cufftPlanMany</span></code> for multiple transforms.</p></li> <li><p><strong>plan[Out]</strong> – Contains a cuFFT 1D plan handle value.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully created the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle. Handle is not valid when the plan is locked.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – The <code class="docutils literal notranslate"><span class="pre">nx</span></code> or <code class="docutils literal notranslate"><span class="pre">batch</span></code> parameter is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftplan2d"> <h3><span class="section-number">3.2.2. </span>cufftPlan2d()<a class="headerlink" href="#cufftplan2d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftPlan2d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftPlan2d</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ny</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftPlan2d" title="Permalink to this definition"></a><br /></dt> <dd><p>Creates a 2D FFT plan configuration according to specified signal sizes and data type.</p> <p>This call can only be used once for a given handle. It will fail and return <code class="docutils literal notranslate"><span class="pre">CUFFT_INVALID_PLAN</span></code> if the plan is locked, i.e. the handle was previously used with a different <code class="docutils literal notranslate"><span class="pre">cufftPlan</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code> call.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – Pointer to an uninitialized <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> object.</p></li> <li><p><strong>nx[In]</strong> – The transform size in the <em>x</em> dimension This is slowest changing dimension of a transform (strided in memory).</p></li> <li><p><strong>ny[In]</strong> – The transform size in the <em>y</em> dimension. This is fastest changing dimension of a transform (contiguous in memory).</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_C2R</span></code> for single precision complex to real).</p></li> <li><p><strong>plan[Out]</strong> – Contains a cuFFT 2D plan handle value.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully created the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle. Handle is not valid when the plan is locked.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – Either or both of the <code class="docutils literal notranslate"><span class="pre">nx</span></code> or <code class="docutils literal notranslate"><span class="pre">ny</span></code> parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftplan3d"> <h3><span class="section-number">3.2.3. </span>cufftPlan3d()<a class="headerlink" href="#cufftplan3d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftPlan3d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftPlan3d</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ny</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nz</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftPlan3d" title="Permalink to this definition"></a><br /></dt> <dd><p>Creates a 3D FFT plan configuration according to specified signal sizes and data type. This function is the same as <code class="docutils literal notranslate"><span class="pre">cufftPlan2d()</span></code> except that it takes a third size parameter <code class="docutils literal notranslate"><span class="pre">nz</span></code>.</p> <p>This call can only be used once for a given handle. It will fail and return <code class="docutils literal notranslate"><span class="pre">CUFFT_INVALID_PLAN</span></code> if the plan is locked, i.e. the handle was previously used with a different <code class="docutils literal notranslate"><span class="pre">cufftPlan</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code> call.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – Pointer to an uninitialized <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> object.</p></li> <li><p><strong>nx[In]</strong> – The transform size in the <em>x</em> dimension. This is slowest changing dimension of a transform (strided in memory).</p></li> <li><p><strong>ny[In]</strong> – The transform size in the <em>y</em> dimension.</p></li> <li><p><strong>nz[In]</strong> – The transform size in the <em>z</em> dimension. This is fastest changing dimension of a transform (contiguous in memory).</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_R2C</span></code> for single precision real to complex).</p></li> <li><p><strong>plan[Out]</strong> – Contains a cuFFT 3D plan handle value.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully created the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle. Handle is not valid when the plan is locked.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the <code class="docutils literal notranslate"><span class="pre">nx</span></code>, <code class="docutils literal notranslate"><span class="pre">ny</span></code>, or <code class="docutils literal notranslate"><span class="pre">nz</span></code> parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftplanmany"> <h3><span class="section-number">3.2.4. </span>cufftPlanMany()<a class="headerlink" href="#cufftplanmany" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftPlanMany"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftPlanMany</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">rank</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">n</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">inembed</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">istride</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">idist</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">onembed</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ostride</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">odist</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftPlanMany" title="Permalink to this definition"></a><br /></dt> <dd><p>Creates a FFT plan configuration of dimension <code class="docutils literal notranslate"><span class="pre">rank</span></code>, with sizes specified in the array <code class="docutils literal notranslate"><span class="pre">n</span></code>. The <code class="docutils literal notranslate"><span class="pre">batch</span></code> input parameter tells cuFFT how many transforms to configure. With this function, batched plans of 1, 2, or 3 dimensions may be created.</p> <p>The <code class="docutils literal notranslate"><span class="pre">cufftPlanMany()</span></code> API supports more complicated input and output data layouts via the advanced data layout parameters: <code class="docutils literal notranslate"><span class="pre">inembed</span></code>, <code class="docutils literal notranslate"><span class="pre">istride</span></code>, <code class="docutils literal notranslate"><span class="pre">idist</span></code>, <code class="docutils literal notranslate"><span class="pre">onembed</span></code>, <code class="docutils literal notranslate"><span class="pre">ostride</span></code>, and <code class="docutils literal notranslate"><span class="pre">odist</span></code>.</p> <p>If <code class="docutils literal notranslate"><span class="pre">inembed</span></code> and <code class="docutils literal notranslate"><span class="pre">onembed</span></code> are set to <code class="docutils literal notranslate"><span class="pre">NULL</span></code>, all other stride information is ignored, and default strides are used. The default assumes contiguous data arrays.</p> <p>All arrays are assumed to be in CPU memory.</p> <p>Please note that behavior of <code class="docutils literal notranslate"><span class="pre">cufftPlanMany</span></code> function when <code class="docutils literal notranslate"><span class="pre">inembed</span></code> and <code class="docutils literal notranslate"><span class="pre">onembed</span></code> is <code class="docutils literal notranslate"><span class="pre">NULL</span></code> is different than corresponding function in FFTW library <code class="docutils literal notranslate"><span class="pre">fftw_plan_many_dft</span></code>.</p> <p>This call can only be used once for a given handle. It will fail and return <code class="docutils literal notranslate"><span class="pre">CUFFT_INVALID_PLAN</span></code> if the plan is locked, i.e. the handle was previously used with a different <code class="docutils literal notranslate"><span class="pre">cufftPlan</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code> call.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – Pointer to an uninitialized <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> object.</p></li> <li><p><strong>rank[In]</strong> – Dimensionality of the transform (1, 2, or 3).</p></li> <li><p><strong>n[In]</strong> – Array of size <code class="docutils literal notranslate"><span class="pre">rank</span></code>, describing the size of each dimension, <code class="docutils literal notranslate"><span class="pre">n[0]</span></code> being the size of the outermost and <code class="docutils literal notranslate"><span class="pre">n[rank-1]</span></code> innermost (contiguous) dimension of a transform.</p></li> <li><p><strong>inembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the input data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>istride[In]</strong> – Indicates the distance between two successive input elements in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>idist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the input data.</p></li> <li><p><strong>onembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the output data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>ostride[In]</strong> – Indicates the distance between two successive output elements in the output array in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>odist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the output data.</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_R2C</span></code> for single precision real to complex).</p></li> <li><p><strong>batch[In]</strong> – Batch size for this transform.</p></li> <li><p><strong>plan[Out]</strong> – Contains a cuFFT plan handle.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully created the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle. Handle is not valid when the plan is locked.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> </section> <section id="cufft-extensible-plans"> <h2><span class="section-number">3.3. </span>cuFFT Extensible Plans<a class="headerlink" href="#cufft-extensible-plans" title="Permalink to this headline"></a></h2> <p>These API routines separates handle creation from plan generation. This makes it possible to change plan settings, which may alter the outcome of the plan generation phase, before the plan is actually generated.</p> <section id="cufftcreate"> <h3><span class="section-number">3.3.1. </span>cufftCreate()<a class="headerlink" href="#cufftcreate" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftCreate"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftCreate</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">plan</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.cufftCreate" title="Permalink to this definition"></a><br /></dt> <dd><p>Creates only an opaque handle, and allocates small data structures on the host. The <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code> calls actually do the plan generation.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – Pointer to a <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> object.</p></li> <li><p><strong>plan[Out]</strong> – Contains a cuFFT plan handle value.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully created the FFT plan.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftdestroy"> <h3><span class="section-number">3.3.2. </span>cufftDestroy()<a class="headerlink" href="#cufftdestroy" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftDestroy"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftDestroy</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.cufftDestroy" title="Permalink to this definition"></a><br /></dt> <dd><p>Frees all GPU resources associated with a cuFFT plan and destroys the internal plan data structure. This function should be called once a plan is no longer needed, to avoid wasting GPU memory. In the case of multi-GPU plans, the plan created first should be destroyed last.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – The <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> object of the plan to be destroyed.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully destroyed the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftmakeplan1d"> <h3><span class="section-number">3.3.3. </span>cufftMakePlan1d()<a class="headerlink" href="#cufftmakeplan1d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftMakePlan1d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftMakePlan1d</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftMakePlan1d" title="Permalink to this definition"></a><br /></dt> <dd><p>Following a call to <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> makes a 1D FFT plan configuration for a specified signal size and data type. The <code class="docutils literal notranslate"><span class="pre">batch</span></code> input parameter tells cuFFT how many 1D transforms to configure.</p> <p>This call can only be used once for a given handle. It will fail and return <code class="docutils literal notranslate"><span class="pre">CUFFT_INVALID_PLAN</span></code> if the plan is locked, i.e. the handle was previously used with a different <code class="docutils literal notranslate"><span class="pre">cufftPlan</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code> call.</p> <p>If <code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> was called prior to this call with multiple GPUs, then <code class="docutils literal notranslate"><span class="pre">workSize</span></code> will contain multiple sizes. See sections on multiple GPUs for more details.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>nx[In]</strong> – The transform size (e.g. 256 for a 256-point FFT). For multiple GPUs, this must be a power of 2.</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_C2C</span></code> for single precision complex to complex). For multiple GPUs this must be a complex to complex transform.</p></li> <li><p><strong>batch[In]</strong> – Number of transforms of size <code class="docutils literal notranslate"><span class="pre">nx</span></code>. Please consider using <code class="docutils literal notranslate"><span class="pre">cufftMakePlanMany</span></code> for multiple transforms.</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size(s) of the work areas.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully created the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle. Handle is not valid when the plan is locked or multi-GPU restrictions are not met.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED`</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – The <code class="docutils literal notranslate"><span class="pre">nx</span></code> or <code class="docutils literal notranslate"><span class="pre">batch</span></code> parameter is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftmakeplan2d"> <h3><span class="section-number">3.3.4. </span>cufftMakePlan2d()<a class="headerlink" href="#cufftmakeplan2d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftMakePlan2d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftMakePlan2d</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ny</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftMakePlan2d" title="Permalink to this definition"></a><br /></dt> <dd><p>Following a call to <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> makes a 2D FFT plan configuration according to specified signal sizes and data type.</p> <p>This call can only be used once for a given handle. It will fail and return <code class="docutils literal notranslate"><span class="pre">CUFFT_INVALID_PLAN</span></code> if the plan is locked, i.e. the handle was previously used with a different <code class="docutils literal notranslate"><span class="pre">cufftPlan</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code> call.</p> <p>If <code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> was called prior to this call with multiple GPUs, then <code class="docutils literal notranslate"><span class="pre">workSize</span></code> will contain multiple sizes. See sections on multiple GPUs for more details.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>nx[In]</strong> – The transform size in the <em>x</em> dimension. This is slowest changing dimension of a transform (strided in memory). For multiple GPUs, this must be factorable into primes less than or equal to 127.</p></li> <li><p><strong>ny[In]</strong> – The transform size in the <em>y</em> dimension. This is fastest changing dimension of a transform (contiguous in memory). For 2 GPUs, this must be factorable into primes less than or equal to 127.</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_C2R</span></code> for single precision complex to real).</p></li> <li><p><strong>workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size(s) of the work areas.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully created the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – Either or both of the <code class="docutils literal notranslate"><span class="pre">nx</span></code> or <code class="docutils literal notranslate"><span class="pre">ny</span></code> parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftmakeplan3d"> <h3><span class="section-number">3.3.5. </span>cufftMakePlan3d()<a class="headerlink" href="#cufftmakeplan3d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftMakePlan3d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftMakePlan3d</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ny</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nz</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftMakePlan3d" title="Permalink to this definition"></a><br /></dt> <dd><p>Following a call to <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> makes a 3D FFT plan configuration according to specified signal sizes and data type. This function is the same as <code class="docutils literal notranslate"><span class="pre">cufftPlan2d()</span></code> except that it takes a third size parameter <code class="docutils literal notranslate"><span class="pre">nz</span></code>.</p> <p>This call can only be used once for a given handle. It will fail and return <code class="docutils literal notranslate"><span class="pre">CUFFT_INVALID_PLAN</span></code> if the plan is locked, i.e. the handle was previously used with a different <code class="docutils literal notranslate"><span class="pre">cufftPlan</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code> call.</p> <p>If <code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> was called prior to this call with multiple GPUs, then <code class="docutils literal notranslate"><span class="pre">workSize</span></code> will contain multiple sizes. See sections on multiple GPUs for more details.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>nx[In]</strong> – The transform size in the <em>x</em> dimension. This is slowest changing dimension of a transform (strided in memory). For multiple GPUs, this must be factorable into primes less than or equal to 127.</p></li> <li><p><strong>ny[In]</strong> – The transform size in the <em>y</em> dimension. For multiple GPUs, this must be factorable into primes less than or equal to 127.</p></li> <li><p><strong>nz[In]</strong> – The transform size in the <em>z</em> dimension. This is fastest changing dimension of a transform (contiguous in memory). For multiple GPUs, this must be factorable into primes less than or equal to 127.</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_R2C</span></code> for single precision real to complex).</p></li> <li><p><strong>workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size(s) of the work area(s).</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully created the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the <code class="docutils literal notranslate"><span class="pre">nx</span></code>, <code class="docutils literal notranslate"><span class="pre">ny</span></code>, or <code class="docutils literal notranslate"><span class="pre">nz</span></code> parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftmakeplanmany"> <h3><span class="section-number">3.3.6. </span>cufftMakePlanMany()<a class="headerlink" href="#cufftmakeplanmany" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftMakePlanMany"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftMakePlanMany</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">rank</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">n</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">inembed</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">istride</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">idist</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">onembed</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ostride</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">odist</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftMakePlanMany" title="Permalink to this definition"></a><br /></dt> <dd><p>Following a call to <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> makes a FFT plan configuration of dimension <code class="docutils literal notranslate"><span class="pre">rank</span></code>, with sizes specified in the array <code class="docutils literal notranslate"><span class="pre">n</span></code>. The <code class="docutils literal notranslate"><span class="pre">batch</span></code> input parameter tells cuFFT how many transforms to configure. With this function, batched plans of 1, 2, or 3 dimensions may be created.</p> <p>The <code class="docutils literal notranslate"><span class="pre">cufftPlanMany()</span></code> API supports more complicated input and output data layouts via the advanced data layout parameters: <code class="docutils literal notranslate"><span class="pre">inembed</span></code>, <code class="docutils literal notranslate"><span class="pre">istride</span></code>, <code class="docutils literal notranslate"><span class="pre">idist</span></code>, <code class="docutils literal notranslate"><span class="pre">onembed</span></code>, <code class="docutils literal notranslate"><span class="pre">ostride</span></code>, and <code class="docutils literal notranslate"><span class="pre">odist</span></code>.</p> <p>If <code class="docutils literal notranslate"><span class="pre">inembed</span></code> and <code class="docutils literal notranslate"><span class="pre">onembed</span></code> are set to <code class="docutils literal notranslate"><span class="pre">NULL</span></code>, all other stride information is ignored, and default strides are used. The default assumes contiguous data arrays.</p> <p>This call can only be used once for a given handle. It will fail and return <code class="docutils literal notranslate"><span class="pre">CUFFT_INVALID_PLAN</span></code> if the plan is locked, i.e. the handle was previously used with a different <code class="docutils literal notranslate"><span class="pre">cufftPlan</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code> call.</p> <p>If <code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> was called prior to this call with multiple GPUs, then <code class="docutils literal notranslate"><span class="pre">workSize</span></code> will contain multiple sizes. See sections on multiple GPUs for more details.</p> <p>All arrays are assumed to be in CPU memory.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>rank[In]</strong> – Dimensionality of the transform (1, 2, or 3)</p></li> <li><p><strong>n[In]</strong> – Array of size <code class="docutils literal notranslate"><span class="pre">rank</span></code>, describing the size of each dimension, <code class="docutils literal notranslate"><span class="pre">n[0]</span></code> being the size of the outermost and <code class="docutils literal notranslate"><span class="pre">n[rank-1]</span></code> innermost (contiguous) dimension of a transform. For multiple GPUs and rank equal to 1, the sizes must be a power of 2. For multiple GPUs and rank equal to 2 or 3, the sizes must be factorable into primes less than or equal to 127.</p></li> <li><p><strong>inembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the input data in memory, <code class="docutils literal notranslate"><span class="pre">inembed[0]</span></code> being the storage dimension of the outermost dimension. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>istride[In]</strong> – Indicates the distance between two successive input elements in the least significant (i.e., innermost) dimension</p></li> <li><p><strong>idist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the input data</p></li> <li><p><strong>onembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the output data in memory, <code class="docutils literal notranslate"><span class="pre">onembed[0]</span></code> being the storage dimension of the outermost dimension. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>ostride[In]</strong> – Indicates the distance between two successive output elements in the output array in the least significant (i.e., innermost) dimension</p></li> <li><p><strong>odist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the output data</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_R2C</span></code> for single precision real to complex). For 2 GPUs this must be a complex to complex transform.</p></li> <li><p><strong>batch[In]</strong> – Batch size for this transform.</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size(s) of the work areas.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully created the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle. Handle is not valid when the plan is locked or multi-GPU restrictions are not met.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftmakeplanmany64"> <h3><span class="section-number">3.3.7. </span>cufftMakePlanMany64()<a class="headerlink" href="#cufftmakeplanmany64" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftMakePlanMany64"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftMakePlanMany64</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">rank</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">n</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">inembed</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">istride</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">idist</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">onembed</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ostride</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">odist</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftMakePlanMany64" title="Permalink to this definition"></a><br /></dt> <dd><p>Following a call to <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> makes a FFT plan configuration of dimension <code class="docutils literal notranslate"><span class="pre">rank</span></code>, with sizes specified in the array <code class="docutils literal notranslate"><span class="pre">n</span></code>. The <code class="docutils literal notranslate"><span class="pre">batch</span></code> input parameter tells cuFFT how many transforms to configure. With this function, batched plans of 1, 2, or 3 dimensions may be created.</p> <p>This API is identical to <code class="docutils literal notranslate"><span class="pre">cufftMakePlanMany</span></code> except that the arguments specifying sizes and strides are 64 bit integers. This API makes very large transforms possible. cuFFT includes kernels that use 32 bit indexes, and kernels that use 64 bit indexes. cuFFT planning selects 32 bit kernels whenever possible to avoid any overhead due to 64 bit arithmetic.</p> <p>All sizes and types of transform are supported by this interface, with two exceptions. For transforms whose size exceeds 4G elements, the dimensions specified in the array <code class="docutils literal notranslate"><span class="pre">n</span></code> must be factorable into primes that are less than or equal to 127. For real to complex and complex to real transforms whose size exceeds 4G elements, the fastest changing dimension must be even.</p> <p>The <code class="docutils literal notranslate"><span class="pre">cufftPlanMany64()</span></code> API supports more complicated input and output data layouts via the advanced data layout parameters: <code class="docutils literal notranslate"><span class="pre">inembed</span></code>, <code class="docutils literal notranslate"><span class="pre">istride</span></code>, <code class="docutils literal notranslate"><span class="pre">idist</span></code>, <code class="docutils literal notranslate"><span class="pre">onembed</span></code>, <code class="docutils literal notranslate"><span class="pre">ostride</span></code>, and <code class="docutils literal notranslate"><span class="pre">odist</span></code>.</p> <p>If <code class="docutils literal notranslate"><span class="pre">inembed</span></code> and <code class="docutils literal notranslate"><span class="pre">onembed</span></code> are set to <code class="docutils literal notranslate"><span class="pre">NULL</span></code>, all other stride information is ignored, and default strides are used. The default assumes contiguous data arrays.</p> <p>This call can only be used once for a given handle. It will fail and return <code class="docutils literal notranslate"><span class="pre">CUFFT_INVALID_PLAN</span></code> if the plan is locked, i.e. the handle was previously used with a different <code class="docutils literal notranslate"><span class="pre">cufftPlan</span></code> or <code class="docutils literal notranslate"><span class="pre">cufftMakePlan</span></code> call.</p> <p>If <code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> was called prior to this call with multiple GPUs, then <code class="docutils literal notranslate"><span class="pre">workSize</span></code> will contain multiple sizes. See sections on multiple GPUs for more details.</p> <p>All arrays are assumed to be in CPU memory.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>rank[In]</strong> – Dimensionality of the transform (1, 2, or 3).</p></li> <li><p><strong>n[In]</strong> – Array of size <code class="docutils literal notranslate"><span class="pre">rank</span></code>, describing the size of each dimension. For multiple GPUs and rank equal to 1, the sizes must be a power of 2. For multiple GPUs and rank equal to 2 or 3, the sizes must be factorable into primes less than or equal to 127.</p></li> <li><p><strong>inembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the input data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>istride[In]</strong> – Indicates the distance between two successive input elements in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>idist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the input data.</p></li> <li><p><strong>onembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the output data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>ostride[In]</strong> – Indicates the distance between two successive output elements in the output array in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>odist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the output data.</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_R2C</span></code> for single precision real to complex). For 2 GPUs this must be a complex to complex transform.</p></li> <li><p><strong>batch[In]</strong> – Batch size for this transform.</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size(s) of the work areas.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully created the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle. Handle is not valid when the plan is locked or multi-GPU restrictions are not met.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtmakeplanmany"> <h3><span class="section-number">3.3.8. </span>cufftXtMakePlanMany()<a class="headerlink" href="#cufftxtmakeplanmany" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtMakePlanMany"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtMakePlanMany</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">rank</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">n</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">inembed</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">istride</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">idist</span></span>, <span class="n"><span class="pre">cudaDataType</span></span><span class="w"> </span><span class="n"><span class="pre">inputtype</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">onembed</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ostride</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">odist</span></span>, <span class="n"><span class="pre">cudaDataType</span></span><span class="w"> </span><span class="n"><span class="pre">outputtype</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span>, <span class="n"><span class="pre">cudaDataType</span></span><span class="w"> </span><span class="n"><span class="pre">executiontype</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtMakePlanMany" title="Permalink to this definition"></a><br /></dt> <dd><p>Following a call to <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> makes an FFT plan configuration of dimension <code class="docutils literal notranslate"><span class="pre">rank</span></code>, with sizes specified in the array <code class="docutils literal notranslate"><span class="pre">n</span></code>. The <code class="docutils literal notranslate"><span class="pre">batch</span></code> input parameter tells cuFFT how many transforms to configure. With this function, batched plans of 1, 2, or 3 dimensions may be created.</p> <p>Type specifiers <code class="docutils literal notranslate"><span class="pre">inputtype</span></code>, <code class="docutils literal notranslate"><span class="pre">outputtype</span></code> and <code class="docutils literal notranslate"><span class="pre">executiontype</span></code> dictate type and precision of transform to be performed. Not all combinations of parameters are supported. Currently all three parameters need to match precision. Parameters <code class="docutils literal notranslate"><span class="pre">inputtype</span></code> and <code class="docutils literal notranslate"><span class="pre">outputtype</span></code> need to match transform type complex-to-complex, real-to-complex or complex-to-real. Parameter <code class="docutils literal notranslate"><span class="pre">executiontype</span></code> needs to match precision and be of a complex type. Example: for a half-precision real-to-complex transform, parameters <code class="docutils literal notranslate"><span class="pre">inputtype</span></code>, <code class="docutils literal notranslate"><span class="pre">outputtype</span></code> and <code class="docutils literal notranslate"><span class="pre">executiontype</span></code> would have values of <code class="docutils literal notranslate"><span class="pre">CUDA_R_16F</span></code>, <code class="docutils literal notranslate"><span class="pre">CUDA_C_16F</span></code> and <code class="docutils literal notranslate"><span class="pre">CUDA_C_16F</span></code> respectively. Similarly, a bfloat16 complex-to-real transform would use <code class="docutils literal notranslate"><span class="pre">CUDA_C_16BF</span></code> for <code class="docutils literal notranslate"><span class="pre">inputtype</span></code> and <code class="docutils literal notranslate"><span class="pre">executiontype</span></code>, and <code class="docutils literal notranslate"><span class="pre">CUDA_R_16BF</span></code> for <code class="docutils literal notranslate"><span class="pre">outputtype</span></code>.</p> <p>The <code class="docutils literal notranslate"><span class="pre">cufftXtMakePlanMany()</span></code> API supports more complicated input and output data layouts via the advanced data layout parameters: <code class="docutils literal notranslate"><span class="pre">inembed</span></code>, <code class="docutils literal notranslate"><span class="pre">istride</span></code>, <code class="docutils literal notranslate"><span class="pre">idist</span></code>, <code class="docutils literal notranslate"><span class="pre">onembed</span></code>, <code class="docutils literal notranslate"><span class="pre">ostride</span></code>, and <code class="docutils literal notranslate"><span class="pre">odist</span></code>.</p> <p>If <code class="docutils literal notranslate"><span class="pre">inembed</span></code> and <code class="docutils literal notranslate"><span class="pre">onembed</span></code> are set to <code class="docutils literal notranslate"><span class="pre">NULL</span></code>, all other stride information is ignored, and default strides are used. The default assumes contiguous data arrays.</p> <p>If <code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> was called prior to this call with multiple GPUs, then <code class="docutils literal notranslate"><span class="pre">workSize</span></code> will contain multiple sizes. See sections on multiple GPUs for more details.</p> <p>All arrays are assumed to be in CPU memory.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>rank[In]</strong> – Dimensionality of the transform (1, 2, or 3).</p></li> <li><p><strong>n[In]</strong> – Array of size <code class="docutils literal notranslate"><span class="pre">rank</span></code>, describing the size of each dimension, <code class="docutils literal notranslate"><span class="pre">n[0]</span></code> being the size of the outermost and <code class="docutils literal notranslate"><span class="pre">n[rank-1]</span></code> innermost (contiguous) dimension of a transform. For multiple GPUs and rank equal to 1, the sizes must be a power of 2. For multiple GPUs and rank equal to 2 or 3, the sizes must be factorable into primes less than or equal to 127.</p></li> <li><p><strong>inembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the input data in memory, <code class="docutils literal notranslate"><span class="pre">inembed[0]</span></code> being the storage dimension of the outermost dimension. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>istride[In]</strong> – Indicates the distance between two successive input elements in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>idist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the input data.</p></li> <li><p><strong>inputtype[In]</strong> – Type of input data.</p></li> <li><p><strong>onembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the output data in memory, <code class="docutils literal notranslate"><span class="pre">onembed[0]</span></code> being the storage dimension of the outermost dimension. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>ostride[In]</strong> – Indicates the distance between two successive output elements in the output array in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>odist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the output data.</p></li> <li><p><strong>outputtype[In]</strong> – Type of output data.</p></li> <li><p><strong>batch[In]</strong> – Batch size for this transform.</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>executiontype[In]</strong> – Type of data to be used for computations.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size(s) of the work areas.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully created the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle. Handle is not valid when multi-GPU restrictions are not met.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> </section> <section id="cufft-plan-properties"> <h2><span class="section-number">3.4. </span>cuFFT Plan Properties<a class="headerlink" href="#cufft-plan-properties" title="Permalink to this headline"></a></h2> <p>Users can further customize cuFFT plans using plan properties. These properties can be set, queried and reset on a per-plan basis as needed, using the routines listed in this section.</p> <p>The current supported properties are listed below:</p> <table class="table-no-stripes docutils align-default"> <colgroup> <col style="width: 17%" /> <col style="width: 12%" /> <col style="width: 55%" /> <col style="width: 17%" /> </colgroup> <thead> <tr class="row-odd"><th class="head"><p>Property</p></th> <th class="head"><p>Underlying Type</p></th> <th class="head"><p>Description</p></th> <th class="head"><p>Behavior</p></th> </tr> </thead> <tbody> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">NVFFT_PLAN_PROPERTY_INT64_PATIENT_JIT</span></code></p></td> <td><p>long long int</p></td> <td><ul class="simple"> <li><p>Runtime LTO kernels are enabled when set to not-zero value. See <a class="reference external" href="index.html#cufft-link-time-optimized-kernels">Link-Time Optimized Kernels</a></p></li> <li><p>Runtime LTO kernles are disabled when set to zero (default)</p></li> </ul> </td> <td><ul class="simple"> <li><p>Can be set / reset before planning</p></li> <li><p>Cannot be set / reset after planning</p></li> </ul> </td> </tr> </tbody> </table> <section id="cufftsetplanpropertyint64"> <h3><span class="section-number">3.4.1. </span>cufftSetPlanPropertyInt64()<a class="headerlink" href="#cufftsetplanpropertyint64" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftSetPlanPropertyInt64"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftSetPlanPropertyInt64</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftProperty</span></span><span class="w"> </span><span class="n"><span class="pre">property</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">propertyValueInt64</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftSetPlanPropertyInt64" title="Permalink to this definition"></a><br /></dt> <dd><p>Associates a cuFFT plan with a property identified by the key <code class="docutils literal notranslate"><span class="pre">property</span></code>. The value for the property is given by value <code class="docutils literal notranslate"><span class="pre">propertyValueInt64</span></code>, which is a signed long long integer.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>property[In]</strong> – The property identifier, of type <code class="docutils literal notranslate"><span class="pre">cufftPlanProperty</span></code>.</p></li> <li><p><strong>propertyValueInt64[In]</strong> – Value to set for the property, a long long signed integer.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully set the property.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_NOT_SUPPORTED</strong> – The property is not supported, or it cannot be set at the time (e.g. some properties cannot be set after calling a planning routine for the plan, see <a class="reference external" href="index.html#cufft-plan-properties">cuFFT Plan Properties</a>).</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – Invalid property or value with which to set the property</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftgetplanpropertyint64"> <h3><span class="section-number">3.4.2. </span>cufftGetPlanPropertyInt64()<a class="headerlink" href="#cufftgetplanpropertyint64" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftGetPlanPropertyInt64"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftGetPlanPropertyInt64</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftProperty</span></span><span class="w"> </span><span class="n"><span class="pre">property</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">propertyValueInt64</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftGetPlanPropertyInt64" title="Permalink to this definition"></a><br /></dt> <dd><p>Retrieves the property value identified by the key <code class="docutils literal notranslate"><span class="pre">property</span></code> associated with the cuFFT plan <code class="docutils literal notranslate"><span class="pre">plan</span></code>. The value for the property, which is a signed long long integer, is set in the address space pointed by <code class="docutils literal notranslate"><span class="pre">propertyValueInt64</span></code>.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>property[In]</strong> – The property identifier, of type <code class="docutils literal notranslate"><span class="pre">cufftPlanProperty</span></code>.</p></li> <li><p><strong>propertyValueInt64[In]</strong> – Pointer to the value to be set with the value of the property.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully retrieved the property value.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_NOT_SUPPORTED</strong> – The property is not supported.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – Invalid property, or pointer <code class="docutils literal notranslate"><span class="pre">propertyValueInt64</span></code> is null</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftresetplanproperty"> <h3><span class="section-number">3.4.3. </span>cufftResetPlanProperty()<a class="headerlink" href="#cufftresetplanproperty" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftResetPlanProperty"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftResetPlanProperty</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftProperty</span></span><span class="w"> </span><span class="n"><span class="pre">property</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftResetPlanProperty" title="Permalink to this definition"></a><br /></dt> <dd><p>Resets the value of the property identified by the key <code class="docutils literal notranslate"><span class="pre">property</span></code>, associated with the cuFFT plan <code class="docutils literal notranslate"><span class="pre">plan</span></code>, to its default value.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>property[In]</strong> – The property identifier, of type <code class="docutils literal notranslate"><span class="pre">cufftPlanProperty</span></code>.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully reset the property value.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_NOT_SUPPORTED</strong> – The property is not supported for <code class="docutils literal notranslate"><span class="pre">plan</span></code>, or cannot be reset at present time (see Behavior column on <a class="reference external" href="index.html#cufft-plan-properties">cuFFT Plan Properties</a>).</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – Invalid property</p></li> </ul> </dd> </dl> </dd></dl> </section> </section> <section id="cufft-estimated-size-of-work-area"> <h2><span class="section-number">3.5. </span>cuFFT Estimated Size of Work Area<a class="headerlink" href="#cufft-estimated-size-of-work-area" title="Permalink to this headline"></a></h2> <p>During plan execution, cuFFT requires a work area for temporary storage of intermediate results. The <code class="docutils literal notranslate"><span class="pre">cufftEstimate*()</span></code> calls return an estimate for the size of the work area required, given the specified parameters, and assuming default plan settings. Some problem sizes require much more storage than others. In particular powers of 2 are very efficient in terms of temporary storage. Large prime numbers, however, use different algorithms and may need up to the eight times that of a similarly sized power of 2. These routines return estimated <code class="docutils literal notranslate"><span class="pre">workSize</span></code> values which may still be smaller than the actual values needed especially for values of <code class="docutils literal notranslate"><span class="pre">n</span></code> that are not multiples of powers of 2, 3, 5 and 7. More refined values are given by the <code class="docutils literal notranslate"><span class="pre">cufftGetSize*()</span></code> routines, but these values may still be conservative.</p> <section id="cufftestimate1d"> <h3><span class="section-number">3.5.1. </span>cufftEstimate1d()<a class="headerlink" href="#cufftestimate1d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftEstimate1d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftEstimate1d</span></span></span><span class="sig-paren">(</span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftEstimate1d" title="Permalink to this definition"></a><br /></dt> <dd><p>During plan execution, cuFFT requires a work area for temporary storage of intermediate results. This call returns an estimate for the size of the work area required, given the specified parameters, and assuming default plan settings.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>nx[In]</strong> – The transform size (e.g. 256 for a 256-point FFT).</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_C2C</span></code> for single precision complex to complex).</p></li> <li><p><strong>batch[In]</strong> – Number of transforms of size <code class="docutils literal notranslate"><span class="pre">nx</span></code>. Please consider using <code class="docutils literal notranslate"><span class="pre">cufftEstimateMany</span></code> for multiple transforms.</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size, in bytes, of the work space.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size of the work space.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – The <code class="docutils literal notranslate"><span class="pre">nx</span></code> parameter is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftestimate2d"> <h3><span class="section-number">3.5.2. </span>cufftEstimate2d()<a class="headerlink" href="#cufftestimate2d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftEstimate2d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftEstimate2d</span></span></span><span class="sig-paren">(</span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ny</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftEstimate2d" title="Permalink to this definition"></a><br /></dt> <dd><p>During plan execution, cuFFT requires a work area for temporary storage of intermediate results. This call returns an estimate for the size of the work area required, given the specified parameters, and assuming default plan settings.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>nx[In]</strong> – The transform size in the <em>x</em> dimension (number of rows).</p></li> <li><p><strong>ny[In]</strong> – The transform size in the <em>y</em> dimension (number of columns).</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_C2R</span></code> for single precision complex to real).</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size, in bytes, of the work space.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size of the work space.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – Either or both of the <code class="docutils literal notranslate"><span class="pre">nx</span></code> or <code class="docutils literal notranslate"><span class="pre">ny</span></code> parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftestimate3d"> <h3><span class="section-number">3.5.3. </span>cufftEstimate3d()<a class="headerlink" href="#cufftestimate3d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftEstimate3d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftEstimate3d</span></span></span><span class="sig-paren">(</span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ny</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nz</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftEstimate3d" title="Permalink to this definition"></a><br /></dt> <dd><p>During plan execution, cuFFT requires a work area for temporary storage of intermediate results. This call returns an estimate for the size of the work area required, given the specified parameters, and assuming default plan settings.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>nx[In]</strong> – The transform size in the <em>x</em> dimension.</p></li> <li><p><strong>ny[In]</strong> – The transform size in the <em>y</em> dimension.</p></li> <li><p><strong>nz[In]</strong> – The transform size in the <em>z</em> dimension.</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_R2C</span></code> for single precision real to complex).</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size, in bytes, of the work space.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size of the work space.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the <code class="docutils literal notranslate"><span class="pre">nx</span></code>, <code class="docutils literal notranslate"><span class="pre">ny</span></code>, or <code class="docutils literal notranslate"><span class="pre">nz</span></code> parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftestimatemany"> <h3><span class="section-number">3.5.4. </span>cufftEstimateMany()<a class="headerlink" href="#cufftestimatemany" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftEstimateMany"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftEstimateMany</span></span></span><span class="sig-paren">(</span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">rank</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">n</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">inembed</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">istride</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">idist</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">onembed</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ostride</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">odist</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftEstimateMany" title="Permalink to this definition"></a><br /></dt> <dd><p>During plan execution, cuFFT requires a work area for temporary storage of intermediate results. This call returns an estimate for the size of the work area required, given the specified parameters, and assuming default plan settings.</p> <p>The <code class="docutils literal notranslate"><span class="pre">cufftEstimateMany()</span></code> API supports more complicated input and output data layouts via the advanced data layout parameters: <code class="docutils literal notranslate"><span class="pre">inembed</span></code>, <code class="docutils literal notranslate"><span class="pre">istride</span></code>, <code class="docutils literal notranslate"><span class="pre">idist</span></code>, <code class="docutils literal notranslate"><span class="pre">onembed</span></code>, <code class="docutils literal notranslate"><span class="pre">ostride</span></code>, and <code class="docutils literal notranslate"><span class="pre">odist</span></code>.</p> <p>All arrays are assumed to be in CPU memory.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>rank[In]</strong> – Dimensionality of the transform (1, 2, or 3).</p></li> <li><p><strong>n[In]</strong> – Array of size <code class="docutils literal notranslate"><span class="pre">rank</span></code>, describing the size of each dimension.</p></li> <li><p><strong>inembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the input data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>istride[In]</strong> – Indicates the distance between two successive input elements in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>idist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the input data.</p></li> <li><p><strong>onembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the output data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>ostride[In]</strong> – Indicates the distance between two successive output elements in the output array in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>odist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the output data.</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_R2C</span></code> for single precision real to complex).</p></li> <li><p><strong>batch[In]</strong> – Batch size for this transform.</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size, in bytes, of the work space.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size of the work space</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> </section> <section id="cufft-refined-estimated-size-of-work-area"> <h2><span class="section-number">3.6. </span>cuFFT Refined Estimated Size of Work Area<a class="headerlink" href="#cufft-refined-estimated-size-of-work-area" title="Permalink to this headline"></a></h2> <p>The <code class="docutils literal notranslate"><span class="pre">cufftGetSize*()</span></code> routines give a more accurate estimate of the work area size required for a plan than the <code class="docutils literal notranslate"><span class="pre">cufftEstimate*()</span></code> routines as they take into account any plan settings that may have been made. As discussed in the section <a class="reference external" href="index.html#work-estimate">cuFFT Estimated Size of Work Area</a>, the <code class="docutils literal notranslate"><span class="pre">workSize</span></code> value(s) returned may be conservative especially for values of <code class="docutils literal notranslate"><span class="pre">n</span></code> that are not multiples of powers of 2, 3, 5 and 7.</p> <section id="cufftgetsize1d"> <h3><span class="section-number">3.6.1. </span>cufftGetSize1d()<a class="headerlink" href="#cufftgetsize1d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftGetSize1d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftGetSize1d</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftGetSize1d" title="Permalink to this definition"></a><br /></dt> <dd><p>This call gives a more accurate estimate of the work area size required for a plan than <code class="docutils literal notranslate"><span class="pre">cufftEstimate1d()</span></code>, given the specified parameters, and taking into account any plan settings that may have been made.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>nx[In]</strong> – The transform size (e.g. 256 for a 256-point FFT).</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_C2C</span></code> for single precision complex to complex).</p></li> <li><p><strong>batch[In]</strong> – Number of transforms of size <code class="docutils literal notranslate"><span class="pre">nx</span></code>. Please consider using <code class="docutils literal notranslate"><span class="pre">cufftGetSizeMany</span></code> for multiple transforms.</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size of the work space.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – The <code class="docutils literal notranslate"><span class="pre">nx</span></code> parameter is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftgetsize2d"> <h3><span class="section-number">3.6.2. </span>cufftGetSize2d()<a class="headerlink" href="#cufftgetsize2d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftGetSize2d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftGetSize2d</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ny</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftGetSize2d" title="Permalink to this definition"></a><br /></dt> <dd><p>This call gives a more accurate estimate of the work area size required for a plan than <code class="docutils literal notranslate"><span class="pre">cufftEstimate2d()</span></code>, given the specified parameters, and taking into account any plan settings that may have been made.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>nx[In]</strong> – The transform size in the <em>x</em> dimension (number of rows).</p></li> <li><p><strong>ny[In]</strong> – The transform size in the <em>y</em> dimension (number of columns).</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_C2R</span></code> for single precision complex to real).</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size of the work space.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – Either or both of the <code class="docutils literal notranslate"><span class="pre">nx</span></code> or <code class="docutils literal notranslate"><span class="pre">ny</span></code> parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftgetsize3d"> <h3><span class="section-number">3.6.3. </span>cufftGetSize3d()<a class="headerlink" href="#cufftgetsize3d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftGetSize3d"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftGetSize3d</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nx</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ny</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nz</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftGetSize3d" title="Permalink to this definition"></a><br /></dt> <dd><p>This call gives a more accurate estimate of the work area size required for a plan than <code class="docutils literal notranslate"><span class="pre">cufftEstimate3d()</span></code>, given the specified parameters, and taking into account any plan settings that may have been made.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>nx[In]</strong> – The transform size in the <em>x</em> dimension.</p></li> <li><p><strong>ny[In]</strong> – The transform size in the <em>y</em> dimension.</p></li> <li><p><strong>nz[In]</strong> – The transform size in the <em>z</em> dimension.</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_R2C</span></code> for single precision real to complex).</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size of the work space.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the <code class="docutils literal notranslate"><span class="pre">nx</span></code>, <code class="docutils literal notranslate"><span class="pre">ny</span></code>, or <code class="docutils literal notranslate"><span class="pre">nz</span></code> parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftgetsizemany"> <h3><span class="section-number">3.6.4. </span>cufftGetSizeMany()<a class="headerlink" href="#cufftgetsizemany" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftGetSizeMany"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftGetSizeMany</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">rank</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">n</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">inembed</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">istride</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">idist</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">onembed</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ostride</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">odist</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftGetSizeMany" title="Permalink to this definition"></a><br /></dt> <dd><p>This call gives a more accurate estimate of the work area size required for a plan than <code class="docutils literal notranslate"><span class="pre">cufftEstimateSizeMany()</span></code>, given the specified parameters, and taking into account any plan settings that may have been made.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>rank[In]</strong> – Dimensionality of the transform (1, 2, or 3).</p></li> <li><p><strong>n[In]</strong> – Array of size <code class="docutils literal notranslate"><span class="pre">rank</span></code>, describing the size of each dimension.</p></li> <li><p><strong>inembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the input data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>istride[In]</strong> – Indicates the distance between two successive input elements in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>idist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the input data.</p></li> <li><p><strong>onembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the output data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>ostride[In]</strong> – Indicates the distance between two successive output elements in the output array in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>odist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the output data.</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_R2C</span></code> for single precision real to complex).</p></li> <li><p><strong>batch[In]</strong> – Batch size for this transform.</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size of the work area.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftgetsizemany64"> <h3><span class="section-number">3.6.5. </span>cufftGetSizeMany64()<a class="headerlink" href="#cufftgetsizemany64" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftGetSizeMany64"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftGetSizeMany64</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">rank</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">n</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">inembed</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">istride</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">idist</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">onembed</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ostride</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">odist</span></span>, <span class="n"><span class="pre">cufftType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftGetSizeMany64" title="Permalink to this definition"></a><br /></dt> <dd><p>This call gives a more accurate estimate of the work area size required for a plan than <code class="docutils literal notranslate"><span class="pre">cufftEstimateSizeMany()</span></code>, given the specified parameters, and taking into account any plan settings that may have been made.</p> <p>This API is identical to <code class="docutils literal notranslate"><span class="pre">cufftMakePlanMany</span></code> except that the arguments specifying sizes and strides are 64 bit integers. This API makes very large transforms possible. cuFFT includes kernels that use 32 bit indexes, and kernels that use 64 bit indexes. cuFFT planning selects 32 bit kernels whenever possible to avoid any overhead due to 64 bit arithmetic.</p> <p>All sizes and types of transform are supported by this interface, with two exceptions. For transforms whose total size exceeds 4G elements, the dimensions specified in the array <code class="docutils literal notranslate"><span class="pre">n</span></code> must be factorable into primes that are less than or equal to 127. For real to complex and complex to real transforms whose total size exceeds 4G elements, the fastest changing dimension must be even.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>rank[In]</strong> – Dimensionality of the transform (1, 2, or 3).</p></li> <li><p><strong>n[In]</strong> – Array of size <code class="docutils literal notranslate"><span class="pre">rank</span></code>, describing the size of each dimension.</p></li> <li><p><strong>inembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the input data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>istride[In]</strong> – Indicates the distance between two successive input elements in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>idist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the input data.</p></li> <li><p><strong>onembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the output data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>ostride[In]</strong> – Indicates the distance between two successive output elements in the output array in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>odist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the output data.</p></li> <li><p><strong>type[In]</strong> – The transform data type (e.g., <code class="docutils literal notranslate"><span class="pre">CUFFT_R2C</span></code> for single precision real to complex).</p></li> <li><p><strong>batch[In]</strong> – Batch size for this transform.</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size of the work area.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtgetsizemany"> <h3><span class="section-number">3.6.6. </span>cufftXtGetSizeMany()<a class="headerlink" href="#cufftxtgetsizemany" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtGetSizeMany"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtGetSizeMany</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">rank</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">n</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">inembed</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">istride</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">idist</span></span>, <span class="n"><span class="pre">cudaDataType</span></span><span class="w"> </span><span class="n"><span class="pre">inputtype</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">onembed</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">ostride</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">odist</span></span>, <span class="n"><span class="pre">cudaDataType</span></span><span class="w"> </span><span class="n"><span class="pre">outputtype</span></span>, <span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">batch</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span>, <span class="n"><span class="pre">cudaDataType</span></span><span class="w"> </span><span class="n"><span class="pre">executiontype</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtGetSizeMany" title="Permalink to this definition"></a><br /></dt> <dd><p>This call gives a more accurate estimate of the work area size required for a plan than <code class="docutils literal notranslate"><span class="pre">cufftEstimateSizeMany()</span></code>, given the specified parameters that match signature of <code class="docutils literal notranslate"><span class="pre">cufftXtMakePlanMany</span></code> function, and taking into account any plan settings that may have been made.</p> <p>For more information about valid combinations of <code class="docutils literal notranslate"><span class="pre">inputtype</span></code>, <code class="docutils literal notranslate"><span class="pre">outputtype</span></code> and <code class="docutils literal notranslate"><span class="pre">executiontype</span></code> parameters please refer to documentation of <code class="docutils literal notranslate"><span class="pre">cufftXtMakePlanMany</span></code> function.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>rank[In]</strong> – Dimensionality of the transform (1, 2, or 3).</p></li> <li><p><strong>n[In]</strong> – Array of size <code class="docutils literal notranslate"><span class="pre">rank</span></code>, describing the size of each dimension.</p></li> <li><p><strong>inembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the input data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>istride[In]</strong> – Indicates the distance between two successive input elements in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>idist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the input data.</p></li> <li><p><strong>inputtype[In]</strong> (<span><span class="c-expr sig sig-inline c"><span class="n">cudaDataType</span></span></span>) – Type of input data.</p></li> <li><p><strong>onembed[In]</strong> – Pointer of size <code class="docutils literal notranslate"><span class="pre">rank</span></code> that indicates the storage dimensions of the output data in memory. If set to NULL all other advanced data layout parameters are ignored.</p></li> <li><p><strong>ostride[In]</strong> – Indicates the distance between two successive output elements in the output array in the least significant (i.e., innermost) dimension.</p></li> <li><p><strong>odist[In]</strong> – Indicates the distance between the first element of two consecutive signals in a batch of the output data.</p></li> <li><p><strong>outputtype[In]</strong> (<span><span class="c-expr sig sig-inline c"><span class="n">cudaDataType</span></span></span>) – Type of output data.</p></li> <li><p><strong>batch[In]</strong> – Batch size for this transform.</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>executiontype[In]</strong> (<span><span class="c-expr sig sig-inline c"><span class="n">cudaDataType</span></span></span>) – Type of data to be used for computations.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size of the work area.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – One or more of the parameters is not a supported size.</p></li> </ul> </dd> </dl> </dd></dl> </section> </section> <section id="cufftgetsize"> <h2><span class="section-number">3.7. </span>cufftGetSize()<a class="headerlink" href="#cufftgetsize" title="Permalink to this headline"></a></h2> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftGetSize"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftGetSize</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftGetSize" title="Permalink to this definition"></a><br /></dt> <dd><p>Once plan generation has been done, either with the original API or the extensible API, this call returns the actual size of the work area required to support the plan. Callers who choose to manage work area allocation within their application must use this call after plan generation, and after any <code class="docutils literal notranslate"><span class="pre">cufftSet*()</span></code> calls subsequent to plan generation, if those calls might alter the required work space size.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>*workSize[In]</strong> – Pointer to the size(s), in bytes, of the work areas. For example for two GPUs worksize must be declared to have two elements.</p></li> <li><p><strong>*workSize[Out]</strong> – Pointer to the size of the work area.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufft-caller-allocated-work-area-support"> <h2><span class="section-number">3.8. </span>cuFFT Caller Allocated Work Area Support<a class="headerlink" href="#cufft-caller-allocated-work-area-support" title="Permalink to this headline"></a></h2> <section id="cufftsetautoallocation"> <h3><span class="section-number">3.8.1. </span>cufftSetAutoAllocation()<a class="headerlink" href="#cufftsetautoallocation" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftSetAutoAllocation"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftSetAutoAllocation</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">autoAllocate</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftSetAutoAllocation" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftSetAutoAllocation()</span></code> indicates that the caller intends to allocate and manage work areas for plans that have been generated. cuFFT default behavior is to allocate the work area at plan generation time. If <code class="docutils literal notranslate"><span class="pre">cufftSetAutoAllocation()</span></code> has been called with autoAllocate set to 0 (“false”) prior to one of the <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code> calls, cuFFT does not allocate the work area. This is the preferred sequence for callers wishing to manage work area allocation.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>autoAllocate[In]</strong> – Indicates whether to allocate work area.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftsetworkarea"> <h3><span class="section-number">3.8.2. </span>cufftSetWorkArea()<a class="headerlink" href="#cufftsetworkarea" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftSetWorkArea"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftSetWorkArea</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workArea</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftSetWorkArea" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftSetWorkArea()</span></code> overrides the work area pointer associated with a plan. If the work area was auto-allocated, cuFFT frees the auto-allocated space. The <code class="docutils literal notranslate"><span class="pre">cufftExecute*()</span></code> calls assume that the work area pointer is valid and that it points to a contiguous region in device memory that does not overlap with any other work area. If this is not the case, results are indeterminate.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>*workArea[In]</strong> – Pointer to <code class="docutils literal notranslate"><span class="pre">workArea</span></code>. For multiple GPUs, multiple work area pointers must be given.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtsetworkareapolicy"> <h3><span class="section-number">3.8.3. </span>cufftXtSetWorkAreaPolicy()<a class="headerlink" href="#cufftxtsetworkareapolicy" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtSetWorkAreaPolicy"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtSetWorkAreaPolicy</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftXtWorkAreaPolicy</span></span><span class="w"> </span><span class="n"><span class="pre">policy</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workSize</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtSetWorkAreaPolicy" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtSetWorkAreaPolicy()</span></code> indicates that the caller intends to change work area size for a given plan handle. cuFFT’s default behavior is to allocate the work area at plan generation time with a default size that depends on the plan type and other parameters. If <code class="docutils literal notranslate"><span class="pre">cufftXtSetWorkAreaPolicy()</span></code> has been called with the <code class="docutils literal notranslate"><span class="pre">policy</span></code> parameter set to <code class="docutils literal notranslate"><span class="pre">CUFFT_WORKAREA_MINIMAL</span></code>, cuFFT will attempt to re-plan the handle to use zero bytes of work area memory. If the <code class="docutils literal notranslate"><span class="pre">cufftXtSetWorkAreaPolicy()</span></code> call is successful the auto-allocated work area memory is released.</p> <p>Currently the policies <code class="docutils literal notranslate"><span class="pre">CUFFT_WORKAREA_PERFORMANCE</span></code>, <code class="docutils literal notranslate"><span class="pre">CUFFT_WORKAREA_USER</span></code> and the <code class="docutils literal notranslate"><span class="pre">workSize</span></code> parameter are not supported and reserved for use in future cuFFT releases.</p> <p>This function can be called once per lifetime of a plan handle.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>policy[In]</strong> – Type of work area policy to apply.</p></li> <li><p><strong>*workSize[In]</strong> – Reserved for future use.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – FFT size does not allow use of the selected policy.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> </ul> </dd> </dl> </dd></dl> </section> </section> <section id="cufft-execution"> <h2><span class="section-number">3.9. </span>cuFFT Execution<a class="headerlink" href="#cufft-execution" title="Permalink to this headline"></a></h2> <section id="cufftexecc2c-and-cufftexecz2z"> <h3><span class="section-number">3.9.1. </span>cufftExecC2C() and cufftExecZ2Z()<a class="headerlink" href="#cufftexecc2c-and-cufftexecz2z" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftExecC2C"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftExecC2C</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftComplex</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">idata</span></span>, <span class="n"><span class="pre">cufftComplex</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">odata</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">direction</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftExecC2C" title="Permalink to this definition"></a><br /></dt> <dd></dd></dl> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftExecZ2Z"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftExecZ2Z</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftDoubleComplex</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">idata</span></span>, <span class="n"><span class="pre">cufftDoubleComplex</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">odata</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">direction</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftExecZ2Z" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftExecC2C()</span></code> (<code class="docutils literal notranslate"><span class="pre">cufftExecZ2Z()</span></code>) executes a single-precision (double-precision) complex-to-complex transform plan in the transform direction as specified by <code class="docutils literal notranslate"><span class="pre">direction</span></code> parameter. cuFFT uses the GPU memory pointed to by the <code class="docutils literal notranslate"><span class="pre">idata</span></code> parameter as input data. This function stores the Fourier coefficients in the <code class="docutils literal notranslate"><span class="pre">odata</span></code> array. If <code class="docutils literal notranslate"><span class="pre">idata</span></code> and <code class="docutils literal notranslate"><span class="pre">odata</span></code> are the same, this method does an in-place transform.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>idata[In]</strong> – Pointer to the complex input data (in GPU memory) to transform.</p></li> <li><p><strong>odata[In]</strong> – Pointer to the complex output data (in GPU memory).</p></li> <li><p><strong>direction[In]</strong> – The transform direction: <code class="docutils literal notranslate"><span class="pre">CUFFT_FORWARD</span></code> or <code class="docutils literal notranslate"><span class="pre">CUFFT_INVERSE</span></code>.</p></li> <li><p><strong>odata[Out]</strong> – ontains the complex Fourier coefficients.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – At least one of the parameters <code class="docutils literal notranslate"><span class="pre">idata</span></code>, <code class="docutils literal notranslate"><span class="pre">odata</span></code>, and <code class="docutils literal notranslate"><span class="pre">direction</span></code> is not valid.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_EXEC_FAILED</strong> – cuFFT failed to execute the transform on the GPU.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftexecr2c-and-cufftexecd2z"> <h3><span class="section-number">3.9.2. </span>cufftExecR2C() and cufftExecD2Z()<a class="headerlink" href="#cufftexecr2c-and-cufftexecd2z" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftExecR2C"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftExecR2C</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftReal</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">idata</span></span>, <span class="n"><span class="pre">cufftComplex</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">odata</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftExecR2C" title="Permalink to this definition"></a><br /></dt> <dd></dd></dl> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftExecD2Z"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftExecD2Z</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftDoubleReal</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">idata</span></span>, <span class="n"><span class="pre">cufftDoubleComplex</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">odata</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftExecD2Z" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftExecR2C()</span></code> (<code class="docutils literal notranslate"><span class="pre">cufftExecD2Z()</span></code>) executes a single-precision (double-precision) real-to-complex, implicitly forward, cuFFT transform plan. cuFFT uses as input data the GPU memory pointed to by the <code class="docutils literal notranslate"><span class="pre">idata</span></code> parameter. This function stores the nonredundant Fourier coefficients in the <code class="docutils literal notranslate"><span class="pre">odata</span></code> array. Pointers to <code class="docutils literal notranslate"><span class="pre">idata</span></code> and <code class="docutils literal notranslate"><span class="pre">odata</span></code> are both required to be aligned to <code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code> data type in single-precision transforms and <code class="docutils literal notranslate"><span class="pre">cufftDoubleComplex</span></code> data type in double-precision transforms. If <code class="docutils literal notranslate"><span class="pre">idata</span></code> and <code class="docutils literal notranslate"><span class="pre">odata</span></code> are the same, this method does an in-place transform. Note the data layout differences between in-place and out-of-place transforms as described in <a class="reference external" href="index.html#cufft-transform-types">Parameter cufftType</a>.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>idata[In]</strong> – Pointer to the real input data (in GPU memory) to transform.</p></li> <li><p><strong>odata[In]</strong> – Pointer to the complex output data (in GPU memory).</p></li> <li><p><strong>odata[Out]</strong> – Contains the complex Fourier coefficients.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the size of the work space.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – At least one of the parameters <code class="docutils literal notranslate"><span class="pre">idata</span></code> and <code class="docutils literal notranslate"><span class="pre">odata</span></code> is not valid.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_EXEC_FAILED</strong> – cuFFT failed to execute the transform on the GPU.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftexecc2r-and-cufftexecz2d"> <h3><span class="section-number">3.9.3. </span>cufftExecC2R() and cufftExecZ2D()<a class="headerlink" href="#cufftexecc2r-and-cufftexecz2d" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftExecC2R"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftExecC2R</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftComplex</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">idata</span></span>, <span class="n"><span class="pre">cufftReal</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">odata</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftExecC2R" title="Permalink to this definition"></a><br /></dt> <dd></dd></dl> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftExecZ2D"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftExecZ2D</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftDoubleComplex</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">idata</span></span>, <span class="n"><span class="pre">cufftDoubleReal</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">odata</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftExecZ2D" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftExecC2R()</span></code> (<code class="docutils literal notranslate"><span class="pre">cufftExecZ2D()</span></code>) executes a single-precision (double-precision) complex-to-real, implicitly inverse, cuFFT transform plan. cuFFT uses as input data the GPU memory pointed to by the <code class="docutils literal notranslate"><span class="pre">idata</span></code> parameter. The input array holds only the nonredundant complex Fourier coefficients. This function stores the real output values in the <code class="docutils literal notranslate"><span class="pre">odata</span></code> array. and pointers are both required to be aligned to <code class="docutils literal notranslate"><span class="pre">cufftComplex</span></code> data type in single-precision transforms and <code class="docutils literal notranslate"><span class="pre">cufftDoubleComplex</span></code> type in double-precision transforms. If <code class="docutils literal notranslate"><span class="pre">idata</span></code> and <code class="docutils literal notranslate"><span class="pre">odata</span></code> are the same, this method does an in-place transform.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>idata[In]</strong> – Pointer to the complex input data (in GPU memory) to transform.</p></li> <li><p><strong>odata[In]</strong> – Pointer to the real output data (in GPU memory).</p></li> <li><p><strong>odata[Out]</strong> – Contains the real output data.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully executed the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – At least one of the parameters <code class="docutils literal notranslate"><span class="pre">idata</span></code> and <code class="docutils literal notranslate"><span class="pre">odata</span></code> is not valid.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_EXEC_FAILED</strong> – cuFFT failed to execute the transform on the GPU.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtexec"> <h3><span class="section-number">3.9.4. </span>cufftXtExec()<a class="headerlink" href="#cufftxtexec" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtExec"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtExec</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">input</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">output</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">direction</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtExec" title="Permalink to this definition"></a><br /></dt> <dd><p>Function <code class="docutils literal notranslate"><span class="pre">cufftXtExec</span></code> executes any cuFFT transform regardless of precision and type. In case of complex-to-real and real-to-complex transforms <code class="docutils literal notranslate"><span class="pre">direction</span></code> parameter is ignored. cuFFT uses the GPU memory pointed to by the <code class="docutils literal notranslate"><span class="pre">input</span></code> parameter as input data. This function stores the Fourier coefficients in the <code class="docutils literal notranslate"><span class="pre">output</span></code> array. If <code class="docutils literal notranslate"><span class="pre">input</span></code> and <code class="docutils literal notranslate"><span class="pre">output</span></code> are the same, this method does an in-place transform.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>input[In]</strong> – Pointer to the input data (in GPU memory) to transform.</p></li> <li><p><strong>output[In]</strong> – Pointer to the output data (in GPU memory).</p></li> <li><p><strong>direction[In]</strong> – The transform direction: <code class="docutils literal notranslate"><span class="pre">CUFFT_FORWARD</span></code> or <code class="docutils literal notranslate"><span class="pre">CUFFT_INVERSE</span></code>. Ignored for complex-to-real and real-to-complex transforms.</p></li> <li><p><strong>output[Out]</strong> – Contains the complex Fourier coefficients.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully executed the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – At least one of the parameters <code class="docutils literal notranslate"><span class="pre">idata</span></code>, <code class="docutils literal notranslate"><span class="pre">odata</span></code>, and <code class="docutils literal notranslate"><span class="pre">direction</span></code> is not valid.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_EXEC_FAILED</strong> – cuFFT failed to execute the transform on the GPU.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtexecdescriptor"> <h3><span class="section-number">3.9.5. </span>cufftXtExecDescriptor()<a class="headerlink" href="#cufftxtexecdescriptor" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtExecDescriptor"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtExecDescriptor</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">input</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">output</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">direction</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtExecDescriptor" title="Permalink to this definition"></a><br /></dt> <dd><p>Function <code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptor()</span></code> executes any cuFFT transform regardless of precision and type. In case of complex-to-real and real-to-complex transforms <code class="docutils literal notranslate"><span class="pre">direction</span></code> parameter is ignored. cuFFT uses the GPU memory pointed to by <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span>                                         <span class="pre">*input</span></code> descriptor as input data and <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span> <span class="pre">*output</span></code> as output data.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>input[In]</strong> – Pointer to the complex input data (in GPU memory) to transform.</p></li> <li><p><strong>output[In]</strong> – Pointer to the complex output data (in GPU memory).</p></li> <li><p><strong>direction[In]</strong> – The transform direction: <code class="docutils literal notranslate"><span class="pre">CUFFT_FORWARD</span></code> or <code class="docutils literal notranslate"><span class="pre">CUFFT_INVERSE</span></code>. Ignored for complex-to-real and real-to-complex transforms.</p></li> <li><p><strong>idata[Out]</strong> – Contains the complex Fourier coefficients.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully executed the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – At least one of the parameters <code class="docutils literal notranslate"><span class="pre">idata</span></code> and <code class="docutils literal notranslate"><span class="pre">direction</span></code> is not valid.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_EXEC_FAILED</strong> – cuFFT failed to execute the transform on the GPU.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_DEVICE</strong> – An invalid GPU index was specified in a descriptor.</p></li> </ul> </dd> </dl> </dd></dl> </section> </section> <section id="cufft-and-multiple-gpus"> <h2><span class="section-number">3.10. </span>cuFFT and Multiple GPUs<a class="headerlink" href="#cufft-and-multiple-gpus" title="Permalink to this headline"></a></h2> <section id="cufftxtsetgpus"> <h3><span class="section-number">3.10.1. </span>cufftXtSetGPUs()<a class="headerlink" href="#cufftxtsetgpus" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtSetGPUs"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtSetGPUs</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">nGPUs</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">whichGPUs</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtSetGPUs" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> identifies which GPUs are to be used with the plan. As in the single GPU case <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> creates a plan and <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code> does the plan generation. In cuFFT prior to 10.4.0, this call will return an error if a non-default stream has been associated with the plan.</p> <p>Note that the call to <code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> must occur after the call to <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code> and prior to the call to <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code>. Parameter <code class="docutils literal notranslate"><span class="pre">whichGPUs</span></code> of <code class="docutils literal notranslate"><span class="pre">cufftXtSetGPUs()</span></code> function determines ordering of the GPUs with respect to data decomposition (first data chunk is placed on GPU denoted by first element of <code class="docutils literal notranslate"><span class="pre">whichGPUs</span></code>).</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>nGPUs[In]</strong> – Number of GPUs to use.</p></li> <li><p><strong>whichGPUs[In]</strong> – The GPUs to use.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully set the GPUs to use.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle, or a <a class="reference external" href="index.html#streamed-cufft-transforms">non-default stream has been associated with the plan in cuFFT prior to 10.4.0</a>.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – The requested number of GPUs was less than 2 or more than 8.</p></li> <li><p><strong>CUFFT_INVALID_DEVICE</strong> – An invalid GPU index was specified.</p></li> <li><p><strong>CUFFT_INVALID_SIZE</strong> – Transform size that <code class="docutils literal notranslate"><span class="pre">plan</span></code> was created for does not meet minimum size criteria.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtsetworkarea"> <h3><span class="section-number">3.10.2. </span>cufftXtSetWorkArea()<a class="headerlink" href="#cufftxtsetworkarea" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtSetWorkArea"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtSetWorkArea</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">workArea</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtSetWorkArea" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtSetWorkArea()</span></code> overrides the work areas associated with a plan. If the work area was auto-allocated, cuFFT frees the auto-allocated space. The <code class="docutils literal notranslate"><span class="pre">cufftXtExec*()</span></code> calls assume that the work area is valid and that it points to a contiguous region in each device memory that does not overlap with any other work area. If this is not the case, results are indeterminate.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>workArea[In]</strong> – Pointer to the pointers to workArea.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully set the GPUs to use.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_DEVICE</strong> – A GPU associated with the plan could not be selected.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufft-multiple-gpu-execution"> <h3><span class="section-number">3.10.3. </span>cuFFT Multiple GPU Execution<a class="headerlink" href="#cufft-multiple-gpu-execution" title="Permalink to this headline"></a></h3> <section id="cufftxtexecdescriptorc2c-and-cufftxtexecdescriptorz2z"> <h4><span class="section-number">3.10.3.1. </span>cufftXtExecDescriptorC2C() and cufftXtExecDescriptorZ2Z()<a class="headerlink" href="#cufftxtexecdescriptorc2c-and-cufftxtexecdescriptorz2z" title="Permalink to this headline"></a></h4> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtExecDescriptorC2C"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtExecDescriptorC2C</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">input</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">output</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">direction</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtExecDescriptorC2C" title="Permalink to this definition"></a><br /></dt> <dd></dd></dl> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtExecDescriptorZ2Z"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtExecDescriptorZ2Z</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">input</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">output</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="n"><span class="pre">direction</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtExecDescriptorZ2Z" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptorC2C()</span></code> (<code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptorZ2Z()</span></code>) executes a single-precision (double-precision) complex-to-complex transform plan in the transform direction as specified by <code class="docutils literal notranslate"><span class="pre">direction</span></code> parameter. cuFFT uses the GPU memory pointed to by <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span> <span class="pre">*input</span></code> as input data. Since only in-place multiple GPU functionality is supported, this function also stores the result in the <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span> <span class="pre">*input</span></code> arrays.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>*input[In]</strong> – Pointer to the complex input data (in GPU memory) to transform.</p></li> <li><p><strong>*output[In]</strong> – Pointer to the complex output data (in GPU memory).</p></li> <li><p><strong>direction[In]</strong> – The transform direction: <code class="docutils literal notranslate"><span class="pre">CUFFT_FORWARD</span></code> or <code class="docutils literal notranslate"><span class="pre">CUFFT_INVERSE</span></code>.</p></li> <li><p><strong>input[Out]</strong> – Contains the complex Fourier coefficients.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully executed the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – At least one of the parameters <code class="docutils literal notranslate"><span class="pre">input</span></code> and <code class="docutils literal notranslate"><span class="pre">direction</span></code> is not valid.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_EXEC_FAILED</strong> – cuFFT failed to execute the transform on the GPU.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_DEVICE</strong> – An invalid GPU index was specified in a descriptor.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtexecdescriptorr2c-and-cufftxtexecdescriptord2z"> <h4><span class="section-number">3.10.3.2. </span>cufftXtExecDescriptorR2C() and cufftXtExecDescriptorD2Z()<a class="headerlink" href="#cufftxtexecdescriptorr2c-and-cufftxtexecdescriptord2z" title="Permalink to this headline"></a></h4> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtExecDescriptorR2C"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtExecDescriptorR2C</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">input</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">output</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtExecDescriptorR2C" title="Permalink to this definition"></a><br /></dt> <dd></dd></dl> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtExecDescriptorD2Z"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtExecDescriptorD2Z</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">input</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">output</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtExecDescriptorD2Z" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptorR2C()</span></code> (<code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptorD2Z()</span></code>) executes a single-precision (double-precision) real-to-complex transform plan. cuFFT uses the GPU memory pointed to by <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span> <span class="pre">*input</span></code> as input data. Since only in-place multiple GPU functionality is supported, this function also stores the result in the <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span> <span class="pre">*input</span></code> arrays.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>*input[In]</strong> – Pointer to the complex input data (in GPU memory) to transform.</p></li> <li><p><strong>*output[In]</strong> – Pointer to the complex output data (in GPU memory).</p></li> <li><p><strong>input[Out]</strong> – Contains the complex Fourier coefficients</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully executed the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – At least one of the parameters <code class="docutils literal notranslate"><span class="pre">input</span></code> and <code class="docutils literal notranslate"><span class="pre">direction</span></code> is not valid.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_EXEC_FAILED</strong> – cuFFT failed to execute the transform on the GPU.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_DEVICE</strong> – An invalid GPU index was specified in a descriptor.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtexecdescriptorc2r-and-cufftxtexecdescriptorz2d"> <h4><span class="section-number">3.10.3.3. </span>cufftXtExecDescriptorC2R() and cufftXtExecDescriptorZ2D()<a class="headerlink" href="#cufftxtexecdescriptorc2r-and-cufftxtexecdescriptorz2d" title="Permalink to this headline"></a></h4> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtExecDescriptorC2R"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtExecDescriptorC2R</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">input</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">output</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtExecDescriptorC2R" title="Permalink to this definition"></a><br /></dt> <dd></dd></dl> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtExecDescriptorZ2D"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtExecDescriptorZ2D</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">input</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">output</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtExecDescriptorZ2D" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptorC2R()</span></code> (<code class="docutils literal notranslate"><span class="pre">cufftXtExecDescriptorZ2D()</span></code>) executes a single-precision (double-precision) complex-to-real transform plan in the transform direction as specified by <code class="docutils literal notranslate"><span class="pre">direction</span></code> parameter. cuFFT uses the GPU memory pointed to by <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span> <span class="pre">*input</span></code> as input data. Since only in-place multiple GPU functionality is supported, this function also stores the result in the <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span> <span class="pre">*input</span></code> arrays.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>*input[In]</strong> – Pointer to the complex input data (in GPU memory) to transform.</p></li> <li><p><strong>*output[In]</strong> – Pointer to the complex output data (in GPU memory).</p></li> <li><p><strong>input[Out]</strong> – Contains the complex Fourier coefficients.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully executed the FFT plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – At least one of the parameters <code class="docutils literal notranslate"><span class="pre">input</span></code> and <code class="docutils literal notranslate"><span class="pre">direction</span></code> is not valid.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_EXEC_FAILED</strong> – cuFFT failed to execute the transform on the GPU.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_DEVICE</strong> – An invalid GPU index was specified in a descriptor.</p></li> </ul> </dd> </dl> </dd></dl> </section> </section> <section id="memory-allocation-and-data-movement-functions"> <h3><span class="section-number">3.10.4. </span>Memory Allocation and Data Movement Functions<a class="headerlink" href="#memory-allocation-and-data-movement-functions" title="Permalink to this headline"></a></h3> <p>Multiple GPU cuFFT execution functions assume a certain data layout in terms of what input data has been copied to which GPUs prior to execution, and what output data resides in which GPUs post execution. The following functions assist in allocation, setup and retrieval of the data. They must be called after the call to <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code>.</p> <section id="cufftxtmalloc"> <h4><span class="section-number">3.10.4.1. </span>cufftXtMalloc()<a class="headerlink" href="#cufftxtmalloc" title="Permalink to this headline"></a></h4> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtMalloc"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtMalloc</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">descriptor</span></span>, <span class="n"><span class="pre">cufftXtSubFormat</span></span><span class="w"> </span><span class="n"><span class="pre">format</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtMalloc" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtMalloc()</span></code> allocates a descriptor, and all memory for data in GPUs associated with the plan, and returns a pointer to the descriptor. Note the descriptor contains an array of device pointers so that the application may preprocess or postprocess the data on the GPUs. The enumerated parameter <code class="docutils literal notranslate"><span class="pre">cufftXtSubFormat_t</span></code> indicates if the buffer will be used for input or output.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>**descriptor[In]</strong> – Pointer to a pointer to a <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span></code> object.</p></li> <li><p><strong>format[In]</strong> – cufftXtSubFormat`` value.</p></li> <li><p><strong>**descriptor[Out]</strong> – Pointer to a pointer to a <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span></code> object.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully allows user to allocate descriptor and GPU memory.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle or it is not a multiple GPU <code class="docutils literal notranslate"><span class="pre">plan</span></code>.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – The allocation of GPU resources for the plan failed.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_DEVICE</strong> – An invalid GPU index was specified in the descriptor.</p></li> </ul> </dd> </dl> </dd></dl> <section id="parameter-cufftxtsubformat"> <h5><span class="section-number">3.10.4.1.1. </span>Parameter cufftXtSubFormat<a class="headerlink" href="#parameter-cufftxtsubformat" title="Permalink to this headline"></a></h5> <p><code class="docutils literal notranslate"><span class="pre">cufftXtSubFormat_t</span></code> is an enumerated type that indicates if the buffer will be used for input or output and the ordering of the data.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">enum</span><span class="w"> </span><span class="nc">cufftXtSubFormat_t</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_XT_FORMAT_INPUT</span><span class="p">,</span><span class="w"> </span><span class="c1">//by default input is in linear order across GPUs</span> <span class="w"> </span><span class="n">CUFFT_XT_FORMAT_OUTPUT</span><span class="p">,</span><span class="w"> </span><span class="c1">//by default output is in scrambled order depending on transform</span> <span class="w"> </span><span class="n">CUFFT_XT_FORMAT_INPLACE</span><span class="p">,</span><span class="w"> </span><span class="c1">//by default inplace is input order, which is linear across GPUs</span> <span class="w"> </span><span class="n">CUFFT_XT_FORMAT_INPLACE_SHUFFLED</span><span class="p">,</span><span class="w"> </span><span class="c1">//shuffled output order after execution of the transform</span> <span class="w"> </span><span class="n">CUFFT_FORMAT_UNDEFINED</span><span class="w"></span> <span class="p">}</span><span class="w"> </span><span class="n">cufftXtSubFormat</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> </section> <section id="cufftxtfree"> <h4><span class="section-number">3.10.4.2. </span>cufftXtFree()<a class="headerlink" href="#cufftxtfree" title="Permalink to this headline"></a></h4> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtFree"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtFree</span></span></span><span class="sig-paren">(</span><span class="n"><span class="pre">cudaLibXtDesc</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">descriptor</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtFree" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtFree()</span></code> frees the descriptor and all memory associated with it. The descriptor and memory must have been returned by a previous call to <code class="docutils literal notranslate"><span class="pre">cufftXtMalloc()</span></code>.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>*descriptor[In]</strong> – Pointer to a <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span></code> object.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully allows user to free descriptor and associated GPU memory.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtmemcpy"> <h4><span class="section-number">3.10.4.3. </span>cufftXtMemcpy()<a class="headerlink" href="#cufftxtmemcpy" title="Permalink to this headline"></a></h4> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtMemcpy"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtMemcpy</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">dstPointer</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">srcPointer</span></span>, <span class="n"><span class="pre">cufftXtCopyType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftXtMemcpy" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> copies data between buffers on the host and GPUs or between GPUs. The enumerated parameter <code class="docutils literal notranslate"><span class="pre">cufftXtCopyType_t</span></code> indicates the type and direction of transfer. Calling <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy</span></code> function for multi-GPU batched FFT plans with <code class="docutils literal notranslate"><span class="pre">CUFFT_COPY_DEVICE_TO_DEVICE</span></code> transfer type is not supported.</p> <p>Note that starting from CUDA 11.2 (cuFFT 10.4.0), <code class="docutils literal notranslate"><span class="pre">cufftSetStream()</span></code> is supported on multi-GPU plans. When associating a stream with a plan, <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> remains synchronous across the multiple GPUs.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>dstPointer[In]</strong> – Pointer to the destination address(es).</p></li> <li><p><strong>srcPointer[In]</strong> – Pointer to the source address(es).</p></li> <li><p><strong>type[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftXtCopyType</span></code>value.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully allows user to copy memory between host and GPUs or between GPUs.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – One or more invalid parameters were passed to the API.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> <li><p><strong>CUFFT_INVALID_DEVICE</strong> – An invalid GPU index was specified in a descriptor.</p></li> </ul> </dd> </dl> </dd></dl> <section id="parameter-cufftxtcopytype"> <h5><span class="section-number">3.10.4.3.1. </span>Parameter cufftXtCopyType<a class="headerlink" href="#parameter-cufftxtcopytype" title="Permalink to this headline"></a></h5> <p><code class="docutils literal notranslate"><span class="pre">cufftXtCopyType_t</span></code> is an enumerated type for multiple GPU functions that specifies the type of copy for <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code>.</p> <p><code class="docutils literal notranslate"><span class="pre">CUFFT_COPY_HOST_TO_DEVICE</span></code> copies data from a contiguous host buffer to multiple device buffers, in the layout cuFFT requires for input data. <code class="docutils literal notranslate"><span class="pre">dstPointer</span></code> must point to a <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span></code> structure, and <code class="docutils literal notranslate"><span class="pre">srcPointer</span></code> must point to a host memory buffer.</p> <p><code class="docutils literal notranslate"><span class="pre">CUFFT_COPY_DEVICE_TO_HOST</span></code> copies data from multiple device buffers, in the layout cuFFT produces for output data, to a contiguous host buffer. <code class="docutils literal notranslate"><span class="pre">dstPointer</span></code> must point to a host memory buffer, and <code class="docutils literal notranslate"><span class="pre">srcPointer</span></code> must point to a <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span></code> structure.</p> <p><code class="docutils literal notranslate"><span class="pre">CUFFT_COPY_DEVICE_TO_DEVICE</span></code> copies data from multiple device buffers, in the layout cuFFT produces for output data, to multiple device buffers, in the layout cuFFT requires for input data. <code class="docutils literal notranslate"><span class="pre">dstPointer</span></code> and <code class="docutils literal notranslate"><span class="pre">srcPointer</span></code> must point to different <code class="docutils literal notranslate"><span class="pre">cudaLibXtDesc</span></code> structures (and therefore memory locations). That is, the copy cannot be in-place. Note that device_to_device <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> for 2D and 3D data is not currently supported.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">enum</span><span class="w"> </span><span class="nc">cufftXtCopyType_t</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_COPY_HOST_TO_DEVICE</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_COPY_DEVICE_TO_HOST</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_COPY_DEVICE_TO_DEVICE</span><span class="w"></span> <span class="p">}</span><span class="w"> </span><span class="n">cufftXtCopyType</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> </section> </section> <section id="general-multiple-gpu-descriptor-types"> <h3><span class="section-number">3.10.5. </span>General Multiple GPU Descriptor Types<a class="headerlink" href="#general-multiple-gpu-descriptor-types" title="Permalink to this headline"></a></h3> <section id="cudaxtdesc"> <h4><span class="section-number">3.10.5.1. </span>cudaXtDesc<a class="headerlink" href="#cudaxtdesc" title="Permalink to this headline"></a></h4> <p>A descriptor type used in multiple GPU routines that contains information about the GPUs and their memory locations.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">cudaXtDesc_t</span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">version</span><span class="p">;</span><span class="w"> </span><span class="c1">//descriptor version</span> <span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">nGPUs</span><span class="p">;</span><span class="w"> </span><span class="c1">//number of GPUs</span> <span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">GPUs</span><span class="p">[</span><span class="n">MAX_CUDA_DESCRIPTOR_GPUS</span><span class="p">];</span><span class="w"> </span><span class="c1">//array of device IDs</span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">data</span><span class="p">[</span><span class="n">MAX_CUDA_DESCRIPTOR_GPUS</span><span class="p">];</span><span class="w"> </span><span class="c1">//array of pointers to data, one per GPU</span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">size</span><span class="p">[</span><span class="n">MAX_CUDA_DESCRIPTOR_GPUS</span><span class="p">];</span><span class="w"> </span><span class="c1">//array of data sizes, one per GPU</span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">cudaXtState</span><span class="p">;</span><span class="w"> </span><span class="c1">//opaque CUDA utility structure</span> <span class="p">};</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">cudaXtDesc_t</span><span class="w"> </span><span class="n">cudaXtDesc</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> <section id="cudalibxtdesc"> <h4><span class="section-number">3.10.5.2. </span>cudaLibXtDesc<a class="headerlink" href="#cudalibxtdesc" title="Permalink to this headline"></a></h4> <p>A descriptor type used in multiple GPU routines that contains information about the library used.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span><span class="w"> </span><span class="nc">cudaLibXtDesc_t</span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">version</span><span class="p">;</span><span class="w"> </span><span class="c1">//descriptor version</span> <span class="w"> </span><span class="n">cudaXtDesc</span><span class="w"> </span><span class="o">*</span><span class="n">descriptor</span><span class="p">;</span><span class="w"> </span><span class="c1">//multi-GPU memory descriptor</span> <span class="w"> </span><span class="n">libFormat</span><span class="w"> </span><span class="n">library</span><span class="p">;</span><span class="w"> </span><span class="c1">//which library recognizes the format</span> <span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">subFormat</span><span class="p">;</span><span class="w"> </span><span class="c1">//library specific enumerator of sub formats</span> <span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">libDescriptor</span><span class="p">;</span><span class="w"> </span><span class="c1">//library specific descriptor e.g. FFT transform plan object</span> <span class="p">};</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">cudaLibXtDesc_t</span><span class="w"> </span><span class="n">cudaLibXtDesc</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> </section> </section> <section id="cufft-callbacks"> <h2><span class="section-number">3.11. </span>cuFFT Callbacks<a class="headerlink" href="#cufft-callbacks" title="Permalink to this headline"></a></h2> <section id="cufftxtsetjitcallback"> <h3><span class="section-number">3.11.1. </span>cufftXtSetJITCallback()<a class="headerlink" href="#cufftxtsetjitcallback" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtSetJITCallback"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtSetJITCallback</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="kt"><span class="pre">char</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">callbackSymbolName</span></span>, <span class="k"><span class="pre">const</span></span><span class="w"> </span><span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">callbackFatbin</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="n"><span class="pre">callbackFatbinSize</span></span>, <span class="n"><span class="pre">cufftXtCallbackType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">caller_info</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.cufftXtSetJITCallback" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtSetJITCallback()</span></code> specifies a load or store LTO callback to be used with the plan.</p> <p>This call is valid only after a call to <code class="docutils literal notranslate"><span class="pre">cufftCreate()</span></code>, but before calling <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code>, which does the plan generation.</p> <p>If there was already an LTO callback of this type associated with the plan, this new callback routine replaces it. If the new callback requires shared memory, you must call <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallbackSharedSize</span></code> with the amount of shared memory the callback function needs. cuFFT will not retain the amount of shared memory associated with the previous callback if the callback function is changed.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>callbackSymbolName[In]</strong> – null-terminated C string containing the (unmangled) callback symbol name (i.e. the name of the LTO callback routine). This symbol name will be runtime-compiled, and modifiers such as <code class="docutils literal notranslate"><span class="pre">extern</span> <span class="pre">"C"</span></code> or <code class="docutils literal notranslate"><span class="pre">namespace</span></code> are not supported.</p></li> <li><p><strong>callbackFatbin[In]</strong> – Pointer to the location in host memory where the callback device function is located, after being compiled into LTO-IR with nvcc or NVRTC.</p></li> <li><p><strong>callbackFatbinSize[In]</strong> – Size in bytes of the data pointed at by <code class="docutils literal notranslate"><span class="pre">callbackFatbin</span></code>.</p></li> <li><p><strong>type[In]</strong> – Type of callback routine.</p></li> <li><p><strong>callerInfo[In]</strong> – Optional array of device pointers to caller specific information, one per GPU.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully associated the callback function with the plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not valid (e.g. the handle was already used to make a plan).</p></li> <li><p><strong>CUFFT_INVALID_TYPE</strong> – The callback type is not valid.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – The pointer to the callback device function is invalid or the size is <code class="docutils literal notranslate"><span class="pre">0</span></code>.</p></li> <li><p><strong>CUFFT_NOT_SUPPORTED</strong> – The functionality is not supported yet (e.g. multi-GPU with LTO callbacks).</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – cuFFT encountered an unexpected error, likely in the runtime linking process; error codes will be expanded in a future release.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtsetcallback"> <h3><span class="section-number">3.11.2. </span>cufftXtSetCallback()<a class="headerlink" href="#cufftxtsetcallback" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtSetCallback"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtSetCallback</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">callbackRoutine</span></span>, <span class="n"><span class="pre">cufftXtCallbackType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">void</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">callerInfo</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.cufftXtSetCallback" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtSetCallback()</span></code> specifies a load or store legacy callback to be used with the plan. This call is valid only after a call to <code class="docutils literal notranslate"><span class="pre">cufftMakePlan*()</span></code>, which does the plan generation. If there was already a legacy callback of this type associated with the plan, this new callback routine replaces it. If the new callback requires shared memory, you must call <code class="docutils literal notranslate"><span class="pre">cufftXtSetCallbackSharedSize</span></code> with the amount of shared memory it needs. cuFFT will not retain the amount of shared memory associated with the previous callback.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>callbackRoutine[In]</strong> – Array of callback routine pointers, one per GPU.</p></li> <li><p><strong>type[In]</strong> – Type of callback routine.</p></li> <li><p><strong>callerInfo[In]</strong> – Optional array of device pointers to caller specific information, one per GPU.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully associated the callback function with the plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle, or a <a class="reference external" href="index.html#streamed-cufft-transforms">non-default stream has been associated with the plan in cuFFT prior to 10.4.0</a>.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_SETUP_FAILED</strong> – The cuFFT library failed to initialize.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtclearcallback"> <h3><span class="section-number">3.11.3. </span>cufftXtClearCallback()<a class="headerlink" href="#cufftxtclearcallback" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtClearCallback"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtClearCallback</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftXtCallbackType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.cufftXtClearCallback" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtClearCallback()</span></code> instructs cuFFT to stop invoking the specified legacy callback type when executing the plan. Only the specified callback is cleared. If no callback of this type had been specified, the return code is <code class="docutils literal notranslate"><span class="pre">CUFFT_SUCCESS</span></code>.</p> <p>Note that this method <strong>does not work</strong> with LTO callbacks.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>type[In]</strong> – Type of callback routine.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully disassociated the callback function with the plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle, or a <a class="reference external" href="index.html#streamed-cufft-transforms">non-default stream has been associated with the plan in cuFFT prior to 10.4.0</a>.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftxtsetcallbacksharedsize"> <h3><span class="section-number">3.11.4. </span>cufftXtSetCallbackSharedSize()<a class="headerlink" href="#cufftxtsetcallbacksharedsize" title="Permalink to this headline"></a></h3> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftXtSetCallbackSharedSize"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftXtSetCallbackSharedSize</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cufftXtCallbackType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="n"><span class="pre">size_t</span></span><span class="w"> </span><span class="n"><span class="pre">sharedSize</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.cufftXtSetCallbackSharedSize" title="Permalink to this definition"></a><br /></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">cufftXtSetCallbackSharedSize()</span></code> instructs cuFFT to dynamically allocate shared memory at launch time, for use by the callback. The maximum allowable amount of shared memory is 16K bytes. cuFFT passes a pointer to this shared memory to the callback routine at execution time. This shared memory is only valid for the life of the load or store callback operation. During execution, cuFFT may overwrite shared memory for its own purposes.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> returned by <code class="docutils literal notranslate"><span class="pre">cufftCreate</span></code>.</p></li> <li><p><strong>type[In]</strong> – Type of callback routine.</p></li> <li><p><strong>sharedSize[In]</strong> – Amount of shared memory requested.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – cuFFT will invoke the callback routine with a pointer to the requested amount of shared memory.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle, or a <a class="reference external" href="index.html#streamed-cufft-transforms">non-default stream has been associated with the plan in cuFFT prior to 10.4.0</a>.</p></li> <li><p><strong>CUFFT_INTERNAL_ERROR</strong> – An internal driver error was detected.</p></li> <li><p><strong>CUFFT_ALLOC_FAILED</strong> – cuFFT will not be able to allocate the requested amount of shared memory.</p></li> </ul> </dd> </dl> </dd></dl> </section> </section> <section id="cufftsetstream"> <h2><span class="section-number">3.12. </span>cufftSetStream()<a class="headerlink" href="#cufftsetstream" title="Permalink to this headline"></a></h2> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftSetStream"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftSetStream</span></span></span><span class="sig-paren">(</span><a class="reference internal" href="#c.cufftHandle" title="cufftHandle"><span class="n"><span class="pre">cufftHandle</span></span></a><span class="w"> </span><span class="n"><span class="pre">plan</span></span>, <span class="n"><span class="pre">cudaStream_t</span></span><span class="w"> </span><span class="n"><span class="pre">stream</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftSetStream" title="Permalink to this definition"></a><br /></dt> <dd><p>Associates a CUDA stream with a cuFFT plan. All kernel launches made during plan execution are now done through the associated stream, enabling overlap with activity in other streams (e.g. data copying). The association remains until the plan is destroyed or the stream is changed with another call to <code class="docutils literal notranslate"><span class="pre">cufftSetStream()</span></code>.</p> <p>Note that starting from CUDA 11.2 (cuFFT 10.4.0), <code class="docutils literal notranslate"><span class="pre">cufftSetStream()</span></code> is supported on multi-GPU plans. When associating a stream with a plan, <code class="docutils literal notranslate"><span class="pre">cufftXtMemcpy()</span></code> remains synchronous across the multiple GPUs. For previous versions of cuFFT, <code class="docutils literal notranslate"><span class="pre">cufftSetStream()</span></code> will return an error in multiple GPU plans.</p> <p>Note that starting from CUDA 12.2 (cuFFT 11.0.8), on multi-GPU plans, <code class="docutils literal notranslate"><span class="pre">stream</span></code> can be associated with any context on any GPU. However, repeated calls to <code class="docutils literal notranslate"><span class="pre">cufftSetStream()</span></code> with streams from different contexts incur a small time penalty. Optimal performance is obtained when repeated calls to <code class="docutils literal notranslate"><span class="pre">cufftSetStream</span></code> use streams from the same CUDA context.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>plan[In]</strong> – The <code class="docutils literal notranslate"><span class="pre">cufftHandle</span></code> object to associate with the stream.</p></li> <li><p><strong>stream[In]</strong> – A valid CUDA stream created with <code class="docutils literal notranslate"><span class="pre">cudaStreamCreate()</span></code>; <code class="docutils literal notranslate"><span class="pre">0</span></code> for the default stream.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – The stream was associated with the plan.</p></li> <li><p><strong>CUFFT_INVALID_PLAN</strong> – The <code class="docutils literal notranslate"><span class="pre">plan</span></code> parameter is not a valid handle, or plan is multi-gpu in cuFFT version prior to 10.4.0.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufftgetversion"> <h2><span class="section-number">3.13. </span>cufftGetVersion()<a class="headerlink" href="#cufftgetversion" title="Permalink to this headline"></a></h2> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftGetVersion"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftGetVersion</span></span></span><span class="sig-paren">(</span><span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">version</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftGetVersion" title="Permalink to this definition"></a><br /></dt> <dd><p>Returns the version number of cuFFT.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>*version[In]</strong> – Pointer to the version number.</p></li> <li><p><strong>*version[Out]</strong> – Contains the version number.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><p><strong>CUFFT_SUCCESS</strong> – cuFFT successfully returned the version number.</p> </dd> </dl> </dd></dl> </section> <section id="cufftgetproperty"> <h2><span class="section-number">3.14. </span>cufftGetProperty()<a class="headerlink" href="#cufftgetproperty" title="Permalink to this headline"></a></h2> <dl class="c function"> <dt class="sig sig-object c" id="c.cufftGetProperty"> <span class="n"><span class="pre">cufftResult</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftGetProperty</span></span></span><span class="sig-paren">(</span><span class="n"><span class="pre">libraryPropertyType</span></span><span class="w"> </span><span class="n"><span class="pre">type</span></span>, <span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="n"><span class="pre">value</span></span><span class="sig-paren">)</span><span class="p"><span class="pre">;</span></span><a class="headerlink" href="#c.cufftGetProperty" title="Permalink to this definition"></a><br /></dt> <dd><p>Return in <code class="docutils literal notranslate"><span class="pre">*value</span></code> the number for the property described by <code class="docutils literal notranslate"><span class="pre">type</span></code> of the dynamically linked CUFFT library.</p> <dl class="field-list simple"> <dt class="field-odd">Parameters</dt> <dd class="field-odd"><ul class="simple"> <li><p><strong>type[In]</strong> – CUDA library property.</p></li> <li><p><strong>value[Out]</strong> – Contains the integer value for the requested property.</p></li> </ul> </dd> <dt class="field-even">Return values</dt> <dd class="field-even"><ul class="simple"> <li><p><strong>CUFFT_SUCCESS</strong> – The property value was successfully returned.</p></li> <li><p><strong>CUFFT_INVALID_TYPE</strong> – The property type is not recognized.</p></li> <li><p><strong>CUFFT_INVALID_VALUE</strong> – <code class="docutils literal notranslate"><span class="pre">value</span></code> is <code class="docutils literal notranslate"><span class="pre">NULL</span></code>.</p></li> </ul> </dd> </dl> </dd></dl> </section> <section id="cufft-types"> <h2><span class="section-number">3.15. </span>cuFFT Types<a class="headerlink" href="#cufft-types" title="Permalink to this headline"></a></h2> <section id="parameter-cuffttype"> <h3><span class="section-number">3.15.1. </span>Parameter cufftType<a class="headerlink" href="#parameter-cuffttype" title="Permalink to this headline"></a></h3> <p>The cuFFT library supports complex- and real-data transforms. The <code class="docutils literal notranslate"><span class="pre">cufftType</span></code> data type is an enumeration of the types of transform data supported by cuFFT.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">enum</span><span class="w"> </span><span class="nc">cufftType_t</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_R2C</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x2a</span><span class="p">,</span><span class="w"> </span><span class="c1">// Real to complex (interleaved)</span> <span class="w"> </span><span class="n">CUFFT_C2R</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x2c</span><span class="p">,</span><span class="w"> </span><span class="c1">// Complex (interleaved) to real</span> <span class="w"> </span><span class="n">CUFFT_C2C</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x29</span><span class="p">,</span><span class="w"> </span><span class="c1">// Complex to complex (interleaved)</span> <span class="w"> </span><span class="n">CUFFT_D2Z</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x6a</span><span class="p">,</span><span class="w"> </span><span class="c1">// Double to double-complex (interleaved)</span> <span class="w"> </span><span class="n">CUFFT_Z2D</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x6c</span><span class="p">,</span><span class="w"> </span><span class="c1">// Double-complex (interleaved) to double</span> <span class="w"> </span><span class="n">CUFFT_Z2Z</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x69</span><span class="w"> </span><span class="c1">// Double-complex to double-complex (interleaved)</span> <span class="p">}</span><span class="w"> </span><span class="n">cufftType</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> <section id="parameters-for-transform-direction"> <h3><span class="section-number">3.15.2. </span>Parameters for Transform Direction<a class="headerlink" href="#parameters-for-transform-direction" title="Permalink to this headline"></a></h3> <p>The cuFFT library defines forward and inverse Fast Fourier Transforms according to the sign of the complex exponential term.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cp">#define CUFFT_FORWARD -1</span> <span class="cp">#define CUFFT_INVERSE 1</span> </pre></div> </div> <p>cuFFT performs un-normalized FFTs; that is, performing a forward FFT on an input data set followed by an inverse FFT on the resulting set yields data that is equal to the input, scaled by the number of elements. Scaling either transform by the reciprocal of the size of the data set is left for the user to perform as seen fit.</p> </section> <section id="type-definitions-for-callbacks"> <h3><span class="section-number">3.15.3. </span>Type definitions for callbacks<a class="headerlink" href="#type-definitions-for-callbacks" title="Permalink to this headline"></a></h3> <p>The cuFFT library supports callback funtions for all combinations of single or double precision, real or complex data, load or store. These are enumerated in the parameter <code class="docutils literal notranslate"><span class="pre">cufftXtCallbackType</span></code>.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">enum</span><span class="w"> </span><span class="nc">cufftXtCallbackType_t</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_CB_LD_COMPLEX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x0</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_CB_LD_COMPLEX_DOUBLE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x1</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_CB_LD_REAL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x2</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_CB_LD_REAL_DOUBLE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x3</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_CB_ST_COMPLEX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x4</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_CB_ST_COMPLEX_DOUBLE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x5</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_CB_ST_REAL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x6</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_CB_ST_REAL_DOUBLE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x7</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">CUFFT_CB_UNDEFINED</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0x8</span><span class="w"></span> <span class="p">}</span><span class="w"> </span><span class="n">cufftXtCallbackType</span><span class="p">;</span><span class="w"></span> </pre></div> </div> <section id="type-definitions-for-lto-callbacks"> <h4><span class="section-number">3.15.3.1. </span>Type definitions for LTO callbacks<a class="headerlink" href="#type-definitions-for-lto-callbacks" title="Permalink to this headline"></a></h4> <p>The LTO callback function prototypes and pointer type definitions are as follows:</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="n">cufftComplex</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackLoadC</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftDoubleComplex</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackLoadZ</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackLoadR</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftDoubleReal</span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackLoadD</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackStoreC</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="n">cufftComplex</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackStoreZ</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="n">cufftDoubleComplex</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackStoreR</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftJITCallbackStoreD</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="n">cufftDoubleReal</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> </pre></div> </div> <p>Notice the difference in the type of the <code class="docutils literal notranslate"><span class="pre">offset</span></code> parameter (<code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">long</span></code>) vs. legacy callbacks (which use <code class="docutils literal notranslate"><span class="pre">size_t</span></code>).</p> </section> <section id="type-definitions-for-legacy-callbacks"> <h4><span class="section-number">3.15.3.2. </span>Type definitions for legacy callbacks<a class="headerlink" href="#type-definitions-for-legacy-callbacks" title="Permalink to this headline"></a></h4> <p>The legacy callback function prototypes and pointer type definitions are as follows:</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="n">cufftComplex</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackLoadC</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftDoubleComplex</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackLoadZ</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackLoadR</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="n">cufftDoubleReal</span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackLoadD</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataIn</span><span class="p">,</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackStoreC</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="n">cufftComplex</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackStoreZ</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="n">cufftDoubleComplex</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackStoreR</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="n">cufftReal</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> <span class="k">typedef</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cufftCallbackStoreD</span><span class="p">)(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">dataOut</span><span class="p">,</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="n">cufftDoubleReal</span><span class="w"> </span><span class="n">element</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">callerInfo</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">sharedPointer</span><span class="p">);</span><span class="w"></span> </pre></div> </div> </section> </section> <section id="other-cufft-types"> <h3><span class="section-number">3.15.4. </span>Other cuFFT Types<a class="headerlink" href="#other-cufft-types" title="Permalink to this headline"></a></h3> <section id="cuffthandle"> <h4><span class="section-number">3.15.4.1. </span>cufftHandle<a class="headerlink" href="#cuffthandle" title="Permalink to this headline"></a></h4> <dl class="c type"> <dt class="sig sig-object c" id="c.cufftHandle"> <span class="k"><span class="pre">type</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">cufftHandle</span></span></span><a class="headerlink" href="#c.cufftHandle" title="Permalink to this definition"></a><br /></dt> <dd><p>A handle type used to store and access cuFFT plans. The user receives a handle after creating a cuFFT plan and uses this handle to execute the plan.</p> </dd></dl> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">cufftHandle</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> <section id="cufftreal"> <h4><span class="section-number">3.15.4.2. </span>cufftReal<a class="headerlink" href="#cufftreal" title="Permalink to this headline"></a></h4> <p>A single-precision, floating-point real data type.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="kt">float</span><span class="w"> </span><span class="n">cufftReal</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> <section id="cufftdoublereal"> <h4><span class="section-number">3.15.4.3. </span>cufftDoubleReal<a class="headerlink" href="#cufftdoublereal" title="Permalink to this headline"></a></h4> <p>A double-precision, floating-point real data type.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">cufftDoubleReal</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> <section id="cufftcomplex"> <h4><span class="section-number">3.15.4.4. </span>cufftComplex<a class="headerlink" href="#cufftcomplex" title="Permalink to this headline"></a></h4> <p>A single-precision, floating-point complex data type that consists of interleaved real and imaginary components.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="n">cuComplex</span><span class="w"> </span><span class="n">cufftComplex</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> <section id="cufftdoublecomplex"> <h4><span class="section-number">3.15.4.5. </span>cufftDoubleComplex<a class="headerlink" href="#cufftdoublecomplex" title="Permalink to this headline"></a></h4> <p>A double-precision, floating-point complex data type that consists of interleaved real and imaginary components.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="n">cuDoubleComplex</span><span class="w"> </span><span class="n">cufftDoubleComplex</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> </section> </section> <section id="common-types"> <h2><span class="section-number">3.16. </span>Common types<a class="headerlink" href="#common-types" title="Permalink to this headline"></a></h2> <section id="cudadatatype"> <span id="common-cudadatatype-types"></span><h3><span class="section-number">3.16.1. </span>cudaDataType<a class="headerlink" href="#cudadatatype" title="Permalink to this headline"></a></h3> <p>The <code class="docutils literal notranslate"><span class="pre">cudaDataType</span></code> data type is an enumeration of the types supported by CUDA libraries.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">enum</span><span class="w"> </span><span class="nc">cudaDataType_t</span><span class="w"></span> <span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">CUDA_R_16F</span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="c1">// 16 bit real</span> <span class="w"> </span><span class="n">CUDA_C_16F</span><span class="o">=</span><span class="w"> </span><span class="mi">6</span><span class="p">,</span><span class="w"> </span><span class="c1">// 16 bit complex</span> <span class="w"> </span><span class="n">CUDA_R_32F</span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="c1">// 32 bit real</span> <span class="w"> </span><span class="n">CUDA_C_32F</span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="c1">// 32 bit complex</span> <span class="w"> </span><span class="n">CUDA_R_64F</span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="c1">// 64 bit real</span> <span class="w"> </span><span class="n">CUDA_C_64F</span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="w"> </span><span class="c1">// 64 bit complex</span> <span class="w"> </span><span class="n">CUDA_R_8I</span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="c1">// 8 bit real as a signed integer</span> <span class="w"> </span><span class="n">CUDA_C_8I</span><span class="o">=</span><span class="w"> </span><span class="mi">7</span><span class="p">,</span><span class="w"> </span><span class="c1">// 8 bit complex as a pair of signed integers</span> <span class="w"> </span><span class="n">CUDA_R_8U</span><span class="o">=</span><span class="w"> </span><span class="mi">8</span><span class="p">,</span><span class="w"> </span><span class="c1">// 8 bit real as an unsigned integer</span> <span class="w"> </span><span class="n">CUDA_C_8U</span><span class="o">=</span><span class="w"> </span><span class="mi">9</span><span class="w"> </span><span class="c1">// 8 bit complex as a pair of unsigned integers</span> <span class="p">}</span><span class="w"> </span><span class="n">cudaDataType</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> <section id="librarypropertytype"> <h3><span class="section-number">3.16.2. </span>libraryPropertyType<a class="headerlink" href="#librarypropertytype" title="Permalink to this headline"></a></h3> <p>The <code class="docutils literal notranslate"><span class="pre">libraryPropertyType</span></code> data type is an enumeration of library property types. (ie. CUDA version X.Y.Z would yield <code class="docutils literal notranslate"><span class="pre">MAJOR_VERSION=X</span></code>, <code class="docutils literal notranslate"><span class="pre">MINOR_VERSION=Y</span></code>, <code class="docutils literal notranslate"><span class="pre">PATCH_LEVEL=Z</span></code>)</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">enum</span><span class="w"> </span><span class="nc">libraryPropertyType_t</span><span class="w"></span> <span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">MAJOR_VERSION</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">MINOR_VERSION</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="n">PATCH_LEVEL</span><span class="w"></span> <span class="p">}</span><span class="w"> </span><span class="n">libraryPropertyType</span><span class="p">;</span><span class="w"></span> </pre></div> </div> </section> </section> </section> <section id="multiple-gpu-data-organization"> <h1><span class="section-number">4. </span>Multiple GPU Data Organization<a class="headerlink" href="#multiple-gpu-data-organization" title="Permalink to this headline"></a></h1> <p>This chapter explains how data are distributed between the GPUs, before and after a multiple GPU transform. For simplicity, it is assumed in this chapter that the caller has specified GPU 0 and GPU 1 to perform the transform.</p> <section id="multiple-gpu-data-organization-for-batched-transforms"> <h2><span class="section-number">4.1. </span>Multiple GPU Data Organization for Batched Transforms<a class="headerlink" href="#multiple-gpu-data-organization-for-batched-transforms" title="Permalink to this headline"></a></h2> <p>For batches of transforms, each individual transform is executed on a single GPU. If possible the batches are evenly distributed among the GPUs. For a batch of size <code class="docutils literal notranslate"><span class="pre">m</span></code> performed on <code class="docutils literal notranslate"><span class="pre">n</span></code> GPUs, where <code class="docutils literal notranslate"><span class="pre">m</span></code> is not divisible by <code class="docutils literal notranslate"><span class="pre">n</span></code>, the first <code class="docutils literal notranslate"><span class="pre">m</span> <span class="pre">%</span> <span class="pre">n</span></code> GPUs will perform <span class="math notranslate nohighlight">\(\left\lfloor \frac{m}{n} \right\rfloor+\ 1\)</span> transforms. The remaining GPUs will perform <span class="math notranslate nohighlight">\(\left\lfloor \frac{m}{n} \right\rfloor\)</span> transforms. For example, in a batch of 15 transforms performed on 4 GPUs, the first three GPUs would perform 4 transforms, and the last GPU would perform 3 transforms. This approach removes the need for data exchange between the GPUs, and results in nearly perfect scaling for cases where the batch size is divisible by the number of GPUs.</p> </section> <section id="multiple-gpu-data-organization-for-single-2d-and-3d-transforms"> <h2><span class="section-number">4.2. </span>Multiple GPU Data Organization for Single 2D and 3D Transforms<a class="headerlink" href="#multiple-gpu-data-organization-for-single-2d-and-3d-transforms" title="Permalink to this headline"></a></h2> <p>Single transforms performed on multiple GPUs require the data to be divided between the GPUs. Then execution takes place in phases. For example with 2 GPUs, for 2D and 3D transforms with even sized dimensions, each GPU does half of the transform in (rank - 1) dimensions. Then data are exchanged between the GPUs so that the final dimension can be processed.</p> <p>Since 2D and 3D transforms support sizes other than powers of 2, it is possible that the data can not be evenly distributed among the GPUs. In general for the case of <code class="docutils literal notranslate"><span class="pre">n</span></code> GPUs, a dimension of size <code class="docutils literal notranslate"><span class="pre">m</span></code> that is not a multiple of <code class="docutils literal notranslate"><span class="pre">n</span></code> would be distributed such that the first <code class="docutils literal notranslate"><span class="pre">m</span> <span class="pre">%</span> <span class="pre">n</span></code> GPUs would get one extra row for 2D transforms, one extra plane for 3D transforms.</p> <p>Take for example, a 2D transform on 4 GPUs, using an array declared in C as <code class="docutils literal notranslate"><span class="pre">data[x][y]</span></code>, where <code class="docutils literal notranslate"><span class="pre">x</span></code> is 65 and <code class="docutils literal notranslate"><span class="pre">y</span></code> is 99. The surface is distributed prior to the transform such that GPU 0 receives a surface with dimensions <code class="docutils literal notranslate"><span class="pre">[17][99]</span></code>, and GPUs 1…3 receive surfaces with dimensions <code class="docutils literal notranslate"><span class="pre">[16][99]</span></code>. After the transform, each GPU again has a portion of the surface, but divided in the y dimension. GPUs 0…2 have surfaces with dimensions <code class="docutils literal notranslate"><span class="pre">[65][25]</span></code>. GPU 3 has a surface with dimensions <code class="docutils literal notranslate"><span class="pre">[65][24]</span></code></p> <p>For a 3D transform on 4 GPUs consider an array declared in C as <code class="docutils literal notranslate"><span class="pre">data[x][y][z]</span></code>, where <code class="docutils literal notranslate"><span class="pre">x</span></code> is 103, <code class="docutils literal notranslate"><span class="pre">y</span></code> is 122, and <code class="docutils literal notranslate"><span class="pre">z</span></code> is 64. The volume is distributed prior to the transform such that each GPUs 0…2 receive volumes with dimensions <code class="docutils literal notranslate"><span class="pre">[26][122][64]</span></code>, and GPU 3 receives a volume with dimensions <code class="docutils literal notranslate"><span class="pre">[25][122][64]</span></code>. After the transform, each GPU again has a portion of the surface, but divided in the y dimension. GPUs 0 and 1 have a volumes with dimensions <code class="docutils literal notranslate"><span class="pre">[103][31][64]</span></code>, and GPUs 2 and 3 have volumes with dimensions <code class="docutils literal notranslate"><span class="pre">[103][30][64]</span></code>.</p> </section> <section id="multiple-gpu-data-organization-for-single-1d-transforms"> <h2><span class="section-number">4.3. </span>Multiple-GPU Data Organization for Single 1D Transforms<a class="headerlink" href="#multiple-gpu-data-organization-for-single-1d-transforms" title="Permalink to this headline"></a></h2> <p>By default for 1D transforms, the initial distribution of data to the GPUs is similar to the 2D and 3D cases. For a transform of dimension x on two GPUs, GPU 0 receives data ranging from 0…(x/2-1). GPU 1 receives data ranging from (x/2)…(x-1). Similarly, with 4 GPUs, the data are evenly distributed among all 4 GPUs.</p> <p>Before computation can begin, data are redistributed among the GPUs. It is possible to perform this redistribution in the copy from host memory, in cases where the application does not need to pre-process the data prior to the transform. To do this, the application can create the data descriptor with <code class="docutils literal notranslate"><span class="pre">cufftXtMalloc</span></code> using the sub-format <code class="docutils literal notranslate"><span class="pre">CUFFT_XT_FORMAT_1D_INPUT_SHUFFLED</span></code>. This can significantly reduce the time it takes to execute the transform.</p> <p>cuFFT performs multiple GPU 1D transforms by decomposing the transform size into factors <code class="docutils literal notranslate"><span class="pre">Factor1</span></code> and <code class="docutils literal notranslate"><span class="pre">Factor2</span></code>, and treating the data as a grid of size <code class="docutils literal notranslate"><span class="pre">Factor1</span></code> x <code class="docutils literal notranslate"><span class="pre">Factor2</span></code>. The four steps done to calculate the 1D FFT are: <code class="docutils literal notranslate"><span class="pre">Factor1</span></code> transforms of size <code class="docutils literal notranslate"><span class="pre">Factor2</span></code>, data exchange between the GPUs, a pointwise twiddle multiplication, and <code class="docutils literal notranslate"><span class="pre">Factor2</span></code> transforms of size <code class="docutils literal notranslate"><span class="pre">Factor1</span></code>.</p> <p>To gain efficiency by overlapping computation with data exchange, cuFFT breaks the whole transform into independent segments or strings, which can be processed while others are in flight. A side effect of this algorithm is that the output of the transform is not in linear order. The output in GPU memory is in strings, each of which is composed of <code class="docutils literal notranslate"><span class="pre">Factor2</span></code> substrings of equal size. Each substring contains contiguous results starting <code class="docutils literal notranslate"><span class="pre">Factor1</span></code> elements subsequent to start of the previous substring. Each string starts substring size elements after the start of the previous string. The strings appear in order, the first half on GPU 0, and the second half on GPU 1. See the example below:</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">transform</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1024</span><span class="w"></span> <span class="n">number</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">strings</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">8</span><span class="w"></span> <span class="n">Factor1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">64</span><span class="w"></span> <span class="n">Factor2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">16</span><span class="w"></span> <span class="n">substrings</span><span class="w"> </span><span class="n">per</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">output</span><span class="w"> </span><span class="n">layout</span><span class="w"> </span><span class="n">is</span><span class="w"> </span><span class="n">Factor2</span><span class="w"> </span><span class="p">(</span><span class="mi">16</span><span class="p">)</span><span class="w"></span> <span class="n">string</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1024</span><span class="o">/</span><span class="mi">8</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">128</span><span class="w"></span> <span class="n">substring</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">128</span><span class="o">/</span><span class="mi">16</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">8</span><span class="w"></span> <span class="n">stride</span><span class="w"> </span><span class="n">between</span><span class="w"> </span><span class="n">substrings</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1024</span><span class="o">/</span><span class="mi">16</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Factor1</span><span class="w"> </span><span class="p">(</span><span class="mi">64</span><span class="p">)</span><span class="w"></span> <span class="n">On</span><span class="w"> </span><span class="n">GPU</span><span class="w"> </span><span class="mi">0</span><span class="o">:</span><span class="w"></span> <span class="n">string</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">has</span><span class="w"> </span><span class="n">substrings</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">indices</span><span class="w"> </span><span class="mf">0.</span><span class="p">.</span><span class="mf">.7</span><span class="w"> </span><span class="mf">64.</span><span class="p">.</span><span class="mf">.71</span><span class="w"> </span><span class="mf">128.</span><span class="p">.</span><span class="mf">.135</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="mf">960.</span><span class="p">.</span><span class="mf">.967</span><span class="w"></span> <span class="n">string</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">has</span><span class="w"> </span><span class="n">substrings</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">indices</span><span class="w"> </span><span class="mf">8.</span><span class="p">.</span><span class="mf">.15</span><span class="w"> </span><span class="mf">72.</span><span class="p">.</span><span class="mf">.79</span><span class="w"> </span><span class="mf">136.</span><span class="p">.</span><span class="mf">.143</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="mf">968.</span><span class="p">.</span><span class="mf">.975</span><span class="w"></span> <span class="p">...</span><span class="w"></span> <span class="n">On</span><span class="w"> </span><span class="n">GPU</span><span class="w"> </span><span class="mi">1</span><span class="o">:</span><span class="w"></span> <span class="n">string</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="n">has</span><span class="w"> </span><span class="n">substrings</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">indices</span><span class="w"> </span><span class="mf">32.</span><span class="p">.</span><span class="mf">.39</span><span class="w"> </span><span class="mf">96.</span><span class="p">.</span><span class="mf">.103</span><span class="w"> </span><span class="mf">160.</span><span class="p">.</span><span class="mf">.167</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="mf">992.</span><span class="p">.</span><span class="mf">.999</span><span class="w"></span> <span class="p">...</span><span class="w"></span> <span class="n">string</span><span class="w"> </span><span class="mi">7</span><span class="w"> </span><span class="n">has</span><span class="w"> </span><span class="n">substrings</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">indices</span><span class="w"> </span><span class="mf">56.</span><span class="p">.</span><span class="mf">.63</span><span class="w"> </span><span class="mf">120.</span><span class="p">.</span><span class="mf">.127</span><span class="w"> </span><span class="mf">184.</span><span class="p">.</span><span class="mf">.191</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="mf">1016.</span><span class="p">.</span><span class="mf">.1023</span><span class="w"></span> </pre></div> </div> <p>The cufftXtQueryPlan API allows the caller to retrieve a structure containing the number of strings, the decomposition factors, and (in the case of power of 2 size) some useful mask and shift elements. The example below shows how cufftXtQueryPlan is invoked. It also shows how to translate from an index in the host input array to the corresponding index on the device, and vice versa.</p> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cm">/*</span> <span class="cm"> * These routines demonstrate the use of cufftXtQueryPlan to get the 1D</span> <span class="cm"> * factorization and convert between permuted and linear indexes.</span> <span class="cm"> */</span><span class="w"></span> <span class="cm">/*</span> <span class="cm"> * Set up a 1D plan that will execute on GPU 0 and GPU1, and query</span> <span class="cm"> * the decomposition factors</span> <span class="cm"> */</span><span class="w"></span> <span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">**</span><span class="n">argv</span><span class="p">){</span><span class="w"></span> <span class="w"> </span><span class="n">cufftHandle</span><span class="w"> </span><span class="n">plan</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">cufftResult</span><span class="w"> </span><span class="n">stat</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">whichGPUs</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">};</span><span class="w"></span> <span class="w"> </span><span class="n">cufftXt1dFactors</span><span class="w"> </span><span class="n">factors</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">stat</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cufftCreate</span><span class="p">(</span><span class="w"> </span><span class="o">&</span><span class="n">plan</span><span class="w"> </span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">stat</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">CUFFT_SUCCESS</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"Create error %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="n">stat</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">}</span><span class="w"></span> <span class="w"> </span><span class="n">stat</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cufftXtSetGPUs</span><span class="p">(</span><span class="w"> </span><span class="n">plan</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">whichGPUs</span><span class="w"> </span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">stat</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">CUFFT_SUCCESS</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"SetGPU error %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="n">stat</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">}</span><span class="w"></span> <span class="w"> </span><span class="n">stat</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cufftMakePlan1d</span><span class="p">(</span><span class="w"> </span><span class="n">plan</span><span class="p">,</span><span class="w"> </span><span class="n">size</span><span class="p">,</span><span class="w"> </span><span class="n">CUFFT_C2C</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">workSizes</span><span class="w"> </span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">stat</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">CUFFT_SUCCESS</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"MakePlan error %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="n">stat</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">}</span><span class="w"></span> <span class="w"> </span><span class="n">stat</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cufftXtQueryPlan</span><span class="p">(</span><span class="w"> </span><span class="n">plan</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="o">&</span><span class="n">factors</span><span class="p">,</span><span class="w"> </span><span class="n">CUFFT_QUERY_1D_FACTORS</span><span class="w"> </span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">stat</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">CUFFT_SUCCESS</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"QueryPlan error %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="n">stat</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">}</span><span class="w"></span> <span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"Factor 1 %zd, Factor2 %zd</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="n">factors</span><span class="p">.</span><span class="n">factor1</span><span class="p">,</span><span class="n">factors</span><span class="p">.</span><span class="n">factor2</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="n">cufftDestroy</span><span class="p">(</span><span class="n">plan</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span> <span class="p">}</span><span class="w"></span> </pre></div> </div> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cm">/*</span> <span class="cm"> * Given an index into a permuted array, and the GPU index return the</span> <span class="cm"> * corresponding linear index from the beginning of the input buffer.</span> <span class="cm"> *</span> <span class="cm"> * Parameters:</span> <span class="cm"> * factors input: pointer to cufftXt1dFactors as returned by</span> <span class="cm"> * cufftXtQueryPlan</span> <span class="cm"> * permutedIx input: index of the desired element in the device output</span> <span class="cm"> * array</span> <span class="cm"> * linearIx output: index of the corresponding input element in the</span> <span class="cm"> * host array</span> <span class="cm"> * GPUix input: index of the GPU containing the desired element</span> <span class="cm"> */</span><span class="w"></span> <span class="n">cufftResult</span><span class="w"> </span><span class="nf">permuted2Linear</span><span class="p">(</span><span class="w"> </span><span class="n">cufftXt1dFactors</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">factors</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">permutedIx</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="o">*</span><span class="n">linearIx</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">GPUIx</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">indexInSubstring</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">whichString</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">whichSubstring</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">// the low order bits of the permuted index match those of the linear index</span> <span class="w"> </span><span class="n">indexInSubstring</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">permutedIx</span><span class="w"> </span><span class="o">&</span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">substringMask</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">// the next higher bits are the substring index</span> <span class="w"> </span><span class="n">whichSubstring</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">permutedIx</span><span class="w"> </span><span class="o">>></span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">substringShift</span><span class="p">)</span><span class="w"> </span><span class="o">&</span><span class="w"></span> <span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">factor2Mask</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">// the next higher bits are the string index on this GPU</span> <span class="w"> </span><span class="n">whichString</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">permutedIx</span><span class="w"> </span><span class="o">>></span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">stringShift</span><span class="p">)</span><span class="w"> </span><span class="o">&</span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">stringMask</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">// now adjust the index for the second GPU</span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">GPUIx</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="n">whichString</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">stringCount</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">}</span><span class="w"></span> <span class="w"> </span><span class="c1">// linear index low order bits are the same</span> <span class="w"> </span><span class="c1">// next higher linear index bits are the string index</span> <span class="w"> </span><span class="o">*</span><span class="n">linearIx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">indexInSubstring</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="n">whichString</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">substringShift</span><span class="w"> </span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="c1">// next higher bits of linear address are the substring index</span> <span class="w"> </span><span class="o">*</span><span class="n">linearIx</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">whichSubstring</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">factor1Shift</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">CUFFT_SUCCESS</span><span class="p">;</span><span class="w"></span> <span class="p">}</span><span class="w"></span> </pre></div> </div> <div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cm">/*</span> <span class="cm"> * Given a linear index into a 1D array, return the GPU containing the permuted</span> <span class="cm"> * result, and index from the start of the data buffer for that element.</span> <span class="cm"> *</span> <span class="cm"> * Parameters:</span> <span class="cm"> * factors input: pointer to cufftXt1dFactors as returned by</span> <span class="cm"> * cufftXtQueryPlan</span> <span class="cm"> * linearIx input: index of the desired element in the host input</span> <span class="cm"> * array</span> <span class="cm"> * permutedIx output: index of the corresponding result in the device</span> <span class="cm"> * output array</span> <span class="cm"> * GPUix output: index of the GPU containing the result</span> <span class="cm"> */</span><span class="w"></span> <span class="n">cufftResult</span><span class="w"> </span><span class="nf">linear2Permuted</span><span class="p">(</span><span class="w"> </span><span class="n">cufftXt1dFactors</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">factors</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">linearIx</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="o">*</span><span class="n">permutedIx</span><span class="p">,</span><span class="w"></span> <span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="n">GPUIx</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">indexInSubstring</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">whichString</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">whichSubstring</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">whichStringMask</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">whichStringShift</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">linearIx</span><span class="w"> </span><span class="o">>=</span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">size</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">CUFFT_INVALID_VALUE</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">}</span><span class="w"></span> <span class="w"> </span><span class="c1">// get a useful additional mask and shift count</span> <span class="w"> </span><span class="n">whichStringMask</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">stringCount</span><span class="w"> </span><span class="mi">-1</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="n">whichStringShift</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">factors</span><span class="o">-></span><span class="n">factor1Shift</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">factor2Shift</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"></span> <span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">stringShift</span><span class="w"> </span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">// the low order bits identify the index within the substring</span> <span class="w"> </span><span class="n">indexInSubstring</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">linearIx</span><span class="w"> </span><span class="o">&</span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">substringMask</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">// first determine which string has our linear index.</span> <span class="w"> </span><span class="c1">// the low order bits indentify the index within the substring.</span> <span class="w"> </span><span class="c1">// the next higher order bits identify which string.</span> <span class="w"> </span><span class="n">whichString</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">linearIx</span><span class="w"> </span><span class="o">>></span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">substringShift</span><span class="p">)</span><span class="w"> </span><span class="o">&</span><span class="w"> </span><span class="n">whichStringMask</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">// the first stringCount/2 strings are in the first GPU,</span> <span class="w"> </span><span class="c1">// the rest are in the second.</span> <span class="w"> </span><span class="o">*</span><span class="n">GPUIx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">whichString</span><span class="o">/</span><span class="p">(</span><span class="n">factors</span><span class="o">-></span><span class="n">stringCount</span><span class="o">/</span><span class="mi">2</span><span class="p">);</span><span class="w"></span> <span class="w"> </span><span class="c1">// next determine which substring within the string has our index</span> <span class="w"> </span><span class="c1">// the substring index is in the next higher order bits of the index</span> <span class="w"> </span><span class="n">whichSubstring</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">linearIx</span><span class="w"> </span><span class="o">>></span><span class="p">(</span><span class="n">factors</span><span class="o">-></span><span class="n">substringShift</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">whichStringShift</span><span class="p">))</span><span class="w"> </span><span class="o">&</span><span class="w"></span> <span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">factor2Mask</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="c1">// now we can re-assemble the index</span> <span class="w"> </span><span class="o">*</span><span class="n">permutedIx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">indexInSubstring</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="o">*</span><span class="n">permutedIx</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">whichSubstring</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">substringShift</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="o">!*</span><span class="n">GPUIx</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="o">*</span><span class="n">permutedIx</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">whichString</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">stringShift</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span> <span class="w"> </span><span class="o">*</span><span class="n">permutedIx</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="p">(</span><span class="n">whichString</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="p">(</span><span class="n">factors</span><span class="o">-></span><span class="n">stringCount</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="o"><<</span><span class="w"></span> <span class="w"> </span><span class="n">factors</span><span class="o">-></span><span class="n">stringShift</span><span class="p">;</span><span class="w"></span> <span class="w"> </span><span class="p">}</span><span class="w"></span> <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">CUFFT_SUCCESS</span><span class="p">;</span><span class="w"></span> <span class="p">}</span><span class="w"></span> </pre></div> </div> </section> </section> <section id="fftw-conversion-guide"> <h1><span class="section-number">5. </span>FFTW Conversion Guide<a class="headerlink" href="#fftw-conversion-guide" title="Permalink to this headline"></a></h1> <p>cuFFT differs from FFTW in that FFTW has many plans and a single execute function while cuFFT has fewer plans, but multiple execute functions. The cuFFT execute functions determine the precision (single or double) and whether the input is complex or real valued. The following table shows the relationship between the two interfaces.</p> <table class="table-no-stripes docutils align-default"> <colgroup> <col style="width: 44%" /> <col style="width: 56%" /> </colgroup> <thead> <tr class="row-odd"><th class="head"><p>FFTW function</p></th> <th class="head"><p>cuFFT function</p></th> </tr> </thead> <tbody> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_dft_1d(),</span> <span class="pre">fftw_plan_dft_r2c_1d(),</span> <span class="pre">fftw_plan_dft_c2r_1d()</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">cufftPlan1d()</span></code></p></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_dft_2d(),</span> <span class="pre">fftw_plan_dft_r2c_2d(),</span> <span class="pre">fftw_plan_dft_c2r_2d()</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">cufftPlan2d()</span></code></p></td> </tr> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_dft_3d(),</span> <span class="pre">fftw_plan_dft_r2c_3d(),</span> <span class="pre">fftw_plan_dft_c2r_3d()</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">cufftPlan3d()</span></code></p></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_dft(),</span> <span class="pre">fftw_plan_dft_r2c(),</span> <span class="pre">fftw_plan_dft_c2r()</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">cufftPlanMany()</span></code></p></td> </tr> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_many_dft(),</span> <span class="pre">fftw_plan_many_dft_r2c(),</span> <span class="pre">fftw_plan_many_dft_c2r()</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">cufftPlanMany()</span></code></p></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">fftw_execute()</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">cufftExecC2C(),</span> <span class="pre">cufftExecZ2Z(),</span> <span class="pre">cufftExecR2C(),</span> <span class="pre">cufftExecD2Z(),</span> <span class="pre">cufftExecC2R(),</span> <span class="pre">cufftExecZ2D()</span></code></p></td> </tr> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">fftw_destroy_plan()</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">cufftDestroy()</span></code></p></td> </tr> </tbody> </table> </section> <section id="fftw-interface-to-cufft"> <h1><span class="section-number">6. </span>FFTW Interface to cuFFT<a class="headerlink" href="#fftw-interface-to-cufft" title="Permalink to this headline"></a></h1> <p>NVIDIA provides FFTW3 interfaces to the cuFFT library. This allows applications using FFTW to use NVIDIA GPUs with minimal modifications to program source code. To use the interface first do the following two steps</p> <ul class="simple"> <li><p>It is recommended that you replace the include file <code class="docutils literal notranslate"><span class="pre">fftw3.h</span></code> with <code class="docutils literal notranslate"><span class="pre">cufftw.h</span></code></p></li> <li><p>Instead of linking with the double/single precision libraries such as <code class="docutils literal notranslate"><span class="pre">fftw3/fftw3f</span></code> libraries, link with both the cuFFT and cuFFTW libraries</p></li> <li><p>Ensure the search path includes the directory containing <code class="docutils literal notranslate"><span class="pre">cuda_runtime_api.h</span></code></p></li> </ul> <p>After an application is working using the FFTW3 interface, users may want to modify their code to move data to and from the GPU and use the routines documented in the <a class="reference external" href="index.html#fftw-conversion-guide">FFTW Conversion Guide</a> for the best performance.</p> <p>The following tables show which components and functions of FFTW3 are supported in cuFFT.</p> <table class="table-no-stripes docutils align-default"> <colgroup> <col style="width: 15%" /> <col style="width: 17%" /> <col style="width: 68%" /> </colgroup> <thead> <tr class="row-odd"><th class="head"><p>Section in FFTW manual</p></th> <th class="head"><p>Supported</p></th> <th class="head"><p>Unsupported</p></th> </tr> </thead> <tbody> <tr class="row-even"><td><p>Complex numbers</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_complex,</span> <span class="pre">fftwf_complex</span></code> types</p></td> <td></td> </tr> <tr class="row-odd"><td><p>Precision</p></td> <td><p>double <code class="docutils literal notranslate"><span class="pre">fftw3</span></code>, single <code class="docutils literal notranslate"><span class="pre">fftwf3</span></code></p></td> <td><p>long double <code class="docutils literal notranslate"><span class="pre">fftw3l</span></code>, quad precision <code class="docutils literal notranslate"><span class="pre">fftw3q</span></code> are not supported since CUDA functions operate on double and single precision floating-point quantities</p></td> </tr> <tr class="row-even"><td><p>Memory Allocation</p></td> <td></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_malloc(),</span> <span class="pre">fftw_free(),</span> <span class="pre">fftw_alloc_real(),</span> <span class="pre">fftw_alloc_complex(),</span> <span class="pre">fftwf_alloc_real(),</span> <span class="pre">fftwf_alloc_complex()</span></code></p></td> </tr> <tr class="row-odd"><td><p>Multi-threaded FFTW</p></td> <td></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw3_threads,</span> <span class="pre">fftw3_omp</span></code> are not supported</p></td> </tr> <tr class="row-even"><td><p>Distributed-memory FFTW with MPI</p></td> <td></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw3_mpi,fftw3f_mpi</span></code> are not supported</p></td> </tr> </tbody> </table> <p>Note that for each of the double precision functions below there is a corresponding single precision version with the letters <code class="docutils literal notranslate"><span class="pre">fftw</span></code> replaced by <code class="docutils literal notranslate"><span class="pre">fftwf</span></code>.</p> <table class="table-no-stripes longtable docutils align-default"> <colgroup> <col style="width: 9%" /> <col style="width: 49%" /> <col style="width: 42%" /> </colgroup> <thead> <tr class="row-odd"><th class="head"><p>Section in FFTW manual</p></th> <th class="head"><p>Supported</p></th> <th class="head"><p>Unsupported</p></th> </tr> </thead> <tbody> <tr class="row-even"><td><p>Using Plans</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_execute(),</span> <span class="pre">fftw_destroy_plan(),</span> <span class="pre">fftw_cleanup()</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_print_plan(),</span> <span class="pre">fftw_cost(),</span> <span class="pre">fftw_flops()</span></code> exist but are not functional</p></td> </tr> <tr class="row-odd"><td><p><strong>Basic Interface</strong></p></td> <td></td> <td></td> </tr> <tr class="row-even"><td><p>Complex DFTs</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_dft_1d(),</span> <span class="pre">fftw_plan_dft_2d(),</span> <span class="pre">fftw_plan_dft_3d(),</span> <span class="pre">fftw_plan_dft()</span></code></p></td> <td></td> </tr> <tr class="row-odd"><td><p>Planner Flags</p></td> <td></td> <td><p>Planner flags are ignored and the same plan is returned regardless</p></td> </tr> <tr class="row-even"><td><p>Real-data DFTs</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_dft_r2c_1d(),</span> <span class="pre">fftw_plan_dft_r2c_2d(),</span> <span class="pre">fftw_plan_dft_r2c_3d(),</span> <span class="pre">fftw_plan_dft_r2c(),</span> <span class="pre">fftw_plan_dft_c2r_1d(),</span> <span class="pre">fftw_plan_dft_c2r_2d(),</span> <span class="pre">fftw_plan_dft_c2r_3d(),</span> <span class="pre">fftw_plan_dft_c2r()</span></code></p></td> <td></td> </tr> <tr class="row-odd"><td><p>Read-data DFT Array Format</p></td> <td></td> <td><p>Not supported</p></td> </tr> <tr class="row-even"><td><p>Read-to-Real Transform</p></td> <td></td> <td><p>Not supported</p></td> </tr> <tr class="row-odd"><td><p>Read-to-Real Transform Kinds</p></td> <td></td> <td><p>Not supported</p></td> </tr> <tr class="row-even"><td><p><strong>Advanced Interface</strong></p></td> <td></td> <td></td> </tr> <tr class="row-odd"><td><p>Advanced Complex DFTs</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_many_dft()</span></code> with multiple 1D, 2D, 3D transforms</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_many_dft()</span></code> with 4D or higher transforms or a 2D or higher batch of embedded transforms</p></td> </tr> <tr class="row-even"><td><p>Advanced Real-data DFTs</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_many_dft_r2c(),</span> <span class="pre">fftw_plan_many_dft_c2r()</span></code> with multiple 1D, 2D, 3D transforms</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_many_dft_r2c(),</span> <span class="pre">fftw_plan_many_dft_c2r()</span></code> with 4D or higher transforms or a 2D or higher batch of embedded transforms</p></td> </tr> <tr class="row-odd"><td><p>Advanced Real-to-Real Transforms</p></td> <td></td> <td><p>Not supported</p></td> </tr> <tr class="row-even"><td><p><strong>Guru Interface</strong></p></td> <td></td> <td></td> </tr> <tr class="row-odd"><td><p>Interleaved and split arrays</p></td> <td><p>Interleaved format</p></td> <td><p>Split format</p></td> </tr> <tr class="row-even"><td><p>Guru vector and transform sizes</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_iodim</span></code> struct</p></td> <td></td> </tr> <tr class="row-odd"><td><p>Guru Complex DFTs</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_guru_dft(),</span> <span class="pre">fftw_plan_guru_dft_r2c(),</span> <span class="pre">fftw_plan_guru_dft_c2r()</span></code> with multiple 1D, 2D, 3D transforms</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_guru_dft(),</span> <span class="pre">fftw_plan_guru_dft_r2c(),</span> <span class="pre">fftw_plan_guru_dft_c2r()</span></code> with 4D or higher transforms or a 2D or higher batch of transforms</p></td> </tr> <tr class="row-even"><td><p>Guru Real-data DFTs</p></td> <td></td> <td><p>Not supported</p></td> </tr> <tr class="row-odd"><td><p>Guru Real-to-real Transforms</p></td> <td></td> <td><p>Not supported</p></td> </tr> <tr class="row-even"><td><p>64-bit Guru Interface</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_guru64_dft(),</span> <span class="pre">fftw_plan_guru64_dft_r2c(),</span> <span class="pre">fftw_plan_guru64_dft_c2r()</span></code> with multiple 1D, 2D, 3D transforms</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_plan_guru64_dft(),</span> <span class="pre">fftw_plan_guru64_dft_r2c(),</span> <span class="pre">fftw_plan_guru64_dft_c2r()</span></code> with 4D or higher transforms or a 2D or higher batch of transforms</p></td> </tr> <tr class="row-odd"><td><p>New-array Execute Functions</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_execute_dft(),</span> <span class="pre">fftw_execute_dft_r2c(),</span> <span class="pre">fftw_execute_dft_c2r()</span></code> with interleaved format</p></td> <td><p>Split format and real-to-real functions</p></td> </tr> <tr class="row-even"><td><p>Wisdom</p></td> <td></td> <td><p><code class="docutils literal notranslate"><span class="pre">fftw_export_wisdom_to_file(),</span> <span class="pre">fftw_import_wisdom_from_file()</span></code> exist but are not functional. Other wisdom functions do not have entry points in the library.</p></td> </tr> </tbody> </table> </section> <section id="deprecated-functionality"> <h1><span class="section-number">7. </span>Deprecated Functionality<a class="headerlink" href="#deprecated-functionality" title="Permalink to this headline"></a></h1> <p>Starting from CUDA 12.0:</p> <ul class="simple"> <li><p>GPU architectures SM35 and SM37 are no longer supported. The minimum required architecture is SM50.</p></li> </ul> <p>Starting from CUDA 11.8:</p> <ul class="simple"> <li><p>CUDA Graphs capture is no longer supported for legacy callback routines that load data in out-of-place mode transforms. Starting from CUDA 12.6 Update 2, LTO callbacks can be used as a replacement for legacy callbacks without this limitation.</p></li> </ul> <p>Starting from CUDA 11.4:</p> <ul class="simple"> <li><p>Support for callback functionality using separately compiled device code (legacy callbacks) is deprecated on all GPU architectures. Callback functionality will continue to be supported for all GPU architectures.</p></li> </ul> <p>Starting from CUDA 11.0:</p> <ul class="simple"> <li><p>GPU architecture SM30 is no longer supported. The minimum required architecture is SM35.</p></li> <li><p>Support for GPU architectures SM35, SM37 (Kepler), and SM50, SM52 (Maxwell) is deprecated.</p></li> </ul> <p>Function <code class="docutils literal notranslate"><span class="pre">cufftSetCompatibilityMode</span></code> was removed in version 9.1.</p> </section> <section id="notices"> <h1><span class="section-number">8. </span>Notices<a class="headerlink" href="#notices" title="Permalink to this headline"></a></h1> <section id="notice"> <h2><span class="section-number">8.1. </span>Notice<a class="headerlink" href="#notice" title="Permalink to this headline"></a></h2> <p>This document is provided for information purposes only and shall not be regarded as a warranty of a certain functionality, condition, or quality of a product. NVIDIA Corporation (“NVIDIA”) makes no representations or warranties, expressed or implied, as to the accuracy or completeness of the information contained in this document and assumes no responsibility for any errors contained herein. NVIDIA shall have no liability for the consequences or use of such information or for any infringement of patents or other rights of third parties that may result from its use. This document is not a commitment to develop, release, or deliver any Material (defined below), code, or functionality.</p> <p>NVIDIA reserves the right to make corrections, modifications, enhancements, improvements, and any other changes to this document, at any time without notice.</p> <p>Customer should obtain the latest relevant information before placing orders and should verify that such information is current and complete.</p> <p>NVIDIA products are sold subject to the NVIDIA standard terms and conditions of sale supplied at the time of order acknowledgement, unless otherwise agreed in an individual sales agreement signed by authorized representatives of NVIDIA and customer (“Terms of Sale”). NVIDIA hereby expressly objects to applying any customer general terms and conditions with regards to the purchase of the NVIDIA product referenced in this document. No contractual obligations are formed either directly or indirectly by this document.</p> <p>NVIDIA products are not designed, authorized, or warranted to be suitable for use in medical, military, aircraft, space, or life support equipment, nor in applications where failure or malfunction of the NVIDIA product can reasonably be expected to result in personal injury, death, or property or environmental damage. NVIDIA accepts no liability for inclusion and/or use of NVIDIA products in such equipment or applications and therefore such inclusion and/or use is at customer’s own risk.</p> <p>NVIDIA makes no representation or warranty that products based on this document will be suitable for any specified use. Testing of all parameters of each product is not necessarily performed by NVIDIA. It is customer’s sole responsibility to evaluate and determine the applicability of any information contained in this document, ensure the product is suitable and fit for the application planned by customer, and perform the necessary testing for the application in order to avoid a default of the application or the product. Weaknesses in customer’s product designs may affect the quality and reliability of the NVIDIA product and may result in additional or different conditions and/or requirements beyond those contained in this document. NVIDIA accepts no liability related to any default, damage, costs, or problem which may be based on or attributable to: (i) the use of the NVIDIA product in any manner that is contrary to this document or (ii) customer product designs.</p> <p>No license, either expressed or implied, is granted under any NVIDIA patent right, copyright, or other NVIDIA intellectual property right under this document. Information published by NVIDIA regarding third-party products or services does not constitute a license from NVIDIA to use such products or services or a warranty or endorsement thereof. Use of such information may require a license from a third party under the patents or other intellectual property rights of the third party, or a license from NVIDIA under the patents or other intellectual property rights of NVIDIA.</p> <p>Reproduction of information in this document is permissible only if approved in advance by NVIDIA in writing, reproduced without alteration and in full compliance with all applicable export laws and regulations, and accompanied by all associated conditions, limitations, and notices.</p> <p>THIS DOCUMENT AND ALL NVIDIA DESIGN SPECIFICATIONS, REFERENCE BOARDS, FILES, DRAWINGS, DIAGNOSTICS, LISTS, AND OTHER DOCUMENTS (TOGETHER AND SEPARATELY, “MATERIALS”) ARE BEING PROVIDED “AS IS.” NVIDIA MAKES NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL NVIDIA BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF ANY USE OF THIS DOCUMENT, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Notwithstanding any damages that customer might incur for any reason whatsoever, NVIDIA’s aggregate and cumulative liability towards customer for the products described herein shall be limited in accordance with the Terms of Sale for the product.</p> </section> <section id="opencl"> <h2><span class="section-number">8.2. </span>OpenCL<a class="headerlink" href="#opencl" title="Permalink to this headline"></a></h2> <p>OpenCL is a trademark of Apple Inc. used under license to the Khronos Group Inc.</p> </section> <section id="trademarks"> <h2><span class="section-number">8.3. </span>Trademarks<a class="headerlink" href="#trademarks" title="Permalink to this headline"></a></h2> <p>NVIDIA and the NVIDIA logo are trademarks or registered trademarks of NVIDIA Corporation in the U.S. and other countries. Other company and product names may be trademarks of the respective companies with which they are associated.</p> </section> </section> </div> </div> <footer> <hr/> <div role="contentinfo"> <img src="../_static/NVIDIA-LogoBlack.svg" class="only-light"/> <img src="../_static/NVIDIA-LogoWhite.svg" class="only-dark"/> <p class="notices"> <a href="https://www.nvidia.com/en-us/about-nvidia/privacy-policy/" target="_blank">Privacy Policy</a> | <a href="https://www.nvidia.com/en-us/about-nvidia/privacy-center/" target="_blank">Manage My Privacy</a> | <a href="https://www.nvidia.com/en-us/preferences/start/" target="_blank">Do Not Sell or Share My Data</a> | <a href="https://www.nvidia.com/en-us/about-nvidia/terms-of-service/" target="_blank">Terms of Service</a> | <a href="https://www.nvidia.com/en-us/about-nvidia/accessibility/" target="_blank">Accessibility</a> | <a href="https://www.nvidia.com/en-us/about-nvidia/company-policies/" target="_blank">Corporate Policies</a> | <a href="https://www.nvidia.com/en-us/product-security/" target="_blank">Product Security</a> | <a href="https://www.nvidia.com/en-us/contact/" target="_blank">Contact</a> </p> <p> Copyright © 2007-2024, NVIDIA Corporation & affiliates. All rights reserved. </p> <p> <span class="lastupdated">Last updated on Oct 10, 2024. </span></p> </div> </footer> </div> </div> </section> </div> <script> jQuery(function () { SphinxRtdTheme.Navigation.enable(false); }); </script> <script type="text/javascript">if (typeof _satellite !== "undefined"){_satellite.pageBottom();}</script> </body> </html>