我正在使用CUDA API / cuFFT API。为了将数据从主机移动到GPU,我使用了cudaMemcpy函数。我正在使用它如下。 len是dataReal和dataImag上的元素数量。
void foo(const double* dataReal, const double* dataImag, size_t len)
{
cufftDoubleComplex* inputData;
size_t allocSizeInput = sizeof(cufftDoubleComplex)*len;
cudaError_t allocResult = cudaMalloc((void**)&inputData, allocSizeInput);
if (allocResult != cudaSuccess) return;
cudaError_t copyResult;
coypResult = cudaMemcpy2D(static_cast<void*>(inputData),
2 * sizeof (double),
static_cast<const void*>(dataReal),
sizeof(double),
sizeof(double),
len,
cudaMemcpyHostToDevice);
coypResult &= cudaMemcpy2D(static_cast<void*>(inputData) + sizeof(double),
2 * sizeof (double),
static_cast<const void*>(dataImag),
sizeof(double),
sizeof(double),
len,
cudaMemcpyHostToDevice);
//and so on.
}
我知道,对void指针的指针算法实际上是不可能的。第二个cudaMemcpy2D仍然可以工作。我仍然会收到编译器的警告,但它可以正常工作。
我尝试过使用static_cast&lt; char *&gt;但这不起作用,因为cuffDoubleComplex *不能静态转换为char *。
我有点困惑为什么带有void指针算法的第二个cudaMemcpy正在工作,据我所知它不应该。编译器是否隐式假设void *后面的数据类型是一个字节长?
我应该在那里换一些东西吗?使用reinterpret_cast&lt; char *&gt;(inputData)例如?
同样在分配期间,我使用旧的C风格(void **)演员。我这样做是因为我收到了“从cufftDoubleComplex **到void **的无效static_cast”。有没有其他方法可以正确地做到这一点?
答案 0 :(得分:1)
你不能对void*
进行算术运算,因为对指针的算术运算是基于指向对象的大小的(并且sizeof(void)
并不意味着什么)。
您的代码编译可能归功于编译器扩展,该扩展将void*
上的算术运算视为char*
上的算术运算。
在您的情况下,您可能不需要算术运算,以下应该可以工作(并且更加健壮):
coypResult &= cudaMemcpy2D(static_cast<void*>(&inputData->y),
sizeof (cufftDoubleComplex),
由于cufftDoubleComplex
只是:
struct __device_builtin__ __builtin_align__(16) double2
{
double x, y;
};