2012-12-21 5 views
0

커널 시작에 문제가 있습니다. 하나의 큰 커널을 사용하는 프로그램이있었습니다. 이제 동기화 문제로 2 개로 분할해야했습니다. 첫 번째 커널은 일부 init 작업을 수행하고 두 번째 커널에 전달 된 인수의 하위 집합을 전달받습니다. 첫 번째 커널 만 실행하면 문제가 없습니다. 두 번째 커널 만 실행하면 초기화가 누락되어 실행하는 동안 실패하지만 커널 자체가 시작됩니다. 두 행을 모두 실행하면 두 번째 커널이 "잘못된 인수"오류로 실패합니다. 필요한 경우 코드를 제공 하겠지만 지금 당장 어떻게 도움이 될지 알 수는 없습니다. 미리 감사드립니다.두 번째 커널에서 cuda "invalid argument"오류가 발생했습니다.

편집 : 여기에 요청 된 실행 코드 :이 일을하기 때문에 하나의 커널을 사용하는 경우

void DeviceManager::integrate(){ 
    assert(hostArgs->neighborhoodsSize > 0); 
    size_t maxBlockSize; 
    size_t blocks; 
    size_t threadsPerBlock; 
    // init patch kernel 
    maxBlockSize = 64; 
    blocks = (hostArgs->patchesSize /maxBlockSize); 
    if(0 != hostArgs->patchesSize % maxBlockSize){ 
    blocks++; 
    } 
    threadsPerBlock = maxBlockSize; 
    std::cout << "blocks: " << blocks << ", threadsPerBlock: " << threadsPerBlock << std::endl; 
    initPatchKernel<CUDA_MAX_SPACE_DIMENSION><<<blocks,threadsPerBlock>>>(devicePatches, hostArgs->patchesSize); 
    cudaDeviceSynchronize(); 

    //calc kernel 
    maxBlockSize = 64; 
    blocks = (hostArgs->neighborhoodsSize /maxBlockSize); 
    if(0 != hostArgs->neighborhoodsSize % maxBlockSize){ 
    blocks++; 
    } 
    threadsPerBlock = maxBlockSize; 
    size_t maxHeapSize = hostArgs->patchesSize * (sizeof(LegendreSpace) + sizeof(LinearSpline)) + hostArgs->neighborhoodsSize * (sizeof(ReactionDiffusionCCLinearForm) + sizeof(ReactionDiffusionCCBiLinearForm)); 
    std::cout << "maxHeapSize: " << maxHeapSize << std::endl; 
    cudaDeviceSetLimit(cudaLimitMallocHeapSize, maxHeapSize); 
    std::cout << "blocks: " << blocks << ", threadsPerBlock: " << threadsPerBlock << std::endl; 
    integrateKernel<CUDA_MAX_SPACE_DIMENSION><<<blocks,threadsPerBlock>>>(deviceNeighborhoods, hostArgs->neighborhoodsSize, devicePatches, hostArgs->patchesSize, hostArgs->biLinearForms, hostArgs->linearForms, deviceRes); 
    cudaDeviceSynchronize(); 
} 

메모리 전송 및 할당은 문제가되지 않습니다.

EDIT 2 : 래퍼 기능을 통해 디버그 모드로 빌드 할 때 각 커널 호출 후에 오류를 확인합니다. 트릭을 붙여하지 않는

cudaError_t cuda_result_code = cudaGetLastError();       
if (cuda_result_code!=cudaSuccess) {          
    fprintf("message: %s\n",cudaGetErrorString(cuda_result_code)); 
} 

죄송이 언급하지 않는, 래퍼 날에 의해 미안되지 않습니다 : 각각의 커널이 실행 된 다음 호출 한 후 그래서. 오른쪽 실패 전에 출력은 다음과 같다 :

blocks: 1, threadsPerBlock: 64 
maxHeapSize: 4480 
blocks: 1, threadsPerBlock: 64 
message: invalid argument 
+1

코드 제공이 도움이 될 것입니다. 특히 두 번째 커널 호출의 시작 매개 변수와 그 파생 방법에 관심이 있습니다. –

+1

적어도 메모리 초기화 및 커널 호출 코드를 알려주십시오 .. – ardiyu07

+1

오류 검사가 표시되지 않습니다. "잘못된 인수 오류"로 커널이 실패하는 것을 어떻게 알 수 있습니까? 또한 두 커널을 시작하기 직전에 blocks 및 threadsPerBlock 변수를 출력합니다. 실패 이전에 어떤 결과물을 얻었습니까? –

답변

2

cudaDeviceSetLimit

cudaLimitMallocHeapSize 제어의 malloc() 및 free()를 장치의 시스템 호출에 의해 사용되는 힙의 바이트 크기. cudaLimitMallocHeapSize를 설정하려면 을 실행 한 다음 malloc() 또는 free() 장치 시스템 호출을 사용하는 커널을 실행해야합니다. 그렇지 않으면 cudaErrorInvalidValue이 반환됩니다. 이 제한은 컴퓨팅 기능이 2.0 이상인 장치에만 적용됩니다. 2.0 이하의 컴퓨팅 기능을 가진 장치에서이 제한을 설정하려고하면 cudaErrorUnsupportedLimit 오류가 반환됩니다.

+0

고마워요. 나는 언젠가는 그 일을 유감스럽게 생각할 시간이있을 때 당신의 제안을 시도 할 것입니다. – soriak

+0

이제 답변을 염두에두고 코드를 확인할 시간이있었습니다. 내 메모리 할당 설계에 여러 가지 버그가있었습니다. 이제는 커널보다 먼저 cudaDeviceSetLimit (연산 능력 2.0이있는 카드가 있음)을 호출하여 메모리를 초기화합니다. 독자적으로 메모리를 할당하고 해제하는 기본 커널 (integrateKernel)보다. 마지막으로 init 커널에 의해 초기화 된 메모리를 해제하는 새로운 커널 (나는 이것을 잊었다). 이제 모든 것이 잘됩니다. 답장을 보내 주셔서 다시 한 번 감사드립니다. – soriak

관련 문제