• No se han encontrado resultados

Despu´es de haber realizado la primera y ´unica transferencia de datos entre hu´esped y dispos- itivo, es decir, la imagen original de entrada, no ha habido necesidad de otra transferencia.

La redimensi´on de im´agenes es posible implementarla en la GPU. Pero, debido a la necesidad de verificar que los c´alculos son correctos, y sin haberse programado c´odigo que pudiera dar los mismos resultados que la versi´on de Matlab, o las funciones de la biblioteca de OpenCV.

Por lo tanto, se requiere redimensionar los mapas conspicuos obtenidos previamente. Y como las funciones de C, no fueron implementadas con c´odigo propio, sino que se utiliz´o una funci´on de OpenCV, se har´a con la implementaci´on en CUDA igualmente. Entonces se requiere transferir del dispositivo al hu´esped, los mapas conspicuos obtenidos previamente.

Se ejecuta la funci´on “cvResize” de OpenCV, para la redimensi´on de la imagen, especi- ficando de tipo “bilinear”, as´ı los resultados obtenidos con esta funci´on ser´an iguales a los obtenidos en la versi´on secuencial de C, y la versi´on de Matlab de la CVA.

Una vez obtenido los mapas conspicuos al tama˜no deseado, las siguientes operaciones y c´alculos pueden ser realizados en la GPU. Por eso, se lleva a cabo otra transferencia de datos, es decir, se copian los mapas redimensionados de la memoria del hu´esped a la memoria del dispositivo.

6.17 Mapas mentales

En esta parte del proceso, los datos requeridos est´an en memoria del dispositivo, o sea, los mapas conspicuos redimensionados. Para obtener un mapa mental, es necesario un operador visual. Al igual que en los mapas visuales, el operador visual, consiste de una secuencia de operaciones y c´alculos, dando como resultado un nuevo mapa. Pero en esta parte del proceso, para obtener un mapa mental, el mapa conspicuo es computado por n operadores visuales, y despu´es es necesario hacer la suma de estos mapas para tener a la salida el mapa mental. Los operadores visuales aplican de la misma forma para cada dimensi´on. Estos c´alculos en lo absoluto se realizan en la GPU.

Lo primero para proceder con el uso de memoria global, se asigna el n´umero mayor de espacios para resultados, que son requeridos por cada operador visual. Despu´es de cada resultado del operador visual, se sobreescribe la informaci´on previamente asignados. Las funciones implementadas en CUDA para los operadores visuales est´an en la secci´on6.19.

En el algoritmo57se refiere a la funci´on cudaMapa Mental Aviones. Ah´ı se enlistan los operadores visuales para crear los mapas mentales de una corteza visual artificial para reconocimiento de aviones. Son las llamadas a funciones en CUDA que se implementaron en esta tesis para la corteza visual artificial de aviones.

Algoritmo 57 cudaMapa Mental Aviones

Entrada: δMC′ Mapa conspicuo escalado

Salida: δMM ⊲Mapa Mental

δMM1 = Resta Imagenes( Gauss Dx Dy( Gauss Dx Dy( Gauss Dx Dy( δMC’, 1, ’y’),

1, ’y’), 1, ’x’), Valor Absoluto( Gauss Dx Dy( δMC’, 1, ’x’)

δMM2 = Gauss Dx Dy( Gauss Dx Dy( δMC’, 1, ’y’), 1, ’y’) δMM3 = Gauss Dx Dy( Gauss Dx Dy( δMC’, 1, ’x’), 1, ’x’)

δMM4 = Raiz Cuadrada( Gauss Dx Dy( Gauss Dx Dy( Gauss Dx Dy(δMC’, 1, ’y’), 1,

’y’), 1, ’x’)

δMM5 = Resta Imagenes( Gauss Dx Dy( Gauss Dx Dy( δMC’, 1, ’y’), 1, ’x’),

Gauss Dx Dy( Gauss Dx Dy( δMC’, 1, ’y’), 1, ’x’) )

δMM6 = Gauss Dx Dy( Gauss Dx Dy( δMC’, 1, ’y’), 1, ’x’)

δMM =P6

k=1(δMMk)

Cada funci´on de CUDA para los operadores visuales se describe su implementaci´on en la secci´on 6.19.1.

6.18 Vector descriptor

Al haber obtenido los mapas mentales de las cuatro dimensiones que maneja la corteza visual artificial, los datos a´un permanecen en la memoria del dispositivo. Y para ventaja de esta implementaci´on en CUDA, obtener el vector descriptor fu´e posible implementarlo en la GPU. La aceleraci´on m´as destacada en la funci´oncudaVector Descriptor, es la implementaci´on para obtener el m´aximo valor. La descripci´on de la funci´on cudaMAX se encuentra en la secci´on 6.19.3.

El algoritmo 58 es la funci´on cudaVector Descriptor. Este algoritmo recibe como entrada los cuatro mapas mentales δMMInt, δMMO, δMMC, δMMF. Una de las ventajas

en el algoritmo58 es el uso de variables de registros, pues evita una latencia alta al utilizar lecturas a memoria global del dispositivo. A trav´es de la funci´on cudaMAX se obtiene tanto el ´ındice del valor m´aximo i, jd como el valor Qd en s´ı. Cada vez que se almacena

un valor m´aximo global entre los mapas mentales δMMk, se registra de donde se obtuvo, y

en la siguiente iteraci´on solo se debe buscar en CUDA el nuevo m´aximo del mapa mental requerido. AL final se obtienen losN valores m´aximos para el vector descriptor δ−→V .

6.19 Algoritmos

En esta secci´on se describe la implementaci´on de algoritmos en CUDA que fueron utilizados en las etapas de creaci´on de mapas visuales, conspicuos y mentales, y el vector que describe la imagen de entrada.

Algoritmo 58 cudaVector Descriptor

Entrada: δMMInt, δMMO, δMMC, δMMF ⊲Mapas Mentales

Salida: δ−→V ⊲Vector Descriptor

γdmax =Ninguno

para k = 1N hacer

δ−→V k =−Inf inito

⊲Si el m´aximo de Intensidad fu´e el mayor de todos en la iteraci´on anterior

siγdmax =Intensidad entonces

γi, jInt,γQInt ←cudaMAX(MMInt)

⊲ Si el m´aximo de Orientci´on fu´e el mayor de todos en la iteraci´on anterior si no si γdmax =Orientacion entonces

γi, jO, γQO←cudaMAX(MMO)

⊲Si el m´aximo de Color fu´e el mayor de todos en la iteraci´on anterior si no si γdmax =Color entonces

γi, jC, γQC ←cudaMAX(MMC)

⊲Si el m´aximo de Forma fu´e el mayor de todos en la iteraci´on anterior si no si γdmax =F orma entonces

γi, jF, γQF ←cudaMAX(MMF)

⊲ Si es la primera iteraci´on del bucle si no

γi, jInt,γQInt ←cudaMAX(MMInt)

γi, jO, γQO←cudaMAX(MMO)

γi, jC, γQC ←cudaMAX(MMC)

γi, jF, γQF ←cudaMAX(MMF)

fin si

⊲Si el m´aximo de Intensidad es el mayor de todos siγQInt >=γQO && γQInt>=γQC && γQInt >=γQF entonces

δ−→Vk←γQInt

γd=Intensidad

δMMInt(i, jInt) =−Inf inito

⊲Si el m´aximo de Orientaci´on es el mayor de todos si no si γQO >=γQInt && γQO >=γQC && γQO>=γQF entonces

δ−→Vk←γQO

γd=Orientacion

δMMO(i, jO) =−Inf inito

⊲ Si el m´aximo de Color es el mayor de todos si no si γQC >=γQInt && γQC >=γQO && γQC >=γQF entonces

δ−→Vk←γQC

γd=Color

δMMC(i, jC) =−Inf inito

⊲ Si el m´aximo de Forma es el mayor de todos si no si γQF >=γQInt && γQF >=γQO && γQF >=γQC entonces

δ−→Vk←γQF

γd=F orma

δMMF(i, jF) = −Inf inito

fin si fin para

6.19.1 Operadores visuales

Los primeros algoritmos son los que componen los operadores visuales. Estos son para mapas visuales de orientaci´on, forma y color. Tambi´en se utilizan en cada dimensi´on de los mapas mentales.

Valor Absoluto

El primer algoritmo, el Algoritmo 59, representa la funci´on cudaValor Absoluto. Esta es una funci´onkernel, donde se recibe como entrada una matrizδMA, y cada hilo extrae el valor

absoluto de su correspondiente elementoide la matriz en la memoria global,y el resultado de cada elemento se almacena y regresa en la matrizδM′

A, que tambi´en se ubica en la memoria

principal del dispositivo.

Algoritmo 59 cudaValor Absoluto

Entrada: δMA ⊲Matriz de datos

Salida: deltaM′

A ⊲ Matriz de datos con valores absolutos

deltaM′

A(i)←|deltaMA(i)|

En CUDA, hay funciones matem´aticas siempre disponibles en c´odigo de dispositivo. En la funci´on anterior, cada hilo obtiene el valor absoluto al ejecutar la funci´on fabsf, que es de tipo device . Esta funci´on del dispositivo recibe como argumento un valor de tipo flotante, calcula su valor absoluto, y retorna un valor flotante; los valores de punto flotante de esta funci´on, son de precisi´on simple.

Aqu´ı los hilos leen directamente de la memoria global, y despu´es escriben nuevamente en esta. Para esta func´on y otras m´as, no es necesario el uso de otro tipo de memoria, debido a que solo hay una operaci´on en la funci´on kernel.

La configuraci´on de hilos para esta funci´on es de tipo unidimensional(solo se requiere un ´ındicei), debido a que cada hilo solo requiere tomar el valor de la matriz de acuerdo al ´ındice y realizar una operaci´on, sin que haya dependencia con elementos vecinos de la matriz de datos.

Multiplicaci´on por constante

Otro algoritmo, es el Algoritmo60, el cual corresponde a la funci´oncudaConstante Multiplica. Este, recibe como entrada una matriz δMA, donde cada hilo CUDA lee su correspondiente

elemento i en memoria global, multiplica el valor obtenido por un valor constante k. En la implementaci´on de la CVAC, esta constante k tiene un valor de 0.05, tomado de la imple- mentaci´on de la CVA en Matlab. Al final, el algoritmo, regresa la matriz δM′

A con nuevos

valores en todos los elementos en la memoria global del dispositivo, resultado de la multipli- caci´on de los valores originales con la constante.

Algoritmo 60 cudaConstante Multiplica

Entrada: δMA ⊲ Matriz de datos

Salida: δM′

A ⊲ Matriz de datos multiplicados por una constante

δM′

A(i)←k∗δMA(i) ⊲ k = 0.05

Aqu´ı los hilos leen directamente de la memoria global, y despu´es escriben nuevamente en esta. La configuraci´on de hilos para esta funci´on es de tipo unidimensional (solo se requiere un ´ındice i).

Ra´ız cuadrada

El Algoritmo 61, corresponde a la funci´on cudaRaiz Cuadrada. Aqu´ı los hilos, sacan la ra´ız cuadrada a todos los elementos i de la matriz δMA que est´a en la memoria global del

dispositivo. Para calcular la ra´ız cuadrada del elemento, los hilos de la funci´onkernel ejecutan una funci´on matem´atica sqrtf de CUDA. Esta funci´on recibe como argumento un valor de punto flotante, calcula su ra´ız cuadrada (de un n´umero no-negativo) y retorna el resultado como valor de tipo flotante; estos valores de punto flotante son de precisi´on simple.

Como requisito, es necesario hacer positivo cualquier valor previo a obtener su ra´ız cuadrada, por tanto se obtiene primeramente el valor absoluto con la funci´on matem´atica fabsf de CUDA. El resultado del algoritmo 61es la matriz δM′

A.

Algoritmo 61 cudaRaiz Cuadrada

Entrada: δMA ⊲Matriz de datos

Salida: δM′

A ⊲Matriz de datos obtenidos de la ra´ız cuadrada

δM′

A(i)←

p

δMA(i)

Aqu´ı los hilos leen directamente de la memoria global, y despu´es escriben nuevamente en esta. La configuraci´on de hilos para esta funci´on es de tipo unidimensional (solo se requiere un ´ındice i).

Al cuadrado

El Algoritmo 62, corresponde a la funci´on cudaAl Cuadrado. Aqu´ı los hilos, elevan al cuadrado todos los elementoside la matrizδMAque est´a en la memoria global del dispositivo.

Cada hilo CUDA eleva a potencia de dos su valor correspondiente al hacer uso de la funci´on powf, que trae por defecto CUDA en su biblioteca de funciones matem´aticas. Esta funci´on recibe como argumentos un valor de punto flotante como la base y otro del mismo tipo para la potencia, que en este caso es 2, entonces eleva el valor base a la potencia de dos y retorna el resultado como valor de tipo flotante; estos valores de punto flotante son de precisi´on simple. El resultado del algoritmo 62es la matriz δM′

Algoritmo 62 cudaAl Cuadrado

Entrada: δMA ⊲Matriz de datos

Salida: δM′

A ⊲ Matriz de datos elevados al cuadrado

δM′

A(i)←(δMA(i))2

Aqu´ı los hilos leen directamente de la memoria global, y despu´es escriben nuevamente en esta. La configuraci´on de hilos para esta funci´on es de tipo unidimensional (solo se requiere un ´ındice i).

Gauss con σ = 1 y σ = 2

La funci´on cudaGauss, corresponde al Algoritmo 63. Este algoritmo recibe una matriz de entradaδMAy un valor deσ(puede ser 1 o 2). De acuerdo al valor deσ, el algoritmo crea una

mascara de Gauss a partir de un rango de valores x e y. La mascara se crea en el hu´esped, por lo que previo a la convoluci´on de datos, se realiza la transferencia de la mascara a la memoria en el dispositivo. Esta mascara se identifica como la matrizδw. Despu´es cada hilo CUDA realiza una convoluci´on de su correspondiente elemento i, j de la matriz de entrada

δMA con los elementos m, n de la matriz de Gauss δw. Y los resultados se almacenan en la

matrizδM′

A.

Algoritmo 63 cudaGauss

Entrada: δMA, σ ⊲Matriz de datos y sigma

Salida: δM′

A ⊲ Matriz de datos convolucionados con mascara de Gauss w(m, n) 2πσ12e

−x

2+y2

2σ2 ⊲ Mascara de Gauss

δw w ⊲ Transferencia de hu´esped al dispositivo

δM′ A(i, j)← P m P nδw(m, n)δMA(2i+m,2j+n)

La convoluci´on es un algoritmo que presenta algunas caracter´ısticas para aprovechar mejor la arquitectura CUDA frente a la CPU. La forma en como el algoritmo cudaGauss realiza la convoluci´on de datos en la tarjeta GPU, tal procedimiento se describe en la secci´on6.19.2.

Gauss de Dx y Dy con σ = 1 y σ = 2

La funci´on cudaGauss Dx Dy, corresponde al Algoritmo 64. Este algoritmo recibe una matriz de entrada δMA, un valor de σ(puede ser 1 o 2) y un ejed. De acuerdo al valor deσ,

el algoritmo crea una mascara de Gaussw a partir de un rango de valores xey. Despu´es los valores de la mascara se derivan enxo eny, de acuerdo al valor de entrada ded. La mascara se crea en el hu´esped, por lo que previo a la convoluci´on de datos, se realiza la transferencia de la mascara a la memoria en el dispositivo. Esta mascara se identifica como la matriz δw. Despu´es cada hilo CUDA realiza una convoluci´on de su correspondiente elemento i, j de la matriz de entrada δMA, con los elementos m, n de la matriz de Gauss δw. Y los resultados

se almacenan en la matriz δM′

Algoritmo 64 cudaGauss Dx Dy

Entrada: δMA, σ,d ⊲ Matriz de datos A, sigma y eje

Salida: δM′

A ⊲Matriz de datos A’ convolucionados con mascara de Gauss g(m)e−(x2

2σ2) ⊲ Mascara unidimensional de Gauss

d(n) (−x)g(m)

σ2 ⊲ Derivada de la mascara de Gauss

si d=x entonces

w(m, n)g(m)d(n) si no si d=y) entonces

w(n, m)g(m)d(n) fin si

δw w ⊲ Transferencia de hu´esped al dispositivo

δM′ A(i, j)← P m P nw(m, n)MA(2i+m,2j+n)

La convoluci´on es un algoritmo que presenta algunas caracter´ısticas para aprovechar mejor la arquitectura CUDA frente a la CPU. La forma en como el algoritmo cudaGauss realiza la convoluci´on de datos en la tarjeta GPU, tal procedimiento se describe en la secci´on6.19.2.

Suma de dos im´agenes

La funci´on cudaSuma Imagenes, corresponde al Algoritmo 65. El algoritmo recibe como entrada dos matrices: δMAyδMB. Cada hilo ejecuta la funci´onkernel cudaSuma Imagenes,

donde lee de memoria global el valoricorrespondiente de la matrizδMAy laδMB, los suma y

almacena el resultado en la posici´onide la matriz δMC en la memoria global del dispositivo.

Algoritmo 65 cudaSuma Imagenes

Entrada: δMA, δMB ⊲ Matrices de datos A y B

Salida: δMC ⊲ Matriz de datos C

δMC(i)←δMA(i) +δMB(i)

Aqu´ı los hilos leen directamente de la memoria global, y despu´es escriben nuevamente en esta. La configuraci´on de hilos para esta funci´on es de tipo unidimensional (solo se requiere un ´ındice i).

Suma de dos im´agenes positivas

La funci´on cudaSuma Imagenes Abs, corresponde al Algoritmo 66. El algoritmo recibe como entrada dos matrices: δMA y δMB. Cada hilo ejecuta la funci´on kernel cuda-

Suma Imagenes Abs, donde lee de memoria global el valor icorrespondiente de la matriz

δMA y la δMB, a cada valor le aplica la funci´on fabsf para obtener su valor absoluto, as´ı

despu´es el hilo suma dos valores absolutos, y por ´ultimo almacena el resultado en la posici´on

Algoritmo 66 cudaSuma Imagenes Abs

Entrada: δMA, δMB ⊲Matrices de datos A y B

Salida: δMC ⊲ Matriz de datos C

δMC(i)←|δMA(i)|+|δMB(i)|

Aqu´ı los hilos leen directamente de la memoria global, y despu´es escriben nuevamente en esta. La configuraci´on de hilos para esta funci´on es de tipo unidimensional (solo se requiere un ´ındice i).

Resta de dos im´agenes

La funci´on cudaResta Imagenes, corresponde al Algoritmo 67. El algoritmo recibe como entrada dos matrices: δMAyδMB. Cada hilo ejecuta la funci´onkernel cudaResta Imagenes,

donde lee de memoria global el valori correspondiente de la matrizδMAy la δMB, realiza la

resta del segundo elemento al primero, despu´es se aplica la funci´on fabsf sobre el resultado para obtener el valor absoluto, y luego se almacena el resultado en la posici´oni de la matriz

δMC en la memoria global del dispositivo.

Algoritmo 67 cudaResta Imagenes

Entrada: δMA, δMB ⊲Matrices de datos A y B

Salida: δMC ⊲ Matriz de datos C

δMC(i)←|δMA(i)−δMB(i)|

Aqu´ı los hilos leen directamente de la memoria global, y despu´es escriben nuevamente en esta. La configuraci´on de hilos para esta funci´on es de tipo unidimensional (solo se requiere un ´ındice i).

Resta de dos im´agenes positivas

La funci´on cudaResta Imagenes Abs, corresponde al Algoritmo 68. El algoritmo recibe como entrada dos matrices: δMA y δMB. Cada hilo ejecuta la funci´on kernel cuda-

Suma Imagenes, donde lee de memoria global el valor i correspondiente de la matrizδMA

y la δMB, a cada valor le aplica la funci´onfabsf para obtener su valor absoluto, as´ı despu´es

el hilo resta dos valores absolutos, y por ´ultimo almacena el resultado en la posici´on i de la matrizδMC en la memoria global del dispositivo.

Algoritmo 68 cudaResta Imagenes Abs

Entrada: δMA, δMB ⊲Matrices de datos A y B

Salida: δMC ⊲ Matriz de datos C

Aqu´ı los hilos leen directamente de la memoria global, y despu´es escriben nuevamente en esta. La configuraci´on de hilos para esta funci´on es de tipo unidimensional (solo se requiere un ´ındice i).

Multiplicaci´on de dos im´agenes

La funci´on cudaMultiplica Imagenes, corresponde al Algoritmo 69. El algoritmo recibe como entrada dos matrices: δMA y δMB. Cada hilo ejecuta la funci´on kernel cudaMulti-

plica Imagenes, donde lee de memoria global el valor i correspondiente de la matriz δMA

y la δMB, los multiplica y almacena el resultado en la posici´on i de la matriz δMC en la

memoria global del dispositivo.

Algoritmo 69 cudaMultiplica Imagenes

Entrada: δMA, δMB ⊲Matrices de datos A y B

Salida: δMC ⊲ Matriz de datos C

δMC(i)←δMA(i)δMB(i)

Aqu´ı los hilos leen directamente de la memoria global, y despu´es escriben nuevamente en esta. La configuraci´on de hilos para esta funci´on es de tipo unidimensional (solo se requiere un ´ındice i).

Divisi´on de dos im´agenes

La funci´oncudaDivide Imagenes, corresponde al Algoritmo70. El algoritmo recibe como entrada dos matrices: δMAyδMB. Cada hilo ejecuta la funci´onkernel cudaDivide Imagenes,

donde lee de memoria global el valor i correspondiente de la matriz δMB, lo asigna a una

variable local γb, de esta forma se evita volver a leer el valor desde la memoria global. Se verifica que el valor deγbsea diferente a 0, en caso contrario, el hilo asigna cero al elemento de la matrizδMC. Siγbes diferente que 0, entonces se lee el elemento ide la matrizMA y se

divide entreγb, y se almacena el resultado en la posici´on i de la matriz δMC en la memoria

global del dispositivo.

Algoritmo 70 cudaDivide Imagenes

Entrada: δMA, δMB ⊲Matrices de datos A y B

Salida: δMC ⊲ Matriz de datos C

γbδMB(i) si γb!= 0 entonces δMC(i)← δMγbA(i) si no δMC(i)←0 fin si

Aqu´ı los hilos leen directamente de la memoria global, y despu´es escriben nuevamente en esta. La configuraci´on de hilos para esta funci´on es de tipo unidimensional (solo se requiere un ´ındice i).

Infimo de dos im´agenes

La funci´oncudaInfimo Imagenes, corresponde al Algoritmo 71. El algoritmo recibe como entrada dos matrices: δMAyδMB. Cada hilo ejecuta la funci´onkernel cudaInfimo Imagenes,

donde lee de memoria global el valor i correspondiente de la matrizδMA y la δMB, y alma-

cena el valor menor como resultado en la posici´on i de la matriz δMC en la memoria global

del dispositivo.

Algoritmo 71 cudaInfimo Imagenes

Entrada: δMA, δMB ⊲Matrices de datos A y B

Salida: δMC ⊲ Matriz de datos C

δMC(i)←MIN(δMA(i), δMB(i))

Aqu´ı los hilos leen directamente de la memoria global, y despu´es escriben nuevamente en esta. La configuraci´on de hilos para esta funci´on es de tipo unidimensional (solo se requiere un ´ındice i).

Supremo de dos im´agenes

La funci´on cudaSupremo Imagenes, corresponde al Algoritmo 72. El algoritmo recibe