多 GPU 批处理 1D FFT:似乎只有一个 GPU 可以工作
Multi-GPU batched 1D FFTs: only a single GPU seems to work
我在 RHEL 100 上有三台特斯拉 V8,带有 CUDA 工具包版本 10.2.89。
我正在尝试计算行主矩阵列的一批 1D FFT。在下面的示例中,矩阵是 16x8,因此对于三个 GPU,我希望 GPU 0 执行前 3 列的 FFT,GPU 1 执行接下来 3 列的 FFT,GPU 2 执行最后 2 列的 FFT。
示例中创建的计划在单个 GPU 上按预期工作,但在三个 GPU 上运行时,仅计算前三列(正确(,其余列保持不变。
当我检查由 cufftXtMalloc 填充的描述符时,我看到它为 GPU 0 和 1 上的 123 个元素分配了空间,在 GPU 2 上为 122 个元素分配了空间。这似乎很奇怪:我希望 GPU 0 和 16 上的 16*3 和 GPU 32=2 和 GPU 2 上的 2*2。事实上,这是cufftMakePlanMany填充的工作空间的大小。当我检查复制的数据时,元素 0-122 位于 GPU 0 上的缓冲区中,元素 123-127 位于 GPU 1 缓冲区的开头。该缓冲区的其余部分和 GPU 2 上的缓冲区是垃圾。
此外,当我将行数增加到 1024 时,我在 cufftXtFree 调用上收到一个 SIGABRT,其中包含消息"free((:损坏的未排序块"。
#include "cufft.h"
#include "cufftXt.h"
#include <vector>
#include <cuComplex.h>
#include <cassert>
#define CUDA_CHECK(x) assert(x == cudaSuccess)
#define CUFFT_CHECK(x) assert(x == CUFFT_SUCCESS)
int main() {
static const int numGPUs = 3;
int gpus[numGPUs] = {0, 1, 2};
int nr = 16;
int nc = 8;
// Fill with junk data
std::vector<cuFloatComplex> h_x(nr * nc);
for (int i = 0; i < nr * nc; ++i) {
h_x[i].x = static_cast<float>(i);
}
cufftHandle plan;
CUFFT_CHECK(cufftCreate(&plan));
CUFFT_CHECK(cufftXtSetGPUs(plan, numGPUs, gpus));
std::vector<size_t> workSizes(numGPUs);
int n[] = {nr};
CUFFT_CHECK(cufftMakePlanMany(plan,
1, // rank
n, // n
n, // inembed
nc, // istride
1, // idist
n, // onembed
nc, // ostride
1, // odist
CUFFT_C2C,
nc,
workSizes.data()));
cudaLibXtDesc *d_x;
CUFFT_CHECK(cufftXtMalloc(plan, &d_x, CUFFT_XT_FORMAT_INPLACE));
CUFFT_CHECK(cufftXtMemcpy(plan, d_x, (void *)h_x.data(), CUFFT_COPY_HOST_TO_DEVICE));
CUFFT_CHECK(cufftXtExecDescriptorC2C(plan, d_x, d_x, CUFFT_FORWARD));
std::vector<cuFloatComplex> h_out(nr * nc);
CUFFT_CHECK(cufftXtMemcpy(plan, (void *)h_out.data(), d_x, CUFFT_COPY_DEVICE_TO_HOST));
CUFFT_CHECK(cufftXtFree(d_x));
CUFFT_CHECK(cufftDestroy(plan));
CUDA_CHECK(cudaDeviceReset());
return 0;
}
感谢@RobertCrovella的回答:
根据文档,从 CUDA 10.2.89 开始,多 GPU 转换不支持跨步输入和输出。
相关文章:
- 有一个打印语句的函数是一种糟糕的编程实践吗
- VSCode-有一个红色下划线,但程序构建和运行正确,并且出现配音错误
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 有没有可能有一个只有ADL才能找到的非好友功能
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 我的程序有一个保存配置文件的GUI,如何双击此配置文件以直接加载带有配置数据的GUI?
- 在学习数据结构之前对STL有一个了解是好的吗?
- 我在 .h 中有一个枚举类,并且在.cpp错误中有一个运算符重载:与"运算符<<不匹配
- 如何在 Gnuplot 中分别绘制 2 个文件数据?我有一个文件"sin.txt",另一个文件"cos.txt",我想将它们分别绘制在一个图表上
- 是否可以在C++中有一个"generic"模板参数,该参数可以是非类型模板参数或类型?
- 我的输出中有一个额外的 0,为什么会这样
- 节点是否为空,即使它有一个值?
- 将数组信息存储到 c++ 向量中有一个"Access violation reading location"
- 在 Stream C++ 文本之前有一个额外的换行符
- 我可以有一个 ELI5 作为参考和指针以及何时使用它们吗?
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 我有一个类,它创建了另一个类的实例.如何将变量通过第一个类传递到第二个类的实例化中?
- 我有一个线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)错误.我认为这是由于内存管理不好.我可以
- 有一个构造函数,但有两个析构函数
- 我有一个关于C++提升的问题:: asio 和 std :: 异步