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 = 1→N 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