2016-06-27 2 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 *으로 캐스트 될 수 없으므로 작동하지 않습니다.

나는 왜 그렇게해서는 안된다는 이유로, void에 대한 포인터 산술 연산을하는 두 번째 cudaMemcpy가 혼란 스럽다. 컴파일러는 void * 뒤에있는 데이터 유형이 1 바이트 길이라고 암묵적으로 가정하고 있습니까?

내가 거기에 바뀌어야합니까? 예를 들어 reinterpret_cast < char *> (inputData)를 사용 하시겠습니까?

할당 도중 이전 C 스타일 (void **)을 사용하고 있습니다. 나는 "무효 static_cast cufftDoubleComplex **에서 무효로 **"때문에이 작업을 수행합니다. 이 작업을 올바르게 수행 할 수있는 또 다른 방법이 있습니까? 참고로

: 포인터 산술 연산이 뾰족한 물체의 크기에 따라 때문에 당신은 void*에 산술 연산을 수행 할 수 없습니다 Link to cudaMemcpy2D Doc

Link to cudaMalloc Doc

+1

시도'(을 static_cast & (inputData-> y))'('+ ...'대신)'2 * sizeof (cufftDoubleComplex)'대신'sizeof (cufftDoubleComplex)'를 사용하십시오 (동일한 값이더라도 첫 번째 것은 더 일반적인 것입니다). – Holt

+0

왜 당신이 무엇인가를 던질 필요성을 느끼는 이유는 명확하지 않습니다. 'cudaMalloc'은 당신이'void ** '로 형 변환 할 것을 요구하지 않으며 niether는'cudaMemcpy2D'가 당신이'void *'형으로 변환 할 것을 요구합니다. –

+0

cudaMalloc은 void **를 예상하고 cudaMemcpy2D는 void *를 예상합니다. 사실 둘 다 바이트에서 작동하고 타입에서는 작동하지 않는다는 것을 알고 있습니다. 사실 char *을 갖고 싶습니다. 그러나 이것은 CUDA API가 원하는 것이 아닙니다. – FreddyKay

답변

1

(그리고 sizeof(void)은 정말 아무것도 의미하지 않는다).

char*에서 산술 연산으로 void*의 산술 연산을 처리하는 컴파일러 확장 덕분에 코드가 컴파일됩니다. 귀하의 경우에는

, 당신은 아마 산술 연산을하지 않아도, 다음이 작동 (더 견고)한다 : cufftDoubleComplex 이후

coypResult &= cudaMemcpy2D(static_cast<void*>(&inputData->y), 
          sizeof (cufftDoubleComplex), 

는 단순히 :

struct __device_builtin__ __builtin_align__(16) double2 
{ 
    double x, y; 
}; 
+0

제안 해 주셔서 감사합니다. 나는 그것도 볼 수 있었어야했는데, 나는 그렇지 않았다 ;-). 최대한 빨리 시도해보고 작동 할 때 답변을 답변으로 표시합니다. 건배! – FreddyKay