Universidad de Extremadura Escuela Politécnica Ingeniería Informática PROYECTO FI DE CARRERA Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Hugo María Vegas Carrasco Septiembre, 2008 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Universidad de Extremadura Escuela Politécnica Ingeniería Informática PROYECTO FI DE CARRERA Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Autor: Hugo María Vegas Carrasco Fdo: Director: Antonio Plaza Miguel Fdo: Tribunal Calificador Presidente: Pablo Martínez Cobo Fdo: Secretario: David Valencia Corrales Fdo: Vocal: José Moreno del Pozo Fdo: CALIFICACIÓ: FECHA: Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 3 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Resumen En el presente Proyecto de Fin de Carrera (PFC) proponemos la utilización de una nueva herramienta para la programación de tarjetas gráficas de la gama NVIDIA, denominada CUDA (Compute Unified Device Architecture), para acelarar el rendimiento computacional de algoritmos de tratamiento de imágenes, con particular énfasis en el tratamiento de imágenes hiperespectrales de la superficie terrestre, obenidas a partir de sensores remotos de observación de la tierra. Los algoritmos de análisis hiperespectral se caracterizan por su gran complejidad de cómputo y por el gran consumo de tiempo que se produce cuando se intentan procesar las imágenes proporcionadas por los sensores a través de soluciones basadas en CPU, debido al gran tamaño de dichas imágenes y a la complejidad computacional inherente a los algoritmos. Conviene destacar que la tecnología CUDA tiene apenas un año de vida, pero su aparición ha supuesto una revolución en cuanto a la posibilidad de desarrollar aplicaciones paralelas de carácter general utilizando tarjetas gráficas programables o graphical processing units (GPUs). En el presente PFC además hemos contextualizado el uso de GPUs frente a otras arquitecturas especializadas de alto rendimiento que se vienen utilizando en aplicaciones de tiempo real relacionadas con observación remota de la tierra, tales como los sistemas reconfigurables de tipo field programable gate array (FPGA). En concreto, el algoritmo seleccionado para ilustrar la posibilidad de implementar técnicas de análisis hiperespectral en GPUs es el método Pixel Purity Index (PPI), que se basa en la búsqueda de píxeles extremos (es decir, espectralmente más puros) en la imagen hiperespectral, de forma que dichos píxels pueden utilizarse para “desmezclar” otros píxels formados por sustancias con diferente composición a nivel sub-píxel como resultado de las limitaciones en la resolución espacial de los sensores. La implementación desarrollada del algoritmo PPI en una GPU es contrastada y evaluada experimentalmente (en términos de precisión en la selección de píxels puros y rendimiento computacional) con respecto a la versión original del algoritmo PPI disponible en la herramienta Environment for Visualizing Images (ENVI) de ITTVIS, utilizando para ello imágenes hiperespectrales simuladas y reales, proporcionadas por el sensor Airborne Visible Infra-Red Imaging Spectrometer (AVIRS) del Jet Propulsion Laboratory de NASA. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 5 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 6 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 1. Motivaciones y Objetivos 1.1. Motivaciones La principal motivación del presente PFC consiste en evaluar la posibilidad de utilizar tarjetas gráficas programables en aplicaciones de observación remota de la tierra a partir del tratamiento de imágenes hiperespectrales. En particular, el uso de algoritmos de detección de píxeles puros en imágenes hiperespectrales es una práctica habitual en este campo, ya que dicho proceso permite abordar el fenómeno de la mezcla espectral que se produce en dichas imágenes, lo cual facilita la utilización y explotación de los datos en diversas aplicaciones independientemente de las limitaciones introducidas por la resolución espacial. Entre los algoritmos más ampliamente utilizados con este fin, se encuentran los algoritmos de detección de píxeles puros o “endmembers”, de entre los cuales uno de los más utilizados es el método PPI (Píxel Purity Index). Este algoritmo tiene la ventaja de ser muy efectivo, además de no estar basado en un método muy complejo de cálculo de los píxeles extremos, lo cual lo hace muy asequible a la hora de ser implementado de forma eficiente mediante arquitecturas de computación paralela. Sin embargo, conviene destacar los algoritmos de análisis hiperespectral generalmente necesitan grandes cantidades de tiempo a la hora de proporcionar resultados, debido a la complejidad computacional de los mismos (en el caso de PPI, el algoritmo debe ejecutar un gran número de iteraciones) y también debido al gran tamaño de las imágenes a procesar, lo cual requiere que la transferencia de datos entre el procesador y el dispositivo hardware especializado utilizado como coprocesador deba optimizarse. Al requerir tantas iteraciones, y tener dentro de estas operaciones no triviales, los algoritmos de análisis hiperespectral generalmente se traducen en un consumo de CPU elevado, por lo que la utilización de arquitecturas especializadas como coprocesadores puede resultar una alternativa altamente interesante. Hasta la fecha, las técnicas tradicionales en la literatura para abordar este problema han optado por soluciones basadas en el uso de clusters y sistemas multiprocesador. La computación cluster, a pesar de su adaptabilidad al problema del Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 7 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables tratamiento de datos hiperspectrales (especialmente, cuando dichos datos se encuentran almacenados en un repositorio de datos en tierra), presenta problemas en cuanto al procesamiento de los datos en tiempo real dado el alto coste y elevados requerimientos en cuanto a espacio, peso y consumo (denominado payload en misiones de observación remota de la tierra). Por otra parte, la instalación de un cluster suele llevar asociada la disponibilidad de un número elevado de ordenadores interconectados entre sí para que compartan el procesamiento de datos a través de sus procesadores, lo cual hace incrementar la velocidad de ejecución y procesamiento de las aplicaciones; sin embargo, cada nodo (u ordenador) lleva ligado un precio y una serie de requerimientos en cuanto a espacio y consumo que alejan esta aproximación de las características requeridas en cuanto a payload en misiones reales de observación remota de la tierra. Para solucionar estos problemas relativos a coste, consumo y peso, y además ofrecer además mejoras sustanciales en cuanto al tiempo de procesamiento, en el presente PFC proponemos una alternativa basada en un nuevo modelo de tratamiento de imágenes hiperespectrales basado en la utilización de GPUs. Conviene destacar que, con una sóla GPU, pueden llegar a obtenerse mejoras notables a la hora de procesar cálculos de tipo científico, como es el caso de los algoritmos de tratamiento de imágenes hiperespectrales, a un coste razonable (no más de 500 euros) y además ocupando un espacio mínimo. No obstante, no todas las tarjetas GPU disponibles en el mercado se ajustan a nuestros requerimientos. Por ello si aplicamos los algoritmos propuestos a través de tarjetas convencionales o de gama baja, veremos que los resultados no sufren ningún tipo de mejoría; es más, podemos llegar a obtener peores resultados. Finalmente, indicar que en este proyecto se ha intentado ir un poco más allá, y para trabajar de forma totalmente innovadora se ha utilizado la arquitectura CUDA incorporada en as tarjetas gráficas de NVIDIA de las series 8 (ó superiores), Quadro y Tesla, siendo algunas de las tarjetas de la primera gama las que han sido objeto de estudio en este PFC. 8 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 1.2. Objetivos El principal objetivo del presente trabajo es el desarrollo y comparación de técnicas computacionalmente eficientes, basadas en procesamiento mediante GPUs, para la detección de píxeles espectralmente puros, a través del algoritmo PPI en imágenes hiperespectrales. Para ello se utilizarán tarjetas GPU de tipo GeForce 8800 GTX y GeForce 8600 GT, un procesador Core 2 Quad Q6600 a 2.40 GHz y 2GB RAM y las implementaciones del algoritmo PPI disponibles en la herramienta ENVI 4.2 y las implementaciones serie y paralelas desarrolladas en los lenguajes C y CUDA con motivo del presente PFC. Para todas las implementaciones propuestas se comparan los resultados obtenidos tanto en lo relativo a la precisión de los algoritmos como en lo relativo a su rendimiento computacional, utilizando para ello imágenes simuladas y reales obtenidas por un sensor hiperespectral de altas prestaciones (AVIRIS). El objetivo general mencionado, se lleva a cabo en la presente memoria mediante unos objetivos específicos, los cuales se enumeran a continuación: • Analizar las ventajas e inconvenientes de las diferentes versiones propuestas para el algoritmo PPI. • Establecer un estudio comparativo de las diferentes versiones paralelas del algoritmo PPI desarrolladas, tanto en lo relativo a su precisión a la hora de identificar los píxels más puros de la imagen como a la hora de analizar su rendimiento computacional con respecto a las versiones serie. • Comparar los resultados obtenidos por la metodología propuesta con respecto a los proporcionados por otras técnicas estándar de análisis hiperespectral. Teniendo presentes los anteriores objetivos, vamos a describir como está organizada esta memoria, viendo sus diferentes capítulos cuyos contenidos se describen a continuación: • Análisis hiperespectral: este capítulo describe conceptos previos sobre análisis hiperespectral, incluyendo el concepto de imagen hiperespectral, las técnicas más populares para desmezclado de este tipo de datos, y la necesidad de paralelismo para su procesamiento eficiente. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 9 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables • Programación de tarjetas gráficas: este apartado describe algunos aspectos fundamentales sobre la programación de tarjetas gráficas, y describe algunas herramientas utilizadas en el presente trabajo tales como el lenguaje CUDA y las GPUs utilizadas en el estudio. • Métodos: en este capítulo se incluyen los datos más técnicos acerca del algoritmo PPI, y además se realiza una explicación de la versión en CPU, GPU y ENVI del algoritmo. • Análisis y discusión de los resultados: en este capítulo se analizan los resultados experimentales obtenidos, analizando las características de una GPU frente a otra, de una CPU frente a la otra, describiendo imágenes simuladas y reales que se han utilizado para realizar las comparativas, y concluyendo con un análisis y discusión detallada de los resultados obtenidos. • Conclusiones y líneas futuras de trabajo: en este apartado se expondrán las principales conclusiones derivadas del proyecto, así como las líneas futuras de trabajo que pueden derivarse a partir del mismo. • Bibliografía: el proyecto incluye una exhaustiva revisión bibliográfica que permitirá al lector profundizar en mayor detalle en los diferentes aspectos teóricos y relativos a la implementación de los algoritmos descritos en la presente memoria. • Anexos: los anexos del PFC incluyen un manual de usuario que explica paso a paso la instalación de los diferents componentes necesarios para crear y ejecutar programas en CUDA, un primer seguimiento de la creación de un proyecto nuevo en CUDA, y los códigos debidamente documentados del algoritmo PPI implementado en la CPU y en la GPU, así como el algoritmo PPI disponible en el paquete ENVI 4.2. 10 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 11 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 2. Análisis hiperespectral El presente capítulo se organiza de la siguiente forma. En primer lugar, describimos el concepto de imagen hiperespectral, detallando las particularidades y características propias de este tipo de imágenes de alta dimensionalidad. A continuación, describimos algunas características genéricas de los sensores de adquisición de este tipo de datos, haciendo énfasis en los sensores utilizados en el presente trabajo. Seguidamente, se muestra una visión general de las técnicas de desmezclado disponibles en la actualidad, con particular énfasis en el modelo lineal de mezcla, utilizado en el presente trabajo para abordar el problema de la caracterización subpíxel de una imagen hiperespectral a partir de la identificación de los píxels espectralmente más puros en la misma. El capítulo concluye destacando la necesidad de de paralelismo en este campo. 2.1. Concepto de imagen hiperspectral El resultado de la toma de datos por parte de un sensor hiperespectral sobre una determinada escena puede ser representado en forma de cubo de datos, con dos dimensiones para representar la ubicación espacial de un píxel, y una tercera dimensión que representa la singularidad espectral de cada píxel en diferentes longitudes de onda [1]. La Figura 1 muestra la estructura de una imagen hiperespectral donde el eje X es el indicador de las líneas, el eje Y es el indicador de las muestras y el eje Z es el número de bandas, es decir, la longitud de onda de esa banda (canal). Como puede apreciarse en la Figura 2.1, el resultado de la toma de datos por parte de un sensor hiperespectral sobre una determinada escena puede ser representado en forma de cubo de datos, con dos dimensiones para representar la ubicación espacial de un pixel, y una tercera dimensión que representa la singularidad espectral de cada pixel en diferentes longitudes de onda. En concreto, la capacidad de observación de los sensores denominados hiperespectrales permite la obtención de una firma espectral detallada para cada píxel de la imagen, dada por los valores de reflectancia adquiridos por el sensor en diferentes longitudes de onda, lo cual permite una caracterización muy precisa de la superficie de nuestro planeta. 12 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Ba nd 1 as -4 ND en banda 4 Muestras ND en banda 3 ND en banda 2 ND en banda 1 Pixel en posición (x,y) Líneas Figura 2.1: Concepto de imagen hiperespectral. Conviene destacar que, en este tipo de imágenes, es habitual la existencia de mezclas a nivel de subpixel, por lo que a grandes rasgos podemos encontrar dos tipos de píxels en estas imágenes: píxel puros y píxel mezcla [2]. Se puede definir un píxel mezcla como aquel en el que cohabitan diferentes materiales. Este tipo de píxel en realidad constituyen la mayor parte de la imagen hiperespectral, en parte, debido a que este fenómeno es independiente de la escala considerada ya que tiene lugar incluso a niveles microscópicos [3]. La Figura 2.2 muestra un ejemplo del proceso de adquisición de píxels puros (a nivel macroscópico) y mezcla en imágenes hiperespectrales. Pixel mezcla (suelo + rocas) Reflectancia 4000 3000 2000 1000 0 300 600 900 1200 1500 1800 2100 2400 Pixel puro (agua) Reflectancia Long. onda (nm) 4000 3000 2000 1000 0 300 600 900 1200 1500 1800 2100 2400 Long. onda (nm) Pixel mezcla (vegetación + suelo) Reflectancia 5000 4000 3000 2000 1000 0 300 600 900 1200 1500 1800 2100 2400 Long. onda (nm) Figura 2.2: El fenómeno de la mezcla en imágenes hiperespectrales. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 13 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables El desarrollo tecnológico introducido por la incorporación de sensores hiperespectrales en plataformas de observación remota de la tierra de última generación ha sido particularmente notable durante los últimos años. En este sentido, conviene destacar que dos de las principales plataformas de tipo satélite que se encuentran en funcionamiento en la actualidad: Earth Observing-1 de NASA (http://eo1.gsfc.nasa.gov) y ENVISAT de la Agencia Espacial Europea (http://envisat.esa.int), llevan incorporados sensores de este tipo, permitiendo así la posibilidad de obtener imágenes hiperespectrales de la práctica totalidad del planeta de manera casi continua. A continuación, describimos brevemente las características de los sensores hiperespectrales utilizados en el presente estudio. 2.2. Sensores hiperespectrales En la actualidad, existe una amplia gama de sensores hiperespectrales de observación remota de la tierra. Dichos sensores pueden clasificarse según el modo en que son transportados (plataforma de transporte) en el momento de la toma de datos [4-6]. La mayor parte de los sensores hiperespectrales actuales son aerotransportados (siendo el ejemplo más claro de este tipo de instrumentos el sensor Airborne Visible InfraRed Imaging Spectrometer (AVIRIS) de NASA Jet Propulsion Laboratory (http://aviris.jpl.nasa.gov). Otros sensores aerotransportados ampliamente utilizados son DAIS 7915 (Digital Airborne Imaging Spectrometer), el cual cubre un amplio rango del espectro mediante 79 canales espectrales comprendidos entre 0.4 y 12.5 µm, y ROSIS (Reflective Optics System Imaging Spectrometer), capaz de medir información espectral entre 0.4 y 0.9 µm utilizando 92 canales espectrales (http://www.dlr.de). También destaca el sensor hiperespectral aerotransportado HYDICE (HYperspectral DIgital Collection Experiment) utilizado en aplicaciones militares. Finalmente, en algunos proyectos se utilizan sensores hiperespectrales instalados en plataformas de tipo satélite como CHRIS/Proba (http://www.chrisproba.org.uk) o Meris (http://envisat.esa.int/instruments/meris) de la Agencia Espacial Europea, o Hyperion de NASA. En el presente trabajo, nos centramos en la utilización del sensor AVIRIS, cuyas principales características son descritas a continuación. 14 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables AVIRIS es un sensor hiperespectral aerotransportado con capacidades analíticas en las zonas visible e infrarroja del espectro [8-10]. Este sensor está en funcionamiento desde 1987. Fue el primer sistema de adquisición de imágenes capaz de obtener información en una gran cantidad de bandas espectrales estrechas y casi contiguas. AVIRIS es un instrumento único en el mundo de la teledetección, pues permite obtener información espectral en 224 canales espectrales contiguos, cubriendo un rango de longitudes de onda entre 0.4 y 2.5 m, siendo el ancho entre las bandas muy pequeño, aproximadamente 0.01 m. En 1989, AVIRIS se convirtió en un instrumento aerotransportado. Desde ese momento, se realizan varias campañas de vuelo cada año para tomar datos mediante AVIRIS. El sensor ha realizado tomas de datos en Estados Unidos, Canadá y Europa, utilizando para ello dos plataformas: • Un avión ER-2 perteneciente a NASA/Jet Propulsion Laboratory. El ER-2 puede volar a un máximo de 20 km sobre el nivel del mar, a una velocidad máxima de aproximadamente 730 km/h. • Un avión denominado Twin Otter, capaz de volar a un máximo de 4 km sobre el nivel del mar, a velocidades de 130 km/h. Algunas de las características más relevantes en cuanto al diseño interno del sensor AVIRIS son las siguientes: • El sensor utiliza un explorador de barrido que permite obtener un total de 614 píxels por cada oscilación. • La cobertura de la parte visible del espectro es realizada por un espectrómetro EFOS- A, compuesto por un array de 32 detectores lineales. • La cobertura en el infrarrojo es realizada por los espectrómetros EFOS-B, EFOS-C y EFOS-D, compuestos todos ellos por arrays de 64 detectores lineales. • La señal medida por cada detector se amplifica y se codifica utilizando 12 bits. Esta señal se almacena en una memoria intermedia donde es sometida a una etapa de preprocesado. • El sensor dispone de un sistema de calibración a bordo, que utiliza una lámpara halógena de cuarzo que proporciona la radiación de referencia necesaria para comprobar el estado de los diferentes espectrómetros. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 15 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables • A lo largo de los últimos años, el sensor ha ido mejorando sus prestaciones en cuanto a la relación señal-ruido o signal-to-noise ratio (SNR), como se muestra en la Figura 2.3, que describe la evolución de la relación SNR del sensor a lo largo de los últimos años. Figura 2.3: Evolución de la relación señal-ruido en el sensor AVIRIS de NASA. 2.3. Técnicas de análisis hiperespectral basadas en el modelo lineal de mezcla La mayoría de las técnicas de análisis hiperespectral desarrolladas hasta la fecha presuponen que la medición obtenida por el sensor en un determinado píxel viene dada por la contribución de diferentes materiales que residen a nivel sub-píxel. El fenómeno de la mezcla puede venir ocasionado por una insuficiente resolución espacial del sensor, pero lo cierto es que este fenómeno ocurre de forma natural en el mundo real, incluso a niveles microscópicos, por lo que el diseño de técnicas capaces de modelar este fenómeno de manera adecuada resulta imprescindible. No obstante, las técnicas basadas en este modelo son altamente costosas desde el punto de vista computacional. En este sentido, el modelo lineal de mezcla [11] expresa los píxels mezcla como una combinación lineal de firmas asociadas a componentes espectralmente puros (llamados endmembers) en la imagen [12]. Este modelo ofrece resultados satisfactorios cuando los componentes que residen a nivel sub-píxel aparecen 16 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables espacialmente separados, situación en la que los fenómenos de absorción y reflexión de la radiación electromagnética incidente pueden ser caracterizados siguiendo un patrón estrictamente lineal. En la actualidad, el modelo lineal de mezcla es el más utilizado en análisis hiperespectral, debido a su sencillez y generalidad. Endmember s Banda j mezcla: c1 s + c2 v = –c3 u mezcla: 1/2 u + 1/2 s s centroide: 1/3 u + 1/3 v + 1/3 s v Endmember v u Endmember u mezcla: 1/2 u + 1/2 v Banda i Figura 3.4: Interpretación gráfica del modelo lineal de mezcla El modelo lineal de mezcla puede interpretarse de forma gráfica en un espacio bidimensional utilizando un diagrama de dispersión entre dos bandas poco correlacionadas de la imagen (ver Fig. 3.4). En la misma, puede apreciarse que todos los puntos de la imagen quedan englobados dentro del triángulo formado por los tres puntos más extremos (los más puros). Los vectores asociados a dichos puntos constituyen un nuevo sistema de coordenadas con origen en el centroide de la nube de puntos, de forma que cualquier punto de la imagen puede expresarse como combinación lineal de los puntos más extremos, siendo estos puntos son los mejores candidatos para ser seleccionados como endmembers [13]. Como consecuencia de este fenómeno, el paso clave a la hora de aplicar el modelo lineal de mezcla consiste en identificar de forma correcta los elementos extremos de la nube de puntos Ndimensional (conviene destacar que la Figura 3.4 ofrece una simplificación reducida en un espacio de dos dimensiones mientras que el proceso de búsqueda de extremos, Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 17 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables en el caso de una imagen hiperespectral real, tiene lugar en un espacio con cientos de dimensiones, tantas como el número de bandas espectrales del sensor. En la literatura reciente se han propuesto numerosas aproximaciones al problema de identificación de endmembers en imágenes hiperespectrales. En el presente trabajo, nos centramos en una de las técnicas más sencillas y eficientes a la hora de su implementación paralela: el método Pixel Purity Index (PPI) [9], que se basa en la generación repetitiva de vectores unitarios con orientación aleatoria en la nube de puntos de forma que todos los puntos de la imagen hiperespectral se proyectan sobre cada vector unitario, identificando los puntos extremos en la dirección definida por dicho vector e incrementando un contador asociado a dichos puntos. Tras la ejecución de un número amplio de iteraciones, se obtiene como resultado una imagen de pureza, formada por los índices asociados a cada uno de los pixels de la imagen, a partir de la cual se extrae un conjunto final de endmembers utilizando técnicas de análisis y visualización interactiva. 2.4. Necesidad de paralelismo Conviene destacar que las técnicas de análisis hiperespectral anteriormente descritas se basan en la realización de operaciones matriciales que resultan muy costosas desde el punto de vista computacional [14]. Sin embargo, el carácter repetitivo de estas operaciones las hace altamente susceptibles de ser implementadas en diferentes tipos de arquitecturas paralelas, permitiendo así un incremento significativo de su rendimiento en términos computacionales y dotando a dichas técnicas de la capacidad de producir una respuesta en tiempo casi real. Esta tarea es clave para la explotación de dichas técnicas en aplicaciones que requieren una respuesta en tiempo casi real. Una ventaja a favor de la utilización de soluciones paralelas en análisis hiperspectral, es que estas operaciones suelen realizarse mediante repeticiones de un mismo procedimiento, lo cual nos lleva a pensar que puedan ser implementadas en diferentes tipos de arquitecturas [15-17], obteniendo un incremento significativo de su rendimiento en términos de cómputo. Tradicionalmente, las técnicas de computación cluster han sido ampliamente utilizadas en aplicaciones de análisis hiperspectral una vez que los datos han sido enviados a tierra. No obstante, las 18 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables características de este tipo de arquitecturas (ver Fig. 3.5) no se adaptan de forma óptima a los requerimientos de procesamiento a bordo y en tiempo real impuestos por algunas aplicaciones de análisis hiperespectral, tales como seguimiento de incendios en tiempo real, monitorización de vertidos químicos en aguas y atmósfera, etc. En este sentido, el uso de clusters en aplicaciones de análisis hiperespectral puede ser una alternativa interesante de cara al procesamiento de grandes repositorios de datos sin requerimientos de tiempo real; sin embargo, desde el punto de vista del coste global del sistema, de su calentamiento, consumo y posibilidad de instalación en un sensor real (payload), existen arquitecturas con mayores prestaciones desde el punto de vista de su utilización a bordo del sensor, tales como dispositivos hardware especializados de tipo FPGA y GPU. Figura 3.5: Configuración típica de un cluster de ordenadores. En el presente proyecto, proponemos abordar este requerimiento mediante arquitecturas multiprocesador de tipo GPU. Pensamos que esta aproximación resulta más económica y además está basada en un tipo de tecnología más sofisticado y adaptado a los requerimientos de procesamiento en tiempo casi real impuestos por las aplicaciones de análisis hiperespectral (la tarjeta GeForce 8800 GTX usada en este PFC lleva incorporados 128 procesadores de tipo “stream”, trabajando cada uno a 1.35 Ghz). En este sentido, la implementación eficiente de las técnicas de análisis hiperespectral propuestas en la presente memoria se lleva a cabo en dos generaciones de tarjetas GPU GeForce 8800 GTX y GeForce 8600 GT, gracias a la arquitectura CUDA integrada en las mismas. En el siguiente capítulo describimos en mayor Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 19 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables detalle la arquitectura CUDA y expondremos de forma más concreta las razones que nos han llevado a usar GPUs como alternativa de procesamiento paralelo de datos. 3. Programación de tarjetas gráficas El presente capítulo se organiza de la siguiente forma. En primer lugar, describimos el papel de las GPUs como elemento de procesamiento especializado para el procesamiento de datos científicos en paralelo. A continuación describimos CUDA como una herramienta eficaz para la programación de tarjetas gráficas en aplicaciones científicas de propósito general, destacando aquellos aspectos que consideramos más relevantes de cara a la presentación de implementaciones de algoritmos de análisis hiperespectral sobre GPUs utilizando CUDA, haciendo especial hincapié en las características concretas del modelo NVidia GeForce 8800 GTX que ha sido utilizado como referencia a la hora de realizar las nuevas implementaciones propuestas en este trabajo las cuales serán abordadas en el siguiente capítulo de la presente memoria. El capítulo concluye destacando algunos aspectos sobre el modelo de programación de tarjetas GPU de última generación utilizando CUDA, el cual sirve como preámbulo al siguiente capítulo en el que describimos la implementación del algoritmo PPI utilizando CUDA que se ha desarrollado en el presente trabajo. 3.1. La GPU como arquitectura de propósito general para el procesamiento de datos científicos Desde un tiempo a esta parte, las GPUs programables han evolucionado como un elemento con una gran carga de trabajo, como podemos apreciar en la Figura 3.1. Con múltiples núcleos dirigidos por un gran ancho de banda de memoria, hoy por hoy las GPUs ofrecen prestaciones muy elevadas para procesamiento gráfico y científico [19-22]. Antes de examinar en detalle la arquitectura de una arquitectura GPU GeForce 8800 GTX de NVidia (http://www.nvidia.com), consideramos relevante explicar como han funcionado las operaciones en un pipeline de una GPU clásica a lo largo de los años. No obstante, para entender este proceso, también debemos introducir los conceptos de vertex shaders y los píxel shaders. 20 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Figura 3.1: Evolución en el número de operaciones en coma flotante por segundo para la CPU y la GPU 3.1.1. Vertex shaders y píxel shaders Los shaders son pequeños programas que se encargan del procesamiento de vértices (vertex shaders) y de pixeles (píxel shaders). La principal ventaja es que, como su naturaleza lo indica, pueden ser programados por el desarrollador, otorgando una flexibilidad que hasta antes de la aparición de los shaders era algo impensable. Recursos como las operaciones condicionales o los saltos se utilizan de forma similar que en los lenguajes más conocidos. Sin los shaders, muchos de los efectos eran realizados en conjunto con la unidad de procesamiento central, disminuyendo en gran medida el rendimiento y limitando el avance a nivel gráfico de los mismos. Un vertex shader es una función que recibe como parámetro un vértice. Sólo trabaja con un vértice a la vez, y no puede eliminarlo, sólo transformarlo. Para ello, modifica propiedades del mismo para que repercutan en la geometría del objeto al que pertenece. Con esto se pueden lograr ciertos efectos específicos, como los que tienen que ver con la deformación en tiempo real de un elemento; por ejemplo, el movimiento de una ola. Donde toma una gran importancia es en el tratamiento de las superficies curvas. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 21 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables En cambio, un píxel shader básicamente especifica el color de un píxel. Este tratamiento individual de los píxeles permite que se realicen cálculos principalmente relacionados con la iluminación del elemento del cual forman parte en la escena, y en tiempo real. La incorporación de los píxel shaders y vertex shaders permite a los programadores una mayor libertad a la hora de diseñar gráficos en tres dimensiones, ya que puede tratarse a cada píxel y cada vértice por separado. De esta manera, los efectos especiales y de iluminación pueden crearse mucho más detalladamente, sucediendo lo mismo con la geometría de los objetos. 3.1.2. Secuencia o pipeline clásico de procesamiento en una GPU Cuando revisamos las arquitecturas hardware, el flujo de datos, y las operaciones pipeline, a menudo es bueno empezar por el nivel más alto, donde los datos llegan desde la CPU a la GPU, y el proceso se desarrolla hacia abajo a través de múltiples fases de procesamiento hasta que un pixel es dibujado definitivamente en la pantalla. Para situarnos, las GPUs han utilizado diseños pipeline tradicionales, como los que aparecen ilustrados en la Figura 3.2. Figura 3.2: Pipeline clásico de procesamiento para una GPU. 22 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Después de que la GPU recibe los datos vertex (vértices) desde el host (CPU), la fase vertex se ejecuta en primer lugar. La función de fijado transforma la imagen y el hardware de luminosidad operado en esta fase se lleva a cabo; entonces los píxeles shaders programables, y el control de flujo dinámico de los modelos shaders entran en juego. El siguiente paso en el pipeline clásico es la configuración, donde los vértices son ensamblados dentro de primitivas como triángulos, líneas o puntos. Las primitivas son convertidas por la fase de “rasterization” en fragmentos de píxeles (o simplemente fragmentos), pero no son considerados píxeles completos en esta fase. Los fragmentos están sometidos a muchas otras operaciones como sombreado, Z-testing, la posible mezcla en el buffer frame, y el antialiasing. Los fragmentos son finalmente considerados píxeles cuando han sido escritos en el buffer frame. A continuación, la siguiente fase es la de píxel shader, que debería ser denominada técnicamente como fase fragment shader, pero utilizamos la notación estándar en la literatura [19-22] debido a su aceptación. En el pasado, los fragmentos sólo podían haber tenido valores de color aplicados de textura simple. Hoy en día, la capacidad de sombreado de un píxel programado de la GPU permite numerosos efectos de sombreado para ser aplicados mientras se trabaja de acuerdo con métodos complejos de multitextura. Específicamente, los fragmentos sombreados (con color y valores Z) desde esta fase píxel son enviados al ROP (Raster Operations). La fase ROP es donde se chequea el buffer Z para asegurar que sólo los fragmentos visibles son procesados rápidamente, y los fragmentos visibles, si son parcialmente transparentes, son mezclados con el buffer de frame existente, junto con los píxeles y aplicandoles antialiased. El píxel procesado final es enviado a la memoria buffer para ser escaneado y visualizado en el monitor [19]. 3.1.3. Evolución del uso de GPUs en aplicaciones científicas La principal razón que justifica la gran popularidad de las arquitecturas GPU en aplicaciones científicas es el hecho de que la GPU está especializada para cómputo intensivo, computación paralela elevada (exactamente sobre lo que trata el renderizado de gráficos) y por tanto se designan más transistores dedicados al procesamiento de datos, que a la recolección de datos y control de flujo. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 23 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Más específicamente, la GPU está especialmente pensada para direccionar problemas que pueden ser expresados como computaciones de datos paralelos (el mismo programa es ejecutado en muchos elementos de datos en paralelo) con gran intensidad aritmética (el ratio de operaciones aritméticas respecto a operaciones de memoria). Como el mismo programa es ejecutado para cada elemento de datos, hay menos requisitos para un flujo de control sofisticado; y como es ejecutado en muchos elementos de datos y tiene gran intensidad aritmética, la latencia de acceso a memoria puede ser ocultada con cálculos, en vez de datos muy grandes de caché [20]. Hasta la fecha, sin embargo, a pesar de acceder a todo el poder de computación contenido en al GPU y usarlo eficientemente para aplicaciones científicas, seguía siendo difícil obtener las siguientes pautas: • La GPU solamente podía ser programada a través de la API (Application Programming Interface) gráfica; esto provocaba que la curva de aprendizaje para un desarrollador principiante fuese muy elevada, ya que tenía que trabajar con una API inadecuada, que no estaba adaptada a la aplicación científica. • La DRAM de la GPU podía ser leída de manera general (los programas de GPU pueden obtener elementos de datos de cualquier parte de la DRAM) pero no se podía escribir de manera general (los programas de GPU no pueden esparcir la información a cualquier parte de la DRAM), eliminando mucha de la flexibilidad de programación ya disponible en la CPU. • Algunas aplicaciones tenían en problema del “cuello de botella”, debido al ancho de banda de la memoria DRAM, utilizando escasamente el poder computacional de la GPU. En este sentido, una de las principales motivaciones del presente PFC es demostrar que dichas limitaciones en la actualidad pueden superarse mediante la utilización de la arquitectura CUDA para procesamiento de datos científicos en la GPU. Dicho aspecto será abordado en detalle en el siguiente subapartado del presente capítulo de la memoria. 24 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 3.2. CUDA: Una nueva arquitectura para procesamiento de datos científicos en GPUs CUDA viene del inglés Compute Unified Device Architecture y es una nueva arquitectura hardware y software, diseñada para dar y manejar procesamientos en la GPU como un elemento de computación de datos paralelos sin la necesidad de mapearlos a una API de gráficos. Está disponible para las versiones GeForce 8 Series, Quadro FX 5600/4600, y Tesla. El mecanismo de multitarea del sistema operativo es responsable de manejar el acceso a la GPU mediante CUDA, y las aplicaciones gráficas funcionan de forma simultánea. A continuación describimos el pipeline unificado del que disponen las actuales GPUs de NVIDIA y que puede ser explotado de forma eficiente mediante CUDA, así como la arquitectura completa de la GeForce 8800 GTX, la GPU con mayores prestaciones considerada en este PFC. El apartado finaliza describiendo los diferentes modelos de programación en CUDA. 3.2.1. Pipeline unificado A partir del modelo de pipeline clásico, con sus flujos de datos empezando en lo más alto, donde los vértices con varios atributos, índices, comandos, y texturas son pasados a la GPU desde la CPU. Las fases de procesamiento mayores siguen una manera lineal segura incluyendo vertex shading, píxel shading, operaciones raster, (que son operaciones a través de las cuales un área espacial queda dividida en celdas regulares, en las que cada una de las cuales presentan unos atributos o valor, como pueden ser la altitud, reflectancia, etc.) y escritura de píxeles en el buffer frame. Con este pipeline unificado y la arquitectura “shader”, el diseño de la GPU GeForce 8800 reduce significativamente el número de fases del pipeline y cambia el flujo secuencial para estar más orientado a bucle. Las entradas son alimentadas en la parte alta del núcleo shader unificado, y las salidas son escritas en registros y entonces vuelven otra vez a la parte alta del núcleo shader para la próxima operación. Como resultado, en el diagrama GPU unificado generalizado que se miestra en la Figura 3.3, los flujos de datos bajan secuencialmente por el pipeline a Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 25 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables través de diferentes tipos “shader”. La figura de la derecha representa un núcleo “shader” unificado con uno o más procesadores “shader” unificados estandarizados. Figura 3.3: Pipeline clásico frente a pipeline unificado. Como puede apreciarse en la Figura 3.3, los datos vienen de la parte superior izquierda del diseño unificado (como vértices), y son llevados al núcleo shader para su procesamiento, y los resultados son enviados de vuelta a la parte superior del núcleo shader, donde son llevados otra vez, procesados otra vez, mandados de vuelta a la parte superior, y así hasta que todas las operaciones shader son ejecutadas y el fragmento de píxel se pasa al subsistema ROP [19]. 3.2.2. Arquitectura GeForce 88GTX A lo largo de la presente memoria hemos cubierto muchos de los puntos básicos de la programación de GPUs de NVidia, así que ahora podemos echar un vistazo a los aspectos específicos de la arquitectura GeForce 8800 GTX, la tarjeta más importante de las que estamos usando para realizar este PFC [19]. La siguiente Figura 3.4 describe la arquitectura hardware de dicha tarjeta. Como podemos apreciar en la figura, el bloque de interfaz del host incluye buffers para recibir comandos, datos vertex, y texturas enviadas a la GPU desde el controlador gráfico ejecutándose en la CPU. Lo siguiente, es el ensamblador de entrada, que encuentra datos vertex desde los buffers y los convierte a formato de coma flotante 32, mientras que también 26 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables genera varios índices que sirven de ayuda para llevar a cabo varias operaciones repetidas en los vértices y las primitivas, y para habilitar el instanciado. Figura 3.4: Arquitectura de la GPU GeForce 8800 GTX de NVidia. La GPU GeForce 8800 GTX incluye 128 procesadores de flujo (SPs) descritos en el diagrama, y cada SP es capaz de ser asignado a cualquier operación “shader” específica. Los datos pueden ser movidos rápidamente desde la salida de un procesador de flujo a la entrada de otro. 3.2.1. Modelo de programación CUDA Antes de profundizar en el modelo de programación empleado por CUDA, destacamos que la pila del software de CUDA se compone de varias capas, tal y como muestra la Figura 3.5. En concreto, dichas capas son un controlador de hardware, una API y su runtime, y dos librerías matemáticas de alto nivel para uso común, CUFFT y CUBLAS. El hardware ha sido diseñado para soportar controladores ligeros y capas runtime, dando como resultado una ejecución óptima. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 27 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables En este sentido, la API de CUDA es una extensión del lenguaje de programación C, lo cual hace que tenga una curva de aprendizaje mínima. Figura 3.5: Pila de CUDA. Por otra parte, CUDA ofrece un direccionamiento de carácter general para la memoria DRAM como ilustra la Figura 3.6. Este modelo de direccionamiento permite obtener mayor flexibilidad en la programación, en el sentido de que ofrece tanto la operación de reparto de datos como la de obtención de estos. Desde una perspectiva de programación, esto se traduce en la habilidad de leer y escribir datos en cualquier lugar de la DRAM, exactamente igual que en la CPU [20]. 28 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Figura 3.6: Operaciones de lectura y escritura en CUDA. Por otra parte, CUDA ofrece una cache de datos paralelos (o memoria on-chip compartida) con un acceso de lectura y escritura general bastante rápido, decidiendo qué hilos se usan para compartir datos entre ellos. Como podemos ver en la Figura 3.7, las aplicaciones pueden tomar ventaja de esto por la minimización de sobrecarga y las idas y vueltas a DRAM, y por tanto llega a ser menos dependiente del ancho de banda de memoria en al DRAM. Figura 3.7: La memoria compartida ofrece datos cerrados a las ALUs Una vez descritos los aspectos introductorios anteriormente mencionados, procedemos a describir el modelo de programación de CUDA, el cual está basado en 3 aspectos clave: el coprocesador multihilo, los hilos para realizar el tratamiento de la información por lotes, y finalmente la implementación hardware en CUDA. 3.2.1.1. Coprocesador Multihilo Cuando programamos a través de CUDA, la GPU es usada por el desarrollador como un dispositivo especializado en cálculo, capaz de ejecutar un gran número de hilos en paralelo. La GPU opera como un coprocesador de la CPU principal, o host: en otras Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 29 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables palabras, datos paralelos, porciones de cálculo intensivas de aplicaciones ejecutándose en el host están descargados en el dispositivo GPU. De manera más precisa, una porción de una aplicación que es ejecutada muchas veces, pero independientemente en datos distintos, puede ser aislada en una función que se ejecuta en el mecanismo tantas veces como hilos distintos hay. Como dicha función es compilada, la instrucción obtenida a partir del device (en nuestro caso, la GPU) y el programa resultante, llamado kernel, se descargan en el device. Tanto el host como el device mantienen su propia DRAM, referidas como memoria del host y memoria del device respectivamente. Una puede copiar datos de una memoria a la otra a través de llamadas a una API optimizada, que usa el Acceso Directo a Memoria (DMA) del device [20]. 3.2.1.2. Hilos de tratamiento por lotes El tratamiento por lotes de los hilos que ejecuta el kernel está organizado como un grid de hilos de bloques, ilustrado en la Figura 3.8. Un bloque de hilos es un lote de hilos que pueden cooperar juntos compartiendo datos eficientemente a través de algunas memorias rápidas de compartición de datos y sincronizando sus ejecuciones para coordinar los accesos a memoria. De forma precisa, uno puede especificar puntos de sincronización en el kernel, donde los hilos en un bloque están suspendidos hasta que todos ellos alcancen el punto de sincronización. Cada hilo es identificado por su identificador de hilo (thread ID), que es el número de hilo con el bloque [20]. Hay un número límite como máximo de hilos que un bloque puede contener (512 hilos concretamente). Sin embargo, los bloques de misma dimensión y tamaño que ejecutan el mismo kernel pueden ser tratados por lotes de forma conjunta, en un grid de bloques, así que el número total de hilos puede ser lanzado en una única invocación del kernel es mucho más largo. Esto se debe al gasto de reducir la cooperación entre hilos, porque los hilos en diferentes bloques de hilos del mismo grid no pueden comunicarse ni sincronizarse con los de los demás. Este modelo permite a los kernels ejecutarse eficientemente sin recompilación en varios devices con diferentes capacidades paralelas: un device puede ejecutar todos los bloques de 30 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables un grid secuencialmente si tiene algunas capacidades, o en paralelo si tiene muchas, o normalmente una combinación de ambas [20]. Figura 3.8: Tratamiento por lotes de hilos de ejecución. Con respecto al modelo de momoria, conviene destacar que un hilo que se ejecuta en el device tiene sólo acceso a la DRAM del device y a la memoria on-chip a través de los espacios de memoria descritos en la Tabla 3.1. Los espacios de memoria global, constante y de textura pueden ser leídos o escritos por el host, y persisten a través del kernel lanzándolos con la misma aplicación. Estos espacios son optimizados por diferentes usos de memoria. La memoria de textura también ofrece diferentes modos de direccionamiento, así como un filtro de datos para algunos formatos específicos [20]. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 31 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Tabla 3.1: Lecturas y escrituras en los diferentes tipos de memorias 3.2.1.3. Implementación hardware y modelo de ejecución El dispositivo GPU es implementado como un conjunto de multiprocesadores como se puede ver en la Figura 3.9. Cada multiprocesador tiene una Instrucción Única (Single Instruction), y arquitectura de Datos Múltiples (Multiple Data architecture ó SIMD): en cada ciclo de reloj dado, cada procesador del multiprocesador ejecuta la misma instrucción, pero opera en datos distintos. Los espacios de memoria local y global son implementados como regiones de la memoria del device. Cada multiprocesador accede a la cache de textura mediante una unidad de textura que implementa los diferentes modos de direccionamiento y filtros de datos [20]. 32 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Figura 3.8: Modelo hardware de la GPU. Con respecto al modelo de ejecución en la GPU, conviene destacar que un grid de bloques de hilos es ejecutado en el device ejecutando uno ó más bloques en cada multiprocesador, usando porciones de tiempo: cada bloque se corta en grupos SIMD de hilos llamados warps (tramas), cada uno de estos warps contiene el mismo número de hilos, llamado warp size (que es de 32 hilos), y es ejecutado por el multiprocesador en un modo SIMD; un programador de hilos selecciona periódicamente de un warp a otro, para maximizar el uso de los recursos de computación del multiprocesador. Una half-warp es o bien la primera o la segunda parte de un warp. La manera en que un bloque es dividido en warps es siempre la misma; cada warp contiene hilos consecutivos, incrementando los IDs de los hilos con el primer warp conteniendo el hilo 0. Un bloque es procesado solamente por un multiprocesador, así que el espacio de memoria compartida reside en la memoria on-chip compartida, llevando a unos accesos a memoria muy rápidos. Los registros del multiprocesador están localizados entre los hilos del bloque. Si el número de registros usados por hilo, multiplicado por el número de hilos en el bloque, es mayor que el número total de registros por multiprocesador, el bloque no puede se ejecutado y el correspondiente kernel fallaría al lanzarse. Por otra parte, varios bloques pueden ser procesados por el mismo multiprocesador concurrentemente, situando los registros del multiprocesador y la memoria compartida entre los bloques. La orden emitida de los bloques con el grid de bloques de hilos no está definida, y no hay un mecanismo de sincronización entre los bloques, así los hilos de dos bloques diferentes del mismo grid no pueden comunicarse de forma segura con los demás a través de la memoria global durante la ejecución del grid [20]. Finalmente, destacamos que el uso de múltiples GPUs, como las devices de CUDA, permiten que una aplicación se ejecute en un sistema multi-GPU solamente si las GPUs son del mismo tipo. Si el sistema está en el modo SLI quizás, sólo una GPU puede ser usada como una device de CUDA ya que todas las GPUs están fusionadas en los niveles más bajos en la pila del driver. El modo SLI necesita estar Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 33 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables apagado en el panel de control de CUDA para ser capaz de ver cada GPU como un device separado [20]. 34 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 4. Métodos El presente capítulo se organiza de la siguiente forma. En primer lugar describimos el algoritmo PPI de forma genérica. A continuación detallamos diferentes implementaciones de dicho algoritmo, incluyendo una versión serie para ejecución en CPUs monoprocesador y una versión paralela para ejecución en GPUs. Finalmente, comentamos algunos aspectos sobre la implementación del algoritmo en el software comercial ENVI, basados en nuestra interpretación de la versión del algoritmo disponible en dicho software comercial. 4.1. Algoritmo Pixel Purity Index (PPI) El algoritmo PPI [9] pertenece al conjunto de los métodos interactivos de extracción de endmembers y es el más representativo. Su objetivo es localizar los puntos espectralmente más puros de la imagen hiperespectral, basándose en la suposición de que los puntos más extremos del conjunto de puntos son los mejores candidatos para ser utilizados como endmembers. Los parámetros de entrada del algoritmo son el número de iteraciones a realizar y el valor umbral para seleccionar pixels puros. A grandes rasgos, el funcionamiento del algoritmo puede resumirse en los siguientes pasos: 1. En primer lugar, el algoritmo asigna un índice de pureza a todos los pixels de la imagen. El contador de cada punto se inicializa al valor 0. 2. Seguidamente, se genera un vector unitario aleatorio, que recibe el nombre de skewer o “divisor”. El objetivo de este vector es particionar el conjunto de puntos, como veremos a continuación. 3. El tercer paso consiste en proyectar todos los puntos de la imagen hiperespectral sobre el vector unitario antes generado, identificando los puntos extremos en la dirección definida por el vector unitario. El índice de pureza de los puntos extremos se incrementa en una unidad. 4. Los pasos 2-3 del algoritmo se repiten tantas veces como el usuario especifique en el parámetro de entrada, número de iteraciones. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 35 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 5. Tras la ejecución de un número amplio de iteraciones, se obtiene como resultado una imagen de pureza formada por los índices asociados a cada uno de los pixels de la imagen. 6. Utilizando el valor umbral especificado como parámetro, se seleccionan los puntos de la imagen cuyo índice de pureza asociado supera dicho valor umbral. Estos puntos son etiquetados como “puros”. La Figura 4.1 ilustra el procedimiento seguido hasta este punto, suponiendo que se trabaja en un espacio de dos dimensiones y que se realizan tres iteraciones y que se seleccionan como endmembers aquellos puntos que han sido seleccionados como extremos una o más veces. 7. Los pixels seleccionados se cargan en una herramienta interactiva disponible en el software ENVI y denominada 4-Dimensional Visualizer, la cual permite realizar diagramas de dispersión de los primeros autovectores obtenidos tras la aplicación de una transformación sobre los datos originales. Utilizando la herramienta anteriormente descrita, el usuario selecciona manualmente aquellos puntos o agrupaciones de puntos que aparecen como extremos en proyecciones sucesivas, identificando un conjunto final de endmembers. En el caso de seleccionar una agrupación de puntos, los endmembers se obtienen a partir del espectro promedio en cada una de las regiones seleccionadas. A partir de la descripción anteriormente mencionada, puede derivarse que el método PPI contiene etapas totalmente automatizadas, como la fase de generación de la imagen de pureza, pero es necesaria una etapa final, altamente interactiva, en la que el usuario selecciona manualmente los pixels que quiere utilizar como endmembers. El usuario no conoce a priori cuál es el número apropiado de endmembers a seleccionar, por lo que debe escoger el número de endmembers en base a su intuición. Este hecho pone de manifiesto la conveniencia de cierto conocimiento a priori sobre la imagen. Esta característica, unida a otras como la aleatoriedad en el proceso de generación de vectores unitarios (ver Figura 4.1), representan los principales inconvenientes de esta metodología [18]. Por otra parte, es importante destacar que el método PPI puede generar endmembers artificiales en caso de que el usuario del método seleccione conjuntos de puntos en el proceso interactivo de identificación de firmas espectrales extremas. 36 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Skewer 1 Pixel extremo Skewer 2 Pixel extremo Skewer 3 Pixel extremo Pixel extremo Figura 4.1: Funcionamiento del algoritmo PPI en un espacio de dos dimensiones. A partir de la Figura 4.1, puede derivarse que el algoritmo PPI se basa en generar un gran número de vectores aleatorios (skewers), los cuales se multiplican escalarmente por cada píxel (vector) de la imagen original. Si el número de vectores generados es muy elevado, esta operación podría tardar varias decenas de minutos en realizarse a través de una computación estándar [18]. Por tanto, nuestra propuesta es implementar esta fase de proyecciones múltiples (la más costosa computacionalmente) en la GPU, de tal forma que cargaremos la imagen en memoria, le pasaremos los datos correspondientes a la GPU, y esta realizará el producto escalar en cada iteración del algoritmo, devolviéndonos los resultados oportunos. Incidiendo en la complejidad computacional de esta fase, la complejidad C de la misma en términos de operaciones MAC (multiplicación seguida de acumulación) puede expresarse como C = 4 x K x D, donde D es el número de bandas, K el número de skewers, y 4 es el número de bandas espectrales de la imagen original. Por ejemplo, procesando el algoritmo PPI en una imagen hiperespectral de satélite de unos 512 x 614 píxeles de 224 bandas con 10000 “skewers”, requiere calcular más de 7 × 1011 MACs, lo cual supone un gran tiempo de computación muy elevado para un microprocesador. Afortunadamente, la computación de todas las proyecciones es independiente y el algoritmo puede implementarse en paralelo de forma muy eficiente. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 37 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Para concluir este apartado, describimos los pasos exactos que se han seguido en la implementación del algoritmo PPI en sus versiones CPU y GPU: 1. Generación de vectores aleatorios (skewers): en este procede a generar un largo número de vectores 4-dimensionales (4 es el número de Bandas de la imagen hiperespectral) aleatorios. Para ello aplica un algoritmo de aleatoriedad basado en que a cada valor aleatorio generado, le vamos a aplicar su norma. En concreto, el cálculo realizado es el siguiente: 4 norma _ it = ∑ v (k ) * v ( k ) k =1 siendo v(k ) el valor en el vector generado aleatoriamente para la banda k. Una vez tenemos calculada la norma, dividimos cada valor del vector aleatorio por dicha norma, quedándonos: skewer _ it = skewer _ it / norma _ it 2. Realización del producto escalar (dot-product): este paso es fundamental a la hora de obtener el cálculo del índice de pureza de cada píxel o PPI. Gracias a dicho cálculo, obtendremos los valores de cada píxel, que después se tendrán en cuenta para calcular los extremos en cada iteración. Este producto escalar será llevado a cabo por cada píxel que forma parte de la imagen junto al skewer perteneciente a la iteración actual. La forma de realizar el producto escalar usada en este PFC es: 4 dp ( x) = ∑ x(k ) * skewer (k ) k =1 es decir, si x = {a1 , a 2 , a3 ,..., a 4 } y skewer = {b1 , b2 , b3 ,..., b4 } , entonces: dp( x) = a1 * b1 + a 2 * b2 + a3 * b3 + ... + a 4 * b4 donde x representa al píxel objeto del producto escalar. 38 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 3. Cálculo de los píxeles extremos: una vez tenemos calculado todos los productos de cada píxel, con el vector aleatorio generado específicamente para la iteración en la que se encuentra el algoritmo, entonces buscamos los extremos de la imagen. Los píxeles extremos, según el criterio que hemos seguido para realizar el PPI, son aquellos píxeles que producen el valor máximo y mínimo en su producto escalar, para esa iteración; luego si identificamos a E, como al conjunto formado por los píxeles extremos, y Pr como el conjunto de productos escalares de esa iteración, entonces un píxel x, es extremo cuando cumple: x ∈ E si y sólo si dp ( x) = MAX (Pr) ∨ dp ( x) = MI4 (Pr) , es decir, cuando producto escalar de ese píxel es, o bien el máximo o bien el mínimo para la iteración it del algoritmo. Los pasos 2 y 3 serán repetidos tantas veces como iteraciones formen el algoritmo, sin embargo, los pasos 1 y 4 sólo serán realizados una vez, al principio y al final respectivamente. 4. Selección final de los endmembers: una vez tenemos escogidos todos los extremos, debemos eliminar aquellos píxeles que no superen un cierto valor umbral indicado en el algoritmo; es decir, todos los píxeles que hayan sido escogido un número menor de veces que dicho umbral, no serán tenidos en cuenta a la hora de formar parte de los extremos reales de la imagen. Si Er, es el conjunto de los extremos que superan dicho umbral, y que formarán la imagen resultado de aplicar el algoritmo PPI, y S es un conjunto que guarda el número de veces que un píxel a sido escogido como extremo a lo largo de la ejecución, lo anteriormente explicado es equivalente a la siguiente ecuación: Si x ∈ E entonces x ∈ Er si y sólo si S ( x) ≥ umbral . Conviene destacar que esta última etapa (paso 4 del algoritmo) puede realizarse de múltiples formas y que en la herramienta ENVI este paso se realiza de forma supervisada. En el presente PFC, nuestro interés radica en acelerar los pasos 13 del algoritmo ya que la imagen PPI puede ser explotada de formas diversas (supervisada y automática) para extraer el conjunto final de endmembers. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 39 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Supongamos, por ejemplo, que para una iteración determinada del algoritmo, los pares (mínimo, iMIN) y (máximo, iMAX) contienen respectivamente (125,36) y (230,63). Esto significa que hasta ahora, el valor de producto escalar más bajo ha sido producido por el píxel 36 y el mayor por el píxel 63. Si el producto escalar actual es igual a 90, entonces el par (125,36) es reemplazado por el par (90, píxel_actual) para esta iteración. Sin embargo, esto no garantiza que dicho píxel foma parte del conjunto final de píxeles extremos, ya que para producirse tal hecho, deberá ser escogido un número mayor o igual de veces que el umbral. Partiendo de la descripción del algoritmo PPI anteriormente descrita, a continuación describimos la implementación que se ha desarrollado para el algoritmo en versión GPU, finalizando con algunos aspectos relativos a la implementación en ENVI del algoritmo. Conviene destacar que, en la versión serie del algoritmo (no descrita) toda la carga de trabajo va a ser llevada única y exclusivamente por el procesador, mientras que la versión paralela descrita a continuación utiliza la GPU como coprocesador. Por razones ilustrativas, la Tabla 4.1 muestra el pseudo-código de la versión serie del algoritmo PPI implementada en el lenguaje C. // Inicialización Comprobar Fichero(); // ver si es correcto, si tiene valores aceptables ObtenerValorMaximo(); NormalizarImagen(); // Valores quedan en el rango [0,1] GenerarVectoresAleatorios(); //para el producto escalar InicializarVectores(); InicializarTimer(); // Empieza a contar el tiempo de procesamiento // PPI Para i desde 1 hasta Iteraciones hacer Inicio ProductoEscalar(); // para todos los píxeles MarcarExtremoMáximo(); MarcarExtremoMínimo(); CalculoRatio(); FinPara // Procesamiento de datos PararTimer(); MostrarTimer(); MostrarRatio(); MarcarExtremosUmbral(); // sólo serán extremos los píxeles >= umbral MostrarCuantosExtremos(); EscribirImagenPPI(); // Liberación de mamoria LiberarMemoriaResevada(); Tabla 4.1: Implementación serie del algoritmo PPI. 40 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 4.2. Implementación del algoritmo PPI en GPUs Como se ha comentado en el capítulo 2 de la presente memoria, las GPUs modernas implementan una generalización del proceso de renderizado (rendering pipeline). Los procesadores de vértices y de fragmentos son los elementos programables del pipeline, y los programas que ejecutan se llaman vertex y fragment shaders, respectivamente. La etapa de procesamiento de vértices realiza operaciones sobre el flujo de vértices enviados a la GPU. Los procesadores de vértices transforman cada uno de esos vértices en un vértice 2D en el espacio de proyección, y calculan la iluminación para determinar su color. En la actualidad, esta etapa es totalmente programable, lo cual permite realizar transformaciones personalizadas para así conseguir efectos especiales. Una vez transformados, los vértices se reensamblan formando triángulos y se rasterizan en un flujo de fragmentos. Estos fragmentos son las porciones discretas de la superficie del triángulo correspondientes a los píxels de la imagen representada. Aparte de identificar los fragmentos que constituyen el triángulo, la etapa de rasterización también interpola atributos almacenados en los vértices, tales como las coordenadas de texturas, y posteriormente almacena dichos valores como atributos de cada fragmento. Los procesadores de fragmentos calculan el color resultante utilizando operaciones aritméticas y de acceso a texturas. Con este propósito, la memoria de texturas se puede indexar con distintas coordenadas de texturas y los valores de textura se pueden obtener a partir de múltiples texturas. Para incrementar la eficiencia computacional, estos procesadores soportan instrucciones vectoriales cortas que operan sobre vectores de 4 componentes (canales Red/Green/Blue/Alpha) al estilo SIMD, e incluyen unidades de acceso a texturas que operan con una caché de texturas segmentada. Además, la latencia de los accesos a datos se oculta utilizando pre-búsqueda de texturas y transfiriendo bloques de datos 2D desde la memoria a la caché de texturas. Finalmente, los resultados obtenidos por el procesador de fragmentos se combinan con la información existente almacenada en la posición 2D asociada en el frame buffer, para producir el color final. Los procesadores de fragmentos son generalmente de mayor utilidad que los procesadores de vértices para implementar aplicaciones no relacionadas con gráficos (como es el caso de la aplicación que nos ocupa). Esto se debe a que su número es mayor, y también a su mejor rendimiento en términos de acceso a memoria. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 41 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables En cualquier caso, es importante destacar que el mapeo de aplicaciones sobre GPU requiere estructurar los cálculos según un modelo de flujos, en el que los núcleos se expresan como programas de fragmentos y los flujos de datos se expresan como texturas. Este paradigma de programación ha sido estudiado por diversos investigadores, que han adaptado un gran número de aplicaciones científicas a las características intrínsecas de las GPUs. Antes de describir la implementación del algoritmo PPI en GPUs, discutimos brevemente los mecanismos a la hora de mapear imágenes hiperespectrales en forma de texturas. Aunque el uso de una sola textura 3D representa la elección más natural y sencilla, las GPUs trabajan mejor con texturas bidimensionales, por lo que se optó por dividir cada imagen hiperespectral en una pila de texturas 2D, tal y como muestra la Figura 4.2 para un caso sencillo con 5 particiones. En caso de que la imagen hiperespectral supere la capacidad de memoria de la GPU, la división se efectúa teniendo en cuenta que la partición almacena píxels (vectores) completos, es decir, cada partición tiene toda la información espectral de una zona espacial localizada. Figura 4.2: Particionamiento de la imagen hiperespectral para su procesamiento. Teniendo en cuenta el esquema de particionamiento anteriormente descrito, a continuación se describe la implementación basada en flujos realizada para el algoritmo PPI. La implementación consta de una serie de pasos claramente diferenciados que iremos desglosando y detallando de forma individual a lo largo del presente apartado. 42 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 1. Inicialización. En esta etapa se crean todas las variables involucradas en la ejecución del algoritmo, así como reservas de memoria, divide la imagen en trozos (según el esquema descrito en la Figura 4.2) y los almacena como flujos en la memoria de la GPU. 2. Cálculo de proyecciones. En esta etapa se calcula el algoritmo PPI propiamente dicho en la GPU, en particular, la etapa en la que se efectúan las proyecciones de los skewers y los píxels de la imagen. La etapa de selección de endmembers final a partir de la imagen PPI no se ha implementado para su ejecución eficiente en la GPU, por lo que queda abierta a diferentes aproximaciones para la selección de endmembers (supervisadas y no supervisadas). 3. Liberación de memoria. Finalmente, en esta etapa se libera la memoria reservada durante el proceso y se finaliza la ejecución en la CPU. A continuación, describimos en mayor detalle técnico cada una de las tres partes de la implementación en GPU del algoritmo PPI, proporcionando ejemplos de codificación por razones de claridad. 3.2.1. Inicialización De forma previa a la descripción de la etapa de inicialización, destacamos algunas variables importantes que serán utilizadas por el algoritmo y cuyo valor será establecido en la etapa de incialización. Dichas variables son las siguientes: • Dimensión de bloque X: esta variable indica el valor de la dimensión X (líneas) de cada bloque o partición de la imagen hiperespectral. • Dimensión de bloque Y: esta variable indica el valor de la dimensión Y (muestras) de cada bloque o partición de la imagen hiperespectral. • Variables device: son variables especiales que se necesitan para procesar los datos en la GPU. Cada variable host (CPU) requiere su homóloga device (GPU) siempre y cuando se requieran esos datos que inicialmente están en CPU para operar en le GPU. En el código se pueden diferenciar porque la nomenclatura de las variables host lleva una “h” en su nombre, y las de device una “d”. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 43 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Conviene destacar que, por definiciones del fabricante, se recomienda que el tamaño total del bloque (número de hilos que contiene) sea siempre múltiplo del tamaño del warp (que es 32); y aun mejor se recomienda que sea múltiplo de 64, porque así el compilador y el organizador de hilos organizan las instrucciones de la manera más óptima posible para evitar conflictos con el banco de registros en memoria. Es por ello que en este proyecto se ha optado por que las dimensiones con las que trabaje la GPU sean X = 8 e Y = 8 para cada bloque. Es también importante destacar que, a lo largo de la implementación, se probaron otros valores, pero no supusieron una mejora de tiempo de ejecución. Una vez descrito el proceso de particionamiento de la imagen hiperespectral, procedemos a comentar los pasos involucrados en la etapa de inicialización. En primer lugar, es preciso incluir una serie de librerías: #include <cutil.h> #include <imagen_kernel.cu> La primera librería, cutil.h, es propia de CUDA y contiene instrucciones útiles para la búsqueda de ficheros, carga de imágenes, funciones para el timer, etc. Por su parte, la segunda librería, imagen_kernel.h, hace referencia al kernel implementado en la GPU, es decir, la función que comunicará a la CPU y a la GPU y que hará posible el intercambio de datos entre una y otra. La implementación GPU comienza con una llamada a la función: CUT_DEVICE_INIT(); Esta función es propia de CUDA, y pone en marcha la GPU y la prepara para recibir datos. Una vez realizado este proceso, el siguiente paso es cargar la imagen con la que queremos trabajar a través de otra función CUDA, perteneciente a la librería cutil.h: char* image_path = cutFindFilePath(image_filename,argv[0]); El siguiente paso consiste en definir las dimensiones para los bloques y el grid: 44 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables dim3 bloque(blockdimX, blockdimY,1); dim3 grid(iDivUp(Lineas,bloque.x), iDivUp(Muestras,bloque.y),1); Conviene destacar que dim3 es un tipo especial de datos CUDA; concretamente un vector de 3 datos de tipo unsigned int, usado para especificar dimensiones. A continuación, el siguiente paso relevante de la implementación consiste en reservar la memoria para ubicar la imagen en memoria: cudaMalloc( (void**) &d_Mat, Muestras*Lineas*Bandas*sizeof(float)); La función cudaMalloc es la proporcionada por CUDA para la reserva de memoria de variables device, es decir, variables que después se van a usar para transferir datos de la memoria a la GPU. Es decir, al igual que malloc se usa en la CPU (host) para reservar memoria, la función enquivalente para reservar memoria en la GPU es cudaMalloc. A continuación describimos el proceso para intercambiar información entre la CPU y la GPU. Para ello, se utilizan las siguientes líneas de código: cudaMemcpy(d_Mat, h_Mat, Muestras*Lineas*Bandas*sizeof(float), cudaMemcpyHostToDevice); Con la función cudaMemcpy intercambiamos los datos entre la CPU y la GPU (e incluso entre variables del mismo tipo). La dirección de intercambio se realiza mediante el último parámetro. En el ejemplo podemos ver como se indica claramente que el intercambio es de CPU a GPU mediante el parámetro cudaMemcpyHostToDevice. Conviene destacar, sin embargo, que cualquiera de las combinaciones es posible. Por último, antes de describir la parte del código relacionada con el procesamiento del algoritmo propiamente dicho, destacamos la utilización de una serie de funciones facilitadas para la creación y puesta en marcha de los timers, que servirán para contabilizar el tiempo transcurrido desde el inicio del algoritmo hasta que este haya calculado los extremos para así poder evaluar el tiempo empleado durante el proceso. Las funciones se utilizan de la siguiente forma: Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 45 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables cutCreateTimer(&timer); cutStartTimer(timer); 3.2.2. Cálculo de proyecciones El primer paso en la implementación propiamente dicha del algoritmo PPI en la GPU es establecer las iteraciones que se van a realizar en el algoritmo. Para ello, es preciso realizar una llamada al kernel denominado CalculoEscalar, que se encarga de realizar todos los cálculos escalares a través de la GPU: CalculoEscalar<<<grid, bloque>>>(d_Mat,d_VEsc,d_aleat,i); Por razones ilustrativas, a continuación mostramos el código completo de dich kernel, que constituye el núcleo fundamental del algoritmo en la GPU: __global__ void CalculoEscalar(float * Mat, float *vec_tot, float* aleat, int iter) { int i; float res; //Calculo del id del hilo correspondiente int ix = blockDim.x * blockIdx.x + threadIdx.x; int iy = blockDim.y * blockIdx.y + threadIdx.y; int id = iy*Lineas + ix //Si el id calculado tiene correspondencia con una posición de la //matriz, realizamos el producto escalar if(id >= 0 && id < Muestras*Lineas){ //Variable que guardará el resultado del producto escalar res = 0.0; //Hacemos el producto escalar. for(i = 0; i < Bandas; i++) res = res + (aleat[iter*Bandas + i] * Mat[id*Bandas + i]); //Asignamos el resultado al pixel correspondiente vec_tot[id] = res; } } 46 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables En el trozo de código mostrado anteriormente, podemos comprobar que lo primero que se realiza es calcular el identificador de hilo correspondiente al hilo que está ejecutando en ese momento dicha función, y que haremos corresponder con un píxel de la imagen. Este trozo de código será ejecutado por todos los hilos de la GPU. Es por ello que no observamos ningún bucle dentro del mismo (a excepción del de el cálculo escalar). Después sencillamente hacemos el producto escalar entre dicho píxel y el vector aleatorio generado para esa iteración, y copiamos el resultado en el vector de los productos escalares, usando otra vez el identificador del hilo calculado previamente, para asignarle la posición concreta. Una vez finalizado el proceso, volvemos a utilizar los timers para obtener el tiempo empleado en el proceso del cálculo de proyecciones: cutStopTimer(timer); printf("Processing time: %f (ms)\n", cutGetTimerValue(timer)); cutDeleteTimer(timer); En primer lugar se calcula el tiempo empleado utlizando el timer; a continuación, se traduce el timer a milisegundos; y finalmente se elimina el timer ya que no volverá a ser utilizado. 3.2.3. Liberación de memoria La última parte de la implementación del algoritmo PPI en la GPU consiste en liberar la memoria. Mientras que en el código CPU se usa la sentencia free para liberar la memoria de los vectores reservados como tales, en la GPU los vectores reservados en memoria device se liberan mediante la sentencia cudaFree: cudaFree(d_aleat); Después de ver todo esto, podemos darnos cuenta de las similitudes existentes entre el código C y el CUDA, lo cual revela que CUDA permite reutilizar una gran parte del código C a la hora de desarrollar la implementación para la GPU. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 47 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 4.3. Implementación del algoritmo PPI en ENVI Para concluir este capítulo describimos la implementación del algoritmo PPI disponible en ENVI, la cual será empleada como referencia a la hora de validar la implementación GPU desarrollada con motivo del presente trabajo. La Figura 4.3 muestra un diagrama de flujo explicando los principales pasos involucrados en la versión implementada en ENVI del algoritmo PPI. ENVI’s N-Dimensional visualizer Figura 4.3: Implementación del algoritmo PPI en ENVI. El primer aspecto destacable en cuanto al algoritmo PPI de ENVI es que dicho algoritmo realiza una etapa de reducción dimensional previa sobre la imagen original basada en la transformación MNF (Minimum 4oise Fraction), que proporciona una descripción detallada de la relación existente entre la cantidad de señal presente en la imagen y la cantidad de ruido. De este modo, la primera banda resultante de la transformación MNF es la que presenta mayor relación SNR. La segunda banda presenta mejor SNR que la tercera, y así sucesivamente. Una vez aplicado el proceso de identificación de píxels puros mediante generación de proyecciones aleatorias, el resultado del PPI es usado normalmente como entrada del visualizado de la herramienta 4-Dimensional Visualizer que permite seleccionar un conjunto de endmembers de forma supervisada. Es importante destacar que el usuario no conoce a priori cuál es el número apropiado de endmembers a seleccionar, por lo que debe escoger el número de endmembers en base a su intuición. Este hecho pone de manifiesto la conveniencia de cierto conocimiento a priori sobre la imagen. 48 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Sí queremos ver este hecho de forma más detallada, podemos usar el Spectral Hourglass Wizard de ENVI, que nos guiará paso a paso a través del flujo de procesamiento, incluyendo al PPI, para encontrar y mapear los endmembers de la imagen espectral desde datos hiperespectrales o multiespectrales. Además, la version de PPI usada por ENVI, está basada en un método denominado Fast PPI, que carga los datos de la imagen en memoria y ejecuta los cálculos en memoria, acelerando mucho más el proceso, que con el método PPI basado en disco, pero requiere una cantidad de memoria adecuada para ello. Dicho método utiliza un subconjunto espacial y espectral o un array pequeño de datos (resolución de submuestras) para ayudar a adecuar los datos de la imagen en la memoria. ENVI nos informa de la cantidad de memoria necesaria para ejecutar el Fast PPI y nos avisa para continuar. Cuando usamos Fast PPI, también tenemos las opciones de crear un nuevo archivo de salida y añadirle la banda de salida existente. Al seleccionat archivos de entrada, podemos usar la opción 4ew Output Band la primera vez que ejecutamos el PPI. Una banda de salida conteniendo el número de veces que cada píxel fue seleccionado como extremo es creada y usada como entrada para el 4-Dimensional Visualizer de ENVI. Después de todo lo visto anteriormente, empezamos con el algoritmo. Lo primero es seleccionar el número de iteraciones. Este número valdrá para indicar el número de veces que los datos serán proyectados en el vector aleatorio. Cuantas más iteraciones ejecutemos, mejor será el resultado obtenido por Envi a la hora de encontrar los píxeles extremos. Debemos balancear el número de iteraciones con respecto al tiempo disponible, ya que cada iteración lleva una cantidad de tiempo asociada, dependiente del la CPU y la carga del sistema. Típicamente, miles de iteraciones son requeridas para el tratamiento de datos de imágenes hiperespectrales. El siguiente paso consiste en seleccionar el factor de umbral que queremos aplicar al PPI. Por ejemplo, un umbral de 2 marca todos los píxeles cuyo número de veces de selección como píxel extremo haya sido 2 (teniendo en cuenta tanto los mínimos como los máximos). Este umbral selecciona los píxeles en los finales del vector proyectado. El umbral debería ser aproximadamente 2 ó 3 veces el nivel de ruido en los datos. Por ejemplo, para datos TM, que típicamente tienen menos de 1 DN de ruido, un umbral de 2 ó 3 estaría bien. Cuando usamos datos MNF, que Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 49 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables normalizan el ruido, un DN es equivalente a una desviación estandar y, de nuevo, un umbral de 2 ó 3 funciona bien. Umbrales más grandes hacen que el PPI encuentre más píxeles extremos, con la desventaja de que estos serán menos propensos a ser seleccionados como endmembers. Para concluir el presente apartado, dedicado a describir la implementación del algoritmo PPI disponible en ENVI, mostramos un ejemplo de utilización de dicho algoritmo en el lenguaje de programación Interactive Data Language (IDL) en el que fue desarrollado ENVI. El motivo de incluir esta descripción es facilitar la comprensión de los parámetros involucrados en dicha implementación, los cuales coinciden con los empleados en las versiones en C y en CUDA del mismo algoritmo y que serán validados y comparados experimentalmente en el siguiente apartado de la presente memoria. Las variables utilizadas en el código IDL que hace uso de la función PPI_DOIT que contiene la implementación del algoritmo PPI en ENVI son las siguientes: • DIMS: usa esta clave para especificar las dimensiones en que se ejecutan las operaciones. DIMS es un vector de 5 elementos de tipo long int con las siguientes definiciones: o DIMS[0]: No se usa para esta function, puesta a -1. o DIMS[1]: El píxel X inicial (el primer pixel es el 0). o DIMS[2]: El píxel X final. o DIMS[3]: El píxel Y inicial (el primer pixel es el 0). o DIMS[4]: El píxel Y final. • FID: se usa para especificar el ID del archivo a abrir. Es el valor retornado desde la palabra reservada D_FID en el procedimiento ENVI_OPEN_FILE. FID es un “long int” con valor mayor que cero. Un ID no válido es especificado como -1. • I_MEMORY: se usa para especificar que salida debe ser almacenada en memoria. Si no está puesto ningún valor, la salida se almacenará en disco. • ITERATIOS: usada para especificar el número total de iteraciones a ejecutar. Si se está usando un PPI_DOIT como salida, entonces especifica el número de iteraciones adicional que se ejecutarán. 50 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables • OUT_BAME: usado para especificar un vector de tipo string para el nombre de la banda de salida, si se desea. • OUT_AME: usado para especificar el nombre del archive de salida para los datos resultado. Si IN_MEMORY está puesto, esta opción no es necesaria. • P_FID: usado para especificar el ID de una archive para un archive de salida previo desde el PPI_DOIT. Si no usa un archivo de un PPI_DOIT previo, entonces P_FID debe ser puesto a -1. • POS: se usa para especificar un vector de 3 elementos de tipo long int de posiciones de bandas. Los elementos de POS son emparejados con elementos del vector FID. • PREV_ITER: usado para poner el número de iteraciones previo ejecutado en los datos. Debe ser puesto a cero si los datos nos son reiniciados en un ciclo de procesamiento previo. • PREV_DATA: se usa para especificar un vector de Total Pixel Counts previo. Este dato se alamcena en una archivo desde la ejecución previa. • R_FID: se usa para especificar una variable llamada que contendrá el ID del archivo desde el dato procesado. Este archivo ID puede ser usado para acceder al dato procesado. • THRESH: se usa para indicar el valor umbral del algoritmo. Teniendo en cuenta las variables anteriormente mencionadas, a continuación mostramos un sencillo ejemplo de uso de la función PPI_DOIT que permite analizar los parámetros de entrada y requerimientos del algoritmo PPI disponible en ENVI: envi, /restore_base_save_files envi_batch_init, log_file='batch.txt' envi_open_file, 'imagen.bsq', r_fid=fid if (fid eq -1) then envi_batch_exit envi_file_query, fid, ns=ns, nl=nl, nb=nb dims = [-1l, 0, ns-1, 0, nl-1] pos = lindgen(nb) out_name = 'testimg' envi_doit,'ppi_doit',fid=fid, pos=pos, dims=dims,p_fid=-1, iterations=10000, thresh=3.0, prev_iter=0, out_name=out_name, r_fid=r_fid envi_batch_exit Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 51 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 5. Análisis y discusión de resultados En este capítulo presentamos una evaluación experimental de las diferentes versiones del algoritmo PPI (implementado en C y en CUDA, y la versión disponible en ENVI) desde el punto de vista de su precisión a la hora de detectar los píxels puros y también desde el punto de vista de su rendimiento computacional. El apartado está organizado de la siguiente forma. En primer lugar, describimos las imágenes hiperespectrales simuladas y reales utilizadas en la validación experimental. A continuación, se describen las caacterísticas de las GPUs usadas para comparar los tiempos de ejecución del algoritmo paralelo. Finalmente, se realiza un exhaustivo análisis y discusión comparativa de los resultados obtenidos al aplicar el PPI en ENVI, su versión en C y su versión CUDA en dos generaciones de GPUs, discutiendo dichos resultados y analizando la validez de la implementación en GPU en base a la comparativa de la misma con respecto a las versiones en C y en ENVI. 5.1. Imágenes hiperespectrales utilizadas en el estudio Con vistas a validar la precisión de las diferentes versiones del algoritmo PPI en la tarea de identificar los píxels puros en imágenes hiperespectrales, hemos utilizado tanto imágenes sintéticas como imágenes reales. Las pruebas con imágenes sintéticas están orientadas a evaluar de forma preliminar el funcionamiento de la metodología propuesta, estudiando el ajuste de parámetros y su impacto en el resultado final obtenido. Por otra parte, el uso de imágenes reales permite establecer un estudio comparativo del algoritmo propuesto con respecto a otros ya existentes de amplia utilización por parte de la comunidad científica dedicada al análisis de imágenes multi-dimensionales. A continuación, describimos la batería de imágenes empleada en el estudio, distinguiendo entre imágenes sintéticas y reales. 5.1.1. Imágenes sintéticas Las imágenes sintéticas permiten adoptar una forma objetiva a la hora de evaluar el rendimiento de un algoritmo de análisis hiperespectral, ya que dichas imágenes se 52 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables generan de forma controlada y la información relativa al grado de pureza de cada píxel puede controlarse a priori. Describimos a continuación el proceso de generación de una imagen sintética mediante un sencillo ejemplo, detallando el proceso de selección de firmas espectrales, la forma en que se establece la asignación de abundancias y el esquema seguido para la generación de ruido. En el ejemplo que nos ocupa, las firmas empleadas en la construcción de la imagen simulada corresponden a una imagen obtenida por el sensor AVIRIS en 1997 sobre la región Jasper Ridge en California. La disponibilidad pública de esta imagen en unidades de reflectancia resulta muy atractiva con objeto de crear imágenes simuladas a partir de firmas espectrales reales. A continuación, se establece la abundancia de cada una de las referencias elegidas en cada pixel de la imagen, de forma que la contribución individual de cada firma se expresa mediante un conjunto de coeficientes de abundancia que cumplen las restricciones de no-negatividad y suma unitaria, propias del modelo lineal de mezcla. La última etapa en la simulación consiste en añadir ruido a la imagen simulada. Nuestro proceso de simulación de ruido en imágenes sintéticas se ha llevado a cabo utilizando un generador aleatorio de números entre 1 y –1. Estos valores siguen un modelo de distribución de probabilidad normal, con lo que su valor medio es 0 y su desviación estándar es 1. El ruido se añade a cada pixel de la imagen en una determinada proporción que determina la relación señal-ruido presente en la escena. Una vez descrito el proceso de generación de imágenes sintéticas, pasamos a describir las imágenes concretas que vamos a emplear en nuestro estudio. La primera imagen simulada tiene dimensiones 100x100 pixels, y viene caracterizada por una situación de mezcla entre componentes progresiva, a intervalos de abundancia muy cortos. Como resultado, los cambios en la abundancia en las regiones que componen esta imagen son muy sutiles. En total, hay 100 regiones de 1 pixel de ancho y 100 pixels de alto. La abundancia del componente suelo decrece de forma lineal de izquierda a derecha, mientras que la abundancia del componente vegetación crece de izquierda a derecha. La Figura 5.1 ilustra el proceso de construcción de esta imagen sintética, que proporciona un conjunto de datos muy apropiado para analizar el proceso de estimación de abundancias realizado por el algoritmo PPI. Este hecho se debe a la situación de mezcla particular que se representa en la imagen. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 53 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 100 R1 Asignación de abundancias R2 ................. 100 Región Suelo Vegetación Ri 1 – (i / 100) i / 100 R99 R100 11 11 Figura 5.1: Regiones y asignación de abundancias para la primera imagen sintética. Por otra parte, la Figura 5.2 muestra los mapas de abundancia empleados para la generación de la primera imagen sintética utilizada en los experimentos, que comprende mapas para dos endmembers simulados (vegetación y suelo). Conviene destacar que la relación SNR en la imagen simulada (tras el proceso de simulación de ruido) es de 110:1 (proporción de señal de 110 veces a 1 sobre el ruido) y el número de bandas es de 224 (correspondiente a un espectro real de AVIRIS) comprendidas entre 0.4 y 2.5 micrómetros, con una nueva banda aproximadamente cada 10 nanómetros. El tamaño total de la imagen es de 4.27 MB. 0.0 0.2 0.4 0.6 0.8 1.0 100 100 a) b) Figura 5.2: Mapas de abundancia empleados en la generación de la primera imagen sintética. a) Mapa de abundancia para el endmember suelo. b) Mapa de abundancia para el endmember vegetación. Finalmente, la Figura 5.3 muestra los mapas de abundancia empleados para la generación de la segunda imagen sintética utilizada en los experimentos, que 54 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables comprende mapas para cinco endmembers simulados (cuatro tipos de vegetación y suelo). De nuevo, la relación SNR en la imagen simulada (tras el proceso de simulación de ruido) es de 110:1 y el número de bandas es de 224, comprendidas entre 0.4 y 2.5 micrómetros. El tamaño total de la imagen es, de nuevo, de 4.27 MB. 100 r1 r2 r1, r2, r5 r2, r5 r1, r3, r5 r3, r5 r2 r2, r4, r5 r3, r4, r5 r3 r1 r5 a) r3 100 r1, r5 r4, r5 r4 r4 r5 1.0 0.5 0.0 b) c) d) e) f) Figura 5.3: Segunda imagen sintética. a) Distribución en la imagen de los cinco píxels puros (endmembers), denotados como r1 , r2 , r3 , r4 y r5 . b-f) Mapas de abundancia empleados en la generación de la segunda imagen sintética. 5.1.2. Imagen real La imagen real seleccionada para validar el algoritmo PPI en el presente trabajo fue obtenida por el sensor AVIRIS sobre la región Indian Pines, Indiana, en el año 1992. La imagen consta de 145x145 pixels de 17 metros, cada uno de los cuales contiene 220 valores de radiancia en el rango 0.4 a 2.5 µm. Los valores de la relación SNR en los diferentes canales del sensor AVIRIS en el año en que se tomó la imagen han sido mostrados con anterioridad en la Figura 2.3. Como puede apreciarse en dicha figura, esta imagen representa un caso de estudio en que el la relación SNR resulta desfavorable. La Figura 5.4 muestra una banda concreta de la imagen junto con sus clases de verdad terreno asociadas. Esta información ha sido hecha pública a la Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 55 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables comunidad científica (http://cobweb.ecn.purdue.edu/~biehl/MultiSpec/). Como puede apreciarse en la Figura 5.4, la mayor parte de la escena está constituida por cultivos agrícolas (soja y maíz), bosques y otros tipos de vegetación. Conviene destacar que, en imágenes reales no resulta tan sencillo realizar la estimación de los píxeles puros, ya que esta imagen está formada por píxels con resolución espacial de 17 metros, lo cual hace pensar que la mayor parte de los píxels en la escena serán píxels mezcla. En cualquier caso, consideramos interesante realizar un estudio preliminar de la posibilidad de detectar los píxels más puros presentes en la imagen real. Figura 5.5: Imagen hiperespectral real obtenida por AVIRIS sobre la región Indian Pines en Indiana, Estados Unidos, con las clases verdad-terreno superimpuestas. 5.2. Arquitecturas GPU empleadas en el estudio Las características de los dos modelos de GPUs empleados en el estudio (NVidia GeForce 8600 GT y NVidia GeForce 8800 GTX) aparecen comparadas en la Tabla 5.1. Como podemos observar, la GeForce 8800 GTX posee unas características mucho más elevadas que la 8600 GT, ya que esta última es una GPU de gama baja. Estas características serán decisivas en los resultados de nuestra aplicación, como podremos ver en la siguiente sección. Por otra parte, la Tabla 5.2 compara las características de las dos CPUs respectivamente utilizadas con cada tarjeta. Por razones ilustrativas, destacamos que la versión del software ENVI utilizada en los experimentos ha sido la 4.2. Finalmente, la versión del compilador utilizada para el desarrollo de los experimentos es el Microsoft Visual Studio .Net 2005. 56 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables GPU 8600 GT 8800 GTX Procesadores tipo "stream" 32 128 Reloj central (MHz) 540 575 Reloj de las unidades de sombreado (MHz) 180 1350 Reloj de la Memoria (MHz) 700 900 256MB GDDR3 768MB GDDR3 128-bit 384-bit 22.4 86.4 8.6 36.8 Memoria Interfaz de Memoria Ancho de banda de Memoria (GB/s) Tasa de relleno millones/s) de texturas (miles de Tabla 5.1: Comparativa de características de GPUs GeForce 8600 GT y 8800 GTX. CPU Core 2 Quad Core 2 Duo 4 2 2 GB 2 GB 2.40 GHz 2.40 GHz Nº de procesadores Memoria RAM Frecuencia de CPU Tabla 5.2: Comparativa de características CPUs empleadas en los experimentos. 5.3. Estudio experimental El presente apartado se organiza de la siguiente forma. En un primer experimento, nos centramos en los resultados relativos a la precisión de las diferentes versiones del algoritmo PPI consideradas (ENVI, C y CUDA) a la hora de identificar los píxels puros en las imágenes simuladas. En un segundo experimento, analizamos la precisión de los algoritmos considerados a la hora de identificar los píxels puros en la imagen real. Finalmente, en un tercer experimento analizamos el rendimiento computacional de los algoritmos desarrollados en las diferentes arquitecturas CPU y GPU consideradas, estableciendo comparativas entre las versiones paralelas y serie en términos del rendimiento computacional y speedup entre dichas versiones. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 57 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 5.3.1. Primer experimento: análisis precisión (imágenes sintéticas) En este experimento analizamos la precisión obtenida en la tarea de detectar los píxels puros en las imágenes sintéticas por las tres versiones del algoritmo PPI, con vistas a evaluar si la versión en GPU (desarrollada en CUDA) proporciona resultados aceptables con respecto a las versiones C y ENVI. Con vistas a comparar de forma cuantitativa los resultados, utilizamos una medida de acierto que denominamos ratio de acierto. Esta medida está basada en que en las imágenes sintéticas conocemos a priori la ubicación de los píxels puros. Por ello, podemos cuantificar, para cada proyección aleatoria generada por una determinada versión del algoritmo PPI, si dicha proyección resulta en la selección de un píxel totalmente puro, en cuyo caso incrementamos un contador de acierto (inicializado al valor 0) en una unidad. En caso contrario, el contador permanece inalterado. Al final del proceso, el ratio de acierto viene dado por el cociente entre el valor del contador de acierto y el número de proyecciones realizadas. También hemos considerado un ratio de acierto alternativo que pretende evaluar el proceso de identificación de proyecciones de forma un poco más detallada. La idea es la siguiente: dado que en las imágenes sintéticas se conoce el grado de pureza de cada píxel, puesto que las abundancias a nivel píxel han sido generadas de forma controlada, en el caso de que una determinada proyección no proporcione un píxel totalmente puro, es posible estudiar el grado de pureza del píxel seleccionado. Por ejemplo, tomando como ejemplo la primera imagen simulada, si una proyección selecciona un píxel en la segunda columna situada desde la parte izquierda de la imagen, es claro que dicha proyección no ha proporcionado un píxel totalmente puro ya que dichos píxels se encuentran ubicados en la primera y última columnas de la imagen. Sin embargo, en este caso la proyección habría seleccionado un píxel casi puro, con una fracción de abundancia de 0.99 (sobre 1.0) para un endmember y 0.01 (sobre 1.0) para el otro, por lo que el resultado está muy cerca de lo que cabría esperar. No obstante, si una determinada proyección selecciona un píxel en la columna central de la misma imagen, en este caso podemos decir que la proyección ha dado como resultado un píxel mezcla, con fracción de abundancia de 0.5 (sobre 1.0) para un endmember y de 0.5 (sobre 1.0) para el otro. Por tanto, en este caso la proyección no resulta tan adecuada como en el caso anterior (segunda columna). 58 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Con vistas a incorporar este aspecto en la evaluación cuantitativa de los algoritmos, proponemos la utilización de un ratio de acierto modificado en el que el contador de acierto no solamente se incrementa en una unidad, como era el caso en el ratio de acierto original, sino que puede incrementarse en fracciones de una unidad dependiendo del grado de pureza del píxel seleccionado en la proyección. Así, si el píxel seleccionado es totalmente puro (por ejemplo, un píxel en la columna situada más a la izquierda en la primera imagen simulada), el contador de acierto se incrementa en una unidad. Si el píxel seleccionado es totalmente mezcla (por ejemplo, un píxel en la columna situada en el centro de la primera imagen simulada), el contador de acierto no se incrementa. Finalmente, si el píxel seleccionado no es totalmente puro ni totalmente mezcla (por ejemplo, un píxel en la segunda columna situada desde la parte izquierda de la primera imagen simulada) el contador de pureza se incrementa de forma proporcional a la pureza del píxel, que se considera comprendida entre los dos casos extremos anteriormente mencionados (incremento en una unidad para un píxel puro e incremento en cero unidades para un píxel mezcla). De esta forma, podemos cuantificar de forma más precisa el funcionamiento del algoritmo sin restringir nuestro análisis a la selección de píxels exclusivamente puros. Teniendo en cuenta este esquema de validación, la Figura 5.6 muestra las imágenes de pureza (en escala de grises) proporcionadas para las versiones ENVI, C y CUDA del algoritmo PPI, para distinto número de proyecciones (1000 y 10000). Conviene destacar que las versiones C y CUDA siempre proporcionan exactamente los mismos resultados puesto que la versión CUDA se obtiene a partir de la versión C. Asimismo, sólo se muestran los resultados de la versión GPU GeForce 8800, ya que los resultados de las versiones ejecutadas en las CPUs y en la GeForce 8600 GT coinciden con los de dicha GPU. En la Figura 5.6, los píxels con mayor valor de intensidad han sido seleccionados un mayor número de veces, mientras que los píxels en negro no han sido nunca seleccionados. Como puede apreciarse, en ambos casos (versión ENVI y versión C/CUDA) la selección de píxels puros se concentra en las columnas primera y última de la imagen simulada, indicando que las diferentes versiones del algoritmo tienden a concentrar sus selecciones en las columnas que contienen los píxels puros de la imagen. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 59 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Iteraciones 1000 10000 Versión EVI Versión C/CUDA Figura 5.6: Imágenes con el índice de pureza calculado para cada píxel por las versiones ENVI, C (en las dos CPUs consideradas) y CUDA (en las dos GPUs consideradas) para la primera imagen simulada. Un aspecto destacable en relación a los resultados presentados en la Figura 5.6 es el hecho de que, como puede apreciarse, la selección de píxels en ambos casos no es idéntica. Esto se debe a que la versión ENVI utiliza un proceso de selección basado en una distribución de probabilidad a la hora de generar los vectores aleatorios que no es conocida (dado el carácter propietario del software) y también al hecho de que ENVI aplica un proceso (denominado Fast PPI) para incrementar el número de píxels que se seleccionan en cada proyección como puros. En la descripción original del algoritmo [9], los autores indican que para cada proyección el máximo de píxels etiquetados es de 2 (los píxels que resultan en los valores de proyección máxima y mínima). No obstante, en la versión Fast PPI de ENVI el número de píxels seleccionados depende de un valor umbral, lo cual hace que para un mismo número de proyecciones dicha versión seleccione muchos más candidatos. Este efecto se ilustra gráficamente en la Figura 5.7, en la que se muestran los píxels que han sido seleccionados al menos una vez por las versiones ENVI y C/GPU del algoritmo PPI. 60 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Iteraciones 1000 10000 Versión EVI Versión C/CUDA Figura 5.7: Imágenes indicando los píxels que han sido seleccionados al menos una vez como puros por las versiones ENVI, C (en las dos CPUs consideradas) y CUDA (en las dos GPUs consideradas) para la primera imagen simulada. Como puede apreciarse en la Figura 5.7, si bien la versión ENVI del algoritmo PPI resulta en un mayor número de píxels seleccionados para el mismo número de proyecciones, es claro que muchas de las selecciones se encuentran ubicadas en columnas centrales (y por tanto, menos puras) de la primera imagen simulada. Por otra parte, la versión C/GPU presenta resultados más centrados en las zonas izquierda y derecha de la imagen, lo cual sugiere que las proyecciones realizadas pueden ser más efectivas ya que solamente los píxels realmente extremos son seleccionados, mientras que en la versión ENVI no solamente los extremos, sino también aquellos píxels que están cercanos a los valores de proyección extremos (según un determinado valor umbral aplicado como parámetro de entrada) son marcados como extremos durante el proceso. Con vistas a ofrecer una medida cuantitativa acerca de la precisión en el proceso de selección de píxels puros, la Figura 5.8 muestra el ratio de acierto modificado para la versión GPU del algoritmo PPI con distintos números de iteraciones. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 61 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Ratio Ratio de Acierto PPI GPU en CS1_RAD_SNR110.bsq 1 0,8 0,6 0,4 0,2 0 1000 10000 Iteraciones Figura 5.8: Ratio de acierto modificado para la versión GPU del algoritmo PPI, aplicado sobre la primera imagen simulada, con distintos números de iteraciones. Como puede apreciarse en la Figura 5.8, el ratio de acierto para la versión GPU del algoritmo PPI es de aproximadamente 0.92 (sobre 1.0), manteniéndose estable para diferentes números de iteraciones. Este resultado indica que la precisión de la versión GPU del algoritmo PPI a la hora de seleccionar los píxels puros de la imagen es bastante alta. Aún teniendo presente que muchas proyecciones (por su carácter aleatorio) no pueden seleccionar los píxels más extremos, la mayor parte de dichas proyecciones consiguen seleccionar los píxels más puros disponibles. También es importante destacar que los ratios de acierto modificados para la versión ENVI no pueden ser obtenidos dado el carácter propietario del software, que impide analizar este hecho de forma cuantitativa dado que no se puede acceder al código del algoritmo. No obstante, los resultados mostrados visualmente en la Figura 5.7 nos permiten anticipar que la versión ENVI da como resultado muchas más selecciones en zonas de la imagen con alta presencia de píxels no puros, y por tanto pensamos que el ratio de acierto modificado de la versión ENVI puede ser más bajo que el valor de 0.92 (sobre 1.0) obtenido por la versión en GPU. A continuación, repetimos el proceso de evaluación para la segunda imagen simulada, teniendo en cuenta que esta imagen presenta un mayor grado de dificultad ya que el número de endmembers aumenta pero el número total de píxels puros disminuye. Mientras que en la primera imagen simulada había un total de 200 píxels puros, 100 de ellos ubicados en la primera columna y 100 de ellos en la última columna, en la segunda imagen simulada el número de píxels puros se limita a 5 (uno en cada esquina y uno en el centro) lo cual a priori reduce las posibilidades de 62 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables identificar dichos píxels con respecto al caso anterior, y más si tenemos en cuenta que el tamaño de las imágenes es exactamente igual (100x100 píxels) con lo que el ratio de píxels puros frente al total de píxels de la imagen es mucho menor para la segunda imagen simulada. Iteraciones 1000 10000 Versión EVI Versión C/CUDA Figura 5.9: Imágenes con el índice de pureza calculado para cada píxel por las versiones ENVI, C (en las dos CPUs consideradas) y CUDA (en las dos GPUs consideradas) para la segunda imagen simulada. Teniendo en cuenta el esquema de validación aplicado para la primera imagen simulada, la Figura 5.9 muestra las imágenes de pureza (en escala de grises) proporcionadas para las versiones ENVI, C y CUDA del algoritmo PPI, para distinto número de proyecciones (1000 y 10000). De nuevo, las versiones C y CUDA proporcionan exactamente los mismos resultados. Asimismo, sólo se muestran los resultados de la versión GPU GeForce 8800, ya que los resultados de las versiones Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 63 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables ejecutadas en las CPUs y en la GeForce 8600 GT de nuevo coinciden con los de dicha GPU. Como puede apreciarse, en ambos casos (versión ENVI y versión C/CUDA) la selección de píxels puros se concentra en las esquinas y en el centro de la imagen simulada, indicando que las diferentes versiones del algoritmo tienden a concentrar sus selecciones alrededor de las ubicaciones que contienen los píxels puros de la imagen. Iteraciones 1000 10000 Versión EVI Versión C/CUDA Figura 5.10: Imágenes indicando los píxels que han sido seleccionados al menos una vez como puros por las versiones ENVI, C (en las dos CPUs consideradas) y CUDA (en las dos GPUs consideradas) para la segunda imagen simulada. Ante la similitud aparente de los resultados mostrados en la Figura 5.9 y, al igual que en el experimento anterior, la Figura 5.10 muestra los píxels que han sido seleccionados al menos una vez por las versiones ENVI y C/GPU del algoritmo PPI en la segunda imagen simulada. De nuevo puede apreciarse en la Figura 5.10 que, si bien la versión ENVI del algoritmo PPI resulta en un mayor número de píxels seleccionados para el mismo número de proyecciones, es claro que muchas de las selecciones se encuentran ubicadas en zonas no cercanas a las esquinas y al centro (y por tanto, menos puras) de la segunda imagen simulada. Por otra parte, la versión 64 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables C/GPU presenta resultados más centrados en dichas zonas, lo cual de nuevo sugiere que las proyecciones realizadas pueden ser más efectivas. La Figura 5.11 muestra el ratio de acierto modificado para la versión GPU del algoritmo PPI con distintos números de iteraciones. Como puede apreciarse en la Figura 5.11, el ratio de acierto para la versión GPU del algoritmo PPI es de aproximadamente 0.99 (sobre 1.0), manteniéndose estable para diferentes números de iteraciones. Este resultado indica que la precisión de la versión GPU del algoritmo PPI a la hora de seleccionar los píxels puros de la segunda imagen simulada es muy elevada. De nuevo, los resultados mostrados visualmente en la Figura 5.10 nos permiten anticipar que la versión ENVI da como resultado muchas más selecciones en zonas de la imagen con alta presencia de píxels no puros, y por tanto pensamos que el ratio de acierto modificado de la versión ENVI puede ser más bajo que el valor de 0.99 (sobre 1.0) obtenido por la versión en GPU. Ratio de Acierto PPI GPU CS2_RAD_SNR110.bsq 1 Ratio 0,8 0,6 0,4 0,2 0 1000 10000 Iteraciones Figura 5.11: Ratio de acierto modificado para la versión GPU del algoritmo PPI, aplicado sobre la segunda imagen simulada, con distintos números de iteraciones. 5.3.2. Segundo experimento: análisis precisión (imagen real) En este experimento, procuramos repetir los mismos pasos realizados para imágenes sintéticas. La Figura 5.12 muestra las imágenes de pureza (en escala de grises) proporcionadas para las versiones ENVI, C y CUDA del algoritmo PPI, para distinto número de proyecciones (1000 y 10000) obtenidas al aplicar el algoritmo sobre la imagen real de Indian Pines. De nuevo, las versiones C y CUDA proporcionan Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 65 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables exactamente los mismos resultados y sólo se muestran los resultados de la versión GPU GeForce 8800, ya que los resultados de las versiones ejecutadas en las CPUs y en la GeForce 8600 GT de nuevo coinciden con los de dicha GPU. Como puede apreciarse, en ambos casos (versión ENVI y versión C/CUDA) la selección de píxels puros se concentra en una serie de zonas determinadas de la imagen. Si comparamos dichas zonas con la verdad terreno para la imagen Indian Pines, mostrada en la Figura 5.5, podemos apreciar que no existe correlación entre las zonas etiquetadas en la verdad terreno y la presencia de píxels puros. Es más, los píxels puros parecen concetrarse en determinadas zonas muy localizadas de la imangen. Este hecho puede deberse a la escasa presencia de píxels puros en la imagen, debido a la escasa cobertura del suelo de los cultivos agrícolas presentes en la imagen (en etapa muy temprana de crecimiento y con una cobertura aproximada del suelo del 5%). De este modo, los resultados extraídos permiten anticipar que las zonas puras de suelo han sido favorecidas durante el proceso de selección de extremos, y no existe una forma intuitiva de establecer una correlación entre las zonas seleccionadas por el algoritmo PPI y la información verdad terreno disponible a priori. Iteraciones 1000 10000 Versión Envi Versión C/CUDA Figura 5.12: Imágenes con el índice de pureza calculado para cada píxel por las versiones ENVI, C (en las dos CPUs consideradas) y CUDA (en las dos GPUs consideradas) para la imagen real. 66 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Teniendo presente esta circunstancia y la dificultad de evaluar el rendimiento del algoritmo con la imagen real, dada la escasa información disponible a priori acerca de la ubicación de los píxels puros, hemos optado por retrasar la toma de decisiones significativas en base a los experimentos con imágenes reales a un futuro estudio, supeditado a la disponibilidad de información más detallada sobre la ubicación de píxels puros en dichas imágenes. En este sentido, consideramos que el estudio realizado con imágenes simuladas resulta suficiente para obtener una idea precisa acerca del rendimiento de la versión GPU desarrollada, en particular, dada la disponibilidad de información verdad terreno de calidad acerca de la pureza de los píxels considerados, la cual está disponible gracias al proceso controlado que se ha seguido a la hora de simular dichas imágenes. 5.3.3. Tercer experimento: análisis de rendimiento En este experimento analizamos el rendimiento computacional de las diferentes implementaciones consideradas. En primer lugar comparamos los tiempos de unas ejecuciones con respecto a otras para, a continuación, mostrar los speedups (incrementos de rendimiento) obtenidos para las versiones GPUs en función del tiempo de ejecución medido en la CPU y en la GPUs. La Figura 5.13 muestra los tiempos de ejecución obtenidos en el procesamiento de la primera imagen simulada por parte de las diferentes implementaciones del algoritmo PPI. Es preciso destacar que todas las implementaciones utilizan exactamente la misma configuración en cuanto a los parámetros de entrada del algoritmo, adoptando el mayor número de iteraciones consideradas en los experimentos con la primera imagen simulada y un valor umbral de 5. En concreto, las implementaciones que se han evaluado en este estudio experimental acerca del rendimiento son las siguientes: • Versión ENVI del algoritmo PPI. • Versión C del algoritmo PPI implementada en una CPU Core 2 Quad. • Versión C del algoritmo PPI implementada en una CPU Core 2 Duo. • Versión CUDA del algoritmo PPI implementada en una GPU 8600 GT. • Versión CUDA del algoritmo PPI implementada en una GPU 8800 GTX. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 67 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Tiempos de Ejecución CS1_RAD_SNR110.bsq 350 Segundos 300 250 GPU 8800 GTX 200 Envi GPU 8600 GT 150 CPU Core 2 Quad CPU Core 2 Duo 100 50 0 1000 5000 10000 15000 Nº de Iteraciones Figura 5.13: Tiempos de ejecución obtenidos por las diferentes versiones del algoritmo PPI con la primera imagen simulada. Como podemos observar en la Figura 5.13, a medida que el número de iteraciones aumenta, los tiempos obtenidos aumentan de forma lineal. Para un número moderado de iteraciones, los mejores tiempos son siempre obtenidos por la versión en la GPU GeForce 8800 GTX, seguido del tiempo obtenido por ENVI y la GPU 8600 GT. Los peores resultados de tiempo los producen las CPUs, como era previsible, siendo del orden de 3 veces más lentas que la mejor versión en la GPU. Conviene destacar que los buenos resultados obtenidos por la versión ENVI parecen deberse a un proceso de optimización interno aplicado por el software que no podemos evaluar dado el carácter propietario del mismo. Sin embargo, la Figura 5.14 revela que el speedup obtenido por la versión GPU GeForce 8800 GTX con respecto a las dos CPUs consideradas está siempre en torno a 3, indicando que se ha podido acelerar el rendimiento del algoritmo de forma significativa con respecto a la versión serie. También resulta destacable el hecho de que los speedups obtenidos por la versión desarrollada en la GPU no sean tan significativos, lo cual indica que la tecnología CUDA está específicamente adaptada para tarjetas de la gama 8800 o superior, mientras que generaciones anteriores de GPUs no pueden obtener beneficios significativos de esta tecnología, de reciente creación, y optimizada para tarjetas NVidia de gama superior. 68 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Speed-up GPUs vs Core 2 Quad CS1_RAD_SNR110.bsq T_Core / T_GPU 3 2 ,5 2 GPU 8800 GTX 1,5 GPU 8600 GT 1 0 ,5 0 10 0 0 5000 10 0 0 0 15 0 0 0 Nº de Iteraciones Speed-up GPUs vs Core 2 Duo CS1_RAD_SNR110.bsq T_Core / T_GPU 3 2 ,5 2 GPU 8800 GTX 1,5 GPU 8600 GT 1 0 ,5 0 10 0 0 5000 10 0 0 0 15 0 0 0 Nº de Iteraciones Figura 5.14: Speedup (tiempo de la versión CPU dividido por el tiempo de la versión GPU) obtenido por la implementación en la GPU 8800 GTX con respecto a las implementaciones en la CPU Core 2 Quad (parte superior) y en la CPU Core 2 Duo (parte inferior) para la primera imagen simulada. Como podemos comprobar en la Figura 5.14, los speedups obtenidos por parte de la GPU 8800 GTX son estables con respecto al número de iteraciones aplicadas por el algoritmo y también con respecto al modelo de CPU considerado. Por su parte, la Figura 5.15 muestra los tiempos de ejecución obtenidos en el procesamiento de la segunda imagen simulada por parte de las diferentes implementaciones del algoritmo PPI. Como cabría esperar, dado que las dimensiones de la segunda imagen son idénticas a las de la primera a pesar de que esta imagen sintética es más compleja, ya que contiene un mayor número de endmembers, ese factor no influye en el tiempo de ejecución del algoritmo. Los resultados obtenidos son similares a los del anterior experimento. Finalmente, la Figura 5.16 muestra los resultados en base a los valores de speedup, que se mantienen estables con respecto a las dos versiones de CPU. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 69 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Tiempos de Ejecución CS2_RAD_SNR110.bsq 35 0 30 0 25 0 s o 20 0 d n u g 15 0 e S10 0 GP U 8800 GTX E nvi GP U 8600 GT CP U Core 2 Quad CP U Core 2 Duo 50 0 1 000 50 00 10 000 150 00 Nº de Ite ra ciones Figura 5.15: Tiempos de ejecución obtenidos por las diferentes versiones del algoritmo PPI con la segunda imagen simulada. Speed-up GPUs vs Core 2 Quad CS2_RAD_SNR110.bsq T_Core / T_GPU 3 2 ,5 2 GPU 8800 GTX 1,5 GPU 8600 GT 1 0 ,5 0 10 0 0 5000 10 0 0 0 15 0 0 0 Nº de Iteraciones Speed-up GPUs vs Core 2 Duo CS2_RAD_SNR110.bsq T_Core / T_GPU 3 2 ,5 2 GPU 8800 GTX 1,5 GPU 8600 GT 1 0 ,5 0 10 0 0 5000 10 0 0 0 15 0 0 0 Nº de Iteraciones Figura 5.16: Speedup (tiempo de la versión CPU dividido por el tiempo de la versión GPU) obtenido por la implementación en la GPU 8800 GTX con respecto a las implementaciones en la CPU Core 2 Quad (parte superior) y en la CPU Core 2 Duo (parte inferior) para la segunda imagen simulada. 70 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Finalmente, mostramos los resultados de rendimiento obtenidos con la imagen real. Esta imagen es la más compleja de todas, ya que los endmembers son difíciles de estimar y encontrar, ya que la imagen está formada por una gran variedad de clases diferentes de imágenes, como se explicó en el punto anterior de esta sección. La Figura 5.17 muestra los tiempos de ejecución obtenidos, que revelan una diferencia sustancial en cuanto al rendimiento computacional ofrecido por la GPU 8800 GTX con respecto al resto de implementaciones. Mientras que los demás siguen manteniendo una diferencia más o menos similar con respecto a los casos anteriores (imágenes simuladas), en el experimento con imagen real esta GPU parece actuar más rápido, produciendo una diferencia de algo más del doble de rapidez con respecto a la segunda mejor ejecución, la de ENVI, y es más de tres veces más rápida que las versiones CPU en este experimento. Tiempos de Ejecución Purdue.bsq 700 Segundos 600 500 GPU 8800 GTX 400 Envi GPU 8600 GT 300 CPU Core 2 Quad CPU Core 2 Duo 200 100 0 1000 5000 10000 15000 Nº de Iteraciones Figura 5.17: Tiempos de ejecución obtenidos por las diferentes versiones del algoritmo PPI con la imagen real. Este efecto también se aprecia en los resultados de speedup mostrados en la Figura 5.18, en las que las que se aprecia cómo la versión en la GPU 8800 GTX es más de tres veces más rápida que la versión en las CPUs. A pesar del incremento de rendimiento obtenido en los experimentos, pensamos que los resultados de speedup son moderados y que dichos resultados pueden mejorarse de forma sustancial en futuras implementaciones del algoritmo, en las que el código CUDA deberá modificarse para aprovechar mejor los recursos hardware disponibles en la GPU. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 71 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Speed-up GPUs vs Core 2 Quad Purdue.bsq T_Core / T_GPU 3 ,5 3 2 ,5 2 GPU 8800 GTX GPU 8600 GT 1,5 1 0 ,5 0 10 0 0 5000 10 0 0 0 15 0 0 0 Nº de Iteraciones Speed-up GPUs vs Core 2 Duo Purdue.bsq T_Core / T_GPU 3 ,5 3 2 ,5 2 GPU 8800 GTX GPU 8600 GT 1,5 1 0 ,5 0 10 0 0 5000 10 0 0 0 15 0 0 0 Nº de Iteraciones Figura 5.18: Speedup (tiempo de la versión CPU dividido por el tiempo de la versión GPU) obtenido por la implementación en la GPU 8800 GTX con respecto a las implementaciones en la CPU Core 2 Quad (parte superior) y en la CPU Core 2 Duo (parte inferior) para la imagen real. 5.3.4. Discusión global de resultados Una vez presentados los resultados obtenidos en nuestro estudio experimental, procedemos a discutirlos de forma global con carácter previo a la presentación de las principales conclusiones extraídas a partir de la realización del presente estudio, las cuales serán descritas en el siguiente capítulo de la memoria. Con respecto a los resultados de precisión, conviene destacar que las imágenes obtenidas como resultado de ejecutar nuestra versión de PPI no parecen, a simple vista, ofrecer tanta información como la que ofrecen los resultados de ENVI. No obstante, como se ha comentado a la hora de presentar dichos resultados, pensamos que el principal motivo de este hecho es que la versión ENVI utiliza un criterio modificado a la hora de aplicar el valor umbral para el algoritmo. En nuestra 72 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables implementación, un valor de umbral alto resulta en pocos píxeles escogidos como píxeles extremos, ya que nuestro criterio de umbral se basa en coger todos los píxeles que superen dicho umbral. Por otra parte, en la versión ENVI un valor de umbral alto resulta en muchos píxels seleccionados, ya que en ENVI se toma el máximo y el mínimo, así como todos los píxeles que esten a distancia umbral de dichos valores en cada iteración. Esto provoca que mientras que en una iteración de nuestra versión sólo escogemos dos píxeles extremos, ENVI puede llegar a seleccionar decenas de ellos. Sin embargo, este enfoque puede no dar resultados más precisos en cuanto a la eficacia a la hora de seleccionar los píxels puros, como hemos destacado en el estudio. En este sentido, cabe destacar que nuestras versiones de PPI quizás seleccionan menos píxeles extremos de las imágenes; sin embargo, los píxeles que son marcados, tienen una altísima probabilidad de que sean píxeles extremos. Esto aparece reflejado en los valores de ratio de acierto modificados mostrados en nuestro estudio experimental, los cuales por ejemplo para la segunda imagen simulada rozan la perfección. Como trabajo futuro, se recomienda hacer una comparativa de los ratios obtenidos por nuestras implementaciones con respecto a los obtenidos por la versión ENVI. En este estudio, sin embargo, dicho análisis no fue posible debido al carácter propietario del software ENVI. Con respecto a los resultados de rendimiento computacional, en todos los experimentos realizados se puede apreciar una clara mejora de tiempo de la implementación en la GPU GeForce 8800 GTX con respecto al resto de versiones. Con esto, queda probada la eficacia de la GPU frente a otros tipos de ejecuciones, con lo que podemos optar por hacer uso de la misma para estos tipos de cálculos, sin miedo a obtener peores resultados de tiempo. Sin embargo, si nos fijamos en los resultados proporcionados por la otra GPU, la GeForce 8600 GT, vemos que los resultados obtenidos son peores, a pesar de seguir siendo algo más rápida que las ejecuciones por CPU, independientemente de que la tecnología CUDA esté optimizada para tarjetas de gama alta (8800 y superior). Esto indica que la selección de la tarjeta a utilizar será clave en nuestra aplicación y que, en líneas generales, debemos hacer uso de tarjetas de gama alta, que tienen un coste más elevado que el habitual, pero que a cambio nos ofrecen unos resultados superiores. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 73 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables Otra observación relevante a partir del estudio se refiere a los resultados obtenidos por las implementaciones realizadas en las dos CPUs consideradas. El tiempo de ejecución obtenido en ambos es prácticamente el mismo, cuando lo que todos esperaríamos realmente, es que los resultados obtenidos con el procesador Core 2 Quad fueran mucho más rápidos que los del Core 2 Duo. La explicación a este hecho se basa en la siguiente observación: para que un procesador Core 2 Quad alcance su máximo rendimiento, debe tener acivada por parte del administrador del equipo la opción Core Multiplexing Technology que nos permite ejecutar CPUs multi núcleo como si fuese una sola, y le permite ejecutar hilos de procesamiento en paralelo. Mientras esto no se haga, o el sistema operativo no sea compatible al 100% con este tipo de procesadores, entonces no podemos realmente optimizar este aspecto y obtendremos resultados similares a los mostrados en este estudio. Con respecto a los resultados de speedups, si bien es cierto que los resultados obtenidos son adecuados, pensamos que dichos resultados pueden mejorarse en futuros estudios mediante una optimización del código desarrollado en CUDA. Por otra parte, nuestros experimentos también indican que la GPU 8800 GTX tiene unas prestaciones claramente superiores a las de las 8600 GT. Como ya hemos visto, la 8800 GTX posee 128 procesadores de flujo frente a los 32 de la 8600 GT, es decir, 4 veces más. Esto podría hacernos llegar a pensar que por este hecho, los resultados de la primera GPU deberían ser del orden de 4 veces más rápidos; sin embargo, debemos darnos cuenta de que la velocidad de trabajo de la tarjeta no sólo recae en este parámetro, sino en él también influyen el resto de parámetros indicados en el primer punto de esta sección, y particularmente en parámetros como el reloj central, el reloj de la memoria o la interfaz de memoria. Este hecho justifica la diferencia en velocidad en torno a 3 órdenes de magnitud en lugar de 4 como cabría esperar al comparar ambas tarjetas, las cuales pertenecen a generaciones diferentes. Precisamente, este hecho permite anticipar mejoras sustanciales con las nuevas generaciones de GPUs. 74 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 6. Conclusiones y líneas futuras de trabajo En la presente memoria se realizado un estudio comparativo de diferentes alternativas para implementar el algoritmo PPI, ampliamente utilizado en la comunidad científica dedicada al análisis de imágenes hiperespectrales obtenidas por sensores remotos de observación de la tierra. En concreto, se han desarrollado nuevas implementaciones GPU del algoritmo utilizando tarjetas NVidia de diferentes generaciones (GeForce 8800 GTX y GeForce 8600 GT), las cuales integran una nueva arquitectura CUDA que ofrece una nueva vía de trabajo para desarrollar cálculos científicos de forma eficiente utilizando la tarjeta gráfica como un coprocesador. En virtud de los resultados experimentales presentados en el estudio, las principales aportaciones del presente trabajo pueden resumirse a continuación: • Después de analizar los resultados del estudio comparativo realizado, podemos concluir que la mejor solución con respecto al tiempo de procesamiento es la ofrecida por la GPU GeForce 8800 GTX. Por otra parte, los reultados sensiblemente inferiores proporcionados por la GPU GeForce 8600 GT permiten anticipar que los resultados obtenidos dependem en gran parte de la potencia de la GPU y las características de la misma, ya que los resultados obtenidos con una GPU perteneciente a una generación anterior no resultan del todo satisfactorios. • En cuanto a los resultados de precisión, podemos concluir que los resultados proporcionados por las versiones GPU desarrolladas son comparables a los proporcionados por la versión original (ENVI) del algoritmo, con similares prestaciones en cuanto a la selección de píxels puros y con un menor ratio de píxels mezcla seleccionados durante el proceso, lo cual resulta del mecanismo de optimización aplicado por la versión ENVI que incrementa el número de píxels seleccionados durante el proceso pero no necesariamente su pureza. • Conviene destacar, llegados a este punto, las ventajas económicas que la implementación GPU ofrece con respecto a otras soluciones paralelas como las basadas en clusters de computadores. En concreto, Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 75 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables mientras que el precio de una GPU de última generación se sitúa en torno a los 300 euros, el precio de un cluster puede ser mucho mayor, además de resultar en una serie de condiciones desfavorables desde el punto de vista de su implantación como módulo de procesamiento a bordo del sensor, con diferentes aspectos que pueden afectar de forma negativa al payload de la misión (peso, consumo energético, calentamiento, mantenimiento, etc.) En este sentido, las GPUs ofrecen una solución mucho más compacta, si bien es cierto que es preciso realizar un estudio detallado de las condiciones de tolerancia de las GPUs a requimientos extremos en cuanto a consumo y sensibilidad a radiación, necesario a la hora de calibrar la adaptabilidad de esta plataforma hardware especializada a misiones reales de observación remota de la tierra. • Como resultado de nuestro estudio, se han aplicado todas las métricas de precisión y rendimiento computacional a una batería de imágenes simuladas (con información muy precisa acerca de la ubicación de los píxels puros) y reales y se ha realizado un detallado estudio comparativo en términos de precisión y rendimiento computacional de las diferentes implementaciones planteadas (ENVI, C y CUDA), ofreciendo resultados que pueden ser relevantes para la comunidad científica y, en particular, para la comunidad dedicada a implementación eficiente de algoritmos de análisis hiperespectral. Para concluir este capítulo, planteamos algunas líneas futuras de trabajo adicionales que serían interesante perseguir en futuras ampliaciones de este proyecto: • Se ha hablado de que la principal ventaja de la implementación GPU con respecto al uso de cluster es el aspecto económico; sin embargo no se ha podido realizar ningún tipo de comparación real entre ambas soluciones en cuanto resultados y tiempos de ejecución, luego sería interesante realizar dicho estudio en el futuro. • Una alternativa interesante a la metodología propuesta viene dada por la posibilidad de implementar algoritmos paralelos en clusters de GPUs, aprovechando las ventajas de ambos paradigmas de computación paralela. 76 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables • Por otra parte, y con vistas a extrapolar los resultados obtenidos en el estudio a otras aplicaciones, otra línea futura de trabajo deberá consistir en probar la implementación GPU con distintos tipos de imágenes (uno de los problemas de CUDA, es que hoy por hoy no dispone de funciones para realizar la carga de ficheros de imágenes directamente en espacios de memoria, excepto para las imágenes de tipo PPM y PGM, con lo cual se produce una carga de imagen quizá poco optimizada). • Finalmente, como línea futura de trabajo se propone optimizar la versión CUDA actualmente disponible utilizando diferentes estrategias. Por ejemplo, la versión presentada en este PFC sólo usa la GPU para realizar el cálculo escalar; pero también podría estudiarse la opción de que realizara en la misma otras operaciones, tales como la búsqueda del máximo y el mínimo por ejemplo. En este PFC se adjunta en los archivos una versión que contempla esta solución; pero no se ha añadido a los resultados por proporcionar peores resultados en cuanto al tiempo de ejecución que los mostrados en el apartado de análisis y discusión de resultados de la presente memoria. Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 77 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 7. Referencias bibliográficas 1. Chang, C.-I, Hyperspectral Imaging: Techniques for Spectral Detection and Classification, Kluwer Academic/Plenum Publishers, 2003. 2. Plaza, A., Chang, C.-I, “Impact of Initialization on Design of Endmember Extraction Algorithms,” IEEE Transactions on Geoscience and Remote Sensing, vol. 44, no. 11, pp. 3397-3407, 2006. 3. Plaza, A., Martínez, P., Pérez, R.M., Plaza, J.. “Spatial/Spectral Endmember Extraction by Multidimensional Morphological Operations”. IEEE Transactions on Geoscience and Remote Sensing, vol. 40, no. 9, pp. 20252041, 2002. 4. Green, R.O. et al., “Imaging spectroscopy and the airborne visible/infrared imaging spectrometer (AVIRIS),” Remote Sens. Environ., vol. 65,pp. 227– 248, 1998. 5. Landgrebe, D., “Hyperspectral Image Data Analysis”, IEEE Signal Processing Magazine, vol. 19, no. 1, pp. 17-28, 2002. 6. Landgrebe, D., “Multispectral Data Analysis, A Signal Theory Perspective” http://dynamo.ecn.purdue.edu/~biehl/MultiSpec/documentation.html, 1998. 7. Goetz, A.F.H., Kindel, B., “Comparison of Unmixing Results Derived from AVIRIS, High and Low Resolution, and HYDICE Images at Cuprite, NV”. En: Proc. IX 4ASA/JPL Airborne Earth Science Workshop, Pasadena, CA, 1999. 8. Goetz, A. F., & Kindel, B. (1999). "Comparison of Unmixing Result Derived from AVIRIS, High and Low Resolution, and HYDICE images at Cuprite, NV". Proc. IX 4ASA/JPL Airborne Earth Science Workshop . 9. Boardman, J., Kruse, F., & Green, R. (1995). "Mapping target signatures via partial unmixing of AVIRIS data". Proc. Summaries JPL Airborne Earth Sci. Workshop , 23-26. 10. Green, R.O. y Pavri, B., “AVIRIS In-Flight Calibration Experiment, Sensitivity Analysis, and Intraflight Stability”, en Proc. IX 4ASA/JPL Airborne Earth Science Workshop, Pasadena, CA, 2000. 78 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 11. Heinz, D. y Chang, C.-I, "Fully constrained least squares linear mixture analysis for material quantification in hyperspectral imagery," IEEE Trans. on Geoscience and Remote Sensing, vol. 39, no. 3, pp. 529-545, March 2001. 12. Plaza, A., Martínez, P., Pérez, R.M., Plaza, J., “A quantitative and comparative analysis of endmember extraction algorithms from hyperspectral data,” IEEE Trans. On Geoscience and Remote Sensing, vol. 42, no. 3, pp. 650-663, March 2004. 13. Bateson, C.A., Curtiss, B., “A method for manual endmember selection and spectral unmixing,” Remote Sensing of Environment, vol. 55, pp.229–243, 1996. 14. Plaza, A., Valencia, D., Plaza, J. y Chang, C.-I, “Parallel Implementation of Endmember Extraction Algorithms from Hyperspectral Data”. IEEE Geoscience and Remote Sensing Letters, vol. 3, no. 3, pp. 334-338, July 2006. 15. Plaza, A., Plaza, J., Valencia, D., “AMEEPAR: Parallel Morphological Algorithm for Hyperspectral Image Classification in Heterogeneous Networks of Workstations.” Lecture 4otes in Computer Science, vol. 3391, pp. 888891, 2006. 16. Setoain, J., Prieto, M., Tenllado, C., Plaza, A., Tirado, F., “Parallel Morphological Endmember Extraction Using Commodity Graphics Hardware,” IEEE Geoscience and Remote Sensing Letters, vol. 43, no. 3, pp. 441-445, 2007. 17. Pérez, R.M., Martinez, P., Plaza, A., Aguilar, P.L. “Systolic Array Methodology for a Neural Model to Solve the Mixture Problem”, in: 4eural 4etworks and Systolic Array Design. Edited by D. Zhang and S.K. Pal. World Scientific, 2002. 18. Lavenier, D., Fabiani, E., Derrien, S., Wagner, C., “Systolic array for computing the pixel purity index (PPI) algorithm on hyper spectral images”. 19. NVIDIA GeForce 8800 GPU Architecture Overview (November 2006 TB02787-001_v0.9) 20. NVIDIA CUDA Compute Unified Device Architecture – Programming Guide, Versión 1.1 (29/11/07) Proyecto Fin de Carrera de Ingeniería Informática – Autor: Hugo María Vegas Carrasco 79 Implementación de algoritmos de tratamiento de imágenes en tarjetas gráficas programables 21. NVIDIA CUDA. Installation and Verification on Microsoft Windows XP and Windows Vista (C Edition). (August 2008 | DU-04165-001_v01) 22. CUDA Technical Training. Volumen 1: Introduction to CUDA Programming (Prepared and Provided by NVIDIA. Q2 2008) 23. CUDA Technical Training. Volumen 2: CUDA Case Studies (Prepared and Provided by NVIDIA. Q2 2008) 80 Proyecto Fin de Carrera Ingeniería Informática - Hugo María Vegas Carrasco