API 参考

本节介绍所有 cuFFTMp 函数。

警告

版本控制 中所述,当版本匹配时,cuFFT 和 cuFFTMp 的单 GPU 和单进程、多 GPU 功能是相同的。但是,多进程功能仅在 cuFFTMp 上可用。本节仅记录与 cuFFTMp 相关的 API。

计划创建、执行和销毁

cufftCreate 和 cufftDestroy

类型 cufftHandle

cuFFTMp 计划的不透明句柄。

cufftResult cufftCreate(cufftHandle *plan)

仅创建不透明句柄,并在主机上分配小型数据结构。cufftMakePlan*() 调用实际上执行计划生成

参数:
  • plan[In] – 指向 cufftHandle 对象的指针

  • plan[Out] – 包含 cuFFT 计划句柄值

返回值:
  • CUFFT_SUCCESS – cuFFTMp 成功创建 FFT 计划

  • CUFFT_ALLOC_FAILED – 计划的资源分配失败

  • CUFFT_INVALID_VALUE – 传递给 API 一个或多个无效参数

  • CUFFT_INTERNAL_ERROR – 检测到内部驱动程序错误

  • CUFFT_SETUP_FAILED – cuFFTMp 库初始化失败。

cufftResult cufftDestroy(cufftHandle plan)

释放与 cuFFT 计划关联的所有 GPU 资源,并销毁内部计划数据结构。一旦不再需要计划,就应调用此函数,以避免浪费 GPU 内存。

参数:
  • plan[In] – 要销毁的计划的 cufftHandle 对象。

返回值:
  • CUFFT_SUCCESS – cuFFT 成功销毁 FFT 计划。

  • CUFFT_INVALID_PLAN – 计划参数不是有效的句柄。

cufftSetStream

cufftResult cufftSetStream(cufftHandle plan, cudaStream_t stream);

将 CUDA 流与 cuFFT 计划关联。计划执行期间进行的所有内核启动现在都通过关联的流完成,从而可以与其他流中的活动(例如数据复制)重叠。关联一直保持到计划被销毁或通过另一次调用 cufftSetStream() 更改流为止。

参数:
  • plan[In] – 要与流关联的 cufftHandle 对象

  • stream[In] – 使用 cudaStreamCreate() 创建的有效 CUDA 流;默认流为 0

返回值:
  • CUFFT_SUCCESS – cuFFT 成功销毁 FFT 计划。

  • CUFFT_INVALID_PLAN – 计划参数不是有效的句柄。

cufftMpAttachComm

枚举 cufftMpCommType
枚举器 CUFFT_COMM_MPI

表示通信句柄是指向 MPI 通信器的指针。在这种情况下,cuFFTMp 将仅为属于 MPI 通信器的进程初始化 NVSHMEM。这等效于调用 nvshmem_init_attr (参见 此处),并使用 NVSHMEMX_INIT_WITH_MPI_COMM

枚举器 CUFFT_COMM_NONE

表示通信句柄为 NULL。在这种情况下,cuFFTMp 将为程序中的所有进程初始化 NVSHMEM。这等效于调用 nvshmem_init (参见 此处)。

NVSHMEM 和 cuFFTMp 将根据环境变量 NVSHMEM_BOOTSTRAP 的值进行引导和初始化。默认值为 NVSHMEM_BOOTSTRAP=PMI,在这种情况下,PMI 将用于引导 NVSHMEM 和 cuFFTMp。在这种情况下,所有 cuFFTMp API(cufftMpAttachCommcufftMakePlan 等)都需要由 PMI 管理的所有进程调用。如果 NVSHMEM_BOOTSTRAP=MPI,则所有 cuFFTMp API 必须由 MPI_COMM_WORLD 中的所有进程调用。有关引导和初始化的更多信息,请参见 NVSHMEM 文档 此处此处

一个枚举,描述通信句柄的类型以及如何初始化 cuFFTMp 和 NVSHMEM。

cufftResult cufftMpAttachComm(cufftHandle plan, cufftMpCommType comm_type, void *comm_handle)

cufftMpAttachComm 将通信句柄附加到计划并启用多进程 API。comm_type 是一个枚举,指示通信句柄的类型,comm_handle 是指向该句柄的指针。comm_handle 是指向通信句柄的指针,并且

  • 指针应保持有效,直到调用 cufftDestroy 为止;

  • 底层句柄应保持有效,直到调用 cufftDestroy 为止。

参数:
  • plan[In]cufftCreate 返回的 cufftHandle

  • comm_type[In] – 一个枚举,指示通信句柄的类型。

  • comm_handle[In] – 指向通信句柄的指针。指向对象的生命周期需要超过计划创建、执行和销毁。

返回值:
  • CUFFT_SUCCESS – cuFFT 成功将通信句柄与计划关联。

  • CUFFT_INVALID_PLAN – 计划无效。

  • CUFFT_INVALID_VALUE – 当 comm_typeCUFFT_COMM_MPI 时,comm_handle 为 null;或者当 comm_typeCUFFT_COMM_NONE 时,comm_handle 不为 null。

警告

当使用 comm_type == CUFFT_COMM_MPI 时,comm_handle 应指向类型为 MPI_Comm 的 MPI 通信器。MPI 实现应与 NVSHMEM MPI 引导程序保持一致,该引导程序是为 OpenMPI 构建的。使用另一个 MPI 实现需要不同的 NVSHMEM MPI 引导程序,否则行为未定义。代码示例中的 extra_bootstraps 目录显示了如何为自定义 MPI 实现构建自定义 MPI 引导程序。

警告

当使用 comm_type == CUFFT_COMM_MPI 时,通信器应在从计划创建到销毁的整个过程中保持有效。这意味着,如果通信器是 MPI_COMM_WORLD,则需要在 cufftDestroy 之后调用 MPI_Finalize。如果通信器是自定义构建的通信器,则需要在 cufftDestroy 之后调用 MPI_Comm_free

警告

comm_handle 是指向通信器的指针时,指针的生命周期应超过计划创建和销毁。这意味着这是无效的

{
   MPI_Comm comm = MPI_COMM_WORLD;
   void* comm_handle = &comm;
   cufftXtAttachComm(plan, CUFFT_COMM_MPI, comm_handle)
} // comm goes out of scope and &comm is dangling
cufftMakePlan(...) // &comm is now dangling and behaviour is undefined
...
cufftDestroy(...) // &comm is now dangling and behaviour is undefined

cufftXtSetDistribution

cufftResult cufftXtSetDistribution(cufftHandle plan, int rank, const long long int *lower_input, const long long int *upper_input, const long long int *lower_output, const long long int *upper_output, const long long int *strides_input, const long long int *strides_output)

cufftXtSetDistribution 向计划指示输入和输出描述符的类型将分别为 CUFFT_XT_FORMAT_DISTRIBUTED_INPUTCUFFTXT_FORMAT_DISTRIBUTED_OUTPUT。在这种情况下,输入和输出数据将分别假定根据 (lower_input, upper_input)(lower_output, upper_output) 分布。(lower_input, upper_input) 描述了当前进程拥有的全局 nx x ny(如果 rank 为 2)或 nx * ny * nz(如果 rank 为 3)空间的区域,(lower_output, upper_output) 也类似。strides_inputstrides_output 分别描述输入和输出中内存中的数据布局。本地数据布局需要采用“C 顺序”,维度之间可能存在填充。元素的数量对于输入应至少为 (upper_input[0] - lower_input[0]) * strides_input[0],对于输出应至少为 (upper_output[0] - lower_output[0]) * strides_output[0]。函数返回后,可以立即释放该函数的全部六个输入数组。

参数:
  • plan[In]cufftCreate 返回的 cufftHandle

  • rank[In] – 变换的秩,以及 lower_inputupper_inputlower_outputupper_outputstrides_inputstrides_output 数组的长度。rank 应为 23

  • lower_input[In] – 长度为 rank 的数组,表示输入描述符中当前进程拥有的全局 nx * ny * nz 数组部分的左下角。

  • upper_input[In] – 长度为 rank 的数组,表示输入描述符中当前进程拥有的全局 nx * ny * nz 数组部分的右上角。

  • lower_output[In] – 长度为 rank 的数组,表示输出描述符中当前进程拥有的全局 nx * ny * nz 数组部分的左下角。

  • upper_output[In] – 长度为 rank 的数组,表示输出描述符中当前进程拥有的全局 nx * ny * nz 数组部分的右上角。

  • strides_input[In] – 长度为 rank 的数组,表示输入描述符在内存中的本地数据布局。所有条目都必须是递减且为正数。

  • strides_output[In] – 长度为 rank 的数组,表示输出描述符在内存中的本地数据布局。所有条目都必须是递减且为正数。

返回值:
  • CUFFT_SUCCESS – cuFFTMp 成功将计划与输入和输出框关联。

  • CUFFT_INVALID_PLAN – 计划无效。

  • CUFFT_INVALID_VALUErank 不是 2 或 3,步幅不是正数且递减,或者 lower/input 数组无效。

cufftXtSetSubformatDefault

cufftResult cufftXtSetSubformatDefault(cufftHandle plan, cufftXtSubFormat subformat_forward, cufftXtSubFormat subformat_inverse)

cufftXtSetSubformatDefault 指示 cufftXtExeccufftExec* 期望的数据分布。必须在使用 cufftXtExeccufftExec* API 之前调用 cufftXtSetSubformatDefault

当执行正向变换时(例如,cufftExecC2C(..., CUFFT_FORWARD)cufftExecR2C),输入数据分布由 subformat_forward 描述,输出数据分布由 subformat_inverse 描述。当执行逆向变换时(例如,cufftExecC2C(..., CUFFT_INVERSE)cufftExecC2R),输入数据分布由 subformat_inverse 描述,输出数据分布由 subformat_forward 描述。

subformat_forwardsubformat_inverse 必须彼此相反。CUFFT_XT_FORMAT_INPLACE 的反面是 CUFFT_XT_FORMAT_INPLACE_SHUFFLED(反之亦然)。CUFFT_XT_FORMAT_DISTRIBUTED_INPUT 的反面是 CUFFT_XT_FORMAT_DISTRIBUTED_OUTPUT(反之亦然)。

cufftXtSetSubformatDefault 已应用于计划时,可以使用 cufftXtExecDescriptorscufftXtExec(或 cufftExec*)。

参数:
  • plan[In]cufftCreate 返回的 cufftHandle

  • subformat_forward[In] – 正向变换的输入子格式。必须是 CUFFT_XT_FORMAT_INPLACECUFFT_XT_FORMAT_INPLACE_SHUFFLEDCUFFT_XT_FORMAT_DISTRIBUTED_INPUTCUFFT_XT_FORMAT_DISTRIBUTED_OUTPUT 之一。

  • subformat_inverse[In] – 逆向变换的输入子格式。必须是 subformat_forward 的反面。

返回值:
  • CUFFT_SUCCESS – cuFFTMp 成功将计划与输入和输出框关联。

  • CUFFT_INVALID_PLAN – 计划无效。

  • CUFFT_INVALID_VALUEsubformat_forward 不是四个接受值之一,或者 subformard_inverse 不是 subformat_forward 的反面。

cufftMakePlan

cufftResult cufftMakePlan2d(cufftHandle plan, int nx, int ny, cufftType type, size_t *workSize)
cufftResult cufftMakePlan3d(cufftHandle plan, int nx, int ny, int nz, cufftType type, size_t *workSize)

在调用 cufftCreate 之后,根据指定的信号大小和数据类型创建 2D(或 3D)FFT 计划配置。对于给定的句柄,此调用只能使用一次。如果计划已锁定,即句柄先前已与不同的 cufftPlancufftMakePlan 调用一起使用,则此调用将失败并返回 CUFFT_INVALID_PLAN。有关内存缓冲区管理的更多详细信息,另请参阅 cuFFTMp 中的 NVSHMEM 内存缓冲区

参数:
  • plan[In]cufftCreate 返回的 cufftHandle

  • nx[In] – x 维度的变换大小。这是变换的最慢变化维度(在内存中跨步)。

  • ny[In] – y 维度的变换大小。

  • nz[In] – z 维度的变换大小。这是变换的最快变化维度(在内存中连续)。

  • type[In] – 变换数据类型(例如,单精度实数到复数的 CUFFT_R2C)。

  • *workSize[Out]

    指向工作区大小(以字节为单位)的指针。

返回值:
  • CUFFT_SUCCESS – cuFFT 成功创建 FFT 计划。

  • CUFFT_INVALID_PLAN – 计划参数不是有效的句柄。

  • CUFFT_ALLOC_FAILED – 计划的 GPU 资源分配失败。

  • CUFFT_INVALID_VALUE – 传递给 API 一个或多个无效参数。

  • CUFFT_INTERNAL_ERROR – 检测到内部驱动程序错误。

  • CUFFT_SETUP_FAILED – cuFFT 库初始化失败。

  • CUFFT_INVALID_SIZE – nx、ny 或 nz 参数中的一个或多个不是支持的大小。

cufftXtExecDescriptor

cufftResult cufftXtExecDescriptor(cufftHandle plan, cudaLibXtDesc *input, cudaLibXtDesc *output, int direction);

函数 cufftXtExecDescriptor 执行任何 cuFFT 变换,无论精度和类型如何。在复数到实数和实数到复数的变换情况下,direction 参数将被忽略。cuFFT 使用 cudaLibXtDesc *input descriptor 指向的 GPU 内存作为输入数据,并使用 cudaLibXtDesc *output 作为输出数据。

参数:
  • plan[In]cufftCreate 返回的 cufftHandle

  • input[In] – 指向要变换的复数输入数据(在 GPU 内存中)的指针

  • output[In] – 指向复数输出数据(在 GPU 内存中)的指针

  • direction[In] – 变换方向:CUFFT_FORWARDCUFFT_INVERSE。对于复数到实数和实数到复数的变换将被忽略。

返回值:
  • CUFFT_SUCCESS – cuFFT 成功执行 FFT 计划。

  • CUFFT_INVALID_PLAN – 计划参数不是有效的句柄。

  • CUFFT_INVALID_VALUE – 参数 input 和 output 中至少有一个无效

  • CUFFT_INTERNAL_ERROR – 检测到内部驱动程序错误。

  • CUFFT_EXEC_FAILED – cuFFT 无法在 GPU 上执行变换。

  • CUFFT_SETUP_FAILED – cuFFT 库初始化失败。

  • CUFFT_INVALID_DEVICE – 在描述符中指定了无效的 GPU 索引。

cufftXtExec, cufftExec*

cufftResult cufftXtExec(cufftHandle plan, void *idata, void *odata, int direction);

在分布式数组上执行计划。idataodata 都必须是 NVSHMEM 分配缓冲区的开头。仅当先前在计划上调用了 cufftXtSetSubformatDefault 时才能调用。相同的条件适用于 cufftExec* API。对于跨步的输入/输出数据(由 cufftXtSetDistribution 设置),在为 NVSHMEM 对称堆分配内存时,NVSHMEM 对称堆中的元素数量对于输入缓冲区应至少为 (upper_input[0] - lower_input[0]) * strides_input[0],对于输出缓冲区应至少为 (upper_output[0] - lower_output[0]) * strides_output[0]。如果每个 GPU 上的元素数量不同,则应使用所有 GPU 中的最大缓冲区大小。由于这会执行通信调用以写入远程 GPU 上的内存缓冲区,因此用户有责任确保在内核执行之前(例如在 API 之前放置同步点/屏障,如 nvshmemx_sync_all_on_stream(stream)),idataodata 和工作区缓冲区(如果有)在所有其他 GPU 上都可用,以避免竞争条件。返回时,所有 GPU 上的内存缓冲区都可用。

参数:
  • plan[In]cufftCreate 返回的 cufftHandle

  • idata[In/Out] – 指向要变换的输入数据(在 GPU 内存和 NVSHMEM 分配中)的指针

  • odata[In/Out] – 指向输出数据(在 GPU 内存和 NVSHMEM 分配中)的指针

  • direction[In] – 变换方向:CUFFT_FORWARDCUFFT_INVERSE。对于复数到实数和实数到复数的变换将被忽略。

返回值:
  • CUFFT_SUCCESS – cuFFT 成功执行 FFT 计划。

  • CUFFT_INVALID_PLAN – 计划参数不是有效的句柄。

  • CUFFT_INVALID_VALUE – 参数 input 和 output 中至少有一个无效

  • CUFFT_INTERNAL_ERROR – 检测到内部驱动程序错误。

  • CUFFT_EXEC_FAILED – cuFFT 无法在 GPU 上执行变换。

  • CUFFT_SETUP_FAILED – cuFFT 库初始化失败。

  • CUFFT_INVALID_DEVICE – 在描述符中指定了无效的 GPU 索引。

描述符

枚举 cufftXtSubFormat
枚举器 CUFFT_XT_FORMAT_INPLACE

描述沿 X 轴分布的内置 Slab 数据分布。

枚举器 CUFFT_XT_FORMAT_INPLACE_SHUFFLED

描述沿 Y 轴分布的内置 Slab 数据分布。

枚举器 CUFFT_XT_FORMAT_DISTRIBUTED_INPUT

描述根据 cufftXtSetDistributionbox_input 参数分布的数据分布

枚举器 CUFFT_XT_FORMAT_DISTRIBUTED_OUTPUT

描述了根据 cufftXtSetDistributionbox_output 参数分布的数据分布。

enum cufftXtCopyType
enumerator CUFFT_COPY_HOST_TO_DEVICE

将数据从主机 CPU 缓冲区复制到设备描述符。数据应根据描述符的子格式进行分布。这不会在进程之间重新分布数据。

enumerator CUFFT_COPY_DEVICE_TO_HOST

将数据从设备描述符复制到主机 CPU 缓冲区。数据将根据描述符的子格式进行分布。这不会在进程之间重新分布数据。

enumerator CUFFT_COPY_DEVICE_TO_DEVICE

将数据从一个设备描述符重新分布到另一个设备描述符。

cufftXtMalloc 和 cufftXtFree

cufftResult cufftXtMalloc(cufftHandle plan, cudaLibXtDesc **descriptor, cufftXtSubFormat format)

cufftXtMalloc 分配一个描述符,以及与计划关联的 GPU 中所有数据的内存,并返回指向描述符的指针。请注意,描述符包含设备指针数组,以便应用程序可以在 GPU 上预处理或后处理数据。枚举参数 cufftXtSubFormat_t 指示缓冲区将用于输入还是输出。有关内存缓冲区管理的更多详细信息,另请参阅 cuFFTMp 中的 NVSHMEM 内存缓冲区

参数:
  • plan[In] – 由 cufftCreate 返回的 cufftHandle

  • descriptor[In/Out] – 指向 cudaLibXtDesc 对象指针的指针

  • format[In]cufftXtSubFormat

返回值:
  • CUFFT_SUCCESS – cuFFT 成功允许用户分配描述符和 GPU 内存。

  • CUFFT_INVALID_PLAN – plan 参数不是有效的句柄,或者它不是多 GPU 计划。

  • CUFFT_ALLOC_FAILED – 计划的 GPU 资源分配失败。

  • CUFFT_INTERNAL_ERROR – 检测到内部驱动程序错误。

  • CUFFT_SETUP_FAILED – cuFFT 库初始化失败。

  • CUFFT_INVALID_DEVICE – 在描述符中指定了无效的 GPU 索引。

cufftResult cufftXtFree(cudaLibXtDesc *descriptor)

cufftXtFree 释放描述符以及与其关联的所有内存。描述符和内存必须是由先前调用 cufftXtMalloc 返回的。

参数:
  • descriptor[In] – 指向 cudaLibXtDesc 对象的指针

返回值:
  • CUFFT_SUCCESS – cuFFT 成功允许用户释放描述符和关联的 GPU 内存。

  • CUFFT_INTERNAL_ERROR – 检测到内部驱动程序错误。

cufftXtMemcpy

cufftResult cufftXtMemcpy(cufftHandle plan, void *dstPointer, void *srcPointer, cufftXtCopyType type)

cufftXtMemcpy 在主机和 GPU 之间或 GPU 之间复制数据。枚举参数 cufftXtCopyType_t 指示传输的类型和方向。

此函数相对于主机是同步的。特别是,如果流与计划关联,则应在调用 cufftXtMemcpy 之前同步该流。

参数:
  • plan[In] – 由 cufftCreate 返回的 cufftHandle

  • dstPointer[Out] – 指向目标地址的指针

  • srcPointer[In] – 指向源地址的指针

  • type[In] – cufftXtCopyType 值

返回值:
  • CUFFT_SUCCESS – cuFFT 成功允许用户在主机和 GPU 之间或 GPU 之间复制内存。

  • CUFFT_INVALID_PLAN – 计划参数不是有效的句柄。

  • CUFFT_INVALID_VALUE – 传递给 API 一个或多个无效参数。

  • CUFFT_INTERNAL_ERROR – 检测到内部驱动程序错误。

  • CUFFT_SETUP_FAILED – cuFFT 库初始化失败。

  • CUFFT_INVALID_DEVICE – 在描述符中指定了无效的 GPU 索引。

独立 Reshape

type cufftReshapeHandle

reshape 操作的不透明句柄。

cufftMpCreateReshape

cufftResult cufftMpCreateReshape(cufftReshapeHandle *handle)

此函数初始化一个 reshape 句柄以供将来使用。此函数不是集体操作。

参数:
  • handle[In/Out] – 指向不透明 cufftReshapeHandle 对象的指针。

返回值:
  • CUFFT_SUCCESS – cuFFT 成功创建了一个 reshape 句柄。

  • CUFFT_ALLOC_FAILED – cuFFT 无法为句柄分配足够的host内存。

cufftMpAttachReshapeComm

cufftResult cufftMpAttachReshapeComm(cufftReshapeHandle handle, cufftMpCommType comm_type, void *comm_handle)

此函数将通信句柄附加到 reshape。此函数不是集体操作。

参数:
  • handle[In] – reshape 操作的句柄,在 cufftMpCreateReshape 之后

  • comm_type[In] – 描述句柄通信类型的枚举。

  • comm_handle[In] – 如果 comm_type 是 CUFFT_COMM_MPI,则这应是指向 MPI 通信器的指针。该指针应保持有效直到句柄销毁。否则,这应为 NULL。

返回值:
  • CUFFT_SUCCESS – cuFFT 成功地将通信句柄与 reshape 关联。

  • CUFFT_INVALID_VALUE – 对于 CUFFT_COMM_MPIcomm_handle 为 NULL,或者对于 CUFFT_COMM_NONEcomm_handle 不为 NULL。

cufftMpMakeReshape

cufftResult cufftMpMakeReshape(cufftReshapeHandle handle, size_t element_size, int rank, const long long int *lower_input, const long long int *upper_input, const long long int *lower_output, const long long int *upper_output, const long long int *strides_input, const long long int *strides_output)

此函数创建一个 reshape,旨在重新分布 3D 数据的全局数组。数据最初根据当前进程上的 *box_in 分布。在 reshape 之后,数据将根据 *box_out 分布。ranklower_inputupper_inputlower_outputupper_outputstrides_inputstrides_output 的含义与 cufftXtSetDistribution 函数相同。每个元素的大小为 element_size 字节。此函数是集体操作,应由所有进程一起调用。所有输入数组可以在此函数返回后立即释放。

参数:
  • handle[In] – reshape 句柄。

  • element_size[In] – 单个元素的大小,以字节为单位。允许的值为 4、8 和 16。

  • rank[In]lower_inputupper_inputlower_outputupper_outputstrides_inputstrides_output 数组的长度。rank 应为 3

  • lower_input[In] – 长度为 rank 的数组,表示输入描述符中当前进程拥有的全局 nx * ny * nz 数组部分的左下角。

  • upper_input[In] – 长度为 rank 的数组,表示输入描述符中当前进程拥有的全局 nx * ny * nz 数组部分的右上角。

  • lower_output[In] – 长度为 rank 的数组,表示输出描述符中当前进程拥有的全局 nx * ny * nz 数组部分的左下角。

  • upper_output[In] – 长度为 rank 的数组,表示输出描述符中当前进程拥有的全局 nx * ny * nz 数组部分的右上角。

  • strides_input[In] – 长度为 rank 的数组,表示输入描述符在内存中的本地数据布局。所有条目都必须是递减且为正数。

  • strides_output[In] – 长度为 rank 的数组,表示输出描述符在内存中的本地数据布局。所有条目都必须是递减且为正数。

返回值:
  • CUFFT_SUCCESS – cuFFT 成功创建了 reshape 操作。

  • CUFFT_INVALID_VALUE – 句柄无效,未调用 cufftMpAttachReshapeComm,rank 不是 3,或者任何数组不正确。

  • CUFFT_ALLOC_FAILED – cuFFT 无法为句柄分配足够的 host 和/或 device 内存。

  • CUFFT_INTERNAL_ERROR – cuFFT 无法初始化底层通信库。

注意

新的实验性多节点实现可以通过在环境中定义 CUFFT_RESHAPE_USE_PACKING=1 来选择。这需要暂存空间,但提供了优于 Infiniband 的性能。

cufftMpGetReshapeSize

cufftResult cufftMpGetReshapeSize(cufftReshapeHandle handle, size_t *workspace_size)

返回执行句柄所需的工作空间大小(以字节为单位)。不保证 workspace_size 在 cuFFTMp 的版本之间会或不会更改。

参数:
  • handle[In] – 使用 cufftMpCreateReshape 创建的句柄。

  • workspace_size[Out] – reshape 执行期间所需的工作空间大小(以字节为单位)

返回值:

CUFFT_SUCCESS – cuFFT 成功返回了工作空间大小。

cufftMpExecReshapeAsync

cufftResult cufftMpExecReshapeAsync(cufftReshapeHandle handle, void *data_out, const void *data_in, void *workspace, cudaStream_t stream)

执行 reshape,使用 workspace 中的工作空间将 data_in 重新分布到 data_out 中。此函数在流 stream 中执行。此函数是集体操作且流有序。用户有责任确保参与通信的所有 GPU 都能够在流中同步,否则可能会发生死锁。对于步幅输入/输出数据,NVSHMEM 对称堆中元素的数量对于输入缓冲区应至少为 (upper_input[0] - lower_input[0]) * strides_input[0],对于输出缓冲区应至少为 (upper_output[0] - lower_output[0]) * strides_output[0](在为 NVSHMEM 对称堆分配内存时)。如果每个 GPU 上的元素数量不同(非对称 reshape),则应使用所有 GPU 中的最大缓冲区大小。由于这会执行通信调用以写入远程 GPU 上的内存缓冲区,因此用户有责任确保 data_indata_outworkspace 在内核执行之前在所有其他 GPU 上都可用(例如,在 API 之前放置同步点/屏障,如 nvshmemx_sync_all_on_stream(stream)),以避免竞争条件。返回时,所有 GPU 上的内存缓冲区都可用。

参数:
  • handle[In] – reshape 句柄。

  • data_out[Out] – 指向输出数据的对称堆指针。此内存应为 NVSHMEM 分配,并且在所有进程上都相同。

  • data_in[In] – 指向输入数据的对称堆指针。此内存应为 NVSHMEM 分配,并且在所有进程上都相同。

  • workspace[Out] – 指向工作空间数据的对称堆指针。此内存应为 NVSHMEM 分配,并且在所有进程上都相同。

  • stream[In] – 在其中运行 reshape 操作的 CUDA 流。

返回值:
  • CUFFT_SUCCESS – cuFFT 成功创建了 reshape 操作。

  • CUFFT_INVALID_VALUE – 在此函数之前未调用 cufftMpMakeReshape。

  • CUFFT_INTERNAL_ERROR – 内核执行期间发生错误。

cufftMpDestroyReshape

cufftResult cufftMpDestroyReshape(cufftReshapeHandle handle)

销毁 reshape 及其所有关联数据。

参数:
  • handle[In] – 要销毁的 reshape 句柄。

返回值:

CUFFT_SUCCESS – 句柄已成功销毁。