quinta-feira, 22 de abril de 2010

Hello World em CUDA

Opa, abaixo um código simples no qual é efetuada a soma de dois vetores.



// soma_vetor.cu soma dois vetores
// para compilar faça: nvcc soma_vetor.cu -o soma_vetor
// e utilizando o modo emulado faça: nvcc soma_vetor.cu -o soma_vetor -deviceemu


#include <stdio.h>

// esta função será executada na gpu
__global__ void soma_vet(int *a, int *b, int *c)
{
    int i = threadIdx.x;
    c[i] = a[i] + b[i];
}

int main()
{

// declaração de variáveis
    int *h_A=0, *h_B=0, *h_C=0; // ponteiros host
    int *d_A=0, *d_B=0, *d_C=0; // ponteiros device
    int dimx = 10; // dimensão de x
    int num_bytes = dimx*sizeof(int); // número de bytes para alocar

// aloca memória na cpu
    h_A = (int *)malloc(num_bytes);
    h_B = (int *)malloc(num_bytes);
    h_C = (int *)malloc(num_bytes);
    
// aloca memória na gpu
    cudaMalloc( (void**)&d_A, num_bytes);
    cudaMalloc( (void**)&d_B, num_bytes);
    cudaMalloc( (void**)&d_C, num_bytes);

    if(h_A==0 || h_B==0 || h_C==0 || d_A==0 || d_B==0 || d_C==0)
    {
        printf("Não foi possível alocar memória.\n");
        return 1;
    }
    
// inicializa com zero memória da gpu
    cudaMemset(d_A, 0, num_bytes);
    cudaMemset(d_B, 0, num_bytes);
    cudaMemset(d_C, 0, num_bytes);
    
// inicializa vetor A e B
    for(int i = 0; i < dimx; i++)
    {
        h_A[i] = i;
        h_B[i] = 10-i;
    }

// copia dados para gpu    
    cudaMemcpy(d_A, h_A, num_bytes, cudaMemcpyHostToDevice);
    cudaMemcpy(d_B, h_B, num_bytes, cudaMemcpyHostToDevice);

    soma_vet<<<1,dimx>>>(d_A, d_B, d_C); // efetua cálculos na gpu

// cópia dados para cpu
    cudaMemcpy(h_C, d_C, num_bytes, cudaMemcpyDeviceToHost);

// imprime resultado
    for(int i = 0; i < dimx; i++)
    {
        printf("%d ",h_C[i]);
    }
    printf("\n");


// libera memória da cpu
    free(h_A);
    free(h_B);
    free(h_C);
// libera memória da gpu
    cudaFree(d_A);
    cudaFree(d_B);
    cudaFree(d_C);

    return 0;
}

3 comentários:

  1. E como devo compilar este exemplo? Não deveria ter um arquivo .c (gcc) e outro .cu (nvcc)?

    ResponderExcluir
  2. Não necessariamente é preciso ter o .c.
    Para compilar no linux faça:
    nvcc soma_vetor.cu -o soma_vetor

    e no windows:
    nvcc soma.cu -o soma -ccbin C:\program files\microsoft visual studio 8\vc\bin

    o -ccbin serve para indicar a pasta que está o linkador, neste caso o cl.exe que é o compilador do visual studio.
    o local do cl.exe pode variar de acordo com a versão do visual studio que você tem instalado.

    abraço.

    ResponderExcluir
  3. Parabens ,me ajudo muito

    ResponderExcluir