2016-06-27 145 views
0

我正在使用CUDA API/cuFFT API。为了将数据从主机移动到GPU,我正在使用cudaMemcpy函数。我像下面一样使用它。 len是dataReal和dataImag上元素的数量。void *指针上的指针运算

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 < char *>但不起作用cuffDoubleComplex *不能静态转换为char *。

我有点困惑为什么第二个cudaMemcpy与void指针算术运行,据我了解它不应该。编译器是否隐含地假定void *背后的数据类型是一个字节长?

我应该改变那里的东西吗?例如,使用reinterpret_cast < char *>(inputData)?

同样在分配期间,我使用旧的C风格(void **)强制转换。我这样做是因为我得到一个“cufftDoubleComplex **无效的static_cast无效**”。有没有其他的方法来正确地做到这一点?

FYI:Link to cudaMemcpy2D Doc

Link to cudaMalloc Doc

+1

尝试'的static_cast ( &(inputData-> y))'(而不是'+ ...')并使用'sizeof(cufftDoubleComplex)'而不是'2 * sizeof(cufftDoubleComplex)'(即使它是相同的值,第一个更通用)。 – Holt

+0

目前尚不清楚为什么你觉得需要投什么东西。 'cudaMalloc'不需要你转换为'void **',并且'cudaMemcpy2D'要求你转换为'void *'。 –

+0

cudaMalloc期望void **和cudaMemcpy2D需要void *。我知道一个事实,他们都在字节而不是类型上工作。我其实希望有一个char *,但这不是CUDA API要我做的。 – FreddyKay

回答

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; 
}; 
+0

感谢您的建议。我应该也能看到,但我没有;-)。将尽快尝试,并将其答案标记为答案。干杯! – FreddyKay