POO en CUDA

Si, son palabras o acrónimos utilizados en informática…

Es posible que algunos de vosotros hayáis aprendido a programar en CUDA utilizando programación estructurada y no hayáis intentado utilizar o penséis que no es posible utilizar el paradigma de la programación orientada a objetos con CUDA, pero… es posible realmente?

En muchos foros de internet se limitan a decir que la arquitectura CUDA no soporta la POO. En parte tienen razón puesto que oficialmente no se empezaron a soportar muchas de las características de C++ hasta la llegada de la arquitectura 2.x pero en la práctica, muchos usuarios aseguran usar estas características en arquitecturas 1.3 e incluso 1.1 pero hay que tener cuidado con estas aseveraciones debido a que algunos de estos usuarios se limitan a utilizar las características propias de la orientación a objetos en el host y esto, ya sabemos que es posible sin mayores complicaciones.

En este pequeño articulo, se va a crear una clase simple con varios métodos, se van a instanciar varios objetos que van a ser introducidos en un vector y estos a su vez en la memoria del device. Una vez allí, se va a crear un kernel donde cada uno de los hilos va a acceder a uno de los objetos del vector y va a ejecutar sus métodos… Parece complicado, pero en la práctica es muy simple. Vamos allá.

Primero la clase.

class Vela {
private:
...
//Variables privadas
...

public:
__device__ __host__ Vela(){
//Código del constructor
...
}

__device__ __host__ void metodo1(...){
//Código del método 1
....
}

};

En esta clase se han definido una serie de métodos y como se puede apreciar, se ha añadido tanto __host__ como __device__ para que puedan ser ejecutados tanto en el host como en el device.

En el main (o donde vayamos a definir el vector) lo creamos y reservamos memoria gracias a la utilización de la libreria thrust que viene incluida en la instalación estandar de CUDA:

thrust::host_vector <Vela> h_velas;
thrust::device_vector <Vela> d_velas;
...
//Rellenamos el vector del host
...
...
//Copiamos el vector del host al device
d_velas=h_velas;
...
//Creamos un puntero que apunte al vector creado
Vela *ptr_Velas = thrust::raw_pointer_cast(d_velas.data());
...
//Y por ultimo ejecutamos el kernel pasando como parámetro el puntero.
//Dentro del kernel, están disponibles todos los métodos que hayamos definido.
kernel<<<bloques, hilos>>>(ptr_Velas);

Hay que tener muy claro que CUDA no soporta todas las características propias de este paradigma de programación y que muchos de los proyectos se pueden resolver utilizando programación estructurada.

 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *