2012-08-06 5 views
0

다음은 병렬로 일부 배열을 계산하기 위해 시작하는 커널입니다. 여기결과 벡터를 0으로 생성하는 Cuda 커널

__device__ bool mult(int colsize,int rowsize,int *Aj,int *Bi,int *val) 
    {  
     for(int j = 0; j < rowsize;j++) 
     {   
      for(int k = 0;k < colsize;k++) 
      { 
       if(Aj[j] == Bi[k]) 
       {  
       return true; 
       }        
      }   
     } 
      return false;  
    } 


__global__ void kernel(int *Aptr,int *Aj,int *Bptr,int *Bi,int rows,int cols,int *Cjc) 
    { 
     int tid = threadIdx.x + blockIdx.x * blockDim.x; 
     int i; 
     if(tid < cols) 
     { 
      int beg = Bptr[tid]; 
      int end = Bptr[tid+1]; 
      for(i = 0;i < rows;i++) 
      { 
       int cbeg = Aptr[i]; 
       int cend = Aptr[i+1]; 
       if(mult(end - beg,cend - cbeg,Aj+cbeg,Bi+beg)) 
       {             
        Cjc[tid+1] += 1; 
        //atomicAdd(Cjc+tid+1,1);   
       } 
      }     
     }    
    } 

그리고 내가 그리드의 구성 및 블록

int numBlocks,numThreads; 

     if(q % 32 == 0) 
     { 
      numBlocks = q/32; 
      numThreads = 32; 
     } 
     else 
     { 
      numBlocks = (q+31)/32; 
      numThreads = 32; 
     } 
findkernel<<<numBlocks,numThreads>>>(devAptr,devAcol,devBjc,devBir,m,q,d_Cjc); 

내가 CC 2.0 GTX 480을 사용하고 결정하는 방법이다. 이제 제가 직면하는 문제는 이 4096 이상으로 증가 할 때마다 Cjc 배열의 값이 모두 0으로 생성된다는 것입니다. X 방향에서 사용할 수있는 최대 블록 수는 65535이고 각 블록의 스레드 수는 최대로 (1024,1024,64)입니다. 그렇다면 왜이 커널은 Cjc 어레이의 잘못된 출력을 계산합니까?

답변

0

OK 그래서 결국 I가 cudaMemcpy에 호스트 장치로부터 d_Cjc 배열을 시도하면, 에러는 다음의 슬로우 cudaError_t을 이용하여 알아 낸.

CUDA error: the launch timed out and was terminated 

findkernel의 계산의 일부는 디스플레이 드라이버 때문에 OS '감시'제한 시간의 프로그램을 종료시킨다 시간의 비교적 큰 양을 복용하는 것으로 나타났다.

난 X 서버 또는 ssh 내 컴퓨터 (다른 컴퓨터에서) 디스플레이를 제거하여 종료해야 할 것입니다.이 시간을 내게 '운영 체제의'워치 독 제한을 초과하지 않습니다 계산을 할 살 것입니다 .

+0

매트릭스가 얼마나 큽니까? 그들이 정말로 크지 않다면 X를 종료하지 않고도이 작업을 수행 할 수 있다고 확신합니다! 우선, 32 개 스레드가 너무 낮게 보인다 - 128 또는 256을 사용해 보셨습니까? 또 다른 가능성은 커널을 다시 작성하는 것입니다. 현재는 각 열에 대해 모든 행을 반복합니다. 'rows'가 큰 경우 이것은 매우 비효율적입니다. 행렬 입력 (0 또는 1) 당 'mult'의 결과를 계산 한 다음 병렬 접두어 합계 (Thrust'scan')를 사용하여 열당 값을 요약 할 수 있습니다. _ (아마도 더 효율적인 방법이있을 것입니다. 이것은 바로 내 마음에 온 것입니다 ...) _ – kroneml

+0

@kroneml ... 행과 열의 순서는'4096','8192' 등입니다 .... 지금은'thrust :: inclusive_scan'을 사용하고 있습니다. 모든 계산이 끝난 후'dCjc'가 다시 호스트 측면에 복사 .... – Recker

0

당신이 게시 코드 문제 몇 가지가있다처럼 보인다 :

내가 findkernel 생각
  1. kernel 위의 CUDA 코드는?
  2. kernel에는 8 개의 매개 변수가 있지만 7 개의 매개 변수 만 사용하여 findkernel을 호출합니다. 이것은 올바르게 보이지 않는다!
  3. kernel에서 if(tid < cols)을 테스트합니다. 이것은 if(tid < count) ??
  4. kernelcount이 포인터가 될 것으로 예상합니까? 나는 int 포인터를 전달하지 않고 일반 정수 값을 findkernel으로 전달한다고 생각합니다.
  5. __device__ bool mult을 사용하지 않는 이유는 무엇입니까? count/int *val

# 3 또는 # 4가 문제의 원인 일 수 있다고 생각하지만 다른 것들도 살펴야합니다.

+0

@kroneml .... 나는 1) 예 2) 3) 4) 5) ... 내가 다시에서 오래된 코드를 가지고 파일을 백업에서 내 코드를 게시 같아요 .... 내 코드를 편집 한 내 코드를 편집했습니다 .. – Recker