2014-09-26 7 views
0

저는 CUDA를 처음 사용했습니다. 나는 그것을 익숙하게하는 데 도움이되는 간단한 연습을하려고 노력했다. 나는 작은 프로그램 인 "Find Prime Numbers"를 코딩했다. 거의 끝났지 만 해결할 수없는 문제가 있습니다.CUDA 오류 메시지 : 잘못된 구성 인수

getPrimeKernel launch failed!!: invalid configuration argument 
findPrimeWithCuda failed!! 

내가 내 코드를 조정해야합니다 : 나는 1027보다 더 입력, 나는 오류 메시지가 표시됩니다 내가 찾을 수있는 최대 번호가 1027 인 것을 발견? 고맙습니다. 여기

내 코드입니다 :

#include "cuda_runtime.h" 
#include "device_launch_parameters.h" 

#include <iostream> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <vector> 

using namespace std; 

cudaError_t findPrimeWithCuda(bool *c, int *a, unsigned int size); 

__host__ __device__ bool checkPrime(int i) 
{ 
    for (int m = 2; m <= i - 1; m++) 
    { 
     if (i%m == 0) return true; 
    } 
    return false; 
} 

__global__ void getPrimeKernel(bool *c, int *a) 
{ 
    int i = threadIdx.x; 
    c[i] = checkPrime(a[i]); 
} 

void cudaGetPrime(int i) 
{ 
    i = i - 3; 
    int *arr = (int *)malloc((size_t)(i * sizeof(int))); 
    bool *rst = (bool *)malloc((size_t)(i * sizeof(bool))); 
    for (int j = 0; j <= i; j++) arr[j] = j + 3; 
    cudaError_t cudaStatus = findPrimeWithCuda(rst, arr, i); 
    if (cudaStatus != cudaSuccess) fprintf(stderr,"findPrimeWithCuda failed!!"); 
} 

void w_CudaArray(int lastNum) 
{ 
    time_t t1 = time(NULL); 
    cudaGetPrime(lastNum); 
    time_t t2 = time(NULL); 
    printf("Time to spent : %d second\n", t2 - t1); 
    cout << "Computing with CUDA to count the prime numbers ends!!" << endl << endl; 
} 

int main() 
{ 
    int lastNum = 0; 
    cout << "The final number which you want to find the prime numbers : "; 
    cin >> lastNum; 
    w_CudaArray(lastNum); 
} 

cudaError_t findPrimeWithCuda(bool *c, int *a, unsigned int size) 
{ 
    int *dev_a = 0; 
    bool *dev_c = false; 
    cudaError_t cudaStatus; 

    cudaStatus = cudaSetDevice(0); 
    if (cudaStatus != cudaSuccess) 
    { 
     fprintf(stderr, "cudaSetDevice failed!!"); 
     goto Error; 
    } 

    size_t totalm, freem; 
    float free_m, total_m, used_m; 
    cudaMemGetInfo(&freem, &totalm); 
    free_m = (size_t)freem/1048576.0; 
    total_m = (size_t)totalm/1048576.0; 
    used_m = total_m - free_m; 
    cout << "Total memory = " << total_m << " MB" << endl; 
    cout << "Used memory = " << used_m << " MB" << endl; 
    cout << "Free memory = " << free_m << " MB" << endl; 

    cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(int)); 
    if (cudaStatus != cudaSuccess) 
    { 
     fprintf(stderr, "cudaMalloc dev_a failed!!"); 
     goto Error; 
    } 

    cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(bool)); 
    if (cudaStatus != cudaSuccess) 
    { 
     fprintf(stderr, "cudaMalloc dev_c failed!!"); 
     goto Error; 
    } 

    cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice); 
    if (cudaStatus != cudaSuccess) 
    { 
     fprintf(stderr, "cudaMemcpy dev_a failed!!"); 
     goto Error; 
    } 

    getPrimeKernel<<<1, size>>>(dev_c, dev_a); 

    cudaStatus = cudaGetLastError(); 
    if (cudaStatus != cudaSuccess) 
    { 
     fprintf(stderr, "getPrimeKernel launch failed!!: %s\n", cudaGetErrorString(cudaStatus)); 
     goto Error; 
    } 

    if (cudaStatus != cudaSuccess) 
    { 
     fprintf(stderr, "cudaDeviceSynchorinze returned error code %d after launching getPrimeKernel!\n", cudaStatus); 
     goto Error; 
    } 

    cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(bool), cudaMemcpyDeviceToHost); 

    if (cudaStatus != cudaSuccess) 
    { 
     fprintf(stderr, "cudaMemory failed!"); 
     goto Error; 
    } 

    int trueNumber = 0; 
    for (int i = 0; i < size; i++) 
    { 
     if (c[i] == false) trueNumber++; 
    } 

    cout << "There are " << trueNumber + 2 << " prime numbers!!" << endl; 

    cudaStatus = cudaDeviceReset(); 
    if (cudaStatus != cudaSuccess) 
    { 
     fprintf(stderr, "cudaDeviceReset failed!!"); 
    } 

Error: 
    cudaFree(dev_c); 
    cudaFree(dev_a); 

    return cudaStatus; 
} 

답변

2

당신은 블록 당 스레드의 수가 size와 커널을 호출하고합니다 (Programming Guide section on Kernel invocation syntax)를 참조하지만, 블록 당 최대 스레드 수는에 따라 제한됩니다. 장치의 계산 기능 블록 당 최대 1024 개의 스레드가있는 장치가있을 수 있습니다. 따라서 더 큰 숫자 (귀하의 경우에는 1027)로 더 이상 작동하지 않습니다. 블록 당 최대 스레드 수 장치의 경우, this table on Wikipedia에 나열됩니다.

cudaDeviceGetProperties을 사용하여 블록 당 최대 스레드 수를 쿼리하고 maxThreadsPerBlock 필드를 볼 수 있습니다.

블록 당 스레드 수보다 큰 입력 크기를 처리하려면 블록이 더 필요합니다! 즉, 더 큰 격자 크기를 사용해야합니다. 따라서 입력에 적합한 격자 및 블록 크기를 계산하고이를 매개 변수로 커널 시작에 전달해야합니다. 다음과 같은 예를 들어

:

int inputSize = ...; // The size of the input data 
int threadsPerBlock = 256; // May be queried from the device properties 
int blocksPerGrid = (inputSize + threadsPerBlock - 1)/threadsPerBlock; 

callKernel<<<blocksPerGrid, threadsPerBlock>>>(...); 

이 단지 기본 개념을 보여줍니다. 자세한 내용은 CUDA 프로그래밍 가이드 또는 사용 가능한 샘플을 참조하십시오. 예를 들어, 스레드 인덱스를 사용해야하고 이 아니고이 잘못된 메모리 영역에 액세스해야합니다. 이것은 커널에 입력 배열의 길이를 전달하여 달성하고 경계에 아직도 여부를 확인 할 수 있습니다

옆으로
__global__ void callKernel(int *array, int arrayLength) { 
    // Make sure to compute the GLOBAL thread index like this: 
    int i = blockDim.x*blockIdx.x + threadIdx.x 
    if (i >= arrayLength) { 
     return; 
    } 
    .... 
} 

(: 연습을 위해, 아무것도, 잘 될 수도 있지만 난 이 형태로 소수를 찾는 것이 실제로 CUDA에 적합한 지 여부는 확실치 않습니다. 벡터 추가 또는 행렬 곱셈과 같은 "클래식"CUDA 예제를 살펴볼 수도 있습니다 ...)

0

일부 부분이 수정되었습니다. 내 코드의 문제가 해결되었습니다.

cudaDeviceProp myCUDA; 
if (cudaGetDeviceProperties(&myCUDA, 0) == cudaSuccess) 
{ 
    printf("Using device %d:\n", 0); 
    printf("%s; global mem: %dB; compute v%d.%d; clock: %d kHz\n", 
     myCUDA.name, (int)myCUDA.totalGlobalMem, (int)myCUDA.major, 
     (int)myCUDA.minor, (int)myCUDA.clockRate); 
} 

int threadsPerBlock = myCUDA.maxThreadsPerBlock; 
int blocksPerGrid = (size + threadsPerBlock - 1)/threadsPerBlock; 
cout << "Maxium number per block = " << threadsPerBlock << endl; 
cout << "Blocks per Grid = " << blocksPerGrid << endl; 

getPrimeKernel<<<blocksPerGrid, threadsPerBlock>>>(dev_c, dev_a, size); 

__global__ void getPrimeKernel(bool *c, int *a, int size) 
{ 
    int i = blockDim.x * blockIdx.x + threadIdx.x; 
    if (i >= size) return; 
    c[i] = checkPrime(a[i]); 
} 

이 지금은 코드의이 부분은 나 같은 새로운 다른 사람을 도울 수 이상의 1027 희망 숫자를 계산할 수 있습니다. :)