Índice:
1.-Introducción
2.-Instalación
2.1.-Configurando Visual Studio 2008
3.-Compilación
3.1.-Hola Mundo
3.2.-Jugando con la memoria

1.-Introducción

La tecnología CUDA (Compute Unified Device Architecture) es una arquitectura de computación paralela desarrollada por nVidia lanzada en 2007. Esta tecnología permite a los programadores desarrollar aplicaciones o programas que se ejecuten en la GPU de la tarjeta gráfica. Este lenguaje es una variación de C, por lo que los que lo conocen, ya tienen una gran ventaja.

No me quiero extender mucho más en la introducción para pasar a lo importante cuanto antes, ya que si has venido buscando cómo empezar a programar en CUDA es de suponer que sabes lo que es.

2.-Instalación

Para empezar, nos descargaremos el Visual Studio 2008 Express (Versión de C++) ya que lo usaremos para escribir y compilar nuestro código (opcional).

Por otra parte, nos tenemos que descargar los archivos relacionados con CUDA, que son dos (o tres, este último que explicaremos será opcional). Todos ellos, los descargaremos de aquí. Por un lado, necesitamos los drivers para CUDA, en los que, importante, no son los mismos para portátiles que para ordenadores de sobremesa.

Por otro lado, nos descargaremos el CUDA Toolkit, que es el que tiene los archivos para los desarrolladores (compilador y demás). Finalmente, y de manera opcional, podemos descargarnos el “CUDA SDK code samples” que incluye códigos de muestra para veamos si funciona.
Si tenemos algún problema en la instalación, podemos probar a reinstalar los drivers (normales) de nuestra tarjeta.

Por otra parte, si no sabemos si nuestra tarjeta tiene CUDA, podemos consultarlo aquí.

2.1.-Configurando Visual Studio 2008

Tras instalar el SDK, en la ruta por defecto de instalación (C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK\SDK Browser) encontraremos un archivo llamado browser.exe, que es el navegador (como su propio nombre indica) sobre el cual podremos ver los archivos de muestra y correrlos para verlos funcionar.

A continuación le daremos a cualquier “Files”, ya que realmente todos nos llevan al mismo directorio (siendo que deberian de llevar cada uno a su propio directorio pero bueno). Si no, directamente nos dirigiremos a C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK\C\src.

Nos metemos en una carpeta cualquiera, en este caso, la de templates y abrimos el fichero template_vc90.sln. Se deberia de abrir con el Visual Studio 2008.

Como podemos observar, es un proyecto formado por 3 ficheros, de los cuales podemos ver que hay algunos con extensión cu. Efectivamente, “cu” va a ser la extensión del código fuente en CUDA. Por otra parte, podemos observar que no nos aparece el código coloreado, sin embargo si que aparece coloreado en el fichero .cpp

Para ello, nos dirigiremos a Herramientas -> Opciones -> Editor de texto -> Extensiones de archivo, y escribiremos “cu” (sin el punto) y le daremos a “Añadir”. Posteriormente, si reiniciamos el Visual Studio ya nos pondrá bien la sintaxis.

Por otra parte, también querremos que las palabras reservadas nos las coloree para que quede más bonito y sencillo a la vista. Para ello, nos dirigiremos a C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK\C\doc\syntax_highlighting\visual_studio_8 y abrimos el archivo usertype.dat con algún editor de texto. Como podremos ver, contiene palabras reservadas, que son las que se volverán de color azul al escribirlas en el VS2K8. Copiamos este archivo, y lo llevamos a la siguiente ruta: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE. Como dije anteriormente, reiniciamos el Visual Studio y podremos ver la nueva sintaxis remarcada.

3.-Compilación

A pesar de haber configurado el Visual C++, al ser nuestra primera compilación, la haremos directamente desde la consola de Windows. Usaremos dos códigos sencillitos, sacados de aquí.

3.1.-Hola Mundo

Como viene muy bien explicado, poco más he de añadir. En este primer ejemplo, simplemente añadiremos la cabecera cuda.h para que comprobemos que, en caso de no tenerlo, nos daria un error.

Lo guardamos como hola.cu en el escritorio por ejemplo, y nos vamos a la consola, usando el NVCC.

//Agregamos libreria standard
#include <stdio.h>
//Agregamos libreria cuda
#include <cuda.h>
//Funcion principal
main()
{
    //Imprimimos texto y salto de linea
    printf("Hola mundo\n");
}

3.2.-Jugando con la memoria

Con este código, tocaremos un poco la memoria interna de nuestra GPU, también viene bastante bien explicado:

//Libreria estandar
#include <stdio.h>
//Libreria cuda
#include <cuda.h>
 
//Definimos el tamanio de nuestro array
#define SIZE 128
 
//Funcion principal
main()
{
    //Definimos
    float *array_pc;    //Aqui guardaremos el array en nuestra RAM
    float *array_pc2;    //Aqui guardaremos la lectura del array cuando vuelva de la grafica
    float *array_grafica;    //Usaremos este puntero para el array en la grafica.
    size_t totaltamanio = sizeof(float)*SIZE;    //Calculamos el tamanio que tendra nuestro array
    int i;            //Variable auxiliar para utilizar en bucle.
 
    //Reservamos espacio para los arrays de nuestra RAM
    array_pc = (float *)malloc(totaltamanio);
    array_pc2 = (float *)malloc(totaltamanio);
    //Reservamos espacio para el array de nuestra grafica
    cudaMalloc((void **)&array_grafica,totaltamanio);
 
    //Bucle de 0 a SIZE (Sin incluir SIZE)
    for(i=0;i<SIZE;i++)
    {
        array_pc[i] = float(i);        //Damos valor a cada una de las casillas de array_pc
    }
    //Ahora copiaremos a la grafica
    cudaMemcpy(array_grafica,array_pc,totaltamanio,cudaMemcpyHostToDevice);
    //Ahora copiamos de la grafica a la RAM (array_pc2)
    cudaMemcpy(array_pc2,array_grafica,totaltamanio,cudaMemcpyDeviceToHost);
    //Imprimimos array_pc2 para ver que ha tenido efecto.
    for(i=0;i<SIZE;i++) printf("%d %.2f\n",i,array_pc2[i]);
 
    //Liberamos espacio, aconsejable al acabar cada programa
    free(array_pc); free(array_pc2); cudaFree(array_grafica);
}

Y tras ejecutarlo: