2013-06-02 4 views
0

전 MATLAB에서 사용할 전경 추출 커널을 썼습니다. 아무 것도 인쇄하지 않아서 순수한 Cuda C로 포팅하여 대부분의 논리를 제거했습니다. 이 일은 아무 것도하지 않고 심지어 반환 전에 cuPrintf 문을 인쇄하지 않습니다. 그 이유는 무엇입니까?커널이 시작되지 않습니까?

#include <cuda.h> 
#include <stdio.h>  /* printf, scanf, NULL */ 
#include <stdlib.h>  /* calloc, exit, free */ 
#include "cuPrintf.cu" 
#include "utils.h" 
#include <time.h>  /* clock_t, clock, CLOCKS_PER_SEC */ 



__global__ void foreground_extract(  unsigned char* inputImageRed, 
             unsigned char* inputImageGreen, 
             unsigned char* inputImageBlue, 

             unsigned char* outputImageRed, 
             unsigned char* outputImageGreen, 
             unsigned char* outputImageBlue,           

             const int xDim, 
             const int yDim) 
{ 


    cuPrintf("print something \n"); 
    //x = col, y = row 
    //xDim = col_dim, yDim = row_dim 
    int x = threadIdx.x + blockIdx.x * blockDim.x; 
    int y = threadIdx.y + blockIdx.y * blockDim.y; 
    int offset = x + y *blockDim.x *gridDim.x; 

    int nnodes = xDim*yDim; 
    if (offset >= nnodes) return; 


    //test equality 

    outputImageRed[offset] = inputImageRed[offset]; 
    outputImageGreen[offset] = inputImageGreen[offset]; 
    outputImageBlue[offset] = inputImageBlue[offset]; 

    cuPrintf("print something here too \n"); 
    cuPrintf("%d \n", outputImageRed[offset]); 

} 

int main() 
{ 

     int xDim = 3; 
     int yDim = 3; 

             unsigned char* h_inputImageRed; 
             unsigned char* h_inputImageGreen; 
             unsigned char* h_inputImageBlue; 

             unsigned char* h_outputImageRed; 
             unsigned char* h_outputImageGreen; 
             unsigned char* h_outputImageBlue; 


        h_inputImageRed = (unsigned char*) calloc ((xDim*yDim), sizeof(unsigned char)); 
        h_inputImageGreen = (unsigned char*) calloc ((xDim*yDim), sizeof(unsigned char)); 
        h_inputImageBlue = (unsigned char*) calloc ((xDim*yDim), sizeof(unsigned char)); 

        h_outputImageRed = (unsigned char*) calloc ((xDim*yDim), sizeof(unsigned char)); 
        h_outputImageGreen = (unsigned char*) calloc ((xDim*yDim), sizeof(unsigned char)); 
        h_outputImageBlue = (unsigned char*) calloc ((xDim*yDim), sizeof(unsigned char)); 


     //initiate input only 
     unsigned char init =0; 
     for (int i=0; i<(xDim*yDim);i++){ 

              h_inputImageRed[i] = init; 
              h_inputImageGreen[i] = init; 
              h_inputImageBlue[i] = init; 

              init++; 

              printf("%d\n", h_inputImageRed[i]); 

     } 

             //device arrays 
             unsigned char* d_inputImageRed; 
             unsigned char* d_inputImageGreen; 
             unsigned char* d_inputImageBlue; 

             unsigned char* d_outputImageRed; 
             unsigned char* d_outputImageGreen; 
             unsigned char* d_outputImageBlue; 


    //cudaMallocs 

    checkCudaErrors(cudaMalloc((void**)&d_inputImageRed, (sizeof(unsigned char)*xDim*yDim))); 
    checkCudaErrors(cudaMalloc((void**)&d_inputImageGreen, (sizeof(unsigned char)*xDim*yDim))); 
    checkCudaErrors(cudaMalloc((void**)&d_inputImageBlue, (sizeof(unsigned char)*xDim*yDim))); 

    checkCudaErrors(cudaMalloc((void**)&d_outputImageRed, (sizeof(unsigned char)*xDim*yDim))); 
    checkCudaErrors(cudaMalloc((void**)&d_outputImageGreen, (sizeof(unsigned char)*xDim*yDim))); 
    checkCudaErrors(cudaMalloc((void**)&d_outputImageBlue, (sizeof(unsigned char)*xDim*yDim))); 

    //cudaMemcpys, Host to Device 

    checkCudaErrors(cudaMemcpy(d_inputImageRed, h_inputImageRed, (sizeof(unsigned char)*xDim*yDim), cudaMemcpyHostToDevice)); 
    checkCudaErrors(cudaMemcpy(d_inputImageGreen, h_inputImageGreen, (sizeof(unsigned char)*xDim*yDim), cudaMemcpyHostToDevice)); 
    checkCudaErrors(cudaMemcpy(d_inputImageBlue, h_inputImageBlue, (sizeof(unsigned char)*xDim*yDim), cudaMemcpyHostToDevice)); 

    checkCudaErrors(cudaMemcpy(d_outputImageRed, h_outputImageRed, (sizeof(unsigned char)*xDim*yDim), cudaMemcpyHostToDevice)); 
    checkCudaErrors(cudaMemcpy(d_outputImageGreen, h_outputImageGreen, (sizeof(unsigned char)*xDim*yDim), cudaMemcpyHostToDevice)); 
    checkCudaErrors(cudaMemcpy(d_outputImageBlue, h_outputImageBlue, (sizeof(unsigned char)*xDim*yDim), cudaMemcpyHostToDevice)); 

    cudaPrintfInit(); 

    int gridSizeX = ceil(float(xDim/8)); 
    int gridSizeY = ceil(float(yDim/8)); 
    int gridSizeZ = 1; 

    int blockSizeX=8; 
    int blockSizeY=8; 
    int blockSizeZ=1; 

    const dim3 gridSize(gridSizeX,gridSizeY,gridSizeZ); 
    const dim3 blockSize(blockSizeX,blockSizeY,blockSizeZ); 

    foreground_extract <<< gridSize, blockSize >>>(d_inputImageRed, 
                d_inputImageGreen, 
                d_inputImageBlue, 

                d_outputImageRed, 
                d_outputImageGreen, 
                d_outputImageBlue, 

                xDim,yDim); 


     cudaPrintfDisplay(stdout,true); 
     cudaPrintfEnd(); 

     checkCudaErrors(cudaMemcpy(h_outputImageRed, d_outputImageRed, (sizeof(unsigned char)*xDim*yDim), cudaMemcpyDeviceToHost)); 
     checkCudaErrors(cudaMemcpy(h_outputImageGreen, d_outputImageGreen, (sizeof(unsigned char)*xDim*yDim), cudaMemcpyDeviceToHost)); 
     checkCudaErrors(cudaMemcpy(h_outputImageBlue, d_outputImageBlue, (sizeof(unsigned char)*xDim*yDim), cudaMemcpyDeviceToHost)); 

     //free gpu data 
    checkCudaErrors(cudaFree(d_outputImageRed)); 
    checkCudaErrors(cudaFree(d_outputImageGreen)); 
    checkCudaErrors(cudaFree(d_outputImageBlue)); 
    checkCudaErrors(cudaFree(d_inputImageRed)); 
    checkCudaErrors(cudaFree(d_inputImageGreen)); 
    checkCudaErrors(cudaFree(d_inputImageBlue)); 

    //free host data 
    free(h_outputImageRed); 
    free(h_outputImageGreen); 
    free(h_outputImageBlue); 
    free(h_inputImageRed); 
    free(h_inputImageGreen); 
    free(h_inputImageBlue); 



     while(true){} 
     return 0; 
} 

답변

3

커널이 실행되고 있지 않아 커널의 printf에서 아무 것도 출력되지 않습니다. 커널에서 cuda error checking이 올바르게 실행되면이 실행됩니다.

커널을 실행하면 반환되는 오류는 invalid configuration argument입니다.

gridSize.xgridSize.y에 잘못된 값이 전달됩니다.

커널이 무엇인지 확인하려면 커널을 호출하기 전에 출력하십시오. (A 일반 디버깅 팁.) 당신이 생각하는 일을하지 이후

것은의이 줄을 살펴 보자 :

int gridSizeX = ceil(float(xDim/8)); 
          ^^ 
           both values inside the parenthesis are *integers* 

당신은에 그 값 (xDim 또는 8) 중 하나를 캐스팅하지 않은 float. 따라서 호스트 컴파일러는 정수 나누기를 사용하여 괄호 안의 수량을 결정합니다. 3/8의 정수 나누기는 0입니다. 그 이후로 아무것도 가치를 바꾸지 않습니다. 여전히 0입니다.

+0

감사합니다. 커널 실행시 오류 검사에 대해 알지 못했습니다. 위에서 보았 듯이 checkCudaErrors를 사용했습니다. 도움이 될만하고 철저한 대답입니다. 예? :) – andandandand

+0

거기. 약간의 경련. –

관련 문제