2016-06-27 225 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