2013-06-05 3 views
0

내가 어려움을 발견 잘못 그러나cudaMalloc 전역 배열 원인은 SEG

float globTemp[3][3] = "some value in here"; 
__device__ float* globTemp_d; 

__global__ void compute(int *a, int w) 
{ 
    int x = threadIdx.x + blockDim.x * blockIdx.x; 
    int y = threadIdx.y + blockDim.y * blockIdx.y; 
    int i = y*w+x; 
    if(x<3 && y<3) 
    a[i] = 1+globTemp_d[i]; 
} 

int hostFunc(){ 
    float *a_d; 
    cudaMalloc((void**)&a_d, 3*3*sizeof(int)); 
    cudaMalloc((void**)&globTemp_d, 3*3*sizeof(int)); 
    cudaMemcpy(globTemp_d,globTemp, 3*3*sizeof(float), cudaMemcpyHostToDevice); 
    compute<<<1,1>>>(a_d,3); 
    cudaMemcpy(a,a_d, 3*3*sizeof(float), cudaMemcpyDeviceToHost); 
} 

을 난 내가 globTemp_d에 액세스하려고 할 때 잘못 SEG 얻을, [I] . 내가 여기서 잘못하고있는거야?

+0

globTemp_d가 이제까지 초기화 되었습니까? – ldrumm

+0

@Ldrumm 나는 cudaMalloc이 globTemp_d를 초기화한다고 생각하십니까? –

+0

컴파일러 속성을 확인했습니다. 나는 피곤해 보이고 아마도 CUDA에 의문을 제기해서는 안됩니다. – ldrumm

답변

1

은 당신의 코드에 다양한 문제가 있습니다

  1. 그리드는 1 차원 threadblocks의 1 차원 격자이다 (사실은 1 개 스레드의 단일 블록을 출시하고)하지만 커널 것처럼 기록이 2D 스레드 블록 구조 (.x.y 기본 제공 변수 사용)가 필요했습니다. 단일 스레드는 작업을 확실하게 처리하지 못하며 1D 스레드 블럭은 커널 코드에서 작동하지 않습니다.
  2. __device__not accessed이고, cudaMalloccudaMemcpy이다. cudaMemcpyToSymbol과 같은 다른 API 호출 집합을 사용합니다.
  3. 문제가있을 때 항상 권장되는 cuda error checking은 수행하지 않습니다. 커널 호출 모두에서 cuda 오류 검사를 수행해야합니다.
  4. 커널 매개 변수 (int *a)의 변수가 인 변수 (a_d)와 int 변수가 혼합되어 있으므로이 코드가 최소한 경고없이 컴파일되지는 않을 것이라고 생각합니다. 그리고 그것을 무시하면 이상한 행동이 생길 수 있습니다.

이 모든 오류를 수정하는 동안이 코드에 올 수있는 가장 가까운 :

#include <stdio.h> 

__device__ float* globTemp_d; 

__global__ void compute(float *a, int w) 
{ 
    int x = threadIdx.x + blockDim.x * blockIdx.x; 
    int y = threadIdx.y + blockDim.y * blockIdx.y; 
    int i = (y*w)+x; 
    if((x<3) && (y<3)) 
    a[i] = 1.0f+globTemp_d[i]; 
} 

int main(){ 
    float *a_d, *d_globTemp; 
    float globTemp[3][3] = {0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f}; 
    float a[(3*3)]; 
    dim3 threads(3,3); 
    dim3 blocks(1); 
    cudaMalloc((void**)&a_d, 3*3*sizeof(float)); 
    cudaMalloc((void**)&d_globTemp, 3*3*sizeof(float)); 
    cudaMemcpy(d_globTemp,globTemp, 3*3*sizeof(float), cudaMemcpyHostToDevice); 
    cudaMemcpyToSymbol(globTemp_d, &d_globTemp, sizeof(float *)); 
    compute<<<blocks,threads>>>(a_d,3); 
    cudaMemcpy(a,a_d, 3*3*sizeof(float), cudaMemcpyDeviceToHost); 

    printf("results:\n"); 
    for (int i = 0; i<(3*3); i++) 
    printf("a[%d] = %f\n", i, a[i]); 
    return 0; 
} 

이 코드는 __device__ 변수로 분배 그냥 커널 매개 변수로 d_globTemp을 전달하여 단순화 할 수있다 globTemp_d에 대한 참조 대신이 값을 사용하십시오. 그러나 나는 그 단순화를하지 않았다.