2013-03-06 7 views
0

GPU에서 임의로 생성 된 숫자를 사용하여 각 병렬 배열의 요소를 100 개 초기화하려고합니다. 그러나, 내 일상은 다양한 난수를 생성하지 않습니다. Visual Studio에서 코드를 디버깅 할 때 배열의 모든 요소에 대해 하나의 숫자가 표시됩니다. 이 코드의 목적은 가능한 한 GPU를 사용하도록 CImg FilledTriangles 루틴을 최적화하는 것입니다.Curand와 CUDA 커널을 사용하여 여러 배열을 난수로 동시에 초기화

내가 뭘 잘못하고 어떻게 해결할 수 있습니까? 나는 그리드에서 한 블록에 (각 요소에 대해) 100 개 스레드를 만들려고 오전 :

여기
__global__ void initCurand(curandState* state, unsigned long seed) 
    int idx = threadIdx.x + blockIdx.x * blockDim.x; 
    curand_init(seed, idx, 0, &state[idx]); 
    __syncthreads(); 
} 

/* 
* CUDA kernel that will execute 100 threads in parallel 
*/ 

__global__ void initializeArrays(float* posx, float* posy,float* rayon, float* veloc, float* opacity 
           ,float * angle, unsigned char** color, int height, int width, curandState* state){ 

    int idx = threadIdx.x + blockIdx.x * blockDim.x; 

    curandState localState = state[idx]; 
    __syncthreads(); 

    posx[idx] = (float)(curand_uniform(&localState)*width); 
    posy[idx] = (float)(curand_uniform(&localState)*height); 
    rayon[idx] = (float)(10 + curand_uniform(&localState)*50); 
    angle[idx] = (float)(curand_uniform(&localState)*360); 
    veloc[idx] = (float)(curand_uniform(&localState)*20 - 10); 
    color[idx][0] = (unsigned char)(curand_uniform(&localState)*255); 
    color[idx][1] = (unsigned char)(curand_uniform(&localState)*255); 
    color[idx][2] = (unsigned char)(curand_uniform(&localState)*255); 
    opacity[idx] = (float)(0.3 + 1.5*curand_uniform(&localState)); 
} 

가 준비하고 이러한 커널을 호출하는 호스트 코드입니다 : 여기 내 코드입니다.

// launch grid of threads 
     dim3 dimBlock(100); 
     dim3 dimGrid(1); 

     initCurand<<<dimBlock,dimGrid>>>(devState, unsigned(time(nullptr))); 
     // synchronize the device and the host 
    cudaDeviceSynchronize(); 
    initializeArrays<<<dimBlock, dimGrid>>>(d_posx, d_posy, d_rayon, d_veloc, d_opacity, d_angle,d_color, img0.height(), img0.width(), devState); 

예선 :

// Define random properties (pos, size, colors, ..) for all triangles that will be displayed. 
    float posx[100], posy[100], rayon[100], angle[100], veloc[100], opacity[100]; 
    // Define the same properties but for the device 
    float* d_posx; 
    float* d_posy; 
    float* d_rayon; 
    float* d_angle; 
    float* d_veloc; 
    float* d_opacity; 
    //unsigned char d_color[100][3]; 
    unsigned char** d_color; 
    curandState* devState; 
    cudaError_t err; 

    // allocate memory on the device for the device arrays 
    err = cudaMalloc((void**)&d_posx, 100 * sizeof(float)); 
    err = cudaMalloc((void**)&d_posy, 100 * sizeof(float)); 
    err = cudaMalloc((void**)&d_rayon, 100 * sizeof(float)); 
    err = cudaMalloc((void**)&d_angle, 100 * sizeof(float)); 
    err = cudaMalloc((void**)&d_veloc, 100 * sizeof(float)); 
    err = cudaMalloc((void**)&d_opacity, 100 * sizeof(float)); 
    err = cudaMalloc((void**)&devState, 100*sizeof(curandState)); 
    errCheck(err); 
    size_t pitch; 
    //allocated the device memory for source array 
    err = cudaMallocPitch(&d_color, &pitch, 3 * sizeof(unsigned char),100); 

얻기 결과 : 이것에

err = cudaMalloc((void**)&devState, 100*sizeof(float)); 

:

// get the populated arrays back to the host for use 
    err = cudaMemcpy(posx,d_posx, 100 * sizeof(float), cudaMemcpyDeviceToHost); 
    err = cudaMemcpy(posy,d_posy, 100 * sizeof(float), cudaMemcpyDeviceToHost); 
    err = cudaMemcpy(rayon,d_rayon, 100 * sizeof(float), cudaMemcpyDeviceToHost); 
    err = cudaMemcpy(veloc,d_veloc, 100 * sizeof(float), cudaMemcpyDeviceToHost); 
    err = cudaMemcpy(opacity,d_opacity, 100 * sizeof(float), cudaMemcpyDeviceToHost); 
    err = cudaMemcpy(angle,d_angle, 100 * sizeof(float), cudaMemcpyDeviceToHost); 
    err = cudaMemcpy2D(color,pitch,d_color,100, 100 *sizeof(unsigned char),3, cudaMemcpyDeviceToHost); 

답변

1

은 확실히 당신이에서 변경해야합니다

err = cudaMalloc((void**)&devState, 100*sizeof(curandState)); 

cuda-memcheck를 통해 코드를 실행 한 경우이 코드를 발견했을 것입니다. 귀하의 initCurand 커널은 이것 때문에 많은 범위를 벗어났습니다.

또한 모든 cuda 호출 및 모든 커널 시작시 error checking을 수행해야합니다. 두 번째 커널 호출이 color[][] 배열의 엉망인 작업으로 인해 실패했다고 생각합니다.

일반적으로 cudaMallocPitch으로 배열을 만들 때 pitch 매개 변수를 사용하여 액세스해야합니다. C에는 실제 배열 너비에 대한 고유 한 지식이 없기 때문에 C 자체로 쌍 첨자 배열이 작동하지 않습니다. 나는이 오류를 제거 할 수 있었다 이러한 변화와

__global__ void initializeArrays(float* posx, float* posy,float* rayon, float* veloc, float* opacity,float * angle, unsigned char* color, int height, int width, curandState* state, size_t pitch){ 

    int idx = threadIdx.x + blockIdx.x * blockDim.x; 

    curandState localState = state[idx]; 
    __syncthreads(); 

    posx[idx] = (float)(curand_uniform(&localState)*width); 
    posy[idx] = (float)(curand_uniform(&localState)*height); 
    rayon[idx] = (float)(10 + curand_uniform(&localState)*50); 
    angle[idx] = (float)(curand_uniform(&localState)*360); 
    veloc[idx] = (float)(curand_uniform(&localState)*20 - 10); 
    color[idx*pitch] = (unsigned char)(curand_uniform(&localState)*255); 
    color[(idx*pitch)+1] = (unsigned char)(curand_uniform(&localState)*255); 
    color[(idx*pitch)+2] = (unsigned char)(curand_uniform(&localState)*255); 
    opacity[idx] = (float)(0.3 + 1.5*curand_uniform(&localState)); 
} 

initializeArrays<<<dimBlock, dimGrid>>>(d_posx, d_posy, d_rayon, d_veloc, d_opacity, d_angle,d_color, img0.height(), img0.width(), devState, pitch); 

unsigned char* d_color; 

:

나는 다음과 같이 변경하여 문제를 해결할 수 있었다 나는 발견하고 코드는 다양한 임의의 값을 뱉어. 나는 모든 가치들을 조사하지는 않았지만 그것은 당신을 시작하게 할 것입니다.

+0

감사합니다. 나는 내가 그것을 놓쳤다라고 생각할 수 없다! 나는 CUDA를 처음 접했습니다. 변경 사항을 포함하도록 질문을 업데이트하겠습니다. –

+0

사실 추가 편집을하면 작동 할 수 있어야한다고 생각합니다. –

+0

저는 여전히 오류가 발생하고 있지만 색상 배열 구조가 변경되고 호출되는 방식 때문일 수 있습니다. 나는 그 변화를 만들 것이고 나는 어떤 일이 일어나는지 보게 될 것이다. 도와 주셔서 대단히 감사합니다. CUDA에서 배울 점이 많습니다. –