281
El Procesamiento Distribuido y su aplicación al Tratamiento de Imágenes Autor: Miguel Hernández Vázquez Tutor: Carlos Platero Dueñas

El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

  • Upload
    haliem

  • View
    220

  • Download
    0

Embed Size (px)

Citation preview

Page 1: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

El Procesamiento Distribuido y

su aplicación al Tratamiento

de Imágenes

Autor: Miguel Hernández Vázquez

Tutor: Carlos Platero Dueñas

Page 2: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones
Page 3: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

A mis padres y a mi hermano, que tanto me han ayudado y apoyado durante toda mi vida.

A mis compañeros de laboratorio Laura, Isaac y Fran, gracias por haberme “soportado” durante todos estos meses.

A mis amigos de la EUITI: Javi, Marina, Patricia, José, Pablo, Antonio, Palomo, Arturo, Bea, Rayito, Rafa, Iván, Lorenzo, Fran, Dani, Alberto… sin ellos esto no hubiera sido lo mismo.

A Carlos Platero, mi tutor del proyecto.

Page 4: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones
Page 5: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Los obstáculos son esas cosas que las personas ven cuando dejan de mirar sus metas

E. JOSEPH COSSMAN

No hay nada imposible para quién sabe esperar

ANÓNIMO

Page 6: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones
Page 7: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Resumen

En este proyecto vamos a tratar de dar una visión sobre los diferentes métodos que existen en la actualidad de procesamiento distribuido – como pueden ser MPI, MatlabMPI, etc, así como las nuevas implementaciones para el lenguaje de programación C++: PVM y CORBA.

Además, también nos centraremos en la aplicación de este procesamiento distribuido a las aplicaciones de renderizado y procesamiento de imágenes, en especial, en el campo de las imágenes médicas.

El proyecto se ha realizado dentro del Grupo de Visión Artificial de la Escuela Universitaria de Ingeniería Técnica Industrial (EUITI). Se finalizó en el año 2005.

Page 8: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones
Page 9: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Abstract

In this project we will try to give a vision on the different methods that exist at the present time of distributed processing - as they can be MPI, MatlabMPI, etc, as well as the new implementations for the programming language C++: PVM AND CORBA.

Also, we will also center ourselves in the application from this distributed processing to the renderizado applications and image processing, especially, in the field of the medical images.

The project has been carried out inside the Group of Artificial Vision of the University School of Engineering Industrial technique (EUITI). You concluded in the year 2005.

Page 10: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones
Page 11: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

1 INTRODUCCIÓN.…………………………….……….......11

1.1 OBJETIVOS………...………..…………..……………...…………12

1.2 SUMARIO DEL PROYECTO………...….……………………….12

2 ESTADO DE LA TÉCNICA………………………...…15

2.1 INTRODUCCIÓN AL PROCESAMIENTO DISTRIBUIDO..…16

2.2 VENTAJAS DEL PROCESAMIENTO DISTRIBUIDO…...…...16

2.3 DESVENTAJAS DEL PROCESAMIENTO DISTRIBUIDO..…18

2.4 OTRAS VENTAJAS ASOCIADAS AL PROCESAMIENTO DISTRIBUIDO…...……………………...…………………………19

2.5 ¿QUÉ ES UN CLUSTER?................................................................20

2.6 CARACTERÍSTICAS DE UN CLUSTER..……………………...21

2.7 CATALOGACIÓN DE LOS CLUSTERS………...……………...24

2.8 TIPOS DE CLUSTERS………………………………..…………..25

2.8.1 CLUSTERS DE ALTO RENDIMIENTO (HP)..………..26

2.8.2 CLUSTERS DE ALTA DISPONIBILIDAD (HA)……...27

Page 12: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

2.8.3 CLUSTERS DE ALTA CONFIABILIDAD (HR)…...…28

3 PROCESAMIENTO DISTRIBUIDO CON MPI.....….30

3.1 ¿QUÉ ES MPI?...................................................................….……..31

3.2 OBJETIVOS Y LIMITACIONES DE MPI…………..…….…….33

3.3 ESTRUCTURA BÁSICA DE LOS PROGRAMAS MPI…...…...35

3.4 LA COMUNICACIÓN EN MPI: COMUNICACIÓN PUNTO A PUNTO………………………………………………………………37

3.4.1 MODELOS DE COMUNICACIÓN……………………..37

3.4.2 MODOS DE ENVÍO EN MPI………………..………….37

3.4.3 COMUNICACIÓN BÁSICA……………...……………..38

3.4.4 RECEPCIÓN POR ENCUESTA…………...……………40

3.5 TIPOS DE DATOS MANEJADOS POR MPI………...…………41

3.6 ETIQUETAS Y COMUNICADORES EN MPI…...………..……42

3.7 OPERACIONES COLECTIVAS EN MPI…………...………..…43

3.7.1 BARRERAS DE SINCRONIZACIÓN……….....………43

3.7.2 BROADCAST (DIFUSIÓN)…………..………………...43

3.7.3 GATHER (RECOLECCIÓN)………...…………….……45

3.7.4 SCATTER (DISTRIBUCIÓN)…………..………………45

3.7.5 REDUCCIÓN……………………..…………………..…46

3.7.6 COMUNICACIÓN TODOS CON TODOS (ALL-TO-ALL)…………………………………………...……...…48

3.8 MODULARIDAD………...……………………………………..…48

3.9 INSTALACIÓN Y CONFIGURACIÓN DE MPICH…..….……51

3.9.1 INSTALACIÓN……………...……………………..……51

3.9.2 CONFIGURACIÓN………………...……………………52

Page 13: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

3.10GENERACIÓN DE APLICACIONES MPI CON VISUAL STUDIO C++.……………………..………………………….….………….…54

3.11UN EJEMPLO CONCRETO………...………………………………59

4 PROCESAMIENTO DISTRIBUIDO DE IMÁGENES GENÉRICO CON VTK…….......…………………........64

4.1 ¿QUÉ ES VTK?.......………………………...……………………...65

4.2 ARQUITECTURA DE VTK……………...……………………….66

4.2.1 EL NÚCLEO DE C++……………..………………….…66

4.2.2 LA CAPA DE INTERPRETACIÓN..…………………...67

4.3 GRAPHICS MODEL………………………...………………….…67

4.3.1 LA VENTANA DE RENDERIZADO..…………………69

4.3.2 RENDERS, MAPPERS Y PROPS…………..…………..70

4.3.3 RENDERIZADO 3D DE DATOS GEOMÉTRICOS...…70

4.3.4 RENDERIZADO 3D DE DATOS VOLUMÉTRICOS…72

4.3.5 COMBINACIÓN DE LA GEOMETRÍA Y LAS LUCES……………..………………………...………….75

4.3.6 RENDERIZADO DE DATOS 2D……………………….77

4.3.7 LUCES, CÁMARAS E INTERACTUACIÓN DE LOS DIFERENTES OBJETOS……………….......………….77

4.4 VISUALIZATION MODEL………..……………………………..79

4.4.1 ARQUITECTURA DEL PIPELINE………...………...…79

4.4.2 LOS DATA OBJECTS…………………………..………80

4.4.3 LOS PROCESS OBJECTS…………………...……….…81

4.5 EJEMPLOS………………………..…………………………….…82

4.6 PROCESAMIENTO DE LAS IMÁGENES CON VTK…...….…85

Page 14: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

4.7 CREACIÓN DE UNA APLICACIÓN GRÁFICA CON VTK.…85

4.8 GENERACIÓN DE PROYECTOS MEDIANTE VTK……....…86

4.9 EJECUCIÓN DE LAS APLICACIONES VTK…………...……..90

4.10UTILIZACIÓN DE VTK CON MPI…………………...…………97

4.11UN EJEMPLO CONCRETO………………………...…………...100

5 PROCESAMIENTO DISTRIBUIDO DE LAS IMÁGENES GENÉRICO CON MATLAB....……......…110

5.1 ¿QUÉ ES MATLABMPI?..............................................................111

5.2 REQUISITOS DEL SISTEMA………………...………………...112

5.3 INSTALACIÓN Y EJECUCIÓN………………..………………113

5.4 IMPLEMENTACIÓN DE UN PROGRAMA DE MATLABMPI………………………………………………………..115

5.5 LANZAMIENTO Y ARCHIVOS DE ENTRADA/SALIDA..…118

5.6 MANEJO DE LOS ERRORES…………………………...…...…119

5.7 EJECUCIÓN DE MATLABMPI SOBRE LINUX…………..…120

5.8 EJECUCIÓN DE MATLABMPI SOBRE MacOSX………...…122

5.9 EJECUCIÓN DE MATLABMPI SOBRE PC………………..…122

5.9.1 INSTALACIÓN EN PC (AUTÓNOMO)………...….…122

5.9.2 INSTALACIÓN EN PC Y UN CLUSTER DE LINUX.123

5.9.3 INSTALACIÓN EN PC Y UN CLUSTER DE PC´s..…124

5.9.4 RESOLUCIÓN DE PROBLEMAS……………….....…125

5.10OPTIMIZACIONES PARA UN MEJOR RENDIMIENTO..…127

5.11EJECUCIÓN POR LOTES………………………………………128

5.12OTRAS CARACTERÍSTICAS………………………………..…129

Page 15: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

5.13DIAGNÓSTICO Y RESOLUCIÓN DE PROBLEMAS….....…130

5.14 PASOS A SEGUIR EN LA EJECUCIÓN DE LAS APLICACIONES DE MATLABMPI…………………..….……131

5.15CONSEJOS PARA LOS USUARIOS…………………..….……132

5.16ARCHIVOS…………………………………………..…………...134

5.17ANCHO DE BANDA……………………………………..………136

5.18CONCLUSIONES Y PRÓXIMOS DESARROLLOS…….....…140

5.19 UN EJEMPLO PRÁCTICO: APLICACIÓN PARALELA PARA EL FILTRADO DE IMÁGENES………………….……..…141

6 PROCESAMIENTO DISTRIBUIDO DE LAS IMÁGENES GENÉRICO CON PARAVIEW.........……147

6.1 ¿QUÉ ES PARAVIEW?...…………………………………..……148

6.2 CARACTERÍSTICAS DE PARAVIEW…………………..……148

6.3 OBJETIVO DE PARAVIEW……………………………...…..…149

6.4 INSTALACIÓN DE PARAVIEW………………………...…..…150

6.5 CONFIGURACIÓN DE PARAVIEW…………………..………150

6.5.1 EJECUCIÓN SOBRE UNIX………..…………….....…154

6.5.2 EJECUCIÓN SOBRE WINDOWS……………….....…154

6.6 FICHEROS SOPORTADOS POR PARAVIEW………..…..…154

6.7 TIPOS DE DATOS ADMITIDOS POR PARAVIEW…………157

6.8 PRINCIPALES COMANDOS UTILIZADOS POR PARAVIEW………………………………………………...………..158

6.9 PARAVIEW CON MPI…………………………………..………160

Page 16: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

7 RENDERIZACIÓN DE UNA NEURONA..……....…163

7.1 INTRODUCCIÓN…………………………………...……………164

7.2 WIREFRAME………………………………..…………………...165

7.3 RENDER SÓLIDO………………………………...…………...…165

7.4 SOMBREADO GOURAUD…………………..……………….…166

7.4.1 PSEUDOCÓDIGO PARA EL SOMBREADO GOURAUD……………………...………………….…...…168

7.4.2 VENTAJAS E INCONVENIENTES……..……….………168

7.5 SOMBREADO PHONG…………………………..………...……169

7.5.1 PSEUDOCÓDIGO PARA EL SOMBREADO PHONG……………..……………..…..………………...…171

7.5.2 VENTAJAS E INCONVENIENTES…………...…………171

7.6 RADIOSIDAD……………………………..……………………...171

7.7 PARALELISMO EN EL PROCESO DE RENDERIZACIÓN..172

7.7.1 EL PARALELISMO FUNCIONAL……………………173

7.7.2 EL PARALELISMO DE DATOS………………..….…174

7.7.3 EL PARALELISMO TEMPORAL……………..…...…174

7.7.4 MÉTODOS HÍBRIDOS…………………..……………174

7.8 CONCEPTOS ALGORÍTMICOS……………..……………..…175

7.9 EJEMPLO: UNA POSIBLE OPCIÓN DE RENDERIZACIÓN DE UNA NEURONA Y SU POSTERIOR RECONSTRUCCIÓN 3D……………………………….……………………………………..177

7.9.1 CÓDIGO FUENTE………………..…………....………178

8 PROCESAMIENTO DISTRIBUIDO CON C++……188

Page 17: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

8.1 BREVE INTRODUCCIÓN A C++…...………………...……..…189

8.2 ESTÁNDARES PARA LA PROGRAMACIÓN PARALELA EN C++……………………………………………………...………….…190

8.2.1 EL ESTÁNDAR MPI…………………………..………191

8.2.2 EL ESTÁNDAR PVM………………………...……..…191

8.2.3 EL ESTÁNDAR CORBA……………………...…….…193

8.3 EL PROCESAMIENTO DISTRIBUIDO EN C++ A TRAVÉS DEL ESTÁNDAR PVM………………………..………………..…………195

8.3.1 INTRODUCCIÓN A PVM…...……...…………………196

8.3.1.1 ¿QUÉ ES PVM?...................................................196

8.3.1.2 VENTAJAS DE USO DE PVM……...…………197

8.3.1.3 DESVENTAJAS DEL USO DE PVM…...…..…199

8.3.2 INSTALACIÓN DE PVM…....………………...………199

8.3.2.1 REQUISITOS NECESARIOS PARA TRABAJAR CON PVM..........................................................199

8.3.2.2 INSTALACIÓN DE PVM 3.4.4 EN LINUX...…200

8.3.3 CONFIGURACIÓN DE PVM……………………….…201

8.3.3.1 PVM SOBRE UNA ÚNICA MÁQUINA FÍSICA………………..………….…….………202

8.3.3.2 PVM SOBRE VARIAS COMPUTADORAS....203

8.3.4 EJECUCIÓN DE APLICACIONES PVM…………..…205

8.3.5 COMANDOS Y FUNCIONES MÁS IMPORTANTES DE PVM………………..…………………..…………...…206

8.3.5.1 COMANDOS…………………....………...…...206

8.3.5.2 FUNCIONES………………………………..…208

8.3.5.3 FUNCIONES DE CONTROL DE PROCESOS..209

8.3.5.4 FUNCIONES DE INFORMACIÓN………….…209

8.3.5.5 FUNCIONES DE CONFIGURACIÓN DE GRUPOS………………...…………...………...210

Page 18: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

8.3.5.6 FUNCIONES DE EMPAQUETAMIENTO DE DATOS Y CONTROL DE BUFFERS……...…212

8.3.5.7 FUNCIONES DE ENVÍO DE MENSAJES.....…213

8.3.5.8 FUNCIONES DE RECEPCIÓN DE MENSAJES……………………….……..…….214

8.4 PASOS PARA REALIZAR LA PARALELIZACIÓN DE UN PROGRAMA USANDO PVM. EJEMPLOS………….…….…..…215

8.4.1 EJEMPLO 1: COMUNICACIÓN MAESTRO ESCLAVO………………….………………………….…..215

8.4.1.1 PROGRAMA MAESTRO…………….………...215

8.4.1.2 PROGRAMA ESCLAVO……………..……..…217

8.4.1.3 ARCHIVO MAKEFILE…………………..….…218

8.4.1.4 EXPLICACIÓN DEL PROGRAMA ANTERIOR…………..………………………..219

8.4.2 EJEMPLO 2: PROGRAMA DE SUMA……………..…221

8.4.2.1 CABECERAS COMUNES..…………….…...…221

8.4.2.2 PROGRAMA MAESTRO………………..…..…222

8.4.2.3 PROGRAMA ESCLAVO..………………...……224

8.4.2.4 ARCHIVO MAKEFILE…………….……...……225

8.4.2.5 EXPLICACIÓN DEL PROGRAMA……………225

8.5 EL PROCESAMIENTO DISTRIBUIDO EN C++ A TRAVÉS DEL ESTÁNDAR CORBA……………..…...………….…………………226

8.5.1 INTRODUCCIÓN…………………………………...…227

8.5.2 OBJETIVOS DE CORBA………………..………….…229

8.5.3 VENTAJAS DE CORBA……………………..……..…230

8.5.4 DESARROLLOS DE CORBA………………...…….…230

8.5.5 EL ORB DE CORBA……………………………...……231

8.5.5.1 ESTRUCTURA DE UN ORB CORBA……............231

8.5.5.2 INVOCACIÓN DE MÉTODOS CORBA ESTÁTICOS CONTRA DINÁMICOS……..............................…233

8.5.5.3 EL LADO DEL SERVIDOR DE CORBA. EL ADAPTADOR DE OBJETOS…………...……..…236

Page 19: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

8.5.5.4 INICIALIZACIÓN DE CORBA…………….…..…239

8.5.6 IDL Y EL REPOSITORIO DE INTERFACES…...……240

8.5.6.1 EL IDL DE CORBA Y SU ESTRUCTURA………240

8.5.6.2 EL REPOSITORIO DE INTERFACES……........…243

8.5.6.3 EL ELNGUAJE IDL………………………….……246

8.5.6.4 CONSIDERACIONES ACERCA DEL MARSHALLING……………………...…..………249

8.5.7 COMUNICACIÓN VÍA CORBA…………...…………250

8.5.8 IMPLEMENTACIÓN DE OBJETOS CORBA……...…251

8.5.9 EL SERVICIO DE CICLO DE VIDA DE OBJETOS DE CORBA………………………….……...…………….……252

8.5.9.1 EL SERVICIO DE EVENTOS DE CORBA……....253

9 CONCLUSIONES Y LÍNEAS DE MEJORA…......…255

9.1 CONCLUSIONES SOBRE MPI……...………………...………..256

9.2 MPI CON VTK Y PARAVIEW………………………...……..…256

9.3 PROCESAMIENTO DISTRIBUIDO CON MATLAB...………257

9.4 PROCESAMIENTO DISTRIBUIDO CON C++……………….258

9.5 LÍNEAS DE MEJORA…………………………………..…….…258

10 BIBLIOGRAFÍA……...……………………..…261

Page 20: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones
Page 21: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

1 Introducción

La resolución de problemas mediante el procesamiento distribuido no es nuevo; de hecho esta basado en el viejo y conocido método de divide y vencerás utilizado para resolver problemas matemáticos, físicos o cualquier tipo de problema de carácter general.

Un sistema distribuido es un conjunto de computadoras conectadas en red que le dan la sensación al usuario de ser una sola computadora. A pesar que agregar complejidad al software y disminuir los niveles de seguridad, los sistemas de procesamiento distribuidos brindan una buena relación precio-desempeño y pueden aumentar su tamaño de manera gradual al aumentar la carga de trabajo.

GVA–ELAI–UPM ® PFC 0084 - 2005 11

Page 22: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Introducción Miguel Hernández Vázquez

El objetivo principal del paralelismo es el reducir el número de ciclos de ejecución de un programa, en relación al número de procesadores que existen en el sistema.

1.1 OBJETIVOS

Los objetivos que persigue el proyecto son dar una visión más en profundidad de lo que entendemos por procesamiento distribuido: el conocimiento y manejo de las implementaciones existentes a la hora de realizar este procesamiento distribuido, como pueden ser MPI y MatlabMPI; la aplicación de estas diversas técnicas de procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones existentes para desarrollar el procesamiento distribuido en otros lenguajes, como es el lenguaje C++: PVM y CORBA.

1.2 SUMARIO DEL PROYECTO

Este proyecto está compuesto por nueve capítulos.

En el segundo capítulo veremos el estado actual de la técnica de procesamiento distribuido y una serie de conceptos y definiciones previas.

En el tercer capítulo introduciremos el procesamiento distribuido a través de la implementación MPI / MPICH, así como sus principales características y ejemplos.

En el cuarto capítulo introduciremos las librerías de visualización VTK.

En el quinto capítulo introduciremos el procesamiento distribuido a través de Matlab, en la implementación MatlabMPI.

12 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 23: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Introducción

En el sexto capítulo introduciremos las librerías de visualización Paraview.

En el séptimo capítulo veremos una aplicación concreta de este procesamiento distribuido a la hora de realizar la renderización de una neurona.

En el octavo capítulo daremos una introducción al procesamiento distribuido en C++, e intentaremos dar una visión de las diferentes implementaciones para lograrlo.

En el noveno capitulo se exponen las conclusiones y líneas de mejora del proyecto, y en el décimo la bibliografía.

GVA–ELAI–UPM ® PFC 0084 - 2005 13

Page 24: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Introducción Miguel Hernández Vázquez

14 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 25: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

2 Estado de la Técnica

En este primer capítulo vamos a tratar de dar una visión general de lo que llamamos procesamiento distribuido, así como sus principales características. En los capítulos siguientes veremos en mayor profundidad los diferentes métodos que existen para llevar a cabo la implementación del procesamiento distribuido en el tratamiento genérico de imágenes.

GVA–ELAI–UPM ® PFC 0084 - 2005 15

Page 26: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Estado de la Técnica Miguel Hernández Vázquez

2.1 INTRODUCCIÓN AL PROCESAMIENTO DISTRIBUIDO

Un sistema distribuido es un conjunto de computadoras conectadas en red de forma que le da la sensación al usuario de ser una sola computadora. Estos sistemas brindan una serie de ventajas: compartición de recursos, la concurrencia, alta escalabilidad, y tolerancia a fallos. Los sistemas de procesamiento distribuidos brindan una buena relación precio-desempeño y pueden aumentar su tamaño de manera gradual al aumentar la carga de trabajo.

2.2 VENTAJAS DEL PROCESAMIENTO DISTRIBUIDO

Entre las principales ventajas que presenta el procesamiento distribuido encontramos las siguientes:

1. Economía: la relación precio rendimiento es mayor que en los sistemas centralizados sobretodo cuando lo que se buscan son altas prestaciones.

2. Velocidad: llega un momento en el que no se puede encontrar un sistema

centralizado suficientemente potente, con los sistemas distribuidos siempre se podrá encontrar un sistema más potente uniendo esos mismos nodos. Se han hecho comparativas y los sistemas distribuidos especializados en cómputo han ganado a los mayores mainframes.

3. Distribución de máquinas: podemos tener unas máquinas inherentemente distribuidas por el tipo de trabajo que realizan.

4. Alta disponibilidad: cuando una máquina falla no tiene que caer todo el sistema sino que este se recupera de las caídas y sigue funcionando con quizás algo menos de velocidad.

16 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 27: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Estado de la Técnica

5. Escalabilidad: puedes empezar un cluster con unas pocas máquinas y según se descubre que la carga es elevada para el sistema, se añaden más máquinas, no hace falta tirar las máquinas antiguas ni inversiones iniciales elevadas para tener máquinas suficientemente potentes.

6. Comunicación: los ordenadores necesariamente están comunicados, para el correcto y eficaz funcionamiento del cluster se crean unas nuevas funcionalidad es avanzadas de comunicación. Estas nuevas primitivas de comunicación pueden ser usadas por los programas y por los usuarios para mejorar sus comunicaciones con otras máquinas.

7. Sistema de ficheros con raíz única: este sistema de ficheros hace que la administración sea más sencilla (no hay que administrar varios discos independientemente) y deja a cargo del sistema varias de las tareas.

8. Capacidad de comunicación de procesos y de intercambio de datos universal: podemos enviar señales a cualquier proceso del cluster, así mismo podemos hacer trabajo conjunto con cualquier proceso e intercambiar con los datos, por lo tanto podríamos tener a todos los procesos trabajando en un mismo trabajo.

Figura 2.1: Sistemas distribuidos. Escalabilidad de servicios

GVA–ELAI–UPM ® PFC 0084 - 2005 17

Page 28: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Estado de la Técnica Miguel Hernández Vázquez

2.3 DESVENTAJAS DEL PROCESAMIENTO DISTRIBUIDO

La principal desventaja de estos sistemas es la complejidad que implica su creación. Básicamente se tienen todos los problemas que se puedan tener en un nodo particular pero escalados. Existen varias desventajas asociadas a las ventajas anteriormente reseñadas:

1. Alta disponibilidad: podemos conseguir alta disponibilidad pues al tener varios nodos independientes, hay muchas menos posibilidades de que caigan todos a la vez. Pero esto por sí sólo no nos da alta disponibilidad. Tenemos que implantar los mecanismos necesarios para que cuando una máquina caiga, se sigan dando todos los servicios.

2. Escalabilidad: el problema es que un mayor número de nodos suele implicar más comunicación, por lo que tenemos que diseñar un sistema lo más escalable posible.

3. Comunicación: un cluster tiene más necesidades de comunicación que los sistemas normales por lo tanto tenemos que crear nuevos métodos de comunicación lo más eficientes posibles.

4. Sistemas de ficheros con raíz única: tenemos que independizar los sistemas de ficheros distintos de cada uno de los nodos para crear un sistema de ficheros general.

5. Capacidad de comunicación de procesos y de intercambio de datos universal: para conseguir este objetivo necesitamos una forma de distinguir unívocamente cada proceso del cluster. La forma más sencilla es dando a cada proceso un PID único, que llamaremos CPID (cluster process ID). Este CPID podría estar formado por el número de nodo y el número de proceso dentro de ese nodo. Una vez podemos direccionar con que proceso queremos comunicarnos, para enviar señales necesitaremos un sencillo mecanismo de comunicación y seguramente el mismo sistema operativo en el otro extremo que entienda las señales. Para compartir datos, podemos enviarlos por la red o podemos crear memoria compartida a lo largo del cluster.

18 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 29: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Estado de la Técnica

2.4 OTRAS VENTAJAS ASOCIADAS AL PROCESAMIENTO DISTRIBUIDO

Otra ventaja de los sistemas distribuidos es que cumple con todos los criterios de transparencia. Pero conseguir estos criterios implica ciertos mecanismos que se tienen que implementar:

1. Transparencia de acceso: Implica tener que mantener el viejo sistema para el nuevo cluster, por ejemplo mantener un árbol de directorios usual para manejar todos los dispositivos de almacenamiento del cluster. No se tienen que romper las APIs para introducir las nuevas funcionalidades.

2. Transparencia de localización: A nivel más bajo tenemos que implantar una forma de conocer donde se encuentran los recursos, tradicionalmente se han usado servidores centralizados que lo sabían todo, ahora ya se va consiguiendo que esta información se distribuya por la red.

3. Transparencia de concurrencia: Se han desarrollado varios métodos para conseguirlo. El mayor problema es la desincronización de los relojes pues es muy complejo que todos los relojes hardware lleven exactamente la misma temporización por tanto algunos ordenadores ven los acontecimientos como futuros o pasados respecto a otros ordenadores.

4. Transparencia de replicación: Básicamente el problema es que el sistema sepa que esas réplicas están ahí y mantenerlas coherentes y sincronizadas. También tiene que activar los mecanismos necesarios cuando ocurra un error en un nodo.

5. Transparencia de fallos: Aunque existan fallos el sistema seguirá funcionando. Las aplicaciones y los usuarios no sabrán nada de estos fallos o intentarán ser mínimamente afectados, como mucho, el

GVA–ELAI–UPM ® PFC 0084 - 2005 19

Page 30: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Estado de la Técnica Miguel Hernández Vázquez

sistema funcionará más lentamente. Este punto está muy relacionado con la transparencia de replicación.

6. Transparencia de migración: Se tienen que solucionar problemas sobre las decisiones que se toman para migrar un proceso, hay que tener en cuenta las políticas de migración, ubicación, etc. Además se tienen que ver otros aspectos prácticos como si al nodo al que se va se puede encontrar los recursos que se necesitan, etc. La aplicación no tiene que saber que fue migrada.

7. Transparencia para los usuarios: Implica una buena capa de software que de una apariencia similar a capas inferiores distintas.

8. Transparencia para programas: La más compleja. Implica que los programas no tienen porque usar llamadas nuevas al sistema para tener ventaja del cluster.

2.5 ¿QUÉ ES UN CLUSTER?

De forma genérica, podemos definir un cluster como un conjunto de máquinas unidas por una red de comunicación trabajando por un objetivo conjunto. Según el tipo puede ser dar alta disponibilidad, alto rendimiento etc...

Sin embargo no existe una definición estricta, por lo que cada autor puede tener diferente concepto sobre la noción de cluster:

• “Un cluster consiste en un conjunto de máquinas y un servidor de cluster dedicado, para realizar los relativamente infrecuentes accesos a los recursos de otros procesos, se accede al servidor de cluster de cada grupo” del libro Operating System Concepts de Silberschatz Galvin.

20 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 31: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Estado de la Técnica

• “Un cluster es la variación de bajo precio de un multiprocesador masivamente paralelo (miles de procesadores, memoria distribuida, red de baja latencia), con las siguientes diferencias: cada nodo es una máquina quizás sin algo del hardware (monitor, teclado, ratón, etc.), el nodo podría ser SMP o PC. Los nodos se conectan por una red de bajo precio como Ethernet o ATM aunque en clusters comerciales se pueden usar tecnologías de red propias. El interfaz de red no está muy acoplado al bus I/O. Todos los nodos tienen disco local.”

• “Cada nodo tiene un sistema operativo UNIX con una capa de software para soportar todas las características del cluster” del libro Scalable Parallel Computing de Kai Hwang y Khiwei Xu.

• “Es una clase de arquitectura de computador paralelo que se basa en unir máquinas independientes cooperativas integradas por medio de redes de interconexión, para proveer un sistema coordinado, capaz de procesar una carga” del autor Dr Thomas Sterling.

2.6 CARACTERÍSTICAS GENERALES DE UN CLUSTER

Para crear un cluster se necesitan al menos dos nodos. Una de las características principales de estas arquitecturas es que exista un medio de comunicación (red) donde los procesos puedan migrar para computarse en diferentes estaciones paralelamente. Un solo nodo no cumple este requerimiento por su condición de aislamiento para poder compartir información. Las arquitecturas con varios procesadores en placa tampoco son consideradas clusters, bien sean máquinas SMP o mainframes debido a que el bus de comunicación no suele ser de red, sino interno.

Podemos resumir las características de un cluster en las siguientes:

1. Un cluster consta de 2 o más nodos. Los nodos necesitan estar conectados para llevar a cabo su misión.

GVA–ELAI–UPM ® PFC 0084 - 2005 21

Page 32: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Estado de la Técnica Miguel Hernández Vázquez

2. Los nodos de un cluster están conectados entre sí por un canal de comunicación funcional.

3. Los clusters necesitan software especializado. Existen varios tipos de software que pueden conformar un cluster:

• Software a nivel de aplicación, es decir, software generado por bibliotecas especiales dedicadas a clusters. Estas bibliotecas de carácter general que permiten la abstracción de un nodo a un sistema conjunto, permitiendo crear aplicaciones en un entorno distribuido de manera lo más abstracta posible. Este tipo de software suele generar elementos de proceso del tipo rutinas, procesos o tareas, que se ejecutan en cada nodo del cluster y se comunican entre sí a través de la red.

• Software a nivel de sistema. Este tipo de software se sitúa a nivel de sistema, suele estar implementado como parte del sistema operativo de cada nodo, o ser la totalidad de este. Es más crítico y complejo, por otro lado suele resolver problemas de carácter más general que los anteriores y su eficiencia, por norma general, es mayor.

Figura 2.2: Cluster a nivel de sistema y a nivel de aplicación

22 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 33: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Estado de la Técnica

4. Dependiendo del tipo de software, el sistema puede estar más o menos acoplado. Entendemos por acoplamiento del software a la integración que tengan todos los elementos software que existan en cada nodo. Gran parte de la integración del sistema la produce la comunicación entre los nodos, y es por esta razón por la que se define el acoplamiento; otra parte es la que implica cómo de crítico es el software y su capacidad de recuperación ante fallos. Aquí hay que hacer un pequeño inciso para decir que todo esto depende de si el sistema es centralizado o distribuido. En cualquier caso, el acoplamiento del software es una medida subjetiva basada en la integración de un sistema cluster a nivel general.

En este punto podemos distinguir tres tipos de acoplamiento:

• Acoplamiento fuerte: El software que entra en este grupo es software cuyos elementos se interrelacionan mucho unos con otros, y hacen la mayoría de las funcionalidades del cluster de manera altamente cooperativa. Un ejemplo de este tipo de acoplamiento son los clusters SSI.

• Acoplamiento medio: A este grupo pertenece un software que no necesita un conocimiento tan exhaustivo de todos los recursos de otros nodos, pero que sigue usando el software de otros nodos para aplicaciones de muy bajo nivel. Un ejemplo de este tipo de acoplamiento serían los clusters openMosix.

• Acoplamiento débil: Son los casos en los que los programas se dividen en diversos nodos y por tanto se necesitan pero que no están a un nivel tan bajo. Generalmente se basan en aplicaciones construidas por bibliotecas preparadas para aplicaciones distribuidas, agrupadas en un conjunto de aplicaciones específicos que generan el cluster en sí: PVM, MPI, CORBA, RPC, etc. Por sí mismos no funcionan y hay que dotarles de una estructura superior que utilice las capacidades del cluster para que éste funcione.

GVA–ELAI–UPM ® PFC 0084 - 2005 23

Page 34: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Estado de la Técnica Miguel Hernández Vázquez

5. Todos los elementos del cluster trabajan para cumplir una funcionalidad conjunta, sea esta la que sea. Es la funcionalidad la que caracteriza el sistema.

2.7 CATALOGACIÓN DE LOS CLUSTERS

En general la catalogación de los clusters se hace en base a cuatro factores de diseño bastante ortogonales entre sí:

• Acoplamiento: este factor ya lo hemos analizado en el punto anterior. Es, quizás, el factor más importante a la hora de catalogar un cluster.

• Control: El parámetro de control implica el modelo de gestión que propone el cluster. Este modelo de gestión hace referencia a la manera de configurar el cluster y es dependiente del modelo de conexionado o colaboración que surgen entre los nodos. Puede ser de dos tipos:

I. Centralizado: en un modelo centralizado, se hace uso de un nodo llamado maestro desde el cual se puede configurar el comportamiento de todo el sistema. Tiene la ventaja de poder realizar una mejor gestión del cluster.

II. Descentralizado: en un modelo distribuido cada nodo debe administrarse y gestionarse en un principio por sí mismo, aunque también pueden ser gestionados mediante aplicaciones de más alto nivel de manera centralizada. Es propio de sistemas distribuidos. Tiene la ventaja de que presenta más tolerancia a fallos como sistema global, y como

24 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 35: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Estado de la Técnica

desventajas que la gestión y administración de los equipos requiere más tiempo.

• Homogeneidad: Se entiende por homogeneidad del cluster a la homogeneidad de los equipos y recursos que conforman a éste. Existen dos tipos de clusters:

I. Homogéneos: formados por equipos de la misma arquitectura. Todos los nodos tienen una arquitectura y recursos similares, de manera que no existen muchas diferencias entre cada nodo.

II. Heterogéneos: formados por nodos con distinciones que pueden estar en los siguientes puntos: Tiempos de acceso distintos, arquitectura distinta, sistema operativo distinto, rendimiento de los procesadores o recursos sobre una misma arquitectura.

• Seguridad

2.8 TIPOS DE CLUSTERS

Existen tres tipos fundamentales de clusters: clusters de ALTO RENDIMIENTO (HP); clusters de ALTA DISPONIBILIDAD (HA); y, por último, clusters de ALTA CONFIABILIDAD (HR).

GVA–ELAI–UPM ® PFC 0084 - 2005 25

Page 36: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Estado de la Técnica Miguel Hernández Vázquez

2.8.1 CLUSTERS DE ALTO RENDIMIENTO (HP)

Los clusters de alto rendimiento han sido creados para compartir el recurso más valioso de un ordenador, es decir, el tiempo de proceso. Generalmente se utilizan en ambientes científicos, o en grandes empresas donde se utilizan para la compilación o renderización. Cualquier operación que necesite altos tiempos de CPU y millones de operaciones puede ser implementada en un cluster de alto rendimiento, siempre que se encuentre un algoritmo que sea paralelizable. Existen clusters que pueden ser denominados de alto rendimiento tanto a nivel de sistema como a nivel de aplicación. A nivel de sistema tenemos OpenMosix, mientras que a nivel de aplicación se encuentran otros como MPI, PVM, Beowulf y otros muchos.

La misión de este tipo de clusters es mejorar el rendimiento en la obtención de la solución de un problema. Esto supone que cualquier cluster que haga que el rendimiento del sistema general aumente respecto al de uno de los nodos individuales puede ser considerado cluster de alto rendimiento. Generalmente, los problemas que se le plantean a un ordenador, suelen ser de carácter computacional. Se podría definir estos sistemas como sistemas distribuidos (en cada nodo) en los cuales se resuelve de manera distribuida un problema de cómputo. Generalmente estos problemas de cómputo suelen estar ligados a problemas matemáticos relativos a problemas científicos, renderizaciones de gráficos, compilación de programas, compresión de cualquier tipo, descifrado de códigos, rendimiento del sistema operativo, etc.

Las técnicas utilizadas dependen de a qué nivel trabaje nuestro cluster. Los clusters implementados a nivel de aplicación, no suelen implementar balanceo de carga; suelen basar todo su funcionamiento en una política de localización que sitúa las tareas en los diferentes nodos del cluster, y las comunica mediante las librerías abstractas. Resuelven problemas de cualquier tipo de los que se han visto anteriormente, pero, se deben diseñar y codificar aplicaciones propias para cada tipo para poderlas utilizar dentro de estos clusters.

Por otro lado están los sistemas de alto rendimiento implementados a nivel de sistema. Estos clusters basan todo su funcionamiento en comunicación y colaboración de los nodos a nivel de sistema operativo, lo que implica generalmente que son clusters de nodos de la misma arquitectura y que basan su funcionamiento en compartición de recursos a cualquier nivel, balanceo de la carga de manera dinámica, funciones de scheduling especiales y otros tantos factores que componen el sistema. Se intentan acercar al sistema SSI; el problema esta en que para obtener un sistema SSI hay que ceder en el apartado de compatibilidad con los sistemas actuales, por lo cual se suele llegar a un factor de compromiso.

26 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 37: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Estado de la Técnica

2.8.2 CLUSTERS DE ALTA DISPONIBILIDAD (HA)

Los clusters de alta disponibilidad son bastante ortogonales en lo que se refieren a funcionalidad con respecto a un cluster de alto rendimiento. Los clusters de alta disponibilidad son clusters donde la principal funcionalidad es estar controlando y actuando para que un servicio o varios se encuentren activos durante el máximo periodo de tiempo posible. En estos casos se puede comprobar como la monitorización de otros es parte de la colaboración entre los nodos del cluster.

Los clusters de alta disponibilidad han sido diseñados para que proporcionen la máxima disponibilidad sobre los servicios que presenta el cluster. Este tipo de clusters son la competencia que abarata los sistemas redundantes, de manera que ofrecen una serie de servicios durante el mayor tiempo posible. Para poder dar estos servicios, los clusters de este tipo se implementan en base a tres factores: confiabilidad, disponibilidad y dotación de servicio.

La mayoría de los problemas que tratan de resolver este tipo de clusters están ligados a la necesidad de dar servicio continuado de cualquier tipo a una serie de clientes de manera ininterrumpida. A esta funcionalidad se suele oponer la ley del caos en una de sus vertientes informáticas. Se suelen producir fallos inesperados en las máquinas; estos fallos provocan la aparición de dos eventos en el tiempo: uno es el tiempo en el que el servicio está inactivo y el otro es el tiempo de reparación del problema. Ambos tiempos no tienen por que estar relacionados, aunque a menudo si lo estén. Entre los problemas que solucionan se encuentran: sistemas de información redundante, sistemas tolerantes a fallos, balanceo de carga entre varios servidores, balanceo de conexiones entre varios servidores, etc.

Las técnicas que emplean este tipo de cluster a la hora de atajar estos problemas se basan en principios muy simples que pueden ser desarrollados hasta crear sistemas complejos especializados para cada entorno particular. En cualquier caso, las técnicas de estos sistemas suelen basarse en excluir del sistema aquellos puntos críticos que pueden producir un fallo y por tanto la pérdida de disponibilidad de un servicio, para esto se suelen implementar desde enlaces de red redundantes hasta disponer de N máquinas para hacer una misma tarea de manera que si caen N-1 máquinas el servicio permanece activo sin pérdida de rendimiento.

GVA–ELAI–UPM ® PFC 0084 - 2005 27

Page 38: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Estado de la Técnica Miguel Hernández Vázquez

2.8.3 CLUSTERS DE ALTA CONFIABILIDAD (HR)

Estos clusters tratan de aportar la máxima confiabilidad en un entorno en el cual se necesite saber que el sistema se va a comportar de una manera determinada. Este tipo de clusters son los más difíciles de implementar, ya que generalmente se basan en no solamente conceder servicios de alta disponibilidad, sino en ofrecer un entorno de sistema altamente confiable. Esto implica en sí mismo mucha sobrecarga en el sistema, son también clusters muy acoplados.

Dar a un cluster SSI capacidad de alta confiabilidad implica gastar los recursos necesarios para evitar que aplicaciones caigan.

Generalmente este tipo de clusters suele ser utilizado para entornos de tipo empresarial y esta funcionalidad solamente puede ser efectuada por hardware especializado. No existe ninguno de estos clusters implementados como software de manera eficiente en tiempo real. Esto se debe a limitaciones de la latencia de la red, así como a la complejidad de mantener los estados. Estos clusters deberían ser una mezcla de clusters de alto rendimiento y alta disponibilidad mejorados. Necesitarían características de cluster SSI, tener un único reloj de sistema conjunto y otras acciones más. Dada la naturaleza asíncrona actual en el campo de los clusters, este tipo de clusters aún será difícil de implementar hasta que no se abaraten las técnicas de comunicación utilizadas en entornos que actualmente consideramos inalcanzables para la mayoría de las organizaciones o con no suficiente coste/rendimiento.

28 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 39: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Estado de la Técnica

GVA–ELAI–UPM ® PFC 0084 - 2005 29

Page 40: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Estado de la Técnica Miguel Hernández Vázquez

30 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 41: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

3 Procesamiento Distribuido con MPI

En este capítulo vamos a dar una visión sobre lo que es MPI (Message Passing Interface), los objetivos que persigue, limitaciones y en definitiva, sus características y partes constituyentes. Más adelante añadiremos una serie de ejemplos prácticos para una mayor y mejor comprensión de la implementación MPI. Este capítulo será un paso previo para poder entender en mayor medida las implementaciones realizadas en los capítulos posteriores.

GVA–ELAI–UPM ® PFC 0084 - 2005 31

Page 42: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

3.1 ¿QUÉ ES MPI?

MPI es, como su nombre indica, un interfaz, lo que quiere decir que el estándar no exige una determinada implementación del mismo. Lo importante es dar al programador una colección de funciones para que éste diseñe su aplicación, sin que tenga necesariamente que conocer el hardware concreto sobre el que se va a ejecutar, ni la forma en la que se han implementado las funciones que emplea.

Los elementos básicos de MPI son una definición de un interfaz de programación independiente de lenguajes, más una colección de bindings o concreciones de ese interfaz para los lenguajes de programación más extendidos en la comunidad usuaria de computadores paralelos: C y FORTRAN.

Un programador que quiera emplear MPI para sus proyectos trabajará con una implementación concreta de MPI, que constará de, al menos, estos elementos:

MPI (acrónimo de Message Passing Interface) es un interfaz estandarizado para la implementación de aplicaciones paralelas basadas en paso de mensajes. El modelo de programación en el que se fundamenta MPI es MIMD (acrónimo de Multiple Instruction streams, Multiple Data streams), aunque también existe otro modelo de programación sobre el que se puede fundamentar, el modelo SPMD (acrónimo de Single Program Multiple Data).

Figura 3.1: Logo de MPI

• Una biblioteca de funciones para C, más el fichero de cabecera mpi.h con las definiciones de esas funciones y de una colección de constantes y macros.

• Una biblioteca de funciones para FORTRAN + mpif.h.

32 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 43: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

• Comandos para compilación, típicamente mpicc, mpif77, que son versiones de los comandos de compilación habituales (cc, f77) que incorporan automáticamente las bibliotecas MPI.

• Comandos para la ejecución de aplicaciones paralelas, típicamente mpirun.

• Herramientas para monitorización y depuración.

MPI no es, evidentemente, el único entorno disponible para la elaboración de aplicaciones paralelas. Existen muchas alternativas, entre las que destacamos las siguientes:

• Utilizar las bibliotecas de programación propias del computador paralelo disponible: NX en el Intel Paragon, MPL en el IBM SP2, etc.

• PVM (Parallel Virtual Machine): de características similares a MPI, se desarrolló con la idea de hacer que una red de estaciones de trabajo funcionase como un multicomputador. Funciona también en multicomputadores, normalmente como una capa de software encima del mecanismo de comunicaciones nativo.

• Usar, si es posible, lenguajes de programación paralelos (FORTRAN 90) o secuenciales (C, FORTRAN 77) con directivas de paralelismo.

• Usar lenguajes secuenciales junto con compiladores que paralicen automáticamente.

Como ya hemos comentado, MPI está especialmente diseñado para desarrollar aplicaciones SPMD. Al arrancar una aplicación se lanzan en paralelo N copias del mismo programa (procesos). Estos procesos no avanzan sincronizados instrucción a instrucción sino que la sincronización, cuando sea necesaria, tiene que ser explícita. Los procesos tienen un espacio de memoria completamente separado. El intercambio de información, así como la sincronización, se hacen mediante paso de mensajes.

GVA–ELAI–UPM ® PFC 0084 - 2005 33

Page 44: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

Se dispone de funciones de comunicación punto a punto (que involucran sólo a dos procesos), y de funciones u operaciones colectivas (que involucran a múltiples procesos). Los procesos pueden agruparse y formar comunicadores, lo que permite una definición del ámbito de las operaciones colectivas, así como un diseño modular.

3.2 OBJETIVOS Y LIMITACIONES DE MPI

MPI ha sido desarrollado por el MPI FORUM - grupo formado por investigadores de universidades, laboratorios y empresas involucrados en la computación de altas prestaciones. Los objetivos fundamentales que persigue el MPI FORUM son:

• Definir un entorno de programación único que garantice la portabilidad de las aplicaciones paralelas.

• Definir totalmente el interfaz de programación, sin especificar cómo debe ser la implementación del mismo.

• Ofrecer implementaciones de calidad, de dominio público, para favorecer la extensión del estándar.

• Convencer a los fabricantes de computadores paralelos para que ofrezcan versiones de MPI optimizadas para sus máquinas.

Los elementos básicos de que consta MPI son:

1. Definición de un interfaz de programación independiente de lenguajes.

2. Una colección de bindings o concreciones de ese interfaz para los lenguajes de programación más extendidos: C y FORTRAN.

34 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 45: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

Sin embargo, todavía existen algunas limitaciones en cuanto al desarrollo del MPI. Algunas de ellas podrían ser:

• No existe un mecanismo estandarizado de entrada/salida paralela.

• La creación dinámica de procesos: MPI asume un número de procesos constante, que es establecido al arrancar la aplicación.

• Las variables compartidas: el modelo de comunicación estandarizado por MPI sólo tiene en cuenta el paso de mensajes.

• Desarrollo de bindings para otros lenguajes: C++ y ADA.

• Soporte para las aplicaciones de tiempo real: MPI no recoge en ningún punto restricciones de tiempo real.

• Las interfaces gráficas: no se define ningún aspecto relacionado con la interacción mediante GUIs con una aplicación paralela.

Figura 3.2: ubicación de MPI en el proceso de programación de aplicaciones paralelas

GVA–ELAI–UPM ® PFC 0084 - 2005 35

Page 46: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

3.3 ESTRUCTURA BÁSICA DE LOS PROGRAMAS MPI

MPI está especialmente diseñado para desarrollar aplicaciones SPMD (acrónimo de Single Program Multiple Data). Al arrancar una aplicación se lanzan en paralelo N copias del mismo programa (N procesos). Estos procesos no están sincronizados instrucción a instrucción, sino que esta, en el caso de que sea necesaria, tiene que ser indicada explícitamente, y se realiza a través del paso de mensajes, al igual que el intercambio de la información. Además, estos procesos tienen un espacio de memoria separado.

Existen diversos tipos de funciones: funciones de comunicación punto a punto – en las que intervienen dos procesos únicamente; funciones colectivas – en las que intervienen varios procesos.

La estructura típica de un programa MPI, usando el binding para C, es la siguiente:

# include "mpi.h" main (int argc, char **argv) { int nproc; /* Número de procesos */ int yo; /* Mi dirección: 0<=yo<= (nproc-1) */ MPI_Init (&argc, &argv); MPI_Comm_size (MPI_COMM_WORLD, &nproc); MPI_Comm_rank (MPI_COMM_WORLD, &yo); /* CUERPO DEL PROGRAMA */ MPI_Finalize (); }

36 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 47: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

En esta estructura típica de programa MPI podemos observar cuatro de las funciones más utilizadas de MPI:

1. MPI_Init (), que utilizamos para iniciar la aplicación paralela.

2. MPI_Comm_size (), que utilizamos para averiguar el número de procesos que toman parte en la aplicación en cuestión.

3. MPI_Comm_rank (), que se utiliza para que cada proceso averigüe su dirección (identificador) dentro del conjunto de diferentes procesos que componen la aplicación en cuestión.

4. MPI_Finalize (), que utilizamos para dar por finalizada la aplicación.

int MPI_Init(int *argc, char ***argv); int MPI_Comm_size (MPI_Comm comm, int *size); int MPI_Comm_rank (MPI_Comm comm, int *rank); int MPI_Finalize(void);

La mayor parte de las funciones MPI devuelven un entero; si el valor devuelto es MPI_SUCCESS, la función se ha realizado con éxito.

La palabra clave MPI_COMM_WORLD hace referencia al comunicador universal, un comunicador predefinido por MPI que incluye a todos los procesos de la aplicación. Todas las funciones de comunicación de MPI necesitan como argumento un comunicador.

GVA–ELAI–UPM ® PFC 0084 - 2005 37

Page 48: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

3.4 LA COMUNICACIÓN EN MPI: COMUNICACIÓN PUNTO A PUNTO

Un gran número de funciones de MPI se dedican a la comunicación entre pares de procesos. Existen diversas formas de intercambiar un mensaje entre dos procesos, en función del modelo y el modo de comunicación elegido.

3.4.1 MODELOS DE COMUNICACIÓN

MPI define dos modelos de comunicación: bloqueante (blocking) y no bloqueante (non-blocking). La elección de uno u otro tipo de modelo está en función del tiempo que un proceso pasa bloqueado tras llamar a una función de comunicación.

Así, una función bloqueante (blocking) mantiene a un proceso bloqueado hasta que la operación solicitada finalice. Una no bloqueante (non-blocking) supone ordenar al sistema la realización de una operación, recuperando el control inmediatamente, sin preocuparnos por el momento si la operación ha finalizado o no.

Esto nos presenta un problema: cuando dar por finalizada la comunicación. En el caso del receptor, damos por finalizada la comunicación cuando en el buffer tengamos un mensaje nuevo. En el caso del emisor este aspecto es más difícil de determinar. Se define que el proceso de comunicación ha terminado cuando el emisor puede volver a utilizar el buffer en el que estaba contenido el mensaje a emitir.

3.4.2 MODOS DE ENVÍO EN MPI

MPI define 4 modos de envío:

• BÁSICO (BASIC): en el modo de envío básico no se especifica la forma en la que se completa la operación: es algo dependiente de la implementación.

38 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 49: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

• CON BUFFER (BUFFERED): en el envío con buffer se guarda, en un buffer en el emisor, una copia del mensaje. La operación se da por completa en cuanto se ha efectuado esta copia. Si no hay espacio en el buffer, el envío fracasa.

• SÍNCRONO (SYNCHRONOUS): en el envío síncrono, la operación se da por terminada sólo cuando el mensaje ha sido recibido en el destino.

• LISTO (READY): únicamente se puede hacer si antes el otro extremo está preparado para una recepción inmediata.

3.4.3 COMUNICACIÓN BÁSICA

El resultado de la combinación de dos modelos y cuatro modos de comunicación nos da 8 diferentes funciones de envío. Funciones de recepción sólo hay dos, una por modelo. Presentamos a continuación los prototipos de las funciones más habituales. Empezamos con MPI_Send () y MPI_Recv que son, respectivamente, las funciones de envío y recepción básicas bloqueantes:

int MPI_Send (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm);

int MPI_Recv (void* buf, int count, MPI_Datatype datatype, int source, int tag,

MPI_Comm comm, MPI_Status *status);

El significado de los parámetros es el siguiente: Buf, count y datatype forman el mensaje a enviar o recibir: count copias de un dato del tipo datatype que se encuentran (o se van a dejar) en memoria a partir de la dirección indicada por buf. Dest es, en las funciones de envío, el identificador del proceso destinatario del mensaje. Source es, en las funciones de recepción, el identificador del emisor del cual esperamos un mensaje. Si no importa el origen del mensaje, podemos poner MPI_ANY_SOURCE. Tag es una etiqueta que se puede poner al mensaje. El significado de la etiqueta lo asigna el programador. Suele emplearse para distinguir entre diferentes clases de mensajes. El emisor pone siempre una etiqueta a los mensajes, y el receptor puede elegir entre recibir sólo los mensajes que tengan una etiqueta dada, o aceptar cualquier etiqueta, poniendo MPI_ANY_TAG como valor de este parámetro. Comm es un comunicador; en muchas ocasiones se emplea el comunicador universal MPI_COMM_WORLD. Status es un resultado que se

GVA–ELAI–UPM ® PFC 0084 - 2005 39

Page 50: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

obtiene cada vez que se completa una recepción, y nos informa de aspectos tales como el tamaño del mensaje recibido, la etiqueta del mensaje y el emisor del mismo. La definición d e la estructura MPI_Status es la siguiente:

typedef struct { int MPI_SOURCE; int MPI_TAG; /* otros campos no accesibles */ } MPI_Status;

Podemos acceder directamente a los campos .MPI_SOURCE y .MPI_TAG, pero a ningún otro más. Si queremos saber el tamaño de un mensaje, lo haremos con la función MPI_Get_count ():

int MPI_Get_count (MPI_Status *status, MPI_Datatype datatype, int *count);

MPI_Isend () y MPI_Irecv () son las funciones de emisión/recepción básicas no bloqueantes.

int MPI_Isend (void* buf, int count, MPI_Datatype datatype, int dest, int tag,

MPI_Comm comm, MPI_Request *request);

int MPI_Irecv (void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request);

int MPI_Wait (MPI_Request *request, MPI_Status *status);

int MPI_Test (MPI_Request *request, int *flag, MPI_Status *status);

int MPI_Cancel (MPI_Request *request);

Las funciones no bloqueantes manejan un objeto request del tipo MPI_Request. Este objeto es una especie de “recibo” de la operación solicitada. Más adelante se podrá utilizar este recibo para saber si la operación ha terminado o no.

La función MPI_Wait () toma como entrada un recibo, y bloquea al proceso hasta que la operación correspondiente termina. Por lo tanto, hacer un MPI_Isend ()

40 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 51: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

seguido de un MPI_Wait () equivale a hacer un envío bloqueante. Sin embargo, entre la llamada a la función de envío y la llamada a la función de espera el proceso puede haber estado haciendo cosas útiles, es decir, consigue solapar parte de cálculo de la aplicación con la comunicación.

Cuando no interesa bloquearse, sino simplemente saber si la operación ha terminado o no, podemos usar MPI_Test (). Esta función actualiza un flan que se le pasa como segundo parámetro. Si la función ha terminado, este flag toma el valor 1, y si no ha terminado pasa a valer 0.

Por último, MPI_Cancel () nos sirve para cancelar una operación de comunicación pendiente, siempre que ésta aún no se haya completado.

A continuación, proponemos un programa de ejemplo de las funciones MPI_Send y MPI_Recv:

char msg [100]; if (my_rank==0) { printf (msg,"\n\n\t Esto es un mensaje del proceso %d al proceso %d", source, dest); MPI_Send (msg, 100, MPI_CHAR, dest, TAG, MPI_COMM_WORLD); printf ("\n Mensaje enviado a %d", dest); } else if (my_rank==1) { MPI_Recv (msg, 100, MPI_CHAR, source, TAG, MPI_COMM_WORLD, &status); printf ("\n Mensaje recibido en %d", dest); printf (msg); }

3.4.4 RECEPCIÓN POR ENCUESTA

Las funciones de recepción de mensajes engloban en una operación la sincronización con el emisor (esperar a que haya un mensaje disponible) con la de

GVA–ELAI–UPM ® PFC 0084 - 2005 41

Page 52: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

comunicación (copiar ese mensaje). A veces, sin embargo, conviene separar ambos conceptos. Por ejemplo, podemos estar a la espera de mensajes de tres clases, cada una asociada a un tipo de datos diferente, y la clase nos viene dada por el valor de la etiqueta. Por lo tanto, nos gustaría saber el valor de la etiqueta antes de leer el mensaje. También puede ocurrir que nos llegue un mensaje de longitud desconocida, y resulte necesario averiguar primero el tamaño para así asignar dinámicamente el espacio de memoria requerido por el mensaje.

Las funciones MPI_Probe () y MPI_Iprobe () nos permiten saber si tenemos un mensaje recibido y listo para leer, pero sin leerlo. A partir de la información de estado obtenida con cualquiera de estas “sondas”, podemos averiguar la identidad del emisor del mensaje, la etiqueta del mismo y su longitud. Una vez hecho esto, podemos proceder a la lectura real del mensaje con la correspondiente llamada a MPI_Recv () o MPI_Irecv ().

int MPI_Iprobe (int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status);

int MPI_Probe (int source, int tag, MPI_Comm comm, MPI_Status *status);

MPI_Probe () es bloqueante: sólo devuelve el control al proceso cuando hay un mensaje listo. MPI_Iprobe () es no bloqueante: nos indica en el argumento flag si hay un mensaje listo o no—es decir, realiza una encuesta.

3.5 TIPOS DE DATOS MANEJADOS POR MPI

Los mensajes gestionados por MPI son secuencias de count elementos del tipo datatype. MPI define una colección de tipos de datos primitivos, correspondientes a los tipos de datos existentes en C. Estos son:

42 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 53: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

Aunque una aplicación desarrollada en C trabaja con los tipos de datos habituales, cuando se realice un paso de mensajes habrá que facilitar a MPI un descriptor del tipo equivalente, tal como lo define MPI. La idea de fondo es la siguiente: los procesadores que participan en una aplicación MPI no tienen por qué ser todos iguales. Es posible que existan diferencias en la representación de los datos en las distintas máquinas. Para eliminar los problemas que puedan surgir, MPI realiza, si son necesarias, transformaciones de sintaxis que posibilitan la comunicación en entornos heterogéneos. La excepción la constituyen los datos de tipo MPI_BYTE, que se copian sin más de una máquina a otra.

3.6 ETIQUETAS Y COMUNICADORES EN MPI

Todo mensaje que se envía con MPI necesariamente ha de ir etiquetado. Este etiquetado se realiza a través del parámetro tag. Mediante el establecimiento de estas etiquetas, podemos diferenciar las diferentes clases de información que pueden intercambiarse los diferentes procesos.

La comunicación se produce dentro de un comunicador (entorno de comunicación), que es básicamente un conjunto de procesos. El comunicador universal MPI_COMM_WORLD está siempre definido, e incluye a todos los procesos que forman parte de la aplicación. Los comunicadores permiten que diferentes grupos de procesos actúen sin interferir, así como dividir la aplicación en

GVA–ELAI–UPM ® PFC 0084 - 2005 43

Page 54: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

fases no solapadas. MPI garantiza la entrega ordenada de mensajes dentro de un mismo comunicador.

3.7 OPERACIONES COLECTIVAS EN MPI

Muchas aplicaciones de MPI son diseñadas o bien requieren la comunicación entre más de dos procesos; es decir, son funciones colectivas. Las funciones colectivas tiene que ser invocadas por todos los participantes en dichas operaciones; además, la mayor parte de estas requieren la designación de un proceso como root, o raíz de la operación. MPI incluye una serie de operaciones colectivas que exponemos a continuación:

3.7.1 BARRERAS DE SINCRONIZACIÓN

Las barreras de sincronización, - (MPI_Barrier ()) -, no exigen ninguna tipo de intercambio de información entre los procesos, ya que esta operación es únicamente de sincronización, de manera que bloquea los procesos de un comunicador hasta que todos ellos pasan por la barrera establecida.

int MPI_Barrier(MPI_Comm comm);

3.7.2 BROADCAST (DIFUSIÓN)

El envío de información en modo difusión, - (MPI_Broadcast ()) -, sirve para que el proceso raíz envíe un mensaje a todos los miembros del comunicador. En esta función todos los participantes en el proceso invocan la misma función, designando un mismo proceso como raíz de la misma.

int MPI_Bcast (void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm);

44 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 55: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

A continuación exponemos un ejemplo de BroadCast:

Char msg [100]; if (my_rank==source) { printf (msg,"\n Esto es un mensaje del proceso %d a todos los demás", source); MPI_Bcast (msg, 100, MPI_CHAR, source, MPI_COMM_WORLD); printf ("\n Mensaje enviado a todos desde %d", source); } else { MPI_Bcast(msg, 100, MPI_CHAR, source, MPI_COMM_WORLD); printf ("\n Mensaje recibido en %d desde %d", my_rank, source); printf (msg); }

Figura 3.3: Esquema de la operación colectiva MPI_Broadcast (): “Buffer envío” indica los contenidos de los bufferes de envío antes de proceder a la operación colectiva. “Buffer recepción” indica los contenidos de los bufferes de recepción

tras completarse la operación.

GVA–ELAI–UPM ® PFC 0084 - 2005 45

Page 56: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

3.7.3 GATHER (RECOLECCIÓN)

En el envío de información en modo recolección, - (MPI_Gather ()) -, se realiza una recolección de datos en el proceso raíz. Este proceso recopila un vector de datos, al que contribuyen todos los procesos del comunicador con la misma cantidad de datos. El proceso raíz almacena las contribuciones de forma consecutiva.

Es el proceso raíz el único que debe preocuparse de los distintos parámetros en juego (recvbuf, recvcount y recvtype). Por el contrario, los valores válidos para los parámetros sendbuf, sendcount y sendtype han de ser facilitados por todos los procesos que entran en juego en el proceso.

También existe una variación de esta función de recolección, llamada MPI_Gatherv (), con la cual podemos almacenar los datos recolectados de forma no consecutiva, y que cada proceso contribuya con bloques de datos de diferente tamaño. La tabla recvcounts establece el tamaño del bloque de datos aportado por cada proceso, y displs indica cuál es el desplazamiento entre bloque y bloque.

int MPI_Gather (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm);

3.7.4 SCATTER (DISTRIBUCIÓN)

En el envío de información en modo distribución, - (MPI_Scatter ()) -, se realiza la operación simétrica a MPI_Gather (). El proceso raíz posee un vector de elementos, uno por cada proceso del comunicador. Tras realizar la distribución, cada proceso tiene una copia del vector inicial.

Si los datos a enviar no están almacenados de forma consecutiva en memoria, o los bloques a enviar a cada proceso no son todos del mismo tamaño, tenemos la función MPI_Scatterv (), que actúa de forma análoga a lo comentado en el apartado anterior para la función MPI_Gather ().

int MPI_Scatter (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm);

46 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 57: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

3.7.5 REDUCCIÓN

Una reducción es una operación realizada de forma cooperativa entre todos los procesos de un comunicador, de tal forma que se obtiene un resultado final que se almacena en el proceso raíz.

MPI define una colección de operaciones del tipo MPI_Op que se pueden utilizar en una reducción: MPI_MAX (máximo), MPI_MIN (mínimo), MPI_SUM (suma), MPI_PROD (producto), MPI_LAND (and lógico), MPI_BAND (and bit a bit), MPI_LOR (or lógico), MPI_BOR (or bit a bit), MPI_LXOR (xor lógico), MPI_BXOR (xor bit a bit), etc.

La operación a realizar puede ser cualquiera. En general se emplean operaciones conmutativas y asociativas, es decir, cuyo resultado no depende del orden con el que se procesan los operandos. Eso se indica con el valor 1 en el parámetro conmute. Si la operación no es conmutativa (conmute = 0) entonces se exige que la reducción se realice en orden de dirección (se empieza con el proceso 0, luego con el 1, con el 2, etc.).

En ocasiones resulta útil que el resultado de una reducción esté disponible para todos los procesos. Aunque se puede realizar un broadcast tras la reducción, podemos combinar la reducción con la difusión usando MPI_Allreduce (). Si el resultado de la reducción es un vector que hay que distribuir entre los procesadores, podemos combinar la reducción y la distribución usando MPI_Reduce_scatter ().

int MPI_Reduce (void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);

Un ejemplo de MPI_Reduce es:

int value; int result; value = my_rank;

GVA–ELAI–UPM ® PFC 0084 - 2005 47

Page 58: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

MPI_Reduce (&value, &result, 1, MPI_INT,MPI_SUM,source,MPI_COMM_WORLD); if (my_rank==source) { printf ("\n Resultado de la suma colectiva %d", result); }

Figura 3.6: Esquema de comunicación de MPI_Scatter

Figura 3.4: Esquema de la operación colectiva MPI_Gather ()

Figura 3.5: Esquema de la operación colectiva MPI_Scatter ()

48 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 59: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

3.7.6 COMUNICACIÓN TODOS CON TODOS (ALL-TO-ALL)

La comunicación de todos los nodos con todos los nodos supone que, inicialmente, cada proceso tiene un vector con tantos elementos como procesos hay en el comunicador.

Para i, j y k entre 0 y N-1 (donde N es el número de procesos del comunicador), cada proceso i envía una copia de sendbuf[j] al proceso j, y recibe del proceso k un elemento, que almacena en recvbuf[k]. MPI_Alltoall () equivale, por tanto, a una sucesión de N operaciones de distribución, en cada una de las cuales el proceso i toma el rol de raíz.

int MPI_Scatter (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm);

Figura 3.7: Esquema de la operación colectiva MPI_Alltoall ()

3.8 MODULARIDAD

MPI permite definir grupos de procesos. Un grupo de procesos es una colección de procesos, y define un espacio de direcciones (desde 0 hasta N-1, donde N es el tamaño del grupo). Los miembros del grupo tienen asignada una dirección dentro de él. Un proceso puede pertenecer simultáneamente a varios grupos, y tener una dirección distinta en cada uno de ellos.

GVA–ELAI–UPM ® PFC 0084 - 2005 49

Page 60: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

Un comunicador consiste en un grupo de procesos, y un contexto de comunicación. Las comunicaciones producidas en dos comunicadores diferentes nunca interfieren entre sí. Este concepto se introdujo para facilitar la elaboración de bibliotecas de programas: el programa de un usuario se ejecuta en un comunicador, y las funciones de la biblioteca en otro diferente. De esta forma no existe el riesgo de que se mezclen mensajes del usuario con mensajes privados de las funciones de la biblioteca, y tampoco hay problemas a la hora de usar etiquetas.

Entre las funciones más comunes sobre comunicadores podemos encontrar las siguientes:

• MPI_Comm_size (): utilizada para averiguar el número de procesos de un comunicador. Su estructura es:

int MPI_Comm_size (MPI_Comm comm, int *size);

• MPI_Comm_rank (): utilizada para que un proceso obtenga su identificación dentro del comunicador. Su estructura es:

int MPI_Comm_rank (MPI_Comm comm, int *rank);

• MPI_Comm_dup (): esta función nos permite crear un nuevo comunicador, con el mismo grupo de procesos, pero diferente con texto. Se puede usar antes de llamar a una función de una biblioteca. Su estructura es:

int MPI_Comm_dup (MPI_Comm comm, MPI_Comm *newcomm);

MPI_Comm_dup (MPI_COMM_WORLD, &newcomm);

/* llamada a función, que se ejecutará dentro */

/* de newcomm */

MPI_Comm_free (&newcomm); …

50 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 61: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

• MPI_Comm_free (): esta función destruye un comunicador que ya no es empleado.

• MPI_Comm_split (): a través de esta función creamos, a partir de un comunicador inicial, varios comunicadores diferentes, cada uno con un conjunto disjunto de procesos. El color determina en qué comunicador queda cada uno de los procesos. Su estructura es:

int MPI_Comm_split (MPI_Comm comm, int color, int key, MPI_Comm *newcomm);

Figura 3.8: Utilización de un comunicador para aislar una función de biblioteca.

Figura 3.9: Arriba: una colección de procesos en el comunicador MPI_COMM_WORLD. Abajo, dos comunicadores: uno con los procesos con dirección global par, y otro con los

procesos con dirección global impar.

GVA–ELAI–UPM ® PFC 0084 - 2005 51

Page 62: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

Figura 3.10: Creación de un intercomunicador entre los dos comunicadores de la Figura 9.

3.9 INSTALACIÓN Y CONFIGURACIÓN DE MPICH

3.9.1 INSTALACIÓN

Para poder llevar a cabo la realización de aplicaciones basadas en el procesamiento paralelo, es necesario la instalación y configuración de la herramienta adecuada para ello. En este caso emplearemos el software MPICH, que podemos encontrar en la web de MPI (www.mcs.anl.gov/mpi/mpich/). En esta sección tendremos que descargarnos los dos ejecutables (mpich.nt.1.2.5.exe y mpich.nt.1.2.5.src.exe). Para que el programa funcione satisfactoriamente será necesario realizar su instalación en cada uno de los nodos de que se compone nuestro cluster.

Con la instalación de MPICH en nuestro equipo se crean una serie de aplicaciones:

1. MPICH JOB MANAGER: permite comprobar si los nodos del cluster tienen trabajos pendientes.

2. MPI UPDATE TOOL: herramienta que permite la actualización del software.

52 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 63: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

3. MPI CONFIGURATION TOOL: permite acceder a la configuración de MPI en cada uno de los nodos donde se encuentre instalado.

4. MPIRUN: ejecutable que lanza la aplicación.

3.9.2 CONFIGURACIÓN

Tendremos que configurar MPICH en cada uno de los nodos de nuestro cluster. Para ello, deberemos seguir los siguientes pasos:

1. Lanzamos la aplicación MPI CONFIGURATION TOOL. Nos aparece un GUI en donde deberemos añadir los nodos en donde está instalado MPICH. Pinchamos en el botón SELECT y nos aparece otra pantalla con en nombre de select hosts. Pinchamos en el botón ACTION y dentro de este, en scan hosts. El programa reconoce los nodos en donde MPICH está instalado. Pinchamos a continuación en OK, después en APPLY y por último en OK:

GVA–ELAI–UPM ® PFC 0084 - 2005 53

Page 64: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

2. Lanzamos el ejecutable de MPICH, MPIRUN.exe. Para poder llevar a cabo la ejecución del programa, es necesario que la aplicación que queramos que se ejecute de forma paralela se encuentre en el mismo directorio en todos los nodos del cluster.

3. Finalmente seleccionamos los hosts en donde queremos que se ejecute nuestra aplicación paralela y pulsamos RUN. En la ventana de OUTPUT nos deberá aparecer el host en donde se está ejecutando el proceso y el propio ejecutable:

54 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 65: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

3.10 GENERACIÓN DE APLICACIONES MPI CON VISUAL STUDIO C++

Los pasos a seguir serán los siguientes:

1. Debemos crear un nuevo proyecto del tipo WIN32 CONSOLE APLICATION. En cuanto al tipo de archivo, será un C++ SOURCE FILE.

2. Escribimos la aplicación a ejecutar, con la estructura que marca el punto 1.1.4.

3. Vamos a las propiedades del proyecto dentro de PROYECT → SETTINGS. Seleccionamos C/C++. Configuramos las propiedades para WIN32 DEBUG. En la pestaña Use run-time library, seleccionamos la opción Multithreaded.

GVA–ELAI–UPM ® PFC 0084 - 2005 55

Page 66: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

4. Configuramos las propiedades para WIN32 RELEASE. En la pestaña Use run-time library, seleccionamos la opción Multithreaded.

5. Configuramos las propiedades para ALL CONFIGURATIONS. En la pestaña de Additional include directories, incluimos el path en donde se encuentre la carpeta Include de MPICH.

56 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 67: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

6. Seleccionamos LINK y dentro de este apartado, la opción INPUT. En la pestaña de Additional library path, incluimos el path en donde se encuentre la carpeta Lib de MPICH.

GVA–ELAI–UPM ® PFC 0084 - 2005 57

Page 68: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

7. Configuramos las propiedades para WIN32 DEBUG. En la pestaña de Object/library modules, añadimos lo siguiente: mpichd.lib.

8. Configuramos las propiedades para WIN32 RELEASE. En la pestaña de Object/library modules, añadimos lo siguiente: mpich.lib.

58 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 69: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

9. Para ALL CONFIGURATIONS. En la pestaña de Object/library modules, añadimos lo siguiente: ws2_32.lib.

10. Pinchamos en OK y salimos.

11. Construimos el proyecto.

GVA–ELAI–UPM ® PFC 0084 - 2005 59

Page 70: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

3.11 UN EJEMPLO CONCRETO

A continuación vamos a exponer un ejemplo de una aplicación paralela que utiliza MPICH para su ejecución y que ha sido implementada a través de Microsoft Visual Studio. La aplicación consiste en un cluster compuesta por tres nodos, que en nuestro caso serán los procesadores EINSTEIN (nodo 0), GAUSS (nodo 1) y NEWTON (nodo 2). El objetivo del programa es sencillo; básicamente es un conversor de euros a pesetas, con la siguiente estructura:

• El nodo 0 (EINSTEIN) es el encargado de lanzar la aplicación y en donde ejecutamos el menú de selección de la conversión que queremos realizar (pesetas → euros o euros → pesetas). También es el encargado de recibir la cantidad a convertir.

• El nodo 1 (GAUSS) es el encargado de realizar la conversión de euros a pesetas. Este nodo recibe del nodo 0 la cantidad de euros a convertir, realiza la conversión, y posteriormente, envía el resultado de vuelta al nodo 0.

• El nodo 2 (NEWTON) es el encargado de realizar la conversión de pesetas a euros. Este nodo recibe del nodo 0 la cantidad de pesetas a convertir, realiza la conversión, y posteriormente, envía el resultado de vuelta al nodo 0.

El programa tiene la siguiente estructura:

#include "stdio.h" #include "conio.h" #include "mpi.h" #define K 166.386 int main(int argc, char **argv) { int ME, Nproc; int namelen; char processor_name[MPI_MAX_PROCESSOR_NAME];

60 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 71: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

MPI_Status status; MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &ME); MPI_Comm_size (MPI_COMM_WORLD, &Nproc); MPI_Get_processor_name (processor_name, &namelen); fprintf(stderr,"Proceso %d ejecutado en el procesador %s\n",ME, processor_name); fflush (stderr); if (ME==2) { int resultado,pesetas; MPI_Recv (&pesetas, 0, MPI_INT, 0, 45, MPI_COMM_WORLD, &status); Resultado=pesetas/K; MPI_Send (&resultado, 2, MPI_INT,0,45,MPI_COMM_WORLD); }; if(ME==1) { int resultado,euros; MPI_Recv (&euros, 0, MPI_INT, 0, 45, MPI_COMM_WORLD, &status); resultado=euros*K; MPI_Send (&resultado, 1, MPI_INT, 0, 45, MPI_COMM_WORLD); }; if(ME==0) { int opcion; printf("Bienvenido al menu de seleccion. Por favor, escoge una opcion:\n"); printf("1: Conversion de pesetas a euros\n"); printf("2: Conversion de euros a pesetas\n"); printf("3: Salir del programa\n"); scanf ("%d",&opcion); if (opcion<1 || opcion>3){ printf("Ha escogido una opcion erronea\n"); getch(); } if(opcion==1){ int pesetas,resultado; printf("Ha escogido la conversion de pesetas a euros\n");

GVA–ELAI–UPM ® PFC 0084 - 2005 61

Page 72: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

printf("Por favor, escriba la cantidad en pesetas a convertir: \n"); scanf ("%f",&pesetas); MPI_Send (&pesetas, 0, MPI_INT, 2, 45, MPI_COMM_WORLD); MPI_Recv (&resultado, 2, MPI_INT, 2, 45, MPI_COMM_WORLD, &status); printf("%f pesetas son %f euros\n",pesetas,resultado); } if(opcion==2){ int euros,resultado; printf ("Ha escogido la conversion de euros a pesetas\n"); printf ("Por favor, escriba la cantidad en euros a convertir: \n"); scanf ("%f", &euros); MPI_Send (&euros, 0, MPI_INT, 1, 45, MPI_COMM_WORLD); MPI_Recv (&resultado, 1, MPI_INT, 1, 45, MPI_COMM_WORLD, &status); printf ("%f euros son %f pesetas\n", euros, resultado); } if (opcion==3) { printf ("Ha escogido salir del programa. Que tenga un buen dia\n"); getch (); } getch (); } }

Una vez ejecutado la aplicación, en el GUI de MPICH tendrá que aparecer una pantalla similar a esta, que nos indicará que el programa se ha ejecutado correctamente:

62 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 73: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con MPI

GVA–ELAI–UPM ® PFC 0084 - 2005 63

Page 74: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con MPI Miguel Hernández Vázquez

64 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 75: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

4 Procesamiento Distribuido de Imágenes Genérico con VTK

En este tercer capítulo vamos a tratar en profundidad una de las implementaciones que vamos a utilizar para llevar a cabo la realización de aplicaciones paralelas: VTK. Veremos como se implementan aplicaciones paralelas sencillas basadas en VTK y también como VTK trata el procesamiento distribuido de imágenes genérico.

GVA–ELAI–UPM ® PFC 0084 - 2005 65

Page 76: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

4.1 ¿QUÉ ES VTK?

VTK nos proporciona un sistema de visualización por software que nos permite, además de poder visualizar geometría, soportar una amplia variedad de algoritmos de visualización y otras modernas de modelado. Aunque VTK no proporciona ningún componente de interfaz de usuario, puede ser integrado con Tk o X/Motíf.

VTK proporciona una variedad de representaciones de datos, incluyendo conjunto de puntos desorganizados, datos poligonales, imágenes, volúmenes y mallas estructuradas, rectilíneas y destructuradas. VTK incluye lectores/importadores y escritores/exportadores para intercambiar datos con otras aplicaciones. Cientos de filtros de procesamiento de datos son capaces de operar con estos datos, oscilando entre la convolución de imágenes y la triangulación Delaunay. El modelo de renderizado de VTK soporta 2D, poligonal, volumétrico y texturas aprovechando que puede ser utilizado en cualquier combinación.

VTK es uno de los sistemas de visualización que podemos utilizar hoy en día. AVS fue uno de los primeros sistemas puestos a disposición de los usuarios. IBM´s Data Explorer (DX), originalmente un producto comercial, es ahora una aplicación open-source (código abierto) conocida como OpenDX. NAG Explorer y Template Graphics Amira son otras aplicaciones populares.

VTK es un sistema de propósito general usado en una gran variedad de aplicaciones, como podemos ver en la figura 12.

VTK (Visualization ToolKit) son un conjunto de librerías que se utilizan para la visualización y el procesamiento de imágenes, aunque también se usan para la generación de objetos gráficos 2D y 3D. Las librerías VTK constan de código abierto y software orientado a objetos. A pesar de ser muy extensas y complejas, se han diseñado con vistas a ser usadas por cualquier lenguaje de programación orientado a objetos, como puedan ser C++, Java, Tcl, Python, etc.

Figura 4.1: Logo de VTK

66 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 77: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

Figura 4.2: VTK puede ser usado en diversas áreas incluyendo la visualización médica (izquierda) y aplicaciones de inspección industrial (derecha)

Debido a que VTK es una aplicación open-source, es de gran difusión en muchas universidades, - como la Universidad de Nueva York, la Universidad de Ohio, Stanford, etc. Laboratorios nacionales como Los Álamos están adaptando VTK al procesamiento paralelo a gran escala. VTK también puede aplicarse a otros muchos campos: la visualización médica, la exploración petrolífera, la mecánica de fluidos, la reconstrucción de superficies a partir de la digitalización con láser, etc.

4.2 ARQUITECTURA DE VTK

VTK consta de dos partes fundamentales: un núcleo compilado (implementado en C++) y una capa de interpretación generada automáticamente. La capa de interpretación soporta Tcl, Java y Pitón.

4.2.1 El NÚCLEO DE C++

Las estructuras de datos, los algoritmos y las funciones de sistema de tiempo crítico están implementadas en el núcleo de C++. Los modelos de diseño más comunes como los objetos y las funciones virtuales aseguran portabilidad y extensibilidad. Debido a que VTK es independiente de cualquier interfaz gráfico de usuario (GUI), no depende del sistema de ventanas que estemos empleando. Se acopla dentro del sistema que estemos utilizando e incluso permite su portabilidad a otro tipo de aplicaciones.

GVA–ELAI–UPM ® PFC 0084 - 2005 67

Page 78: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

4.2.2 LA CAPA DE INTERPRETACIÓN

Mientras el núcleo nos proporciona velocidad y eficiencia, la capa de interpretación nos ofrece flexibilidad y extensibilidad. Por ejemplo, usando herramientas como Tcl/Tk, Pitón/Tk o Java AWT nos permite el desarrollo de aplicaciones rápidamente.

4.3 GRAPHICS MODEL

VTK consta de dos grandes subsistemas – el graphics model y el visualization model. El graphics model forma una capa abstracta por encima del lenguaje de los gráficos (por ejemplo, OpenGL) para asegurar la portabilidad entre las diferentes plataformas. Cuando el desarrollo de VTK comenzó en 1993, la plataforma de cada computadora tenía su propio lenguaje gráfico – XGL para Sun, Starbase para HP y gl para Silicon Graphics. Los conceptos de gráficos abstractos y capas independientes de los dispositivos crearon el modelo gráfico. Desde ese momento la industria ha adoptado el estándar de OpenGL. Aunque ahora este es sólo uno de los lenguajes gráficos de bajo nivel que soporta VTK, la capa abstracta no ha sido abandonada. En el futuro, nuevos lenguajes gráficos serán más populares pudiendo incluso llegar a remplazar a OpenGL como estándar. El mantenimiento de esta capa abstracta nos permite actualizar a VTK con nuevos desarrollos tecnológicos sin afectar a la compatibilidad con desarrollos anteriores.

Hemos tomado los nombres de las clases en el graphics model de la industria cinematográfica. Luces, cámaras, actores y props son clases que el usuario necesita para crear una escena. Encontraremos que el modelo usado para el renderizado de polígonos 3D (luces, cámaras, actores) es análogo al usado para el volumen u otro tipo de renderizados (luces, cámaras, actores).

68 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 79: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

Mediante la combinación de todos los objetos que componen el Graphics Model creamos una escena. Los objetos principales que componen el Graphics Model son los siguientes:

Figura 4.3: Dos renders en una ventana de renderizado combinando volumen, superficie y renderizado 2D. El render de la izquierda contiene un cubo; el de la derecha contiene una superficie poligonal y el renderizado del volumen de un electrón.

• vtkActor, vtkActor2D, vtkVolume: representa lo que vemos en escena. No se representan directamente su geometría, sino que esta se ve referida a “mappers”, una de cuyas funciones es la de representación de los datos.

• vtkLight: se usan para representar y manipular la iluminación de la escena. Solo se emplean en visualizaciones 3D.

• vtkCamera: controla cómo la geometría 3D es proyectada en imagen 2D durante el proceso de renderización. Tiene varios métodos para posicionar y orientar, controla la perspectiva de la proyección y la visión estéreo.

• vtkProperty, vtkProperty2D.

• vtkMapper, vtkMapper2D: se usa para transformar y renderizar geometría. El mapper proporciona la interfaz entre el pipeline de visualización y el graphics model.

• vtkTransform.

GVA–ELAI–UPM ® PFC 0084 - 2005 69

Page 80: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

• vtkLookupTable, vtkColorTransferFunction: se usan para transformar y renderizar geometría. VtkLookupTable es una subclase de vtkScalarsToColors, también lo es vtkColorTransferFunction, la cual se usa para renderizar volúmenes. Las subclases de vtkScalarsToColors son responsables de “mapear” los valores de los datos a color.

• vtkRenderer: se usa para dirigir la interfaz entre la “máquina gráfica” y el sistema de ventanas del ordenador.

• vtkRenderWindow: se usan para dirigir la interfaz entre la “máquina gráfica” y el sistema de ventanas del ordenador. La render window es la ventana del ordenador donde el renderer crea el objeto.

• vtkRenderWindowInteractor: es uno de los métodos utilizados en VTK para interactuar con los datos de la escena. Es una herramienta que utilizamos para manipular la cámara, mover objetos, etc.

4.3.1 LA VENTANA DE RENDERIZADO (WINDOW RENDER)

Para poder visualizar nuestros datos, lo primero que necesitamos es abrir una ventana en la pantalla de nuestro ordenador. VtkRenderWindow es una superclase abstracta que utilizamos para la representación de objetos que hemos dibujado en uno o más renders. Para la mayor parte de los objetos gráficos, automáticamente seleccionan el dispositivo correcto en cada plataforma para su visualización. VtkRenderWindow es una clase contenedora para objetos vtkRenderer, y múltiples renders pueden ser colocados en una única ventana de renderizado para crear visualizaciones complejas.

En el siguiente ejemplo, colocaremos dos renders con colores de fondo diferentes uno junto a otro en una misma ventana de renderizado:

vtkRenderWindow renWin renWin SetSize 600 300 vtkRenderer ren1 ren1 SetViewport 0.0 0.0 0.5 1.0

70 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 81: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK ren1 SetBackground 0.8 0.4 0.2 renWin AddRenderer ren1 vtkRenderer ren2 ren1 SetViewport 0.5 0.0 1.0 1.0 ren1 SetBackground 0.1 0.2 0.4 renWin AddRenderer ren2 RenWin Render

El objeto vtkRenderWindow controla el proceso, de forma que una única llamada a Render provocará la aparición de una ventana y los renders actualizarán su contenido. En este ejemplo sólo aparecerá un único color de fondo debido a que no hemos definido ningún prop.

4.3.2 RENDERS, MAPPERS Y PROPS

Los props son los objetos añadidos al render para crear una escena. La clase vtkProp es una superclase abstracta válida para todos los props 2D y 3D y contiene información sobre visibilidad, orientación, tamaño y posición. Los props se asocian con los mappers y las propiedades del objeto.

Los mappers se refieren a los objetos de entrada, y saben la forma de renderizar estos objetos.

Las propiedades de los objetos contienen parámetros del renderizado como el color y las características del material.

4.3.3 RENDERIZADO 3D DE DATOS GEOMÉTRICOS

Una subclase específica de vtkProp que puede ser empleada para la representación 3D de datos geométricos en una escena es vtkActor. El actor generará automáticamente un vtkProperty object por defecto, pero requiere que el usuario

GVA–ELAI–UPM ® PFC 0084 - 2005 71

Page 82: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

especifique una subclase de vtkMapper. Dependiendo de la naturaleza de la geometría referida al mapper, debemos usar bien la subclase vtkDataSetMapper o vtkPolyDataMapper. Si los datos contienen puntos, líneas y polígonos representados usando vtkPolyData, entonces usaremos vtkPolyDataMapper. De otra manera usaremos vtkDataSetMapper.

A continuación presentaremos un ejemplo. El siguiente fragmento de código Tcl puede ser usado para crear un cubo y colocarlo en una escena:

vtkCubeSource cubeData vtkPolyDataMapper cubeMapper cubeMapper SetInput \ [cubeData GetOutput] vtkActor cubeActor cubeActor SetMapper cubeMapper ren1 AddProp cubeActor ren1 ResetCamera RenWin Render

Como la salida de vtkCubeSource es un dato poligonal, emplearemos vtkPolyDataMapper.

El siguiente fragmento de código Tcl gira el cubo y cambia su color:

cubeActor RotateX 30.0 cubeActor RotateY 20.0 [cubeActor GetProperty] \ SetColor 1.0 0.7 0.7 renWin Render

72 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 83: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

4.3.4 RENDERIZADO 3D DE DATOS VOLUMÉTRICOS

El objeto vtkImageData puede ser usado para representar imágenes de 1, 2 o 3 dimensiones. Como subclase de vtkDataSet, vtkImageData puede ser representado por un vtkActor y renderizado con un vtkDataSetMapper. En 3D estos datos pueden ser considerados como un volumen. Como alternativa, puede ser representado por un vtkVolume y renderizado por una subclase de vtkVolumeMapper. Como algunas subclases de vtkVolumeMapper usan técnicas geométricas para renderizar los volúmenes, la distinción entre volúmenes y actores aumenta.

VTK soporta actualmente tres tipos de renderizado de volúmenes – ray tracing, 2D texture mapping y un método que usa VolumePro graphics borrad.

A continuación veremos un ejemplo que utiliza 2D texture mapping. Para comenzar con nuestro ejemplo, partiremos de una estructura 3D conformada de valores unsigned y la usaremos como entrada para vtkVolumeTectureMapper2D:

vtkSLCReader negReader negReader SetFileName “neghip.slc” vtkVolumeTextureMapper2D negMapper negMapper SetInput \ [negReader GetOutput]

El paso más complicado en la visualización de volúmenes es frecuentemente la definición de las funciones de transferencia que transforman los datos escalares en color y opacidad:

vtkPieceWiseFunction negOpacity negOpacity AddPoint 0 0.0 negOpacity AddPoint 255 0.2 vtkColorTransferFunction negColor NegColor AddRGBPoint 64 1.0 0.0 0.0 NegColor AddRGBPoint 128 0.0 0.0 1.0 NegColor AddRGBPoint 196 0.0 1.0 0.0

GVA–ELAI–UPM ® PFC 0084 - 2005 73

Page 84: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

El primer valor que definimos cuando añadimos un punto a una función de transferencia es siempre el valor escalar, con un valor seguido por vtkPiecewiseFunction o un RGB triple seguido de vtkColorTransferFunction. Como estamos visualizando datos de 8 bits, los valores escalares van desde 0 a 255.

A continuación definimos las dos funciones de transferencia requeridas para la definición de las propiedades del volumen y la creación del volumen:

vtkVolumeProperty negProperty negProperty SetColor negColor negProperty SetScalarOpacity \ negOpacity vtkVolume negVolume negVolume SetMapper negMapper negVolume SetProperty negProperty ren2 AddProp negVolume ren2 ResetCamera RenWin Render

74 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 85: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

Figura 4.4: Objetos dataset en VTK

GVA–ELAI–UPM ® PFC 0084 - 2005 75

Page 86: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

4.3.5 COMBINACIÓN DE LA GEOMETRÍA Y LAS LUCES

El proceso de renderizado de VTK puede combinar múltiples actores y volúmenes en la misma escena.

En el siguiente ejemplo una superficie poligonal es representada combinada con un volumen:

vtkPolyDataReader posReader posReader SetFileName \ “poshipsurface.vtk” vtkPolyDataMapper posMapper posMapper SetInput \ [posReader GetOutput] vtkActor posActor posActor SetMapper posMapper ren2 AddProp posActor RenWin Render

El proceso combinado de renderización de VTK tiene una serie de limitaciones:

1. VTK no soporta la translucidez de los datos geométricos debido a que las primitivas no están ordenadas de atrás hacia delante antes del renderizado.

2. Múltiples volúmenes pueden ser renderizados en la misma escena sólo si los límites de los volúmenes no se solapan.

76 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 87: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

4.3.6 RENDERIZADO DE DATOS 2D

Además de volúmenes y datos 3D, VTK también visualiza datos 2D como imágenes y texto. El concepto de actores, mappers y propiedades se puede aplicar tanto a datos 2D como a 3D, aunque algunos parámetros específicos cambian. Veamos el siguiente ejemplo:

vtkTextMapper titleMapper titleMapper SetInput \ “This is a Pink Cube” titleMapper \ SetJustificationToCentered vtkActor2D titleActor titleActor SetMapper titleMapper [titleActor GetProperty] \ SetColor 1 1 0 set pc [titleActor \ GetPositionCoordinate] $pc SetCoordinateSystemToNormalized- Viewport $pc SetValue 0.5 0.92 ren1 AddProp titleActor RenWin Render

Figura 4.5: Una red de visualización de VTK. Los Process objects (filtros) aparecen como esferas rojas y los Data objects como cubos azules. Los otros objetos representan props,

propiedades, el render y la ventana de renderizado.

GVA–ELAI–UPM ® PFC 0084 - 2005 77

Page 88: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

El código necesario para cambiar el color del texto puede parecerse al código para cambiar el color del cubo. Sin embargo, los actores 3D son posicionados usando World coordinates, mientras que elegimos la posición del actor 2D a través de un sistema de coordenadas normalizado.

Como los datos 2D son frecuentemente utilizados para la anotación, VTK ofrece varios objetos que combinan múltiples actores 2D y mappers en un solo actor 2D. Por ejemplo, vtkScalarBarActor combina texto y polígonos 2D para mostrar una representación:

vtkScalarBarActor scalarBar scalarBar SetLookupTable negColor scalarBar SetTitle “Density” set sPC \ [scalarBar GetPositionCoordinate] $sPC SetCoordinateSystemTo- NormalizedViewport $sPC SetValue 0.8 0.1 ren2 AddProp scalarBar renWin Render

4.3.7 LUCES, CÁMARAS E INTERACTUACIÓN DE LOS DIFERENTES OBJETOS

Muchas aplicaciones nunca crean explícitamente un vtkLight o vtkCamera, sino que el render los crea automáticamente si no son definidos en el primer render. Una vez que el sistema crea una cámara, puedes acceder a ella desde el render para cambiar los parámetros de la cámara, como la posición, el punto focal y el campo de visión. La cámara posee algunos métodos adecuados para el giro de la posición y el punto focal como Azimuth, Elevation, Roll, Pitch y Yaw:

set cam [ren2 GetActiveCamera] $cam Azimuth 20.0 $cam Elevation 10.0 RenWin Render

78 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 89: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

La luz creada automáticamente es una luz blanca con la misma posición y punto focal que el de la cámara. Si usamos un interactor, esta luz seguirá a la cámara. Podemos usar el siguiente código para añadir una segunda luz a la escena de renderizado del volumen. Esta luz viene de la derecha y es verde. Como la iluminación está desactivada por defecto, la luz verde no alterará el volumen:

vtkLight light light SetFocalPoint 0.0 0.0 0.0 light SetPosition 1.0 0.0 0.0 light SetColor 0.0 1.0 0.0 light SetIntensity 0.5 ren2 AddLight light renWin Render

Preferimos usar el ratón para controlar la posición de la cámara y su orientación, y los props en la escena. VtkRenderWindowInteractor proporciona esta funcionalidad y puede ser activado de la siguiente forma:

vtkRenderWindowInteractor iren iren SetRenderWindow renWin iren Initialize

El interactor puede ser colocado en modo joystick o trackball usando las teclas “j” o “t”. El botón izquierdo del ratón controla la rotación; el botón central controla la traslación del plano focal; el botón derecho controla el zoom. La tecla “r” se usa para resetear todas las funciones de la cámara.

VTK también proporciona interactuación entre el usuario y la aplicación, como muestra el siguiente código:

proc changeTitle {} { titleMapper SetInput [.top.entry \ get] renWin Render }

GVA–ELAI–UPM ® PFC 0084 - 2005 79

Page 90: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

Toplevel .top Entry .top.entry .top.entry insert 0 \ {This is a Pink Cube} Pack .top.entry Bind .top.entry <Return> changeTitle

4.4 VISUALIZATION MODEL

El pipeline de procesamiento de datos de VTK transforma los datos de forma que puedan ser visualizados en los subsistemas gráficos descritos con anterioridad. Por ejemplo, podemos leer un conjunto de puntos desorganizados, crear una red poligonal a través de la triangulación Delaunay para después visualizarlos usando el renderizado poligonal.

El modelo Visualization Model es el encargado de construir la representación geométrica que será renderizada por el pipeline gráfico. Los objetos principales que componen el Visualization Model son los siguientes:

• vtkDataObject: Los “data objects” representan datos de varios tipos. La clase vtkDataObject puede interpretarse como un conjunto genérico de datos. A los datos que tienen una estructura formal se les llama “dataset” (de la clase vtkDataSet).

• vtkProcessObject: Los “process objects”, también llamados filtros, operan en los data objects para generar nuevos data objects. Representan los algoritmos del sistema. Process y data objects se conectan para formar los pipelines de visualización.

4.4.1 ARQUITECTURA DEL PIPELINE

El pipeline, o de forma alternativa, la red de visualización, se construye conectando Process objects y Data objects. Los Data objects representan y

80 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 91: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

proporcionan el acceso a los datos, y los Process objects operan sobre los Data objects. Estas redes pueden ser elaboradas y pueden incluir ramas y vueltas. En la implementación, los conectores pueden hacerse usando SetInput ()/GetOutput ():

aFilter SetInput [bFilter \ GetOutput]

ADVERTENCIA: los Data objects no se crean explícitamente.

Una vez construido, la ejecución de la visualización del pipeline debe ser cuidadosamente controlada. Los filtros sólo deberían reejecutarse cuando su estado interno cambie o cuando la salida del filtro cambie. VTK emplea un proceso de actualización distribuido. Cada objeto en VTK mantiene un tiempo interno que es automáticamente actualizado cuando el estado del objeto cambia (generalmente como resultado del establecimiento del valor de una variable). Los Process y Data objects mantienen tiempos adicionales que son actualizados cuando se ejecuta el pipeline. El sistema compara estos tiempos (cada uno de los cuales es único, monótonamente creciente, de valor unsigned) para determinar cuales objetos están desfasados y por lo tanto que parte de la red debemos reejecutar. Muchos sistemas de visualización utilizan un control ejecutivo para controlar la ejecución de la red, lo que puede llegar a producir cuellos de botella en grandes aplicaciones paralelas. El mecanismo de ejecución distribuida de VTK permite un procesamiento paralelo escalable.

4.4.2 LOS DATA OBJECTS

La figura muestra los Data objects que soporta VTK. Los Data objects representan información muy general como un campo (un array o arrays). Los Data sets son una especialización de los Data objects con estructura topológica y geométrica. Además de su estructura, los Data sets también tiene attribute data asociados con su topología y/o estructura. Los attribute data consisten en escalares, vectores, tensores, normales, etc.

GVA–ELAI–UPM ® PFC 0084 - 2005 81

Page 92: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

4.4.3 LOS PROCESS OBJECTS

VTK ofrece varios cientos de Process objects. Muchos de los filtros operan sobre un único tipo de dato (por ejemplo, los filtro de procesamiento de imágenes). Algunos filtros como vtkContourFilter acepta como entrada un solo tipo (volumen) y genera una salida de otro tipo (polígonos).

Los Process objects son asemejados normalmente a filtros. Específicamente, VTK clasifica a los Process objects en tres categorías: fuentes, filtros y mappers. Las fuentes no tienen entradas de datos de VTK, pero producen una o más salidas; los filtros aceptan una o más entradas y generan una o más salidas; los mappers finalizan la visualización del pipeline, bien acoplándolo al subsistema gráfico o escribiendo sus datos en un disco o en una red.

82 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 93: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

4.5 EJEMPLOS

A continuación vamos a crear un pipeline complejo. Este ejemplo lee un conjunto de datos poligonales generados desde una digitalización de láser, y aplicando una serie de filtros, genera una superficie normal:

vtkBYUReader reader reader SetGeometryFileName “fran.g”

A continuación generamos el pipeline, consistente en un decimator, smoother y un generador normal:

vtkDecimatePro deci deci SetInput [reader GetOutput] deci SetTargetReduction 0.9 deci PreserveTopologyOn vtkSmoothPolyDataFilter smoother smoother SetInput [deci GetOutput] vtkPolyDataNormals normals normals SetInput [smoother \ GetOutput] normals SetFeatureAngle 60 vtkPolyDataMapper mapper mapper SetInput [normals GetOutput] vtkActor fran fran SetMapper mapper [fran GetProperty] \ SetColor 1 0.49 0.25

La primera entrada es un Data set que contiene algunos puntos; la segunda define un glyph representado con datos poligonales. Usamos el filtro vtkMaskPoints para seleccionar al azar los puntos del glyph:

GVA–ELAI–UPM ® PFC 0084 - 2005 83

Page 94: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

vtkMaskPoints ptMask ptMask SetInput [normals GetOutput] ptMask SetOnRatio 10 ptMask RandomModeOn vtkConeSource cone cone SetResolution 6 vtkTransform transform transform Translate 0.5 0.0 0.0 vtkTransformPolyDataFilter \ TransformF transformF SetInput [cone GetOutput] transformF SetTransform transform vtkGlyph3D glyph glyph SetInput [ptMask GetOutput] glyph SetSource [transformF \ GetOutput] glyph SetVectorModeToUseNormal glyph SetScaleModeToScaleByVector glyph SetScaleFactor 0.004 vtkPolyDataMapper spikeMapper spikeMapper SetInput [glyph GetOutput] vtkActor spikeActor spikeActor SetMapper spikeMapper [spikeActor GetProperty] \ SetColor 0 .79 .34

A continuación añadimos los dos actores al render y renderizamos la escena:

vtkRenderer ren3 vtkRenderWindow renWin2 renWin2 AddRenderer ren3

84 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 95: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK vtkRenderWindowInteractor iren2 iren2 SetRenderWindow renWin2 ren3 AddActor fran ren3 AddActor spikeActor renWin2 Render

Figura 4.6: esta figura muestra una malla poligonal adquirida de un escáner de láser que ha sido decimated, smoothed y glyphed para indicar la superficie normal.

GVA–ELAI–UPM ® PFC 0084 - 2005 85

Page 96: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

4.6 PROCESAMIENTO DE LAS IMÁGENES CON VTK

VTK tiene un extenso número de métodos para el procesamiento de imágenes y renderización de volúmenes. Los datos de imágenes 2D y 3D vienen dados por la clase vtkImageData. En un dataset de imagen los datos son ordenados en un vector regular alineado con los ejes. Mapas de bits y mapas de píxeles son ejemplos de datasets de imágenes 2D, y volúmenes (pilas de imágenes 2D) lo son de datasets de imágenes 3D.

Los process objects en un pipeline de imagen siempre tienen como entradas y salidas data objects de imagen. Debido a la naturaleza regular y simple de los datos, el pipeline de imagen tiene otros rasgos importantes. La renderización de volumen se usa para visualizar objetos 3D de la clase vtkImageData, y visores especiales de imágenes se usan para ver objetos 2D. La mayoría de los process objets en el pipeline de imagen están multiensamblados y son capaces de hacer fluir los datos por partes (para hacer un uso satisfactorio del límite de memoria).

Los filtros detectan de forma automática el número disponible de procesos en el sistema y crean el mismo número de uniones durante la ejecución; igualmente separan automáticamente los datos en partes que fluyen a través del pipeline.

4.7 CREACIÓN DE UNA APLICACIÓN GRÁFICA CON VTK

Crear aplicaciones gráficas con VTK es un proceso que consiste en dos partes básicas:

1. Construcción de un pipeline de datos para procesar los datos: es decir, conectar fuentes (crear datos), filtros (procesar datos) y mappers (transformar datos en gráficos). Están disponibles muchos tipos distintos de fuentes, filtros y mappers, en función del tipo de datos que se estén procesando y de la funcionalidad que se desee.

86 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 97: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

2. Creación de los objetos gráficos necesarios para interpretar esos datos. Para crear objetos gráficos los pasos típicos pueden ser:

1. Crear una ventada de renderización para trabajar en ella.

2. Crear un render.

3. Crear un interactor (que permite interactuar con los datos).

4. Crear uno o más actores (cada uno de los cuales es unido a un mapper).

5. Renderizar.

4.8 GENERACIÓN DE PROYECTOS MEDIANTE VTK

Los pasos a seguir para llevar a cabo la generación de proyectos con VTK serán los siguientes:

1. Debemos instalar la herramienta Cmake, que podremos encontrar en www.CMake.org.

2. A continuación debemos instalar también el conjunto de librerías VTK que podremos encontrar en www.vtk.org. En las opciones de instalación, seleccionaremos la compatibilidad para Python, Java y Tcl.

3. Copiamos la carpeta VTK-SRC-WINDOWS desde el CD de la aplicación hasta el directorio del disco duro donde hallamos instalado las librerías VTK.

GVA–ELAI–UPM ® PFC 0084 - 2005 87

Page 98: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

4. Creamos una nueva carpeta en el directorio del disco duro donde se encuentre VTK con el nombre de DEBUGBUILD, en donde almacenaremos la configuración de VTK.

5. Iniciamos la aplicación Cmake, ejecutando CmakeSetup.exe. a continuación debemos configurar VTK.

6. En el directorio del código fuente, establecemos el path en donde se encuentre el source de VTK.

7. En el directorio de destino, donde se crearán las dll´s y los build de VTK, establecemos lo siguiente:

8. Seleccionamos el compilador a utilizar.

9. Pinchamos en CONFIGURE. En el GUI se nos resaltan unas opciones en rojo. Activamos la casilla VTK_USE_PARALLEL.

88 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 99: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

10. Pinchamos en CONFIGURE. Activamos la opción VTK_USE_MPI.

GVA–ELAI–UPM ® PFC 0084 - 2005 89

Page 100: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

11. Pinchamos en CONFIGURE. Nos informará de que no encuentra el lugar donde se encuentra el ejecutable de MPI, el include y sus librerías; añadimos la información requerida:

MPIRUN.exe: ….\MPICH\MPD\BIN\MPIRUN.exe

INCLUDE PATH: ….\MPICH\SDK\INCLUDE

LIBRARY PATH: ….\MPICH\SDK\|LIB\MPICH.lib

12. Pinchamos en CONFIGURE. Después pinchamos en OK.

90 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 101: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

4.9 EJECUCIÓN DE LAS APLICACIONES VTK

1. Lanzamos el compilador con el que estemos trabajando (en nuestro caso, Microsoft Visual Studio C++ 6.0).

2. Generamos un nuevo archivo *.cpp a través de la pestaña NEW → FILES → C++ SOURCE FILE.

3. Escribimos el programa a ejecutar y lo guardamos.

4. A continuación tenemos que crear el archivo de configuración CMakeLists.txt. Este archivo suele tener la siguiente estructura:

PROJECT (nombre del proyecto) INCLUDE (${CMAKE_ROOT}/Modules/FindVTK.cmake) IF (USE_VTK_FILE) INCLUDE (${USE_VTK_FILE}) ENDIF (USE_VTK_FILE) LINK_LIBRARIES ( vtkRendering vtkGraphics vtkImaging vtkFiltering vtkCommon … … … ) ADD_EXECUTABLE (nombre del proyecyo nombre del proyecto.cpp)

GVA–ELAI–UPM ® PFC 0084 - 2005 91

Page 102: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

5. Guardamos el archivo *.txt con el nombre de CMakeLists. Tanto el archivo *.cpp como el *.txt han de estar localizados en una misma carpeta.

6. Lanzamos la aplicación Cmake. En el código fuente, incluimos el path del directorio donde se encuentren los archivos *.cpp y *.txt. En el destino, la carpeta donde queremos que se genere la aplicación:

7. Pinchamos en CONFIGURE. Nos informa de que no encuentra el path de VTK_DIR. Ponemos el path donde se encuentra ese directorio, que será ….\VTK\DEBUGBUILD. Pinchamos en CONFIGURE y después en OK.

8. Lanzamos el compilador que hallamos seleccionado (en nuestro caso, Visual Studio C++ 7.0). Seleccionamos OPENWORKSPACE y abrimos el archivo *.dsw que se encontrará en el directorio de resultados.

9. Ejecutamos la aplicación y, si no se encuentran errores, nos pedirá que le proporcionemos la ruta del ejecutable a utilizar, que en nuestro caso será VTK.exe:

….\VTK\BIN\VTK.exe

10. Vamos al directorio de resultamos, y ejecutamos la aplicación obtenida.

A continuación vamos a ver un ejemplo sencillo de la utilización de VTK. En este ejemplo vamos a desarrollar una simple ventana de ejecución de VTK en donde incluiremos un cubo con el que podremos obtener sus diferentes vistas:

#include "vtkCubeSource.h" #include "vtkPolyDataMapper.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h"

92 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 103: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK Static HANDLE hinst; long FAR PASCAL WndProc(HWND, UINT, UINT, LONG); class myVTKApp { public: myVTKApp (HWND parent); ~myVTKApp (); private: vtkRenderWindow *renWin; vtkRenderer *renderer; vtkRenderWindowInteractor *iren; vtkCubeSource *cube; vtkPolyDataMapper *cubeMapper; vtkActor *cubeActor; }; int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) { static char szAppName[] = "Win32Cube"; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; if (!hPrevInstance) { wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.lpszMenuName = NULL; wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH); wndclass.lpszClassName = szAppName; RegisterClass (&wndclass); }

GVA–ELAI–UPM ® PFC 0084 - 2005 93

Page 104: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

hinst = hInstance; hwnd = CreateWindow ( szAppName, "Draw Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 480, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, nCmdShow); UpdateWindow (hwnd); while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } return msg.wParam; } long FAR PASCAL WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam) { static HWND ewin; static myVTKApp *theVTKApp; switch (message) { case WM_CREATE: { ewin = CreateWindow("button","Exit", WS_CHILD | WS_VISIBLE | SS_CENTER, 0,400,400,60, hwnd,(HMENU)2, (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE), NULL);

94 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 105: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK theVTKApp = new myVTKApp(hwnd); return 0; } case WM_COMMAND: switch (wParam) { case 2: PostQuitMessage (0); if (theVTKApp) { delete theVTKApp; theVTKApp = NULL; } break; } return 0; case WM_DESTROY: PostQuitMessage (0); if (theVTKApp) { delete theVTKApp; theVTKApp = NULL; } return 0; } return DefWindowProc (hwnd, message, wParam, lParam); } myVTKApp::myVTKApp(HWND hwnd) { this->renderer = vtkRenderer::New(); this->renWin = vtkRenderWindow::New(); this->renWin->AddRenderer(this->renderer); this->renWin->SetParentId(hwnd); this->iren = vtkRenderWindowInteractor::New(); this->iren->SetRenderWindow(this->renWin); this->cube = vtkCubeSource::New();

GVA–ELAI–UPM ® PFC 0084 - 2005 95

Page 106: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

this->cube->SetXLength( 5 ); this->cube->SetYLength( 5 ); this->cube->SetZLength( 5 ); this->cubeMapper = vtkPolyDataMapper::New(); this->cubeMapper->SetInput(this->cube->GetOutput()); this->cubeActor = vtkActor::New(); this->cubeActor->SetMapper(this->cubeMapper); this->renderer->AddActor(this->cubeActor); this->renderer->SetBackground(0.2,0.4,0.3); this->renWin->SetSize(400,400); this->renWin->Render(); } myVTKApp::~myVTKApp() { renWin->Delete(); renderer->Delete(); iren->Delete(); cube->Delete(); cubeMapper->Delete(); cubeActor->Delete(); }

A continuación el fichero Cmake.lists que necesitaremos generar será el siguiente:

PROJECT (Win32Cube) INCLUDE (${CMAKE_ROOT}/Modules/FindVTK.cmake) IF (USE_VTK_FILE) INCLUDE(${USE_VTK_FILE}) ENDIF (USE_VTK_FILE) LINK_LIBRARIES( vtkRendering vtkGraphics vtkImaging vtkIO

96 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 107: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK vtkFiltering vtkCommon ) ADD_EXECUTABLE(Win32Cube WIN32 Win32Cube.cxx)

El resultado de nuestra aplicación será el siguiente:

GVA–ELAI–UPM ® PFC 0084 - 2005 97

Page 108: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

4.10 UTILIZACIÓN DE VTK CON MPI

Para poder utilizar MPI con VTK es necesario haber realizado la instalación de VTK en nuestra máquina. VTK dispone de una serie de clases preparadas para su aplicación en el procesamiento en paralelo. Estas clases están desarrolladas para que puedan hacer uso de la librería MPI. Entre las más destacadas se encuentran las siguientes:

• vtkMPIController: es una clase concreta que lleva a cabo los métodos de mando de multi-proceso definida en vtkMultiProcessController que usa

MPI. También proporciona la funcionalidad específica a MPI y no el presente en el vtkMultiProcessController.

• vtkMPICommunicator: se ocupa de la supervisión de los comunicadores definidos por el propio usuario.

• vtkMPIGroup: se ocupa de la supervisión de los comunicadores definidos por el propio usuario.

• vtkMPIEventLog

• vtkMultiProcessController

El uso de comunicadores definidos por el usuario se realiza a través de vtkMPICommunicator y vtkMPIGroup. Notar que un duplicado del comunicador definido por el usuario se usa para las comunicaciones interiores (RMIs). Este communicator tiene las mismas propiedades como el usuario uno sólo que tiene un nuevo contexto que impide a los dos communicators interferir entre sí.

Las funciones que más se utilizan de esta clase, para conseguir que funcione correctamente el procesamiento en paralelo son las siguientes:

98 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 109: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

• Inicialize (int *argc, char ***argv): Es necesario llamar a esta función para iniciar los procesos. Se tiene que poner solo una vez.

• GetLocalProcessId (): Sirve para que cada proceso averigüe su dirección (identificador) dentro de la colección de procesos que componen la aplicación.

• GetNumberOfProcesses (): Sirve para averiguar el número de procesos que participan en la aplicación.

• Finalize (): Sirve para dar por finalizada la aplicación.

Se dispone también de una gran cantidad de funciones de envío y recepción de datos. Tiene funciones configuradas para enviar y recibir todo tipo de datos incluso imágenes (vtkDataObject):

1. Funciones de envío bloqueantes

Send (int *data, int length, int remoteProcessId, int tag)

Send (unsigned long *data, int length, int remoteProcessId, int tag)

Send (char *data, int length, int remoteProcessId, int tag)

Send (unsigned char *data, int length, int remoteProcessId, int tag)

Send (float *data, int length, int remoteProcessId, int tag)

Send (double *data, int length, int remoteProcessId, int tag)

GVA–ELAI–UPM ® PFC 0084 - 2005 99

Page 110: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

Send (vtkDataObject *data, int remoteId, int tag)

Send (vtkDataArray *data, int remoteId, int tag)

2. Funciones de recepción bloqueantes

Receive (int *data, int length, int remoteProcessId, int tag)

Receive (unsigned long *data, int length, int remoteProcessId, int tag)

Receive (char *data, int length, int remoteProcessId, int tag)

Receive (unsigned char *data, int length, int remoteProcessId, int tag)

Receive (float *data, int length, int remoteProcessId, int tag)

Receive (double *data, int length, int remoteProcessId, int tag)

Receive (vtkDataObject *data, int remoteId, int tag)

Receive (vtkDataArray *data, int remoteId, int tag)

100 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 111: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

Figura 4.7

4.11 UN EJEMPLO CONCRETO

A continuación vamos a presentar un ejemplo que nos permite la reconstrucción en 3D a partir de una serie de imágenes superpuestas. El programa a continuación descrito está basado sobre la plataforma Microsoft Visual Studio:

// ------------------------------------------------------------------------------------------------ // Llamamos a los archivos de cabecera de VTK para hacer posible la ejecución de todos // los comandos de VTK // ------------------------------------------------------------------------------------------------ #include "vtkActor.h" #include "vtkCamera.h" #include "vtkContourFilter.h" #include "vtkGenericRenderWindowInteractor.h" #include "vtkImageData.h"

GVA–ELAI–UPM ® PFC 0084 - 2005 101

Page 112: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

#include "vtkInteractorStyleTrackballCamera.h" #include "vtkLight.h" #include "vtkOutlineFilter.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkPolyDataNormals.h" #include "vtkPropPicker.h" #include "vtkProperty.h" #include "vtkRenderWindow.h" #include "vtkRenderer.h" #include "vtkStripper.h" #include "vtkVolume16Reader.h" int main( int argc, char *argv[] ) { // ------------------------------------------------------------------------------------------------ // Creamos un Renderer, una ventana de renderizado y un interactor para la ventana de // renderizado // ------------------------------------------------------------------------------------------------ vtkCamera *aCamera = vtkCamera::New(); aCamera->SetClippingRange(279.912 , 911.861); aCamera->SetDistance(559.088); aCamera->SetFocalPoint(100.8 , 100.8 , 69); aCamera->SetPosition(338.682 , 605.953 , 40.5167); aCamera->SetViewAngle(30); aCamera->SetViewUp(-0.0163052 , -0.048633 , -0.998684); aCamera->SetParallelProjection(0); aCamera->SetUseHorizontalViewAngle(0); vtkRenderer *aRenderer = vtkRenderer::New(); aRenderer->SetActiveCamera(aCamera); aRenderer->SetBackground(1 , 1 , 1); aRenderer->SetLightFollowCamera(1); vtkRenderWindow *renWin = vtkRenderWindow::New(); renWin->AddRenderer(aRenderer); renWin->SetSize(500 , 406);

102 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 113: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); iren->SetRenderWindow(renWin); iren->SetLightFollowCamera(1); // ------------------------------------------------------------------------------------------------ // Creamos el pipeline de VTK // ------------------------------------------------------------------------------------------------ vtkVolume16Reader *v16 = vtkVolume16Reader::New(); v16->SetDataDimensions(64 , 64); v16->SetDataSpacing(3.2 , 3.2 , 1.5); v16->SetFilePrefix("F:/PROYECTO/vtkGUI101/vtkdata/Data/headsq/quarter"); v16->SetImageRange(1 , 93); v16->SetDataByteOrder(1); vtkContourFilter *skinExtractor = vtkContourFilter::New(); skinExtractor->SetInput((vtkDataSet *) v16->GetOutput()); skinExtractor->SetValue(0 , 500); skinExtractor->SetComputeNormals(1); skinExtractor->SetComputeScalars(1); vtkPolyDataNormals *skinNormals = vtkPolyDataNormals::New(); skinNormals->SetInput((vtkPolyData *) skinExtractor->GetOutput()); skinNormals->SetFeatureAngle(60); skinNormals->SetComputeCellNormals(0); skinNormals->SetComputePointNormals(1); skinNormals->SetFlipNormals(0); skinNormals->SetSplitting(1); vtkStripper *skinStripper = vtkStripper::New(); skinStripper->SetInput((vtkPolyData *) skinNormals->GetOutput()); skinStripper->SetMaximumLength(1000); vtkPolyDataMapper *skinMapper = vtkPolyDataMapper::New(); skinMapper->SetInput((vtkPolyData *) skinStripper->GetOutput()); skinMapper->SetNumberOfPieces(1); skinMapper->SetScalarRange(0 , 1); skinMapper->SetColorMode(0); skinMapper->SetResolveCoincidentTopology(0);

GVA–ELAI–UPM ® PFC 0084 - 2005 103

Page 114: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

skinMapper->SetScalarMode(0); skinMapper->SetImmediateModeRendering(0); skinMapper->SetScalarVisibility(0); skinMapper->SetUseLookupTableScalarRange(0); vtkActor *skin = vtkActor::New(); skin->SetMapper(skinMapper); skin->GetProperty()->SetAmbientColor(1 , 1 , 1); skin->GetProperty()->SetColor(1 , 0.607692 , 0.423077); skin->GetProperty()->SetDiffuseColor(1 , 0.49 , 0.25); skin->GetProperty()->SetOpacity(1); skin->GetProperty()->SetInterpolation(1); skin->GetProperty()->SetRepresentation(2); skin->GetProperty()->SetBackfaceCulling(0); skin->GetProperty()->SetEdgeVisibility(0); skin->GetProperty()->SetFrontfaceCulling(0); skin->SetOrigin(0 , 0 , 0); skin->SetPosition(0 , 0 , 0); skin->SetScale(1 , 1 , 1); skin->SetPickable(1); skin->SetVisibility(1); vtkContourFilter *boneExtractor = vtkContourFilter::New(); boneExtractor->SetInput((vtkDataSet *) v16->GetOutput()); boneExtractor->SetValue(0 , 1150); boneExtractor->SetComputeNormals(1); boneExtractor->SetComputeScalars(1); vtkPolyDataNormals *boneNormals = vtkPolyDataNormals::New(); boneNormals->SetInput((vtkPolyData *) boneExtractor->GetOutput()); boneNormals->SetFeatureAngle(60); boneNormals->SetComputeCellNormals(0); boneNormals->SetComputePointNormals(1); boneNormals->SetFlipNormals(0); boneNormals->SetSplitting(1); vtkStripper *boneStripper = vtkStripper::New();

104 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 115: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK boneStripper->SetInput((vtkPolyData *) boneNormals->GetOutput()); boneStripper->SetMaximumLength(1000); vtkPolyDataMapper *boneMapper = vtkPolyDataMapper::New(); boneMapper->SetInput((vtkPolyData *) boneStripper->GetOutput()); boneMapper->SetNumberOfPieces(1); boneMapper->SetScalarRange(0 , 1); boneMapper->SetColorMode(0); boneMapper->SetResolveCoincidentTopology(0); boneMapper->SetScalarMode(0); boneMapper->SetImmediateModeRendering(0); boneMapper->SetScalarVisibility(0); boneMapper->SetUseLookupTableScalarRange(0); vtkActor *bone = vtkActor::New(); bone->SetMapper(boneMapper); bone->GetProperty()->SetAmbientColor(1 , 1 , 1); bone->GetProperty()->SetColor(1 , 1 , 0.9412); bone->GetProperty()->SetDiffuseColor(1 , 1 , 0.9412); bone->GetProperty()->SetOpacity(1); bone->GetProperty()->SetInterpolation(1); bone->GetProperty()->SetRepresentation(2); bone->GetProperty()->SetBackfaceCulling(0); bone->GetProperty()->SetEdgeVisibility(0); bone->GetProperty()->SetFrontfaceCulling(0); bone->SetOrigin(0 , 0 , 0); bone->SetPosition(0 , 0 , 0); bone->SetScale(1 , 1 , 1); bone->SetPickable(1); bone->SetVisibility(1); vtkOutlineFilter *outlineData = vtkOutlineFilter::New(); outlineData->SetInput((vtkDataSet *) v16->GetOutput()); vtkPolyDataMapper *mapOutline = vtkPolyDataMapper::New(); mapOutline->SetInput((vtkPolyData *) outlineData->GetOutput()); mapOutline->SetNumberOfPieces(1); mapOutline->SetScalarRange(0 , 1);

GVA–ELAI–UPM ® PFC 0084 - 2005 105

Page 116: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

mapOutline->SetColorMode(0); mapOutline->SetResolveCoincidentTopology(0); mapOutline->SetScalarMode(0); mapOutline->SetImmediateModeRendering(0); mapOutline->SetScalarVisibility(1); mapOutline->SetUseLookupTableScalarRange(0); vtkActor *outline = vtkActor::New(); outline->SetMapper(mapOutline); outline->GetProperty()->SetAmbientColor(0 , 0 , 0); outline->GetProperty()->SetColor(0 , 0 , 0); outline->GetProperty()->SetDiffuseColor(0 , 0 , 0); outline->GetProperty()->SetOpacity(1); outline->GetProperty()->SetInterpolation(1); outline->GetProperty()->SetRepresentation(2); outline->GetProperty()->SetBackfaceCulling(0); outline->GetProperty()->SetEdgeVisibility(0); outline->GetProperty()->SetFrontfaceCulling(0); outline->SetOrigin(0 , 0 , 0); outline->SetPosition(0 , 0 , 0); outline->SetScale(1 , 1 , 1); outline->SetPickable(1); outline->SetVisibility(1); // ------------------------------------------------------------------------------------------------ // Insertamos todos los actores en el render // ------------------------------------------------------------------------------------------------ aRenderer->AddActor( outline ); aRenderer->AddActor( skin ); aRenderer->AddActor( bone ); // ------------------------------------------------------------------------------------------------ // Reseteamos la camera y la inicializamos // ------------------------------------------------------------------------------------------------ aRenderer->ResetCamera(); aRenderer->ResetCameraClippingRange(); renWin->Render(); iren->Initialize();

106 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 117: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK iren->Start(); // ------------------------------------------------------------------------------------------------ // Eliminamos las instancias de VTK creadas // ------------------------------------------------------------------------------------------------ aCamera->Delete(); aRenderer->Delete(); bone->Delete(); boneExtractor->Delete(); boneMapper->Delete(); boneNormals->Delete(); boneStripper->Delete(); iren->Delete(); mapOutline->Delete(); outline->Delete(); outlineData->Delete(); renWin->Delete(); skin->Delete(); skinExtractor->Delete(); skinMapper->Delete(); skinNormals->Delete(); skinStripper->Delete(); v16->Delete(); return 0; }

A continuación, deberemos crear el archivo Cmake.lists necesario para ejecutar la aplicación. Este archivo deberá tener la siguiente estructura:

PROJECT (1.cpp) INCLUDE (${CMAKE_ROOT}/Modules/FindVTK.cmake) IF (USE_VTK_FILE) INCLUDE(${USE_VTK_FILE}) ENDIF (USE_VTK_FILE)

GVA–ELAI–UPM ® PFC 0084 - 2005 107

Page 118: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

ADD_EXECUTABLE(1 1.cpp) TARGET_LINK_LIBRARIES(1 vtkRendering vtkIO vtkCommon)

Una vez ejecutado el programa, el resultado que obtenemos es el siguiente:

108 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 119: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con VTK

GVA–ELAI–UPM ® PFC 0084 - 2005 109

Page 120: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con VTK

110 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 121: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

5 Procesamiento Distribuido de Imágenes Genérico con Matlab

En este capítulo vamos a tratar otra forma de realizar el procesamiento distribuido con MPI. Si hasta ahora, a la hora de realizar aplicaciones paralelas las implementábamos en lenguaje C, ahora vamos a introducir una nueva implementación de nuevo desarrollo: el MatlabMPI, es decir, la implementación de aplicaciones paralelas en lenguaje Matlab.

GVA–ELAI–UPM ® PFC 0084 - 2005 111

Page 122: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

5.1 ¿QUÉ ES MATLABMPI?

Matlab es el lenguaje de programación predominante y más extendido para la implementación de cómputos numéricos, y es ampliamente usado también para el desarrollo e implementación de algoritmos, simulación, reducción de datos, comprobación y evaluación de sistemas. La popularidad de Matlab se debe a la alta tasa de productividad y rendimiento que logra, ya que una única línea de código en Matlab puede remplazar a diez líneas de código en C o FORTRAN. Muchos programas de Matlab pueden beneficiarse de su ejecución en sistemas distribuidos, ya que estos son mucho más rápidos. Ha habido muchos intentos previos de proporcionar un mecanismo eficiente para poder ejecutar aplicaciones y programas de Matlab en sistemas distribuidos paralelas.

En el mundo del cómputo paralelo, MPI (Message Passing Interface) es el estándar empleado para la implementación de programas en múltiples computadoras. MPI define funciones de lenguaje C para realizar la comunicación punto a punto en aplicaciones paralelas. MPI ha demostrador ser un modelo efectivo para esta implementación de aplicaciones paralelas y es usado en la mayor parte de las aplicaciones más demandadas en el mundo, como podrían ser modelos climáticos, simulación armamentística, diseño aeronáutico y simulación de procesos de señales.

MatlabMPI es una implementación para Matlab de MPI (Message Passing Interface) que permite que cualquier programa creado bajo Matlab pueda ser ejecutado en múltiples procesadores. MatlabMPI consiste en un conjunto de

Hoy en día, los verdaderos costos del gran desarrollo de la computación están dominados por el software. Para poder controlar estos costos es necesario migrar a lenguajes de alta productividad como Matlab.

Figura 5.1: logo de MPI y Matlab

112 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 123: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

instrucciones de Matlab que implementan un subconjunto de MPI, permitiendo que cualquier programa de Matlab pueda ser ejecutado en una computadora paralela. Además, MatlabMPI podrá ejecutarse en cualquier sistema de computadoras que soporten Matlab.

Actualmente MatlabMPI implementa las seis funciones básicas que son el núcleo de la comunicación estándar MPI punto a punto. Esta implementación ha sido probada tanto en sistemas distribuidos de memoria compartida como en sistemas de memoria distribuida (SUN, SGI, HP, IBM Y LINUX). La innovación técnica que introduce MatlabMPI es que implementa el “look and feel” de MPI en el estándar de los ficheros de entrada/salida de Matlab; con esto lo que conseguimos es que esta implementación tenga tres características principales:

• Que obtengamos una implementación extremadamente compacta (aproximadamente 100 líneas de código).

• Que resulte una implementación muy pura.

• Esta implementación funcionará en cualquier punto en donde Matlab también funcione.

MatlabMPI puede igualar el ancho de banda de comunicación del lenguaje C basado en MPI en el envío de mensajes de gran tamaño.

5.2 REQUISITOS DEL SISTEMA

En sistemas de memoria compartida, MatlabMPI sólo necesita de una única licencia de Matlab a partir de la cual cualquier usuario es capaz de lanzar múltiples sesiones de Matlab.

En un sistema de memoria distribuida, MatlabMPI necesita de una licencia de Matlab por máquina. Debido a que MatlabMPI utiliza archivos de entrada/salida para establecer la comunicación, también deberá existir un directorio, que deberá ser

GVA–ELAI–UPM ® PFC 0084 - 2005 113

Page 124: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

visible para cualquier máquina (este aspecto normalmente también se requiere a la hora de instalar Matlab).

5.3 INSTALACIÓN Y EJECUCIÓN

Los pasos básicos a seguir para llevar a cabo la instalación y posterior ejecución de MatlabMPI son los siguientes:

1. Copiar el directorio de MatlabMPI en una localización que sea visible para todas las computadoras.

2. Añadir el directorio MatlabMPI/src al path de Matlab en nuestro archivo MATLAB/startupsav.m, que se encuentra en ~\Matlab7\toolbox\local:

addpath ~/MatlabMPI/src

ADVERTENCIA: puede ser necesario introducir un path diferente al anterior dependiendo de donde se realizara la instalación de MatlabMPI.

3. OPCIONAL: configurar rsh o ssh, incluir el path al ejecutable de Matlab.

4. Escribir “help MatlabMPI” para conseguir una lista de todas las funciones de MatlabMPI.

5. Escribir “help function_name” para conseguir más información sobre una función en particular.

114 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 125: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

6. Ir al directorio de ejemplos dentro de MatlabMPI.

7. Para realizar la ejecución de cualquier programa de MatlabMPI desde la línea de comandos de Matlab, tendremos que escribir:

eval( MPI_Run('xbasic', 2,machines) ); eval( MPI_Run('basic', 2,machines) ); eval( MPI_Run('multi_basic',2,machines) ); eval( MPI_Run('probe', 2,machines) ); eval( MPI_Run('speedtest', 2,machines) ); eval( MPI_Run('basic_app', 2,machines) ); eval( MPI_Run('broadcast', 2,machines) ); eval( MPI_Run('blurimage', 2,machines) );

MPI_Run tiene tres argumentos: el nombre del programa de MatlabMPI (sin la extensión *.m), el número de procesadores en donde queremos que se ejecute el programa y el argumento “machines”, que contiene una lista de los nombres de los procesadores en donde se ejecutará el programa. Si el usuario configura MPI_Run para usar N procesadores y la lista de “machines” contiene M nombres, donde M > N, entonces MPI_Run ejecutará el programa en los N primeros procesadores de la lista.

El argumento “machines” puede estar expresado de las siguientes maneras:

machines = {}; Ejecución el en procesador local.

machines = {'machine1' 'machine2'}) ); Ejecución en múltiples procesadores.

machines = {'machine1:dir1' 'machine2:dir2'})); Ejecución en multiprocesador y comunicación vía

dir1 y dir2, los cuales deben ser visibles para ambos

procesadores

GVA–ELAI–UPM ® PFC 0084 - 2005 115

Page 126: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

8. Para ejecutar los programas de MatlabMPI usando el compiler de Matlab, debemos primero iniciar Matlab y después escribimos:

eval( MPI_Run( MPI_cc('xbasic'), 2,machines) );

o

MPI_cc('xbasic'); eval( MPI_Run( 'compiled xbasic.exe'), 2,machines) );

ADVERTENCIA: el comando MPI_cc sólo funcionará si tenemos adecuadamente configurado los paths de forma que nuestro código compilará (por ejemplo, nuestro LD_LIBRARY_PATH, etc…), lo que nos puede llevar un pequeño esfuerzo. En sistemas que funcionan bajo Linux, tendremos que añadir (como mínimo):

matlab/extern/lib/glnx86 matlab/bin/glnx86 matlab/sys/os/glnx86

5.4 IMPLEMENTACIÓN DE UN PROGRAMA DE MATLABMPI

A continuación, proponemos un ejemplo de un programa de MatlabMPI básico basado en el envío y recepción de mensajes:

MPI_Init; % Initialize MPI. comm = MPI_COMM_WORLD; % Create communicator. comm_size = MPI_Comm_size(comm); % Get size. my_rank = MPI_Comm_rank(comm); % Get rank. source = 0; % Set source. dest = 1; % Set destination. tag = 1; % Set message tag. if(comm_size == 2) % Check size.

116 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 127: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

if (my_rank == source) % If source. data = 1:10; % Create data. MPI_Send(dest,tag,comm,data); % Send data. end if (my_rank == dest) % If destination. data=MPI_Recv(source,tag,comm); % Receive data. end end MPI_Finalize; % Finalize MatlabMPI. exit; % Exit Matlab

La estructura del programa anterior es muy similar a los programas de MPI escritos para C o Fortran, pero con la particularidad de un lenguaje de alto nivel.

La primera parte del programa establece el MPI world; la segunda parte establece el rango y ejecuta el programa; la tercera parte cierra MPI world y sale de Matlab. Si el programa anterior fuera escrito en un archivo de Matlab llamado SendRecieve.m, este se ejecutaría llamando al siguiente comando desde el prompt de Matlab:

eval( MPI_Run(’SendReceive’,2,machines) );

Donde el argumento machines puede tener cualquiera de la siguientes formas:

machines = {}; Ejecución en el procesador local. machines = {’machine1’ ’machine2’}; Ejecución en múltiples procesadores.

machines = {’machine1:dir1’ ’machine2:dir2’}; Ejecución en múltiples procesadores y comunicación usando dir1 y dir2, que deben ser visibles para ambas máquinas.

El comando MPI_Run lanza un script de Matlab en las máquinas especificadas con la salida redirigida a un archivo. Si el proceso de rango 0 está siendo ejecutado en la máquina local, MPI_Run devuelve una cadena conteniendo los comandos para inicializar MatlabMPI, lo que permite a MatlabMPI ser invocado

GVA–ELAI–UPM ® PFC 0084 - 2005 117

Page 128: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

dentro de un programa de Matlab de la misma manera que el modelo empleado en OpenMP.

El ejemplo SendRecieve nos muestra las seis funciones básicas de MPI (además de MPI_Run) que han sido implementadas en MatlabMPI:

MPI Run Ejecuta un script de Matlab en paralelo.

MPI Init Inicia MPI.

MPI Comm size Obtiene el número de procesadores en la

comunicación.

MPI Comm rank Obtiene el rango del procesador dentro de la

comunicación.

MPI Send Envía un mensaje a un procesador (no bloqueante).

MPI Recv Recibe un mensaje de un procesador (bloqueante).

MPI Finalize Finaliza MPI.

Por conveniencia, tres funciones adicionales han sido implementadas que proporcionan una funcionalidad importante a MatlabMPI:

MPI Abort Función para eliminar todos los trabajos comenzados

por MatlabMPI.

MPI Bcast Informa sobre un mensaje (bloqueante).

MPI Probe Devuelve una lista de todos los mensajes entrantes.

MatMPI Save Función de MatlabMPI que previene que los

messages mensajes sean borrados.

MatMPI Función de MatlabMPI utilizada para eliminar todos

Delete all los archivos creados por MatlabMPI.

118 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 129: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

5.5 LANZAMIENTO Y ARCHIVOS DE ENTRADA/SALIDA

El lanzamiento desde la línea de comandos de Matlab usando eval (MPI_Run (…)) permite una variedad de comportamientos. MPI_Run (…) hace dos cosas. Primero, lanza un script de Matlab en los procesadores especificados con salida redirigida a un archivo. Segundo, si el rango es igual a 0 el proceso está siendo ejecutado en el procesador local, MPI_Run (…) retorna un string.h conteniendo los comandos para inicializar MatlabMPI, que permite a MatlabMPI ser llamado desde cualquier programa de Matlab.

Este lanzamiento y el comportamiento de salida es resumido en el cuadro a continuación:

Machine MPI Rank = 0 MPI Rank > 0

Local exec() > screen unix > file

Remote rsh > file rsh > file

Los archivos que contiene el programa de salida son almacenados en el directorio MatMPI, que es creado por MPI_Run. Los nombres de los archivos son de la forma:

program.rank.out

Donde “program” es el nombre del programa de MatlabMPI y “rank” es el rango del proceso de MatlabMPI que genera el archivo de salida.

GVA–ELAI–UPM ® PFC 0084 - 2005 119

Page 130: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

5.6 MANEJO DE LOS ERRORES

MatlabMPI maneja errores bastante similares a los existentes en Matlab; sin embargo, la ejecución de cientos de procesos simultáneamente conlleva ciertos puntos adicionales:

• Si un error es encontrado y el script de Matlab tiene una sentencia “exit” (lo que debería ser), entonces todos los procesos de Matlab deberían finalizar correctamente.

• Si un trabajo de Matlab está esperando un mensaje que nunca llegará, entonces tendremos que finalizarlo a mano para comenzar una nueva sesión de Matlab y escribir:

MPI_Abort

Si esto no funciona, necesitaremos iniciar la sesión en cada procesador, escribir “top” y finalizar los procesos de Matlab uno a uno.

• MatlabMPI puede dejar una gran variedad de archivos tirados, los cuales son mejor eliminar una vez que se produce un error, comenzado Matlab y escribiendo:

MatMPI_Delete_all

Si esto no funciona, podemos eliminar los archivos a mano. Los archivos pueden encontrarse en dos lugares – el directorio de ejecución y el directorio de comunicación (que por defecto están en el mismo lugar).

En el directorio de ejecución podemos tener archivos sobrantes de la forma:

120 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 131: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

MatMPI/*

En el directorio de comunicación podemos tener archivos sobrantes de la forma:

p<rank>_p<rank>_t<tag>_buffer.mat

p<rank>_p<rank>_t<tag>_lock.mat

Es muy importante que se eliminen estos archivos. En general, si estamos usando un directorio público para realizar la comunicación (por

ejemplo, /tmp), deberíamos crear primero un subdirectorio (por ejemplo, /tmp/joe), y usar este directorio para la comunicación.

5.7 EJECUCIÓN DE MATLABMPI SOBRE LINUX

MatlabMPI también puede ser implementado en clusters basados en Linux. La clave consiste en cambiar el parámetro “acdirmin” desde 30 segundos a 0.1 segundos cuando nuestro NFS lanza el archivo del sistema que es usado para la comunicación. El comando lazador que encontramos tendrá la siguiente forma:

mount -o acdirmin=0.1, \ rw,sync,hard,intr,rsize=8192,wsize=8192,nfsvers=2,udp \ node-a:/export/gigabit /wulf/gigabit

ADVERTENCIA: si elegimos establecer estos parámetros en el automounter, debemos reiniciar el automounter en cada máquina que este en la lista.

GVA–ELAI–UPM ® PFC 0084 - 2005 121

Page 132: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

ADVERTENCIA: existe un error con la interfaz gráfica (GUI) de Matlab bajo Linux. Puede que nos encontremos con el siguiente error (o cualquier otro error extraño):

??? Error using ==> mkdir tcsh: No entry for terminal type "'MATLAB Command Window'"tcsh:

using dumb terminal settings.

Si nos encontramos con este error, podemos intentar una de las siguientes soluciones:

1. Ejecutar el siguiente comando y reiniciar Matlab:

setenv MATLAB_SHELL /bin/sh

Si esto soluciona el problema, entonces puede que queramos añadir esta línea a nuestro .bashrc (o archivo equivalente *.dot si utilizamos una máscara diferente).

2. Si el establecimiento de las variables de entorno de MATLAB_SHELL no soluciona el problema, intentaremos eliminar nuestro directorio ~/.matlab y reiniciaremos Matlab desde la línea de comandos usando el comando:

matlab –nojvm

122 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 133: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

5.8 EJECUCIÓN DE MATLABMPI SOBRE MacOSX

MatlabMPI trabaja sobre MacOSX sin ninguna modificación. La mayor parte de las veces tendremos que usar ssh en ves de rsh.

5.9 EJECUCIÓN DE MATLABMPI SOBRE PC

La instalación y ejecución de MatlabMPI sobre PC requiere una serie de pasos adicionales. A continuación vamos a describir la instalación de MatlabMPI en un PC. Si estamos instalando MatlabMPI como una parte de otro paquete (por ejemplo, Matlab), entonces tenemos que reemplazar todas las referencias a MatlabMPI con el packagename\MatlabMPI (por ejemplo Matlab\MatlabMPI).

5.9.1 INSTALACIÓN EN PC (AUTÓNOMO)

Los pasos a seguir si queremos realizar este tipo instalación son los siguientes:

1. Si estamos instalando directamente sobre un PC, recuerde que el archivo startupsav.m se encuentra típicamente en:

~matlabroot/toolbox/local

Lo que en nuestro caso sería:

C:\MATLAB7\toolbox\local\startupsav.m

GVA–ELAI–UPM ® PFC 0084 - 2005 123

Page 134: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

2. Agregamos .\ MatMPI al path en el archivo startupsav.m:

addpath .\ MatMPI

3. Si no hemos agregado MatlabMPI\src al path, por ejemplo:

addpath C:\MatlabMPI\src

5.9.2 INSTALACIÓN EN PC Y UN CLUSTER DE LINUX

Los pasos a seguir si queremos realizar este tipo instalación son los siguientes:

1. Si estamos instalando directamente sobre un PC, recuerde que el archivo startupsav.m se encuentra típicamente en:

~matlabroot/toolbox/local

Lo que en nuestro caso sería:

C:\MATLAB7\toolbox\local\startupsav.m

2. Agregamos .\ MatMPI al path en el archivo startupsav.m:

addpath .\ MatMPI

3. Si no hemos agregado MatlabMPI\src al path, por ejemplo:

124 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 135: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

addpath C:\MatlabMPI\src

5.9.3 INSTALACIÓN EN PC Y CLUSTER DE PC´s

Los pasos a seguir si queremos realizar este tipo instalación son los siguientes:

1. Debemos tener un sistema de archivos montado de forma cruzada de forma que todos nuestros PCs puedan ver los mismos archivos. Asumimos que este sistema a sido montado en la unidad Z:.

2. Copiamos MatlabMPI a Z:\MatlabMPI

3. Agregamos la siguiente sentencia a Z:\matlab\startupsav.m:

addpath Z:\MatlabMPI\src addpath .\MatMPI

4. En cada uno de los PCs añadimos lo siguiente a nuestro fichero local startupsav.m:

addpath Z:\matlab startup

5. ADVERTENCIA: asegúrese que la licencia de Matlab flexLM está ejecutándose en cada PC. Una forma de asegurarse es simplemente iniciar la sesión de la consola en cada máquina.

GVA–ELAI–UPM ® PFC 0084 - 2005 125

Page 136: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

6. ADVERTENCIA: los PCs no deben estar registrados por varios usuarios al mismo tiempo, por lo que debemos procurar que esto no ocurra.

7. Cada vez que lo ejecutemos deberíamos usar el siguiente sintaxis relativo al nombre de las máquinas, lo que explícitamente informa a Matlab los tipos de máquinas sobre los que estamos ejecutando nuestra aplicación:

machines = {'mypc:pc' 'node-1:pc' 'node-2:pc'}

8. IMPORTANTE: el comando de MatlabMPI MPI_Abort sólo puede eliminar procesos en máquinas remotas que operen bajo Windows XP. Esto se debe a que XP es la única versión de Windows que cuenta con el comando “taskkill”, que permite eliminar procesos. Una utilidad para “eliminar” procesos para otras versiones de Windows se incluye en los kits de actualización. También es posible el empleo de utilidades gratuitas. MPI_Abort puede ser modificado por estas utilidades.

9. IMPORTANTE: el comando de MatlabMPI MPI_Abort eliminará todos los procesos de MatlabMPI en una máquina remota bajo Windows XP que se estén ejecutando en la sesión del usuario. Esto puede causar problemas si el usuario está ejecutando Matlab en otros procesadores.

5.9.4 RESOLUCIÓN DE PROBLEMAS

• Los nombres de las computadoras en Windows se escriben en mayúsculas. Esto puede causar problemas si el nombre de la computadora es especificado en la lista de máquinas en minúscula y la computadora no tiene un rsh daemon instalado. Por ejemplo, supongamos que el nombre de una computadora es “MYCOMP”. Si el nombre de la computadora es especificado en la lista de máquinas como “mycomp”:

machines = {'mycomp:pc'...}

126 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 137: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

Esto causará que MatlabMPI intente rsh en MYCOMP en vez de ejecutar el programa directamente.

• Si iniciamos Matlab en un directorio que no contenga un directorio de MatlabMPI, aparecerá un mensaje de advertencia como este:

Warning: Name is nonexistent or not a directory: .\ MatMPI. > In C:\MATLAB7\toolbox\matlab\general\path.m at line 116 In C:\MATLAB7\toolbox\matlab\general\addpath.m at line 88 In z:\matlab\startupsav.m at line 6 In C:\MATLAB7\toolbox\local\startupsav.m at line 2 In C:\MATLAB7\toolbox\local\matlabrc.m at line 199

Si queremos ocultar este error, debemos modificar el archivo startupsav.m de la siguiente forma:

warning off: addpath .\MatMPI warning on;

La llamada al comando de advertencia suprimirá cualquier advertencia posterior.

• El comando MPI_Abort, por defecto, trabajo sólo bajo Windows XP. Esto es debido a que XP es la única versión de Windows que contiene la utilidad “taskkill.exe” para eliminar procesos. Una herramienta similar, “kill.exe”, es utilizable bajo Windows 2000. Para usar MPI_Abort con Win2K, será necesario actualizar nuestra versión de Windows y sustituir el comando “kill.exe” por “taskkill.exe” en el archivo MPI_Abort.m.

Si no nos es posible actualizar nuestra versión de Windows 2000, existen otras herramientas gratuitas que nos proporcionan la misma función, como las Pstolos de Sysinternals (que podemos conseguir en www.sysinternals.com).

GVA–ELAI–UPM ® PFC 0084 - 2005 127

Page 138: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

Desafortunadamente, Windows 2000 no proporciona un “contexto de usuario”. Como consecuencia, cuando se ejecuta MPI_Abort, este eliminará todos los procesos de Matlab que se estén ejecutando en la máquina, sin tener en cuenta el usuario que esta ejecutando cada proceso. La utilidad “taskkill” evita este problema, eliminando sólo los procesos de Matlab que pertenezcan al usuario que ejecute el comando MPI_Abort.

5.10 OPTIMIZACIONES PARA UN MEJOR RENDIMIENTO

Para proporcionar un mejor rendimiento de MatlabMPI en un cluster, podemos intentar realizar los siguientes pasos:

1. Instalar una copia de Matlab en cada nodo.

2. Montar de forma cruzada todos los discos locales de forma que cada nodo reciba los archivos sobre su propio disco.

ADVERTENCIA: con estas optimizaciones, puede que algunas veces Matlab se ejecute demasiado rápido, de forma que surjan errores NFS como resultado. Una forma de evitar que surjan estos errores es eliminando todas las sentencias de path desde nuestro archivo .cshrc. De la misma forma, podemos encontrarnos con comportamientos extraños cuando trabajamos con mensajes de gran tamaño (~100 Mbyte); la forma de solucionarlo sería tratando de trabajar con mensajes de menor tamaño. También algunas veces una gran cantidad de tráfico NFS GETATTR puede ser generado si estamos esperando durante mucho tiempo la recepción de los archivos. Podemos comprobar este tráfico registrando el servidor NFS como raíz y escribiendo “snoop | Grez <machine-name>”, y buscando los paquetes “GETATTR”.

128 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 139: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

5.11 EJECUCIÓN POR LOTES

Existen varios métodos para tratar la ejecución por lotes:

1. Solicitar una cola interactiva (muchos sistemas lo permiten).

2. Escribir un script de Matlab que contenga nuestro comando MPI_Run (por ejemplo, RUN.m) y añadir en nuestro batch script lo siguiente:

matlab –nojvm –nosplash –display null < RUN.m

3. Si queremos hacer las cosas de forma manual, la mejor manera es ver lo que ocurre cuando ejecutamos un programa en una máquina “inexistente”; por ejemplo:

MPI_Run ('xbasic', 2, {'unknown'});

Launching MPI rank: 1 on: unknown Launching MPI rank: 0 on: unknown

unix_launch = rsh unknown -n 'cd /home/kepner/MatlabMPI/examples; /bin/sh ./MatMPI/Unix_Commands.unknown.0.sh &' &

El resultado de arriba nos muestra el comando exacto rsh que es generado. Podemos copiar y editar este comando para ejecutar nuestro programa. Además, deberíamos examinar el archivo que contiene las llamadas a Matlab, y que es:

GVA–ELAI–UPM ® PFC 0084 - 2005 129

Page 140: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

./MatMPI/Unix_Commands.unknown.0.sh

5.12 OTRAS CARACTERÍSTICAS

El archivo:

MatlabMPI/src/MatMPI_Comm_settings.m

Puede ser editado por los usuarios de Matlab para modificar el comportamiento de MatlabMPI. Actualmente, las características incluidas son:

• Unix vs. Windows (deshabilitado)

• Rsh vs. Ssh (método que empleamos para ejecutar procesos de MatlabMPI sobre máquinas remotas)

• Establecimiento de la localización del ejecutable de Matlab

Los usuarios podemos, bien editar este archivo directamente, o bien copiarlo en el directorio que estamos empleando y modificarlo localmente.

Por defecto, MatlabMPI emplea rsh. Desafortunadamente, el cambio de rsh a ssh requiere algo más que cambiar simplemente las propiedades de machine_db_settings.remote_launch. El siguiente procedimiento nos permitirá usar ssh sin ser preguntado por una contraseña (un requisito necesario para MatlabMPI):

130 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 141: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

1. Colocar machine_db_settings.remote_launch dentro de MatMPI_Comm_settings.m

2. Crear una llave RSA con el siguiente comando (acepta todos por defecto):

ssh-keygen -t rsa

3. Añadir la llave RSA a la lista de llaves autorizadas:

cat ~/.ssh/id_rsa >> ~/.ssh/authorized_hosts

4. Iniciar la sesión en cada una de las máquinas en donde MatlabMPI ejecutará los procesos y aceptar cada una de las claves de las mismas.

5.13 DIAGNÓSTICO Y RESOLUCIÓN DE PROBLEMAS

1. Asegúrese de que ha iniciado Matlab: escriba “which matlab” en cada una de las máquinas en donde estemos intentando ejecutarlo. Si nos aparece la siguiente sentencia:

matlab: Command not found

Entonces necesitaremos ponerlo en nuestro path. También podemos codificar el path dentro de MatlabMPI editando el archivo MatlabMPI/src/MatMPI_Comm_settings.m y cambiando la línea:

GVA–ELAI–UPM ® PFC 0084 - 2005 131

Page 142: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

matlab_location = ' matlab ';

Asegúrese que todavía se puede ejecutar Matlab desde la línea de comandos de la máquina en la cual estemos ejecutando nuestro programa de MatlabMPI.

2. Comprobar que MatlabMPI está incluido en nuestro path: iniciamos Matlab y escribimos:

help MatlabMPI

Si nos aparece el siguiente error:

MatlabMPI not found

Entonces necesitaremos incluir MatlabMPI/src en nuestro path de la misma manera que lo hicimos en el apartado de INSTALACIÓN Y EJECUCIÓN.

5.14 PASOS A SEGUIR EN LA EJECUCIÓN DE LAS APLICACIONES DE MATLABMPI

A continuación vamos a mostrar una serie de ejemplos que mostrarán los pasos a seguir para realizar la inicialización de los programas de MatlabMPI:

1. (Este paso es común y se realizará de la misma manera en todos los ejemplos que veamos a continuación) Vamos al directorio de

132 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 143: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

ejemplos que se encuentra dentro del directorio de MatlabMPI. Editamos el archivo RUN.m de forma que sólo se ejecute el archivo *.m que queramos ejecutar (que según los casos podrá ser “xbasic”, “basic”, “multi_basic”, “speedtest”, “blurimage”, etc). También deberemos modificar la variable “machines” de forma que el programa de MatlabMPI sólo se ejecute en las máquinas que nosotros deseemos. Guardamos los cambios realizados en el archivo RUN.m

2. Iniciamos Matlab y ejecutamos el archivo RUN.m. Esto debería llevar unos pocos segundos y, si todo ha funcionado correctamente, debería aparecer un mensaje en la command window de Matlab con la frase ‘SUCCESS’.

3. Finalizamos Matlab y miramos la salida de los otros procesadores escribiendo, por ejemplo:

more MatMPI/*.out

5.15 CONSEJOS PARA LOS USUARIOS

• Eliminar copias antiguas de MatlabMPI antes de ejecutar nuestro programa.

• Usar el script RUN.m incluido en el directorio de ejemplos de MatlabMPI para ejecutar nuestros programas: RUN.m elimina procesos sobrantes de la ejecución de un programa de MatlabMPI anterior, elimina el directorio MatMPI y ejecuta nuestro programa.

• Asegúrese que el directorio que contiene el programa de MatlabMPI no está protegido contra la escritura, ya que MatlabMPI necesita crear y escribir en el directorio MatMPI.

GVA–ELAI–UPM ® PFC 0084 - 2005 133

Page 144: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

• Asegúrese que cuando instale una nueva versión de MatlabMPI, todo el código fuente de la versión anterior es eliminado o que el path sólo contenga las especificaciones de la nueva versión. Será necesario comprobar que no existen copias de cualquier código fuente de antiguas versiones de MatlabMPI en el directorio de trabajo.

• No cambiar la estructura del directorio de MatlabMPI.

• Asegúrese de que nuestro programa no usa “clear” o “clear all” en cualquier punto del código de MatlabMPI. Cuando ejecutamos:

eval( MPI_Run('...', ..., ...) );

Se crea una variable local llamada MPI_COMM_WORLD. Casi todas las funciones de MatlabMPI requieren la información contenida en esta variable.

• Asegúrese que nuestra aplicación no cambia su directorio de trabajo durante su ejecución. De otra forma, MatlabMPI no puede encontrar/acceder al directorio MatMPI.

• El reinicio de Matlab entre ejecuciones de programas de MatlabMPI puede mejorar el rendimiento. El reinicio de Matlab conlleva una serie de tareas, como por ejemplo, el limpiado de memoria, cerrado de archivos, etc. que pueden mejorar el desarrollo de una nueva sesión de Matlab.

134 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 145: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

5.16 ARCHIVOS

Descripción de los archivos/directorios que podemos encontrar en el paquete de software de MatlabMPI:

doc/ Documentación sobre MatlabMPI. examples/ Directorio que contiene los ejemplos y programas. src/ Código fuente de MatlabMPI.

doc/

README.vX.X Lo que es nuevo en esta versión. credit Créditos. mit_license MIT Licencia. todo Lista.

examples/

xbasic.m Programa de MatlabMPI que imprime por pantalla el rango de cada procesador.

basic.m Programa de MatlabMPI que envía datos desde el procesador con rango 1 al procesador con rango 0.

multi_basic.m Programa de MatlabMPI que envía datos desde el procesador con rango 1 al procesador con rango 0 varias veces.

probe.m Programa de MatlabMPI que demuestra el uso de MPI_Probe para comprobar la recepción de mensajes.

broadcast.m Comprueba el comando de MatlabMPI broadcast.

basic_app.m Ejemplos de los usos más comunes de MatlabMPI. basic_app2.m Ejemplos de los usos más comunes de MatlabMPI. basic_app3.m Ejemplos de los usos más comunes de MatlabMPI. basic_app4.m Ejemplos de los usos más comunes de MatlabMPI.

GVA–ELAI–UPM ® PFC 0084 - 2005 135

Page 146: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

blurimage.m MatlabMPI comprueba la aplicación de procesamiento paralelo de

imágenes. speedtest.m Cronometra MatlabMPI para una gran variedad de mensajes. synch_start.m Función para sincronizar los inicios. machines.m Ejemplo de script para la creación de descripciones de las

máquinas. unit_test.m Envoltura para usar un ejemplo como unit test. unit_test_all.m Llama a todos los ejemplos comprobando la librería completa. unit_test_mcc.m Envoltura para usar un ejemplo como mcc unit test. unit_test_all_mcc.m

Llama a todos los ejemplos usando MPI_cc comprobando la librería completa.

src/ ------- Core Lite Profile -------

MPI_Run.m Ejecuta un script de Matlab en paralelo. MPI_Init.m

Inicializa el comienzo de MatlabMPI.

MPI_Comm_size.m Obtiene el número de procesadores en un comunicador. MPI_Comm_rank.m Obtiene el rango del procesador actual con un comunicador. MPI_Send.m Envía un mensaje a un procesador (no bloqueante). MPI_Recv.m Recibe un mensaje desde un procesador (bloqueante). MPI_Finalize.m Finaliza MatlabMPI.

------- Core Profile -------

MPI_Abort.m Función para finalizar todos los trabajos de Matlab iniciados por MatlabMPI.

MPI_Bcast.m Informa de un mensaje (bloqueante). MPI_Probe.m Devuelve una lista de todos los mensajes entrantes. MPI_cc.m Compila usando Matlab mcc.

------- Core Plus Profile -------

[Ninguna función por el momento.]

136 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 147: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

------- User Utility functions -------

MatMPI_Comm_dir.m Función de MatlabMPI para el cambio de directorio usado para llevar a cabo la comunicación.

MatMPI_Save_messages.m Función de MatlabMPI para prevenir que los mensajes sean eliminados. Útil para procesos de depuración.

MatMPI_Delete_all.m Función de MatlabMPI para eliminar todos los archivos. MatMPI_Comm_settings.m Puede ser editado por los usuarios para cambiar las

características de MatlabMPI (unix/windows, rsh/ssh, ...).

------- Library Utility functions -------

MatMPI_Buffer_file.m Función de MatlabMPI para generar archivos de nombre buffer. Usada por MPI_Send and MPI_Recv.

MatMPI_Lock_file.m Función de MatlabMPI para generar archivos de nombre lock. Usada por MPI_Send and MPI_Recv.

MatMPI_Commands.m

Función de MatlabMPI para generar comandos. Usada por MPI_Run.

MatMPI_Comm_init.m Función de MatlabMPI para crear MPI_COMM_WORLD. Usada por MPI_Run.

MatMPI_mcc_wrappers/ Contiene funciones de envoltorio para usar con MPI_cc.

5.17 ANCHO DE BANDA

La gran mayoría de las aplicaciones de MATLAB son raramente aplicaciones paralelas, por lo que requieren de una mínima parte del potencial de implementación de MATLAB MPI. Estas aplicaciones raramente explotan todas las posibilidades de comunicación.

MATLAB MPI ha sido ejecutado en SUN, HP, IBM, SGI Y LINUX. Los resultados indican que para mensajes de gran tamaño (es decir, de aproximadamente 1 Mbyte), MATLAB MPI es capaz de igualar el resultando de la implementación de MPI en lenguaje C. Para mensajes de menor tamaño, MATLAB MPI se ve limitado por su latencia (aproximadamente de 35 milisegundos), la cual es significativamente más elevada que para la implementación en C de MPI (ver Figura 4.3).

GVA–ELAI–UPM ® PFC 0084 - 2005 137

Page 148: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

Figura 5.2: Ancho de banda en un cluster de

LINUX.

Figura 5.3: Ancho de banda. Ancho de banda en función del tamaño del mensaje probado en el SGI ORIGIN 2000. MATLAB MPI iguala la implementación en lenguaje C en mensajes de

gran tamaño.

138 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 149: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

Para comprobar más en profundidad la escalabilidad de MATLAB MPI se utilizo una simple aplicación consistente en el filtrado de una imagen. La aplicación del procesamiento de la imagen fue ejecutada con una carga constante por procesador (imagen de 1024 x 1024 píxeles por procesador) en grandes sistemas de memoria compartida/distribuida (el IBM SP2 en el MAUI HIGH PERFORMANCE COMPUTING CENTER). En dichas pruebas, se consiguió unas velocidades de 300 en 304 CPUs y un pico de sistema del 15% (450 gigaflops) (ver Figura 4.4 y Figura 4.5).

Figura 5.4: velocidad de la

memoria paralela compartida

Figura 5.5: velocidad paralela

compartida/distribuida

GVA–ELAI–UPM ® PFC 0084 - 2005 139

Page 150: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

El objetivo que se busca a la hora de ejecutar MATLAB en sistemas distribuidos es el poder incrementar la productividad del programador y disminuir el gran costo en software al usar sistemas HPC. La figura 4.6 muestra el coste en software (medido en líneas de software de código o SLOCs) en función del máximo rendimiento obtenido (medido en unidades de pico de procesador), para la misma aplicación de filtrado de imagen implementada con diferentes librerías y lenguajes (USIPL, MPI, OPENMP, C++, C y MATLAB). Los datos muestran que aquellos lenguajes de nivel superior necesitan un menor número de líneas para implementar el mismo nivel de funcionalidad. Para la obtención de resultados más extensos, se requiere de un número mayor de líneas de código.

Para medir la productividad del software en los grandes sistemas distribuidos se han desarrollado dos medidas de gran utilidad: los gigaflops/SLOC y las CPUs/SLOC. Los resultados de la aplicación anterior obtuvieron unos resultados de 0.85 gigaflops/SLOC y 4.4 CPUs/SLOC.

Figura 5.6: Productividad vs rendimiento. Las línea de código como función del

máximo rendimiento alcanzado (medido en unidades de pico de procesador) para diferentes implementaciones para la misma aplicación de filtrado de imagen

140 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 151: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

5.18 CONCLUSIONES Y PRÓXIMOS DESARROLLOS

MATLAB MPI demuestra que el estándar propuesto para escritura de las aplicaciones paralelas en C y FORTRAN, es también válido en MATLAB. Además usando archivos de MATLAB de entrada/salida, es posible implementar completamente MATLAB MPI con el desarrollo de MATLAB, haciéndolo en seguida migrable a todas las computadoras en donde se ejecute MATLAB. La mayor parte de aplicaciones paralelas de MATLAB son triviales y no necesitan de un gran desarrollo. Sin embargo, MATLAB MPI puede igualar los resultados de la implementación en C de MPI para grandes mensajes. Además, el uso de archivos de entrada/salida como mecanismo de comunicación paralela no es nuevo y es ahora cada vez más factible con la disponibilidad de los bajos costos de los discos de alta velocidad. Por otra parte, el uso de estos archivos de entrada/salida tiene varias ventajas funcionales adicionales, que lo hacen fácil para implementar bufferes de gran tamaño, etc. por último, MATLAB MPI es aplicable a cualquier lenguaje (IDL, PYTHON, PERL).

MATLAB MPI proporciona la mayor productividad posible en el desarrollo de aplicaciones paralelas. Sin embargo, debido a que es una librería de comunicación punto a punto, una cantidad considerable de código debe ser añadida a cualquier aplicación para poder realizar aplicaciones paralelas básicas. En la aplicación comprobada con anterioridad, el número de líneas de código MATLAB se incremento de 35 a 70. Mientras que una aplicación paralela de 70 líneas es extremadamente pequeña, esto representaría un aumento significativo en el caso de que contáramos con un único procesador.

La simplicidad y funcionalidad de MATLAB MPI lo hace una elección muy aconsejable para programadores que quieran acelerar sus códigos MATLAB en computadoras paralelas. El trabajo para el futuro será el de crear objetos de mayor rango (como, por ejemplo, matrices distribuidas). El resultado será la construcción de una capa de comunicaciones dentro de MATLAB MPI, que permita a un usuario lograr un aceptable desarrollo paralelo sin un aumento de las líneas de código.

GVA–ELAI–UPM ® PFC 0084 - 2005 141

Page 152: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

Figura 5.7: futura arquitectura en forma de capas: diseño de unas herramientas paralelas de Matlab las cuales crearán una estructura de datos distribuida y objetos dataflow construidos

en la cima de MatlabMPI

5.19 UN EJEMPLO PRÁCTICO: APLICACIÓN PARALELA PARA EL FILTRADO DE IMÁGENES

MPI_Init; % Inicia MPI.

comm = MPI_COMM_WORLD; % Crea el comunicador.

comm_size = MPI_Comm_size(comm); % Obtiene el tamaño.

my_rank = MPI_Comm_rank(comm); % Obtiene el rango.

% Sincroniza el comienzo.

starter_rank = 0;

142 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 153: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

delay = 30; % Segundos.

synch_start(comm,starter_rank,delay);

n_image_x = 2.^(10+1)*comm_size; % Establece el tamaño de la imagen

% (usa potencia de 2).

n_image_y = 2.^10;

n_point = 100; % Número de puntos para poner en

% cada subimágen.

% Establece el tamaño del filtro (usa potencias de 2).

n_filter_x = 2.^5;

n_filter_y = 2.^5;

n_trial = 2; % Establece el número de veces que

% se realizará el filtrado.

% Calcular el número de operaciones.

total_ops = 2.*n_trial*n_filter_x*n_filter_y*n_image_x*n_image_y;

if(rem(n_image_x,comm_size )~= 0)

disp(‘ERROR: processors need to evenly divide image’);

exit;

end

disp([‘my_rank: ‘,num2str(my_rank)]); % Imprimir por pantalla el rango.

left = my_rank - 1; % Establece quién es la fuente y

% quién es el destino.

if (left < 0)

left = comm_size - 1;

GVA–ELAI–UPM ® PFC 0084 - 2005 143

Page 154: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

end

right = my_rank + 1;

if (right >= comm_size)

right = 0;

end

tag = 1; % Crea una etiqueta de identificación

% para el mensaje.

start_time = zeros(n_trial);

end_time = start_time;

zero_clock = clock; % Pone el reloj a 0.

n_sub_image_x = n_image_x./comm_size; % Calcula las subimágenes para

% cada procesador.

n_sub_image_y = n_image_y;

% Crea la imágen original y las imagines con las que trabajaremos.

sub_image0 = rand(n_sub_image_x,n_sub_image_y).^10;

sub_image = sub_image0;

work_image = zeros(n_sub_image_x+n_filter_x,n_sub_image_y+n_filter_y);

% Crea el núcleo.

x_shape = sin(pi.*(0:(n_filter_x-1))./(n_filter_x-1)).ˆ2;

y_shape = sin(pi.*(0:(n_filter_y-1))./(n_filter_y-1)).ˆ2;

kernel = x_shape * y_shape;

% Crea los índices.

144 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 155: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

lboxw = [1,n_filter_x/2,1,n_sub_image_y];

cboxw = [n_filter_x/2+1,n_filter_x/2+n_sub_image_x,1,n_sub_image_y];

rboxw = [n_filter_x/2+n_sub_image_x+1,n_sub_image_x+n_filter_x,1,n_sub_image_y];

lboxi = [1,n_filter_x/2,1,n_sub_image_y];

rboxi = [n_sub_image_x-n_filter_x/2+1,n_sub_image_x,1,n_sub_image_y];

start_time = etime(clock,zero_clock); % Set start time.

for i_trial = 1:n_trial

work_image(cboxw(1):cboxw(2),cboxw(3):cboxw(4)) = sub_image;

if (comm_size > 1)

ltag = 2.*i_trial; % Create message tag.

rtag = 2.*i_trial+1;

% Envía la subimágen izquierda.

l_sub_image = sub_image(lboxi(1):lboxi(2),lboxi(3):lboxi(4));

MPI_Send( left, ltag, comm, l_sub_image );

% Recibe la parte derecha.

r_pad = MPI_Recv( right, ltag, comm );

work_image(rboxw(1):rboxw(2),rboxw(3):rboxw(4)) = r_pad;

% Envía la subimágen derecha.

r_sub_image = sub_image(rboxi(1):rboxi(2),rboxi(3):rboxi(4));

MPI_Send( right, rtag, comm, r_sub_image );

GVA–ELAI–UPM ® PFC 0084 - 2005 145

Page 156: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

% Recibe la parte izquierda.

l_pad = MPI_Recv( left, rtag, comm );

work_image(lboxw(1):lboxw(2),lboxw(3):lboxw(4)) = l_pad;

end

work_image = conv2(work_image,kernel,’same’); % Compute convolution.

% Extrae la subimágen.

sub_image = work_image(cboxw(1):cboxw(2),cboxw(3):cboxw(4));

end

end_time = etime(clock,zero_clock); % Obtiene el tiempo de finalización.

total_time = end_time - start_time % Imprime por pantalla los resultados.

% Imprime por pantalla los cálculos computacionales.

gigaflops = total_ops / total_time / 1.e9;

disp([‘GigaFlops: ‘,num2str(gigaflops)]);

MPI_Finalize; % Finaliza MatlabMPI.

exit;

146 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 157: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con MATLAB

GVA–ELAI–UPM ® PFC 0084 - 2005 147

Page 158: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con MATLAB

148 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 159: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

6 Procesamiento Distribuido de Imágenes Genérico con Paraview

En este capítulo vamos a tratar otra de las formas que existen a la hora de realizar el procesamiento distribuido de imágenes genérico. En este caso vamos a emplear la herramienta Paraview. Esta herramienta es una de las existentes en el mercado para llevar a cabo la implementación de aplicaciones paralelas. En este capítulo veremos sus principales características y algunos ejemplos prácticos.

GVA–ELAI–UPM ® PFC 0084 - 2005 149

Page 160: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con Paraview

6.1 ¿QUÉ ES PARAVIEW?

ParaView es una aplicación que se utiliza para visualizar datos en dos o tres dimensiones. Esta aplicación puede ser utilizada en un solo puesto de trabajo o también en un cluster de ordenadores (conjunto de ordenadores interconectados entre sí). Esto último permite a ParaView ejecutar grandes cadenas de datos mediante la utilización de procesamiento distribuido.

Figura 6.1: Logo de ParaView

6.2 CARACTERÍSTICAS DE PARAVIEW

Las características más importantes de ParaView son las siguientes:

• Es una aplicación de visualización multiplataforma de libre distribución.

• Soporta procesamiento distribuido para procesar grandes cantidades de datos.

• Dispone de una flexible e intuitiva interfaz de usuario.

• Desarrolla una extensible arquitectura basada en estándares abiertos.

ParaView usa Visualization ToolKit (VTK) para procesar los datos y como motor de renderización y tiene un interfaz de usuario escrito usando una única mezcla de Tcl/Tk y C++. Esta arquitectura hace que ParaView sea una muy potente y flexible herramienta de visualización. Los datos fuente de VTK y los

150 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 161: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con Paraview

datos procesados por los filtros son inmediatamente accesibles o pueden ser añadidos escribiendo un simple fichero de configuración. Además, el uso de lenguaje Tcl permite que los usuariospuedan modificar el motor de procesado y el interfaz de usuario de ParaView ajustándolo a sus necesidades.

Figura 6.2: Pantalla de inicio de ParaView

6.3 OBJETIVO DE PARAVIEW

El objetivo de ParaView es desarrollar una herramienta paralela escalable que realice procesamiento distribuido de memoria. ParaView incluye algoritmos en paralelo, infraestructura de entrada y salida, ayuda, y dispositivos de demostración. Una característica significativa es que todo el software desarrollado está hecho como código abierto, por lo que es totalmente gratuito.

GVA–ELAI–UPM ® PFC 0084 - 2005 151

Page 162: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con Paraview

6.4 INSTALACIÓN DE PARAVIEW

ParaView utiliza Cmake para la construcción del sistema. Para poder compilar ParaView es necesario tener instalado Cmake, que podremos descargar de la página www.cmake.org. ParaView completo contiene VTK y Tcl/Tk 8.3.2, por tanto no es necesario bajarse VTK o Tcl/Tk para compilar.

Una vez instalado Cmake y Paraview, será necesario realizar la configuración de Paraview para poder llevar a cabo la realización de aplicaciones. Los pasos a seguir para llevar a cabo dicha configuración los veremos en el siguiente punto.

6.5 CONFIGURACIÓN DE PARAVIEW

Los pasos a seguir a la hora de realizar la configuración de Paraview son los siguientes:

1. Instalamos la aplicación Cmake, que podemos descargar de la página www.Cmake.org.

2. A continuación debemos instalar la aplicación Paraview, que podemos descargar de la página www.Paraview.org.

3. Descargamos el source de Paraview, y lo instalamos en la carpeta en donde hallamos realizado la instalación de Paraview.

4. Creamos una carpeta en el directorio de Paraview con el nombre de DEBUGBUILD, en donde se almacenarán las dll´s y los build.

152 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 163: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con Paraview

5. Lanzamos la aplicación Cmake a través de su ejecutable Cmake.exe. Una vez lanzada, configuraremos las propiedades para Paraview.

6. En el directorio del código fuente, ponemos el path en donde se encuentra nuestro código de Paraview, que en nuestro caso puede ser:

C:\Archivos de programa\ParaView 1.8

7. En el directorio de destino, ponemos el path en donde queremos que se almacenen las configuraciones de Paraview (DEBUGBUILD):

C:\Archivos de programa\ParaView 1.8\DebugBuild

8. Por último, debemos seleccionar el compilador a utilizar (en nuestro caso, utilizaremos el Microsoft Visual Studio C++ 6.0).

GVA–ELAI–UPM ® PFC 0084 - 2005 153

Page 164: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con Paraview

9. Pinchamos en CONFIGURE. Activamos la casilla VTK_USE_MPI.

10. Pinchamos en CONFIGURE. Volvemos a incluir el MPIRUN.exe, el include y las librerías:

MPIRUN.exe: ….\MPICH\MPD\BIN\MPIRUN.exe

INCLUDE PATH: …. \MPICH\SDK\INCLUDE

LIBRARY PATH: …. \MPICH\SDK\LIB\MPICH.lib

154 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 165: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con Paraview

11. Pinchamos en CONFIGURE, y después en OK.

12. Una vez que hemos finalizado con Cmake, debemos lanzar el compilador que hemos especificado en la casilla (en nuestro caso Microsoft Visual Studio C++ 6.0). dentro del compilador seleccionamos File → Open Workspace. En este punto seleccionamos el workspace que se nos habrá generado, que tendrá un nombre similar a ParaViewComplete.dsw. A continuación seleccionamos ALL_BUILD project, y construimos el proyecto.

Una vez realizados estos pasos, estaremos en disposición de poder llevar a cabo la implementación de aplicaciones paralelas de Paraview.

GVA–ELAI–UPM ® PFC 0084 - 2005 155

Page 166: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con Paraview

6.5.1 EJECUCIÓN SOBRE UNIX

Si se instalara en un directorio que está actualmente en el path de la búsqueda ($PATH o $path), podemos invocar ParaView desde la línea de comandos:

$ paraview

Si esto falla, tendremos que modificar el path de la búsqueda o invocar ParaView especificando el path completo del ejecutable. Por ejemplo, si el path de la instalación es /usr/local/bin, el siguiente lanzará la aplicación:

$/ el usr/local/bin/paraview

ParaView reconoce muchos argumentos de línea de comandos. Para obtener una lista de todos los argumentos disponibles, invoque ParaView con la opción –help opcion.

6.5.2 EJECUCIÓN SOBRE WINDOWS

Inicie ParaView seleccionando “Todos los Programas | ParaView 1.6 | paraview” desde el menú de inicio.

6.6 FICHEROS SOPORTADOS POR PARAVIEW

ParaView soporta los siguientes tipos de ficheros:

• ParaView Files: Éste es el formato del archivo predefinido para ParaView. Soporta cualquier tipo de archivo de los soportados por ParaView (Image Data, Rectilinear Grid, Structured Grid,

156 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 167: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con Paraview

Unstructured Grid, Polygonal Data).La extensión del archivo es .* pvd.

• VTK Files: XML es el formato de archivo usado por VTK. Soporta cualquier tipo de archivo de los soportados por ParaView (Image Data, Rectilinear Grid, Structured Grid, Unstructured Grid, Polygonal Data). Las extensiones de los archivos son: .*vtp, para Polygonal Data; .*vti, para Image Data; .*vtr, para Rectilinear Grid; .*vts, para Structured Grid; .*vtu, para Unstructured Grid.

• Parallel VTK files: los Parallel VTK files contienen información sobre la distribución espacial de los datos. Soporta cualquier tipo de archivo de los soportados por ParaView (Image Data, Rectilinear Grid, Structured Grid, Unstructured Grid, Polygonal Data). Las extensiones de los archivos son: .*pvtp, para Polygonal Data; .*pvti, para Image Data; .*pvtr, para Rectilinear Grid; .*pvts, para Structured Grid; .*pvtu, para Unstructured Grid.

• Legacy VTK Files: los archivos de este tipo tienen la extensión .*vtk. Soporta cualquier tipo de archivo de los soportados por ParaView (Image Data, Rectilinear Grid, Structured Grid, Unstructured Grid, Polygonal Data).

• Parallel legacy VTK: los archivos de este tipo tienen la extensión .*pvtk. Soporta cualquier tipo de archivo de los soportados por ParaView (Image Data, Rectilinear Grid, Structured Grid, Unstructured Grid, Polygonal Data).

• EnSight Files: este formato de archivos es utilizado por CEI´s EnSight (disponible en www.ensight.com). También son soportados formatos como ASCII, binary Ensight 6 y binary Ensight Gold. Tienen la extensión .*case. Soporta cualquier tipo de archivo de los soportados por ParaView (Image Data, Rectilinear Grid, Structured Grid, Unstructured Grid, Polygonal Data).

• PLOT3D Files: este el formato original de los archivos utilizados por el pack desarrollado por la NASA. Las extensiones son .*xyz para los

GVA–ELAI–UPM ® PFC 0084 - 2005 157

Page 168: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con Paraview

archivos de geometría y .*q para las soluciones. Sólo soporta un tipo de formato (Structured Grid).

• Stereo Lithography: ParaView puede leer archivos estéreo litográficos binarios o ASCII. Sólo soporta un tipo de formato (Polygonal Data).

• BYU Files: ParaView puede leer archivos MOVIE.BYU. estos archivos tienen la extensión .*g. Sólo soporta un tipo de formato (Polygonal Data).

• POP Ocean Files: Son ficheros creados para Parallel Ocean Program (POP) software. La extensión del fichero es *.pop.

• Protein Data Bank Files: es el formato de archivo usado por Protein Data Bank (PDB), un archivo experimental para determinar las tres dimensiones de las macromoléculas biológicas. Estos archivos tienen la extensión .*pdb. Produce una salida del tipo Polygonal Data.

• Xmol Files: es un archivo utilizado para la representación de moléculas. Tienen la extensión .*xyz. Produce una salida del tipo Polygonal Data.

• XDMF Files: tienen la extensión .*xmf. Sólo soporta los tipos de formato (Rectilinear Grid y Unstructured Grid).

158 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 169: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con Paraview

6.7 TIPOS DE DATOS ADMITIDOS POR PARAVIEW

Los tipos de datos utilizados por ParaView son:

• Image Data (rejilla rectilínea uniforme o volumen): Un image dataset es una colección de puntos y celdas colocados en una rejilla rectangular. Las filas, columnas y planos de la rejilla son paralelos a las coordenadas x-y-z del sistema.

• Rectilinear Grid (rejilla rectilínea no uniforme): El rectilinear dataset es una colección de puntos y celdas colocados en una rejilla rectangular. Las filas, columnas y planos de la rejilla son paralelos a las coordenadas x-y-z del sistema. Mientras la topología de los datos es regular, la geometría es solo parcialmente regular (el espacio entre los puntos puede variar).

• Structured Grid (rejilla curvilínea): Un structured grid es un dato con topología regular y geometría irregular. La rejilla puede ser desviada en alguna configuración en que las celdas no se corten.

• Unstructured Grid: es el tipo más general de datos con el que nos podemos encontrar. Tanto la topología como la geometría están completamente destructuradas.

• Polygonal Data: Polygonal data es una colección de figuras geométricas primarias, normalmente usadas por el motor de renderización para generar las imágenes dispuestas en el Display Area. El polygonal dataset consiste en vértices, polivértices, líneas, polilíneas, polígonos y triángulos

GVA–ELAI–UPM ® PFC 0084 - 2005 159

Page 170: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con Paraview

Figura 6.3: tipos de datos de Paraview

6.8 PRINCIPALES COMANDOS UTILIZADOS POR PARAVIEW

Existen una serie de comandos que son los que comúnmente utilizamos a la hora de ejecutar ParaView. Distinguiremos tres categorías:

General:

• start-empty, -e: Inicia ParaView sin ningún módulo por defecto.

160 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 171: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con Paraview

• disable-registry, -dr: utilizaremos este comando para hacer pruebas sobre

ParaView.

• play-demo, -pd: Ejecuta la demo de ParaView.

• batch, -b: Carga y ejecuta un específico batch script.

• stereo: habilita stereo rendering.

• use-offscreen-rendering, -os: Render offscreen en procesos satélites.

• render-module: Usa un módulo específico de renderización module (--rendermodule=...)

• help: Visualiza los comandos válidos.

Paralelo:

• use-rendering-group, -p: Usa un subconjunto de procesos para renderizar. Permite ejecutar ParaView sobre más de un nodo.

• group-file, -gf: Cuando usamos las opciones de --use-rendering-group, el número de nodos dónde realizar la renderización, se leen del fichero (usage --groupfile= fname).

• use-tiled-display, -td: Duplica el dato final a todos los nodos y el nodo raíz muestra 1-n en una demostración total.

• tile-dimensions-x, -tdx: -tdx=X, donde X es el número de muestras en cada fila de la muestra.

GVA–ELAI–UPM ® PFC 0084 - 2005 161

Page 172: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con Paraview

• tile-dimensions-y, -tdy: -tdy=Y, donde Y es el número de muestras en cada columna de la muestra.

Client/Server:

• client, -c: Inicia ParaView en modo cliente.

• server, -v: Inicia ParaView en modo servidor.

• host: proporciona al cliente cual la identidad del servidor (por defecto --host=localhost). Usa esta opción junto con la opción --client.

Mesa:

• use-software-rendering, -r: Usa software (Mesa) rendering en todos los nodos.

• use-satellite-software, -s: Usa software (Mesa) rendering solo en procesos satélites.

Esto es útil cuando el usuario quiere tener una ventana solo en el primer nodo.

6.9 PARAVIEW CON MPI

Si compilamos ParaView para soportar MPI, ParaView se podrá lanzar como cualquier otra aplicación MPI. El método para comenzar el uso de MPI depende del sistema y de la implementación con la que se haya instalado.

162 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 173: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel hernández Vázquez Procesamiento Distribuido de Imágenes Genérico con Paraview

Una vez que esté comenzado, el interfaz de uso aparecerá el la pantalla con el proceso (proceso con la identificación 0). El display de otros procesos (procesos basados en los satélites), aparecerán ventanas independientes. Éstos no tienen asociados interfaces de uso y no se pueden manipular por el usuario. Observamos que todos los procesos tienen un display para visualizarlo.

Esto no requiere la presencia de un monitor. Mientras ParaView pueda abrir ventanas de todos los procesos y leer su contenido, funcionará correctamente. Si varios procesos comparten el mismo display, ocurriría como si las ventanas abiertas por estos procesos se solapasen. Si sucede esto, el contenido de esas ventanas no se puede leer por ParaView y la imagen en la ventana principal (la que está con el interfaz de uso) será errónea. Igualmente pueden suceder si hay otras ventanas que ocultan la parte o toda la ventana de los procesos basados en los satélites. ParaView apoya fuera de la pantalla la representación en nodos basados en los satélites.

Para lanzar ParaView en paralelo con MPI hay que realizarlo de igual modo que cualquier otra aplicación MPI, es decir, en la línea de comandos habrá que poner algo como:

C:\temp\mpirun –np 4 –localroot C:\ParaView\bin\debug\ParaView

Una vez realizado lo anterior se abrirá la pantalla de ParaView (solo en el nodo raíz) y podremos realizar las operaciones que queramos interactuando con los menús.

GVA–ELAI–UPM ® PFC 0084 - 2005 163

Page 174: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido de Miguel Hernández Vázquez Imágenes Genérico con Paraview

164 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 175: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

7 Renderización de una Neurona

En este capítulo vamos a intentar dar una visión de este procesamiento distribuido aplicado a un ejemplo concreto, que sería el renderizado de una neurona. Este renderizado constaría de dos partes: en una primera parte trataríamos la imagen (aplicaríamos filtros a la imagen. Es en este punto en donde se utiliza el procesamiento distribuido); y una segunda parte en la que nos encargaríamos de la reconstrucción 3D de la imagen.

GVA–ELAI–UPM ® PFC 0084 - 2005 165

Page 176: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

7.1 INTRODUCCIÓN

Denominamos Renderización al proceso mediante el cual una estructura poligonal (tridimensional) digital más o menos básica obtiene una definición mucho mayor con juegos de luces, texturas y acentuado y mejorado de los polígonos, simulando ambientes y estructuras físicas.

Cuando se está trabajando en un programa profesional de diseño 3D por computadora, no se puede visualizar en tiempo real el resultado del diseño de un objeto o escena compleja ya que esto requiere una potencia de cálculo extremadamente elevada, por lo que luego de diseñar el trabajo con una forma de visualización más simple y técnica, se realiza el proceso de renderización luego del cual se puede apreciar el verdadero aspecto (aspecto final) de una imagen estática o animación.

Algunos métodos de Render son:

• Wireframe

• Sólido

• Sombreado Goraud

• Sombreado Phong

• Radiosidad

166 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 177: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

7.2 WIREFRAME

Wireframe es un algoritmo de renderización del que resulta una imagen semitransparente, de la cual sólo se dibujan las aristas de la malla que constituye al objeto. De ahí su nombre.

Casi nunca se emplea en la representación final de una imagen, pero sí en su edición, debido a la escasa potencia de cálculo necesaria (comparada con otros métodos).

Para conseguir una imagen en wireframe sólo tenemos que tener en cuenta las posiciones de los puntos en el espacio tridimensional y las uniones entre ellos para formas los polígonos.

Habitualmente estas imágenes no tienen en cuenta la presencia de luces en la escena.

7.3 RENDER SÓLIDO

El render sólido es un algoritmo de renderización algo más complejo que el Wireframe en el que se usan técnicas de sombreado rudimentarias.

Cada malla de la escena está formada por polígonos, cada uno de uno color. El Render sólido calcula el vector normal a cada polígono y calcula (frecuentemente mediante un producto escalar) lo perpendicular que es el polígono a una fuente de luz puntual. De esta forma, cuanto más se acerca el ángulo formado por la normal y el vector que está en el centro del polígono a cero se considera que el polígono debe de estar más iluminado.

El sombreado es uniforma para todo el polígono.

GVA–ELAI–UPM ® PFC 0084 - 2005 167

Page 178: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

7.4 SOMBREADO GOURAUD

El sombreado Gouraud es un algoritmo de renderización desarrollado por Henri Gouraud. En este algoritmo la información del color se interpola a través de la cara del polígono para determina el color de cada píxel.

Este algoritmo interpola los valores de iluminación en los vértices del polígono teniendo en cuenta la superficie curva mediante la malla. Para calcular las normales en los vértices primero debemos determinar las normales en las caras alrededor del vértice y entonces promediar para obtener la normal.

A través de la implementación de este algoritmo, evitamos el aspecto cuadrado que tienen algunos objetos. Esta técnica consiste en realizar el sombreado de un polígono teniendo en cuenta a los otros que le rodean, de esta forma conseguimos una mayor suavidad en las sombras y que una superficie formada por triángulos tenga el aspecto de una superficie curva.

Los pasos a seguir para la aplicación del sombreado Gouraud son:

1. Para todos los vértices de las caras visibles:

a) Se calcula la normal (UNITARIA) asociada al vértice como promedio de las normales (UNITARIAS) de las caras que contienen el vértice (incluidas las caras ocultas), en RW.

168 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 179: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

b) Se calcula la iluminación (color) asociada al vértice, usando esta normal.

2. Iluminación asociada a píxel/punto de la cara como interpolación bilineal de las iluminaciones de los vértices:

a) Cara ABC.

b) Intersección de scan con AB y AC: P1, P2.

c) Punto/píxel P, entre P1 y P2.

d) Iluminaciones en P1, P2 como interpolación de iluminaciones en A, B, C:

e) Iluminación en P como interpolación de iluminaciones en P1, P2

f) Cálculo incremental de iluminación en P: siguiente punto del scan, Q, tiene xQ = xP + 1

GVA–ELAI–UPM ® PFC 0084 - 2005 169

Page 180: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

También es posible cálculo incremental de I1, I2

Figura 7.1: Ejemplo de sombreado Gouraud

7.4.1 PSEUDOCÓDIGO PARA ELSOMBREADO GOURAUD

renderGouraud(ListaPolígonos lp, Luces luces, Punto3D puntoVista) { para cada polígono poli en lp { Color[] colorVértice; para cada vértice i en poli colorVértice[i]=aplicaModeloIluminación(poli.vértice[i],poli.material, poli.vértice[i].normal,luces,puntoVista); para cada (x,y) en poli { color=interpola(x,y,poli,colorVértice); PintaPixel(x,y,color); } } }

7.4.2 VENTAJAS E INCONVENIENTES

• Mejora la representación de superficies curvas.

• Mala representación de las transiciones abruptas;

170 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 181: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

• Anomalías debido a la interpolación después de las proyecciones;

• La interpolación depende de la orientación del polígono (ya que se hace según las horizontales);

• Malas reflexiones especulares.

7.5 SOMBREADO PHONG

El sombreado Phong es un método muy sofisticado de sombreado, que fue desarrollado por Phong Bui-tuong. Este algoritmo de renderización se caracteriza por crear precisos brillos especulares. A cada píxel se le da un color basado en el modelo de iluminación aplicado al punto, por lo que este algoritmo necesitará de mayor nivel de computación que el Gouraud.

En gráficas 3D, los polígonos de los que está hecha la imagen necesitan ser sombreados. El sombreado Phong es una de las técnicas más sofisticadas para este propósito.

Funciona como sombreado Goraud pero requiere más recursos del computador, aunque entrega mejores resultados.

Los pasos a seguir son:

1. Cálculo de la normal (UNITARIA) asociada a cada vértice.

GVA–ELAI–UPM ® PFC 0084 - 2005 171

Page 182: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

2. Interpolación bilineal de normales para encontrar normal a punto/píxel de la cara:

3. Se calcula iluminación en P a partir de este vector normal :

4. Obtención de y :

a) obtener punto P en mundo real correspondiente a píxel bajo estudio es difícil

b) se puede aproximar y usar y constantes a toda la cara (p. ej., promedio de los de los vértices)

c) se pueden interpolar (vectores o ángulos) a partir de los valores en los vértices

Figura 7.2: Ejemplo de sombreado Phong

172 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 183: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

7.5.1 PSEUDOCÓDIGO PARA EL SOMBREADO PHONG

renderPhong(ListaPolígonos lp, Luces luces, Punto3D puntoVista) { para cada polígono poli en lp { para cada (x,y) en poli { Punto3D puntoOriginal=poli.puntoOriginal(x,y); Vector3D normal=poli.interpolaNormal(x,y); Color color=aplicaModeloIluminación(puntoOriginal,poli.material, normal,luces,puntoVista); PintaPixel(x,y,color); } } }

7.5.2 VENTAJAS E INCONVENIENTES

• Aspecto muy realista.

• Bastante lento: hay que calcular una ecuación de iluminación por píxel, normalizar e interpolar las normales.

• Demasiados cálculos, especialmente normalizaciones

7.6 RADIOSIDAD

Conjunto de algoritmos de Renderización, que tratan de resolver el problema básico de la renderización de la forma más realista posible.

Este algoritmo es el más prefecto de todos los sistemas de renderizado, pero también el más lento. En este algoritmo calculamos las interacciones entre la luz y el color de los objetos más o menos próximos.

GVA–ELAI–UPM ® PFC 0084 - 2005 173

Page 184: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

Este es un sistema perfecto para simulaciones muy realistas en el campo de la arquitectura, especialmente en interiores, ya que ilustra muy bien el comportamiento de la luz en esas condiciones. También se utiliza mucho para crear los escenarios de algunos videojuegos en 3D para aportar realismo.

El problema es el transporte de la luz sólo se puede modelar de forma óptima considerando que cada fuente luminosa emite un número enorme de fotones, que rebotan al chocar contra una superficie describiendo una cantidad de trayectorias imposibles de simular en un computador.

La radiosidad emplea métodos como el de Monte Carlo para resolver este problema de forma estadística.

El auge de la radiosidad y otros métodos eficientes de renderización han posibilitado un auge en la infografía, siendo muy habitual encontrar por ejemplo películas que aprovechan estas técnicas para realizar efectos especiales.

7.7 PARALELISMO EN EL PROCESO DE RENDERIZACIÓN

Existen diferentes tipos de paralelismo aplicables al proceso de renderización; entre ellos destacan por su importancia:

1. El paralelismo Funcional

2. El paralelismo de Datos

3. El paralelismo Temporal

4. Métodos híbridos

174 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 185: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

Estos tipos básicos pueden combinarse en sistemas híbridos que emplean diferentes formas de paralelismo.

7.7.1 EL PARALELISMO FUNCIONAL

Consiste en dividir el proceso de renderización en una serie de etapas que pueden aplicarse de forma sucesiva a un conjunto de datos.

Si se asigna una o varias de estas etapas a cada procesador, de modo que los datos van recorriendo los procesadores de uno en uno, entonces se forma una segmentación (pipeline) del proceso. Cuando una de las unidades de procesamiento acaba de procesar un conjunto de datos, env__a su resultado hacia la unidad siguiente, y recibe nuevos datos para procesar de la unidad anterior. Idealmente, una vez que la red se completa, el grado de paralelismo alcanzado es igual al número de unidades funcionales.

Este enfoque funciona especialmente bien para la visualización de superficies y de polígonos, donde las primitivas geométricas se introducen al comienzo de la red, y a la salida se obtienen los valores de los píxeles.

Las dos limitaciones principales de este tipo de paralelismo son las siguientes:

• Por una parte, el hecho de que la velocidad conjunta queda determinada por su etapa más lenta, con lo que hay que diseñar el algoritmo cuidando mucho el balanceo de la carga.

• Por otro lado, el paralelismo disponible está limitado por el número de etapas de segmentación.

GVA–ELAI–UPM ® PFC 0084 - 2005 175

Page 186: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

7.7.2 EL PARALELISMO DE DATOS

En lugar de aplicarse una secuencia de operaciones consecutivas a un único flujo de datos, existe la posibilidad de dividir los datos en múltiples flujos y operar con ellos en unidades de procesamiento independientes.

Este sistema tiene la ventaja de ser más adecuado para números elevados de procesadores, con lo que ha sido adoptado habitualmente en máquinas masivamente paralelas.

Dentro del paralelismo de datos, se distingue entre el paralelismo de objeto y el paralelismo de imagen. El primero se refiere a las operaciones realizadas de forma independiente en varias particiones del volumen de datos inicial, e incluye las primeras etapas de la visualización, como las transformaciones de la vista, clipping o el cálculo de la iluminación. El segundo tipo aparece en las últimas fases de la red de visualización, e incluye las operaciones llevadas a cabo para calcular los valores de los píxeles.

7.7.3 EL PARALELISMO TEMPORAL

En la generación de animaciones, a menudo es más importante el tiempo total requerido para renderizar todas las imágenes que el retardo producido en la renderización de cada imagen individual. En este caso, el paralelismo puede obtenerse de forma casi inmediata dividiendo el número de imágenes entre los procesadores disponibles, de modo que la unidad de trabajo sea una imagen completa.

7.7.4 MÉTODOS HÍBRIDOS

Es posible integrar varias formas de paralelismo en un mismo sistema. Por ejemplo, los paralelismos funcional y de datos pueden incorporarse de forma conjunta dividiendo el conjunto de datos en varios fragmentos, que a su vez serán procesados de forma segmentada por varios procesadores.

176 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 187: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

7.8 CONCEPTOS ALGORÍTMICOS

La mayor parte de algoritmos paralelos introducen una serie de sobrecargas que no están presentes en sus equivalentes secuenciales. Las causas de dichas sobrecargas pueden ser las siguientes:

• Comunicación entre procesos

• Desvíos en el balanceo de la carga

• Computación redundante

• Mayor espacio de almacenamiento requerido, debido a estructuras de datos replicadas o auxiliares.

La aparición y la importancia de estas sobrecargas están relacionadas con una serie de características, tanto de los algoritmos paralelos en general como de la visualización en particular:

• Coherencia: la coherencia, en el campo de los gráficos por ordenador, consiste en la tendencia que presentan las características cercanas en el espacio o en el tiempo a tener propiedades similares. Los algoritmos de visualización paralelos deben tener en cuenta la coherencia para reducir las comunicaciones y aumentar el balanceo de la carga. Si no se tiene presente la coherencia, un algoritmo paralelo puede presentar sobrecargas que no están presentes en su equivalente secuencial. La coherencia entre imágenes consecutivas en una animación permite realizar un mejor reparto de la carga. La coherencia entre _las consecutivas de una imagen puede aprovecharse en un algoritmo secuencial de renderización de polígonos para interpolar de forma eficiente los valores de los píxeles entre los vértices de un polígono.

GVA–ELAI–UPM ® PFC 0084 - 2005 177

Page 188: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

• Mapeado del espacio de objeto al espacio de imagen: este mapeado no es fijo, sino que depende de las transformaciones y parámetros presentes en el momento en que se visualiza una escena. Si se dividen entre los procesadores tanto el volumen como la imagen, entonces en algún momento de la red de visualización deberá producirse una comunicación entre procesos para componer los resultados de todos ellos. Debido a la naturaleza esencialmente arbitraria de la función de mapeado, no puede establecerse un patrón de comunicación de forma previa. El manejo de esta comunicación es un punto crucial en muchos estudios sobre renderización en paralelo, especialmente en máquinas de memoria distribuida.

• Descomposición de la tarea y de los datos: los algoritmos basados en el paralelismo de datos se dividen en dos categorías, dependiendo de cómo se produzca la división del problema en tareas individuales. Puede paralelizarse el objeto o volumen a renderizar, en cuyo caso cada uno de los procesadores renderiza una zona concreta de la escena. Según este enfoque, es necesaria una tarea de composición de las imágenes obtenidas por cada procesador. Por otro lado, puede paralelizarse la imagen resultante, con lo que cada procesador debe encargarse de proyectar aquellos voxels o primitivas gráficas que afecten a la zona de la imagen que tiene asignada. En este caso, en cada nueva renderización debe enviarse a cada nodo la porción de datos que necesitará, o bien, si no existen muchas limitaciones en cuanto a memoria disponible, cada uno de los nodos puede contener el volumen completo de forma local.

• Balanceo de la carga: el principal problema que aparece a la hora de repartir la carga de forma equilibrada entre procesadores es el hecho de que los datos no se distribuyen de forma homogénea por el volumen (ni por la imagen). Por lo tanto, la posibilidad de dividir el volumen (o la imagen) en N fragmentos consecutivos (para N procesadores) de igual tamaño resulta, en general, de escasa eficiencia, ya que unos procesadores tendrán mucha mayor carga computacional que otros.

Las estrategias para dividir los datos pueden clasificarse como estáticas y dinámicas. Las primeras realizan una partición fija de los datos. En general esta es la opción más sencilla, pero su problema es que una partición en que los bloques se escojan demasiado grandes resultará en una división no homogénea del trabajo, mientras que una

178 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 189: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

división basada en fragmentos demasiado pequeños deja de aprovechar gran parte de la coherencia espacial de los datos.

Las técnicas de balanceo dinámico de la carga van ajustando el reparto del trabajo a medida que se realiza la renderización. Los dos esquemas básicos dentro de este grupo son el balanceo bajo demanda, en el cuál el trabajo se reparte en pequeñas tareas independientes, de modo que cuando un procesador termina una de ellas, solicita y recibe otra, y así sucesivamente; mientras que el balanceo adaptativo consiste en retrasar las decisiones relativas a división de trabajo hasta que uno de los procesadores queda libre, momento en el cuál toda la tarea restante se divide de nuevo entre los procesadores.

En general las técnicas dinámicas presentan potencialmente un balanceo más preciso, pero también introducen mayores sobrecargas de computación y comunicación, y sólo son eficientes, en general, en máquinas de memoria compartida, mientras que en las máquinas de paso de mensajes suele ser menos costoso el mantenimiento de una estrategia estática.

7.9 EJEMPLO: UNA POSIBLE OPCIÓN DE RENDERIZACIÓN DE UNA NEURONA Y SU POSTERIOR RECONSTRUCCIÓN 3D

En este capítulo voy a exponer el código fuente programado en Matlab para la realización de una posible renderización de una neurona.

Partimos del código fuente AbrirPic.m. A través de este script lo que hacemos es abrir la imagen de una neurona segmentada en 76 rodajas (slices), con el nombre NUEVO1.PIC. A continuación reducimos las dimensiones de la imagen original (512 x 512 x 3), para reducir el tiempo computacional (128 x 128x 3).

A continuación dividimos la imagen abierta en tres subimágenes distintas para llevar a cabo la renderización por separado de cada una de las subimágenes.

GVA–ELAI–UPM ® PFC 0084 - 2005 179

Page 190: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

Una vez realizada la segmentación seleccionamos el algoritmo de filtrado a utilizar (Average, Disk, Gaussian, Motion, Prewitt, Sobel, Unsharp).

Después realizamos la visualización conjunta de la imagen y subimágenes originales y de la imagen y subimágenes filtradas.

A continuación realizamos la reconstrucción 3D de la imagen filtrada y de las subimágenes.

7.9.1 CÓDIGO FUENTE

% Apertura de la imagen de la neurona img3D = AbrirPic('nuevo1.pic', 38, 40); I = img3D(200:200+127,200:200+127,:); ver(:,:,1,:)=I; montage(ver); pause % División de la imagen en tres subimágenes cform = makecform('srgb2lab'); lab_he = applycform(I,cform); ab = double(lab_he(:,:,2:3)); nrows = size(ab,1); ncols = size(ab,2); ab = reshape(ab,nrows*ncols,2); nColors = 3; [cluster_idx cluster_center] = kmeans(ab,nColors,'distance','sqEuclidean','Replicates',3); pixel_labels = reshape(cluster_idx,nrows,ncols); segmented_images = cell(1,3); rgb_label = repmat(pixel_labels,[1 1 3]); for k = 1:nColors color = I; color(rgb_label ~= k) = 0; segmented_images{k} = color;

180 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 191: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

end J = segmented_images{1}; figure, imshow(J), title('Subimágen 1'); pause K = segmented_images{2}; imshow(K), title('Subimágen 2'); pause L = segmented_images{3}; imshow(L), title('Subimágen 3'); pause % Menú De Selección Del Filtro A Utilizar button = listdlg('PromptString','Seleccione el filtro a emplear:',... 'SelectionMode','single',... 'ListSize',[160 100],... 'Name','GVA-ELAI Miguel 1.0',... 'OKString','Aceptar',... 'CancelString','Cancelar',... 'ListString',{'Average';'Disk';'Gaussian';'Motion';'Prewitt';'Sobel';'Unsharp'}) switch button % Filtro Average case 1 h = fspecial('average'); U = imfilter(I,h); M = imfilter(J,h); Q = imfilter(K,h); X = imfilter(L,h); figure, imshow([I,U]), title('Imágen Original e Imágen Original Filtrada'); pause figure, imshow([J,M]), title('Subimágen 1 Original y subimágen 1 filtrada'); pause

GVA–ELAI–UPM ® PFC 0084 - 2005 181

Page 192: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

figure, imshow([K,Q]), title('Subimágen 2 Original y subimágen 2 filtrada'); pause figure, imshow([L,X]), title('Subimágen 3 Original y subimágen 3 filtrada'); pause figure, freqz2(h), colorbar, title('Filtro Aplicado'); pause % Filtro Disk case 2 h = fspecial('disk'); U = imfilter(I,h); M = imfilter(J,h); Q = imfilter(K,h); X = imfilter(L,h); figure, imshow([I,U]), title('Imágen Original e Imágen Original Filtrada'); pause figure, imshow([J,M]), title('Subimágen 1 Original y subimágen 1 filtrada'); pause figure, imshow([K,Q]), title('Subimágen 2 Original y subimágen 2 filtrada'); pause figure, imshow([L,X]), title('Subimágen 3 Original y subimágen 3 filtrada'); pause figure, freqz2(h), colorbar, title('Filtro Aplicado'); pause % Filtro Gaussian case 3 h = fspecial('gaussian'); U = imfilter(I,h); M = imfilter(J,h); Q = imfilter(K,h); X = imfilter(L,h); figure, imshow([I,U]), title('Imágen Original e Imágen Original Filtrada'); pause figure, imshow([J,M]), title('Subimágen 1 Original y subimágen 1 filtrada');

182 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 193: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

pause figure, imshow([K,Q]), title('Subimágen 2 Original y subimágen 2 filtrada'); pause figure, imshow([L,X]), title('Subimágen 3 Original y subimágen 3 filtrada'); pause figure, freqz2(h), colorbar, title('Filtro Aplicado'); pause % Filtro Motion case 4 h = fspecial('motion'); U = imfilter(I,h); M = imfilter(J,h); Q = imfilter(K,h); X = imfilter(L,h); figure, imshow([I,U]), title('Imágen Original e Imágen Original Filtrada'); pause figure, imshow([J,M]), title('Subimágen 1 Original y subimágen 1 filtrada'); pause figure, imshow([K,Q]), title('Subimágen 2 Original y subimágen 2 filtrada'); pause figure, imshow([L,X]), title('Subimágen 3 Original y subimágen 3 filtrada'); pause figure, freqz2(h), colorbar, title('Filtro Aplicado'); pause % Filtro Prewitt case 5 h = fspecial('prewitt'); U = imfilter(I,h); M = imfilter(J,h); Q = imfilter(K,h); X = imfilter(L,h); figure, imshow([I,U]), title('Imágen Original e Imágen Original Filtrada'); pause figure, imshow([J,M]), title('Subimágen 1 Original y subimágen 1 filtrada'); pause

GVA–ELAI–UPM ® PFC 0084 - 2005 183

Page 194: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

figure, imshow([K,Q]), title('Subimágen 2 Original y subimágen 2 filtrada'); pause figure, imshow([L,X]), title('Subimágen 3 Original y subimágen 3 filtrada'); pause figure, freqz2(h), colorbar, title('Filtro Aplicado'); pause % Filtro Sobel case 6 h = fspecial('sobel'); U = imfilter(I,h); M = imfilter(J,h); Q = imfilter(K,h); X = imfilter(L,h); figure, imshow([I,U]), title('Imágen Original e Imágen Original Filtrada'); pause figure, imshow([J,M]), title('Subimágen 1 Original y subimágen 1 filtrada'); pause figure, imshow([K,Q]), title('Subimágen 2 Original y subimágen 2 filtrada'); pause figure, imshow([L,X]), title('Subimágen 3 Original y subimágen 3 filtrada'); pause figure, freqz2(h), colorbar, title('Filtro Aplicado'); pause % Filtro Unsharp case 7 h = fspecial('unsharp'); U = imfilter(I,h); M = imfilter(J,h); Q = imfilter(K,h); X = imfilter(L,h); figure, imshow([I,U]), title('Imágen Original e Imágen Original Filtrada'); pause figure, imshow([J,M]), title('Subimágen 1 Original y subimágen 1 filtrada'); pause figure, imshow([K,Q]), title('Subimágen 2 Original y subimágen 2 filtrada');

184 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 195: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

pause figure, imshow([L,X]), title('Subimágen 3 Original y subimágen 3 filtrada'); pause figure, freqz2(h), colorbar, title('Filtro Aplicado'); pause end % Reconstrucción 3D de las rodajas seleccionadas figure, colordef(gcf,'black'), title('Reconstrucción 3D de la imagen') D = squeeze(U); [x y z D] = subvolume(D, [nan nan nan nan nan 4]); p = patch(isosurface(x,y,z,D, 5), 'FaceColor', 'red', 'EdgeColor', 'none'); p2 = patch(isocaps(x,y,z,D, 5), 'FaceColor', 'interp', 'EdgeColor', 'none'); isonormals(x,y,z,D,p); view(3); daspect([1 1 .4]) camva(9); box on lighting gouraud axis tight % Reconstrucción 3D por separado de cada una de las subimágenes % Reconstrucción 3D por separado de la subimágen 1 figure, colordef(gcf,'black'), title('Reconstrucción 3D subimágen 1') D = squeeze(M); [x y z D] = subvolume(D, [nan nan nan nan nan 4]); p = patch(isosurface(x,y,z,D, 5), 'FaceColor', 'red', 'EdgeColor', 'none'); p2 = patch(isocaps(x,y,z,D, 5), 'FaceColor', 'interp', 'EdgeColor', 'none'); isonormals(x,y,z,D,p); view(3); daspect([1 1 .4]) camva(9); box on lighting gouraud axis tight % Reconstrucción 3D por separado de la subimágen 1

GVA–ELAI–UPM ® PFC 0084 - 2005 185

Page 196: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

figure, colordef(gcf,'black'), title('Reconstrucción 3D subimágen 2') D = squeeze(Q); [x y z D] = subvolume(D, [nan nan nan nan nan 4]); p = patch(isosurface(x,y,z,D, 5), 'FaceColor', 'red', 'EdgeColor', 'none'); p2 = patch(isocaps(x,y,z,D, 5), 'FaceColor', 'interp', 'EdgeColor', 'none'); isonormals(x,y,z,D,p); view(3); daspect([1 1 .4]) camva(9); box on lighting gouraud axis tight % Reconstrucción 3D por separado de la subimágen 1 figure, colordef(gcf,'black'), title('Reconstrucción 3D subimágen 3') D = squeeze(X); [x y z D] = subvolume(D, [nan nan nan nan nan 4]); p = patch(isosurface(x,y,z,D, 5), 'FaceColor', 'red', 'EdgeColor', 'none'); p2 = patch(isocaps(x,y,z,D, 5), 'FaceColor', 'interp', 'EdgeColor', 'none'); isonormals(x,y,z,D,p); view(3); daspect([1 1 .4]) camva(9); box on lighting gouraud axis tight

186 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 197: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

Figura 7.1

Figura 7.2

Figura 7.3

GVA–ELAI–UPM ® PFC 0084 - 2005 187

Page 198: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

Figura 7.4

Figura 7.5: reconstrucción 3D de la imagen

188 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 199: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Renderización de una Neurona

GVA–ELAI–UPM ® PFC 0084 - 2005 189

Page 200: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Renderización de una Neurona Miguel Hernández Vázquez

190 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 201: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

8 PROCESAMIENTO DISTRIBUIDO CON C++

En este capítulo vamos a dar una pequeña introducción acerca de la implementación del procesamiento distribuido en el lenguaje de programación C++. Veremos las principales implementaciones que existen, así como una pequeña aproximación a dos de las implementaciones menos estudiadas: PVM y CORBA.

GVA–ELAI–UPM ® PFC 0084 - 2005 191

Page 202: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

8.1 BREVE INTRODUCCIÓN A C++

El lenguaje C++ proviene del lenguaje C. El lenguaje C nació en los laboratorios Bell de AT&T de la mano de Kernighan y Ritchie en los años 70. Su eficiencia y claridad, y la posibilidad de realizar tanto acciones de bajo como de alto nivel han hecho de este lenguaje el principal tanto en el mundo del desarrollo de sistemas operativos como de aplicaciones tanto industriales como de ofimática.

Con el tiempo y la experiencia el lenguaje fue evolucionando para dotarlo de mayor eficiencia desde el punto de vista del programador. En 1980 se añaden al lenguaje C características como las clases como resultado de la evolución de las estructuras, chequeo del tipo de los argumentos de una función y su conversión si es posible etc, dando como resultado lo que en ese momento se llamó C con clases. Su Bjarne Stroustrup.

En 1983 este lenguaje fue rediseñado y comenzó a utilizarse fuera de AT&T. Se introdujeron las funciones virtuales, la sobrecarga de funciones y operadores. Tras refinamientos y modificaciones menores, este nuevo lenguaje apareció documentado y listo para su uso bajo el nombre de C++.

Posteriormente C++ ha sido ampliamente revisado lo que ha dado lugar a añadir nuevas características como la herencia múltiple, las funciones miembro static y const, miembros protected, tipos de datos genéricos o plantillas, y la manipulación de excepciones. Se revisaron aspectos de la sobrecarga y manejo de memoria, se incremento la compatibilidad con C, etc. El éxito alcanzado por el lenguaje fue arrollador por lo que la AT&T se vió en la necesidad de promover su estandarización internacional. En 1989 se convocó el comité de la ANSI que más tarde entró a formar parte de la estandarización ISO. El trabajo conjunto de estos comités permitió publicar en 1998 el estandar ISO C++ (ISO/IEC 14882) de forma que el lenguaje pase a ser estable y el código generado utilizable por distintos compiladores y en distintas plataformas.

Dentro de esta estandarización se incluye un conjunto de clases, algoritmos y plantillas que constituyen la librería estandar de C++. Esta librería introduce facilidades para manejar las entradas y salidas del programa, para la gestión de listas, pilas, colas, vectores, para tareas de búsqueda y ordenación de elementos, para el manejo de operaciones matemáticas complejas, gestión de cadenas de caracteres,

192 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 203: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

tipos de datos genéricos, etc. A este conjunto de algoritmos, contenedores y plantillas, se los denomina habitualmente por las siglas STL (Standard Template Library).

El resultado de todo ello es un potente lenguaje de programación que admite la programación procedural (al igual que en C) y la programación orientada a objetos. El resultado es mucho mejor que C, soportando la abstracción de datos, y la programación genérica gracias a las plantillas.

La parte de C incluida en C++ es conocida como C- y puede compilarse en C++ sin ningún problema. La sintaxis y las reglas de edición en general son iguales, por lo que a las modificaciones introducidas por C++ a la edición de código procedural (es decir, como si se tratase de C) se las denomina modificaciones menores ya que son fácilmente asumibles por un programador de C.

A las modificaciones introducidas para soportar la programación orientada a objetos y la programación genérica, se las denomina modificaciones mayores, puesto que requieren para su uso de un cambio radical en la filosofía de programación.

8.2 ESTÁNDARES PARA LA PROGRAMACIÓN PARALELA EN C++

El lenguaje C++ no incluye ninguna primitiva para poder realizar la implementación de aplicaciones paralelas. No existe ninguna manera a través del lenguaje C++ para especificar que dos o más instrucciones deberían ser ejecutadas de forma paralela.

Aunque existen versiones especiales de C++ que implementan la programación paralela, vamos a presentar una serie de métodos sobre cómo la programación paralela puede ser implementada usando el estándar de ISO para C++. La librería que da soporte a la programación paralela es la más flexible. Las librerías del sistema y las librerías del usuario pueden ser empleadas para soportar el paralelismo en C++. Las librerías del sistema son aquellas librerías que son proporcionadas por el propio sistema operativo. Por ejemplo, la librería POSIX (Portable Operating System Interface) es un conjunto de llamadas del sistema que

GVA–ELAI–UPM ® PFC 0084 - 2005 193

Page 204: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

puede ser usado conjuntamente con C++ para soportar la programación paralela. Estas librerías forman parte de una nueva especificación de UNIX.

8.2.1 EL ESTÁNDAR MPI

MPI es la implementación estándar para llevar a cabo la comunicación basándose en el intercambio de mensajes. MPI fue desarrollado para su ejecución tanto en máquinas paralelas como en clusters de estaciones de trabajo. Para trabajar con MPI utilizamos la implementación MPICH. MPICH es una implementación de MPI libre y portable. MPICH proporciona al programador de C++ un conjunto de APIs y librerías que soportan programación paralela. MPI es especialmente útil para la programación SPMD (Single Program Multiple Data) y MPMD (Multiple Program Multiple Data). En los capítulos anteriores hemos podido ver las principales características de MPI y su implementación en diversas aplicaciones.

8.2.2 EL ESTÁNDAR PVM

PVM significa “Parallel Virtual Machine”. Esta implementación es relativamente nueva ya que sus inicios se remontan al verano de 1989 en el Oak Ridge National Laboratory. Es un software que permite ejecutar aplicaciones paralelas distribuidas en redes de ordenadores heterogéneos. PVM es, junto con MPI, uno de los paquetes de software más utilizados para implementar aplicaciones paralelas.

PVM explota el paralelismo en un ambiente de varias computadoras unidas mediante una red, siendo lo más común una red Ethernet; por tal motivo se tendrá un ambiente heterogéneo en cuanto a procesadores, y la memoria será distribuida.

PVM es un paquete de software que permite a una colección heterogénea de computadoras conectarse mutuamente a través de una red para ser utilizadas como una gran computadora paralela. El objetivo de un sistema PVM es permitir que una colección de computadoras puedan ser utilizadas para la computación paralela. PVM soporta:

• Heterogeneidad en términos de máquinas, redes y aplicaciones

194 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 205: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

• Modelos de pase de mensajes explícitos

• Computación basada en procesos

• Soporte multiprocesador (MPP, SMP)

• Acceso al hardware: las aplicaciones bien pueden ignorar o aprovechar las diferencias entre el hardware.

• Lista de host configurable dinámicamente: los procesadores pueden ser añadidos o eliminados y se pueden incluir procesadores mixtos.

PVM es el desarrollo más fácil y flexible disponible para la programación de tareas básicas paralelas que requieran la intervención de diferentes tipos de computadoras que trabajen sobre diferentes sistemas operativos. La librería PVM es especialmente útil para sistemas de varios procesadores que pueden ser conectados juntos para formal un procesador virtual paralelo. Además es el estándar para llevar a cabo la implementación de clusters heterogéneos y está disponible gratuitamente y es muy utilizado. Proporciona un soporte excelente para MPMD – Multiple Program Multiple Data (MIMD – Multiple Instruction Multiple Data) y SPMD – Single Program Multiple Data (SIMD – Single Instruction Multiple Data).

Un programa paralelo en PVM, generalmente, constará de un proceso maestro y varios procesos esclavos, realizando cada esclavo una parte del trabajo global. En la figura 6.1 se ven dos posibles (no son los únicos) esquemas de trabajo para programas realizados en PVM.

GVA–ELAI–UPM ® PFC 0084 - 2005 195

Page 206: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

Figura 8.1: Esquemas Maestro-Esclavo

Un programa PVM también puede explotar una arquitectura multiprocesador con memoria compartida, ya que se generaría y se repartirían automáticamente los procesos que creados. Sin embargo esta dirigido para utilizar varias computadoras unidas por algún mecanismo como puede ser una red ethernet o redes mucho más especializadas para explotar este paralelismo.

Se trabajará bajo el modelo de paso de mensajes, el cual se realizará bajo primitivas de tipo bloqueante, con lo que obtendremos un método de sincronización bastante sencillo.

8.2.3 EL ESTÁNDAR CORBA

En computación, Common Object Request Broker Architecture (CORBA) es un estándar que establece una plataforma de desarrollo de sistemas distribuidos facilitando la invocación de métodos remotos bajo un paradigma orientado a objetos.

CORBA fue definido y está controlado por el Object Management Group (OMG) que define las APIs, - el protocolo de comunicaciones y los mecanismos

196 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 207: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

necesarios para permitir la interoperabilidad entre diferentes aplicaciones escritas en diferentes lenguajes y ejecutadas en diferentes plataformas -, lo que es fundamental en computación distribuida.

En un sentido general CORBA "envuelve" el código escrito en otro lenguaje en un paquete que contiene información adicional sobre las capacidades del código que contiene, y sobre cómo llamar a sus métodos. Los objetos que resultan pueden entonces ser invocados desde otro programa (u objeto CORBA) desde la red. En este sentido CORBA se puede considerar como un formato de documentación legible por la máquina, similar a un archivo de cabeceras pero con más información.

CORBA utiliza un lenguaje de definición de interfaces (IDL) para especificar los interfaces con los servicios que los objetos ofrecerán. CORBA puede especificar a partir de este IDL la interfaz a un lenguaje determinado, describiendo cómo los tipos de dato CORBA deben ser utilizados en las implementaciones del cliente y del servidor. Implementaciones estándar existen para Ada, C, C++, Smalltalk, Java y Python. Hay también implementaciones para Perl y TCL.

Al compilar una interfaz en IDL se genera código para el cliente y el servidor (el implementador del objeto). El código del cliente sirve para poder realizar las llamadas a métodos remotos. Es el conocido como stub, el cual incluye un proxy (representante) del objeto remoto en el lado del cliente. El código generado para el servidor consiste en unos skeletons (esqueletos) que el desarrollador tiene que rellenar para implementar los métodos del objeto.

CORBA se encarga habitualmente de los siguientes aspectos en los sistemas distribuidos:

• Registro de objetos

• Localización de objetos

• Activación de objetos

• Gestión de errores

GVA–ELAI–UPM ® PFC 0084 - 2005 197

Page 208: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

• Multiplexación y desultiplexación de invocaciones

• Aplanado y desaplanado de datos

Los tipos de componentes de los que consta CORBA son, generalmente:

• Object Services: independientes de dominio, útiles para muchos programas distribuidos (localización de objetos por nombre o por características, transacciones, notificación de sucesos, etc.)

• Common Facilities: para aplicaciones de usuarios finales (Distributed Document Component Facility)

• Domain Interfaces: para dominios específicos (Ej.: para telecomunicaciones)

• Application Interfaces: para aplicaciones específicas (no normalizados)

8.3 EL PROCESAMIENTO DISTRIBUIDO EN C++ A TRAVÉS DEL ESTÁNDAR PVM

Con anterioridad hemos visto una pequeña reseña de PVM. En este apartado intentaremos dar una visión en mayor profundidad de la programación paralela y distribuida en C++ utilizando el estándar PVM.

198 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 209: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

8.3.1 INTRODUCCIÓN A PVM

8.3.1.1 ¿Qué es PVM?

PVM es un paquete de software (conjunto de librerías) que nos permiten crear y ejecutar aplicaciones concurrentes o paralelas, basándose en el modelo de paso de mensajes. Funciona sobre un conjunto heterogéneo de ordenadores con sistema operativo UNIX conectados por una o mas redes. PVM permite trabajar tanto con arquitecturas de ordenadores diferentes como con redes de varios tipos.

PVM tiene dos componentes básicos:

1. El proceso daemon (pvmd3): es un proceso Unix encargado de controlar el funcionamiento de los procesos de usuario en la aplicación PVM y de coordinar las comunicaciones. Tiene las siguientes características:

• Un daemon se ejecuta en cada máquina configurada en la máquina virtual paralela.

• Cada daemon mantiene una tabla de configuración e información de los procesos relativa a su máquina virtual (/tmp/pvmd.uid).

• Los procesos de usuario se comunican unos con otros a través de los daemons. Primero se comunican con el daemon local vía la librería de funciones de interface. Luego el daemon local manda/recibe mensajes de/a daemons de los host remotos.

• Cada máquina debe tener su propia versión de pvmd3 instalada y construida de acuerdo con su arquitectura y además accesible con $PVM_ROOT.

2. La librería de rutinas de interface (libpvm3.a, libfpvm3.a & libgpvm3.a):

GVA–ELAI–UPM ® PFC 0084 - 2005 199

Page 210: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

• libpvm3.a: es una librería en lenguaje C de rutinas de interface. Son simples llamadas a Funciones que el programador puede incluir en la aplicación paralela. Proporciona capacidad de iniciar y terminar procesos; empaquetar, enviar, y recibir mensajes; sincronizar mediante barreras; conocer y dinámicamente cambiar la configuración de la máquina virtual paralela. Las rutinas de la librería no se conectan directamente con otros procesos, si no que mandan y reciben la configuración de la máquina virtual paralela.

• libgpvm3.a: Se requiere para usar grupos dinámicos.

• libfpvm3.a: Para programas en Fortran

8.3.1.2 Ventajas del uso de PVM

Algunas de las ventajas que presenta la utilización de PVM son las siguientes:

• Fiabilidad: promete cumplir los requerimientos que necesita la computación distribuida del futuro, permitiendo escribir programas que utilicen una serie de recursos capaces de operar independientemente y que son coordinados para obtener un resultado global que depende de los cálculos realizados en todos ellos.

• Reduce el "wall clock execution time".

• Fácil instalación y uso: con una interface de programación simple y completa.

• Extensión: Es un software de dominio público con creciente aceptación y uso.

• Flexibilidad: se adapta a diversas arquitecturas, permite combinaciones de redes locales con las de área extendida, cada

200 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 211: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

aplicación "decide" donde y cuando sus componentes son ejecutados y determina su propio control y dependencia, se pueden programar diferentes componentes en diferentes lenguajes, es fácil la definición y la posterior modificación de la propia Máquina Virtual Paralela.

• Tolerancia a fallos: si por cualquier razón falla uno de los ordenadores que conforman nuestra PVM y el programa que la usa está razonablemente bien hecho, nuestra aplicación puede seguir funcionando sin problemas. Siempre hay alguna razón por la que alguna máquina puede fallar, y la aplicación debe continuar haciendo los cálculos con aquel hardware que continúe disponible.

• Precio: así como es mucho más barato un computador paralelo que el computador tradicional equivalente, un conjunto de ordenadores de mediana o baja potencia es muchísimo más barato que el computador paralelo de potencia equivalente. Al igual que ocurrirá con el caso del computador paralelo, van a existir factores (fundamentalmente, la lentitud de la red frente a la velocidad del bus del computador paralelo) que van a hacer de que sean necesarios más ordenadores de pequeña potencia que los teóricos para igualar el rendimiento. Sin embargo, aun teniendo esto en cuenta, la solución es mucho más barata. Además, al no ser PVM una solución que necesite de máquinas dedicadas (es decir, el daemon de PVM corre como un proceso más), podemos emplear en el proceso los tiempos muertos de los procesadores de todas las máquinas de nuestra red a las que tengamos acceso. Por ello, si ya tenemos una red Unix montada, el costo de tener un supercomputador paralelo va a ser cero ya disponemos de las máquinas, no tendremos que comprar nada nuevo, y además la biblioteca PVM es software libre, por lo que no hay que pagar para usarla.

• Heterogeneidad: podemos crear una máquina paralela virtual a partir de ordenadores de cualquier tipo. PVM nos va a abstraer la topología de la red, la tecnología de la red, la cantidad de memoria de cada máquina, el tipo de procesador y la forma de almacenar los datos. Este último punto es de extrema importancia, ya que el principal problema que tendríamos en los sockets era la programación de rutinas de conversión de formato de datos entre todos los ordenadores de la red, puesto que la codificación, tanto de enteros como de flotantes, puede ser distinta. Por último, nos permite incluir en nuestra PVM hasta máquinas paralelas. Una máquina paralela en una PVM se puede comportar tanto como una sola máquina secuencial (caso, por

GVA–ELAI–UPM ® PFC 0084 - 2005 201

Page 212: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

ejemplo, del soporte SMP de Linux) o, como ocurre en muchas máquinas paralelas, presentarse a la PVM como un conjunto de máquinas secuenciales.

• Disponibilidad: la disponibilidad de PVM es completa.

8.3.1.3 Desventajas del uso de PVM

Algunas de las desventajas que se encuentran asociadas al uso de PVM son:

• Nos podemos olvidar del paralelismo fuertemente acoplado: si disponemos de una red Ethernet, simplemente la red va a dejar de funcionar para todas las aplicaciones (incluida PVM) de la cantidad de colisiones que se van a producir en caso de que intentemos paralelismo fuertemente acoplado. Si disponemos de una red de tecnología más avanzada, es decir, más cara (como ATM) el problema es menor, pero sigue existiendo.

• La abstracción de la máquina virtual, la independencia del hardware y la independencia de la codificación tienen un coste: PVM no va a ser tan rápida como son los Sockets. Sin embargo, si el grado de acoplamiento se mantiene lo suficientemente bajo, no es observable esta diferencia.

8.3.2 INSTALACIÓN DE PVM

8.3.2.1 Requerimientos necesarios para trabajar con PVM

Los requerimientos necesarios para trabajar con PVM son:

• Procesadores Unix conectados en Red (usualmente protocolo Internet).

202 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 213: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

• Daemon PVM, construido para cada arquitectura e instalado en cada máquina.

• Librerías PVM, construidas e instaladas para cada arquitectura.

• Ficheros particulares de aplicación específica: Programas (master/slave, SPMD,...), PVM hostfile (define que máquinas físicas componen la máquina virtual propia), ficheros $HOME/.rhosts.

8.3.2.2 Instalación de PVM 3.4.4 en LINUX

Una vez que hemos obtenido el fichero pvm3.3.10.tar.gz, los pasos a seguir serán los siguientes:

1. Descomprimir el ficheropvm3.3.10.tar.gz. Esto generará el archivo pvm3.3.10.tar.

2. Generar la estructura de directorios de pvm tar xvf pvm3.3.10.tar

3. Poner las variables de entorno ( Preferiblemente en el profile):

PVM_ROOT = $HOME/pvm3

PVM_ROOT = $HOME/pvm3

PVM_DPATH = $PVM_ROOT/lib/pvmd

PVM_ARCH = LINUX

Export PVM_ROOT PVM_DPATH PVM_ARCH

4. Ejecutar aimk s c g( en el directorio $HOME/pvm3 )

GVA–ELAI–UPM ® PFC 0084 - 2005 203

Page 214: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

5. Añadir $PVM_ROOT/lib al path.

Para verificar que la instalación es correcta escriba pvm. Esta orden invoca la consola de PVM. Debe aparecer el prompt pvm>. Ahora teclee conf. Se visualiza el nombre y las características técnicas de las computadoras físicas adscritas a la máquina virtual. Un ejemplo de dicha salida por pantalla es:

1 host, 1 data format HOST DTID ARCH SPEED DSIG dixxx.edv.uniovi.es 40000 LINUX 1000 0x00408841 pvm>

Para finalizar y volver al shell teclee halt. Si durante los pasos anteriores no se produce por pantalla la salida mencionada la instalación NO ES correcta.

La instalación de la librería PVM concluye con la etapa de verificación de la instalación descrita. Desde el punto de vista del administrador no hay tareas adicionales que realizar salvo, claro está, las asociadas con la concesión de permisos y la correcta configuración de las máquinas físicas para integrarlas en una red de computadoras.

Los siguientes pasos en la configuración de PVM corresponden a los usuarios finales, que son quienes determinas dónde, cuándo y cómo se va a constituir una máquina virtual para soportar la ejecución paralela de una aplicación. Estos pasos se describen en el siguiente apartado.

8.3.3 CONFIGURACIÓN DE PVM

En este apartado se detallan las distintas etapas para poder utilizar PVM desde una cuenta de usuario. El proceso de configuración está dividido en dos etapas:

1. PVM sobre una única máquina física.

204 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 215: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

2. PVM sobre varias computadoras, siguiendo una estructura incremental; esto es, lo dicho para una única máquina física es necesario para varias computadoras.

Para las explicaciones suponemos que PVM está instalado en el mismo directorio en todas las máquinas físicas. En caso contrario se debe recurrir a los manuales de PVM o a Message Passing with PVM and MPI: Advanced Features and Trends (Markus Fischer), para determinar los parámetros necesarios.

Por último, hay que resaltar la importancia de seguir correctamente los pasos que a continuación se van a detallar. En caso contrario puede suceder que la máquina virtual no funcione correctamente. De hecho, los problemas típicos de PVM están ligados a la falta de permisos o a que los daemons no encuentran el resto de procesos o ficheros por una mala configuración. Otra causa habitual de un funcionamiento anómalo de PVM es la modificación de scripts asociados al shell sin haber lanzado un nuevo shell (o entrar otra vez en sesión). Las modificaciones realizadas normalmente no están disponibles hasta que no se lance de nuevo el shell.

8.3.3.1 PVM sobre una única máquina física

En este supuesto el proceso es muy simple. Para que el funcionamiento de la consola de PVM sea más explícito, se puede crear un fichero en $HOME, con nombre .pvmrc, con un contenido similar al siguiente ejemplo:

alias ? help alias print_environment spawn -> /bin/env alias h help alias j jobs alias t ps alias tm trace alias v version setenv PVM_EXPORT DISPLAY tm addhosts delhosts halt tm pvm_mytid pvm_exit pvm_parent tm send recv nrecv probe mcast trecv sendsig recvf version id conf

GVA–ELAI–UPM ® PFC 0084 - 2005 205

Page 216: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

Ahora, cuando ejecutamos la orden pvm, el resultado por pantalla será:

............ version 3.4.4 id t40001 conf

1 host, 1 data format

HOST DTID ARCH SPEED DSIG dixxx.edv.uniovi.es 40000 LINUX 1000 0x00408841 pvm>

Volveremos al shell desde la consola de PVM tecleando halt.

8.3.3.2 PVM sobre varias computadoras

Para usar más de un nodo real de proceso, con indicarlo al invocar la consola de PVM es suficiente. Es decir, ejecutar pvm con un argumento, el nombre de un fichero donde se reflejan los nombres lógicos o direcciones físicas de los citados ordenadores. Si el usuario que va ha ejecutar procesos en el seno da la máquina virtual es el mismo en todas las computadoras reales, entonces el fichero tendrá el siguiente aspecto:

m1.dominio1.uniovi.es ep=$HOME/bin:$PVM_ROOT/bin/LINUX m2.dominio2.uniovi.es ep=$HOME/bin:$PVM_ROOT/bin/MIPS m3.dominio3.uniovi.es ep=$HOME/bin:$PVM_ROOT/bin/ALPHA

Donde el flag ep indica a PVM donde están los ejecutables de nuestra aplicación (por defecto PVM busca en $PVM_ROOT/bin/arquitectura. Si están ahí no es necesario dicho flag) y el flag dx donde reside la instalación de PVM en dicha computadora (este flag solamente es necesario si PVM está instalado en un lugar distinto al usado para instalar PVM en la computadora que arranca la máquina virtual). Obviamente, el usuario, la instalación de PVM, la ubicación de los

206 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 217: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

ejecutables de las aplicaciones, etc. pueden ser distintos. Los flag asociados a cada caso se pueden consultar en la documentación de PVM, en Message Passing with PVM and MPI: Advanced Features and Trends (Markus Fischer) o en pvm_config.

Para el ejemplo propuesto y supuesto que el fichero creado lo hemos llamado pvm_hosts, el resultado de invocar la orden "pvm pvm_hosts" cambiando los nombres ficticios por nombres lógicos reales:

3 host, 3 data formats HOST DTID ARCH SPEED DSIG di137.edv.uniovi.es 80000 LINUX 1000 0x00408841 di127.edv.uniovi.es 40000 LINUX 2000 0x00408c41

di133.edv.uniovi.es 60000 LINUX 3000 0x00408d41 pvm>

Como siempre, volveremos al shell desde la consola de PVM tecleando halt.

El proceso para crear la máquina virtual es el siguiente. Por cada línea del fichero pvm_hosts PVM trata de lanzar la ejecución del proceso pvmd3 en la computadora referenciada por el nombre lógico o la dirección física. Por este motivo, se debe añadir al fichero de configuración de hosts (pvm_hosts en nuestro caso) el nombre lógico de la computadora desde donde estamos lanzando la máquina virtual. Además, hay que recordar que por defecto PVM busca en todas las computadoras el ejecutable pvmd3 usando el path de la máquina que invoca la orden "pvm pvm_hosts", que usa el mismo username, la misma ubicación de los ficheros de la aplicación, el mismo directorio de trabajo temporal, etc. Si hay diferencias se pueden utilizar los flags mencionados anteriormente.

Para lanzar la ejecución del proceso pvmd3 en una computadora física distinta a la que ejecuta la orden "pvm pvm_hosts", PVM utiliza el soporte remote shell (rsh, consultar el manual para más información). Entonces, hay que tener la seguridad de que el username utilizado puede lanzar la ejecución remota de comandos de/hacia la computadora origen a las de destino. Además, se debe asegurar que a nivel global los administradores de las máquinas implicadas tienen habilitado dicho servicio (para más información consultar con los administradores de cada computadora).

GVA–ELAI–UPM ® PFC 0084 - 2005 207

Page 218: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

Supuesto que no hay restricciones de orden superior, las indicadas en el párrafo anterior, cada usuario debe permitir en cada computadora el acceso desde otro usuario y computadora. En otras palabras, en cada computadora hay que decir qué usuarios de qué computadoras pueden lanzan el proceso pvmd3. Esto se hace mediante un fichero de nombre .rhosts y que debe estar en $HOME. Su formato es (para más información mirar el manual de rsh):

computadora_remota1 username_en_computadora_remota1 computadora_remota2 username_en_computadora_remota2 computadora_remota3 username_en_computadora_remota3

Así, los username de las computadoras indicadas en .rhosts son los únicos que podrán lanzar la ejecución de pvmd3. Obviamente, debe haber una concordancia entre lo dicho en pvm_hosts y .rhosts.

Finalmente, hay que resaltar que la utilización del .rhosts es peligrosa, ya que los usuarios de las máquinas indicadas en él pueden lanzar la ejecución de cualquier comando del shell, como por ejemplo "rm -rf *". Luego se deben tomar precauciones, como por ejemplo poner en .rhosts lo imprescindible o no utilizar comodines. Otras medidas muy eficientes son cambiarle el nombre cuando no se utilice PVM y eliminar los permisos de acceso a .rhosts a otros usuarios (chmod 600 .rhosts).

8.3.4 EJECUCIÓN DE APLICACIONES PVM

Los pasos necesarios para poder ejecutar un programa PVM serán los siguientes:

1. Configurar las variables de entorno PVM_ROOT, PVM_ARCH y crear un directorio ~/pvm3/bin/ARCH en cada máquina.

2. Crear/Configurar el fichero ~/.rhosts (opcional)

3. Crear/Configurar el fichero 'hostpvm_file' (Si es necesario)

208 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 219: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

4. Iniciar el master pvmd3 con:

a) pvmd3 hostpvm_file &

b) pvm (Para iniciar la consola) o pvm hostpvm_file

5. Ejecutar la aplicación :

a) Desde la línea de comandos: a.out (o como se llame nuestra aplicación)

b) Desde consola: spawn a.out

6. Parar PVM usando halt en el prompt de la consola o usando UNIX kill en el servidor y asegurándose de que todos los ficheros /tmp/pvmd.uid han sido borrados en todos los ordenadores que componían la máquina virtual.

8.3.5 COMANDOS Y FUNCIONES MÁS IMPORTANTES DE PVM

8.3.5.1 Comandos

Algunos de los comandos más importantes son:

• add máquina: incorpora la máquina indicada a la máquina paralela virtual.

• delete máquina: elimina la máquina indicada del conjunto de máquinas asociadas a la máquina paralela virtual. Como es lógico, no podremos eliminar la máquina desde la que estamos ejecutando el intérprete de comandos.

• conf: configuración actual de la máquina paralela virtual.

GVA–ELAI–UPM ® PFC 0084 - 2005 209

Page 220: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

• ps: listado de procesos de la máquina paralela virtual. ps -a lista todos los procesos.

• halt: apaga la máquina paralela virtual. Esto significa que mata todas las tareas de PVM, elimina el daemon de forma ordenada y sale del programa pvm.

• help: lista los comandos del programa. Tremendamente útil en los momentos de desesperación.

• id: imprime el TID de la consola.

• jobs: genera un listado de los trabajos en ejecución.

• kill: mata un proceso de PVM.

• mstat: muestra el estado de una máquina de las pertenecientes a PVM.

• pstat: muestra el estado de un proceso de los pertenecientes a PVM.

• quit: sale de la máquina paralela virtual sin apagarla.

• reset: inicializa la máquina. Eso supone matar todos los procesos de PVM, salvo los programas monitores en ejecución, limpiar las colas de mensajes y las tablas internas y pasar a modo de espera todos los servidores.

• setenv: lista todas las variables de entorno del sistema.

• sig señal tarea: manda una señal a una tarea.

210 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 221: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

• spawn: arranca una aplicación bajo PVM. Es un comando bastante complejo cuyas opciones veremos en una sección aparte.

• trace: actualiza o visualiza la máscara de eventos traceados.

• alias: define un alias predefinido, es decir, un atajo para teclear un comando.

• unalias: elimina un alias predefinido.

• version: imprime la versión usada de PVM.

8.3.5.2 Funciones

PVM proporciona casi 70 funciones para programar aplicaciones en C. Las podemos dividir en seis tipos diferentes:

1. Funciones de Control de Procesos.

2. Funciones de Información.

3. Funciones de Configuración de grupos.

4. Funciones de Empaquetamiento de datos y control de Buffers.

5. Funciones de Envío de Mensajes.

6. Funciones de Recepción de mensajes.

GVA–ELAI–UPM ® PFC 0084 - 2005 211

Page 222: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

8.3.5.3 Funciones de control de procesos

Las funciones de control de procesos son las siguientes:

• int pvm-mytid (): aparece necesariamente en todo programa escrito para PVM porque es la función que hace entrar el proceso correspondiente en la máquina virtual que simula PVM. Esta rutina no tiene ningún argumento y devuelve el tid correspondiente al proceso desde el que ha sido invocada.

• int pvm-exit (): permite al proceso salir de PVM, pero no lo termina, por lo que tras la invocación de esta función el proceso puede seguir ejecutándose como cualquier otro proceso Unix.

• int pvm_spawn (char *task, char **argv, int flag, char *where, int ntask, int *tids)

• int pvm-kill (int tid): ordena la terminación de la tarea de PVM identificada por tid. No debe usarse esta rutina para eliminar la tarea que la invoca; para ello debe llamarse a pvm_exit () seguido de exit ().

8.3.5.4 Funciones de información

Las funciones de información son las siguientes:

• int pvm_parent (): devuelve el tid del proceso que lanzó esta tarea, es decir, aquella desde la que se llama a esta función. En el caso de que esta tarea no haya sido creada por pvm_spawn devuelve PvmNoParent.

• int pvm_mytid (tid): devuelve el tid correspondiente al proceso desde el que ha sido invocada.

212 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 223: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

• int pvm_pstat (int tid): devuelve el estado de la tarea PVM identificada por tid Si la tarea se está ejecutando devuelve PvmOk, PvmNoTask en caso contrario, y PvmBadParam si tid es inválido.

• it pvm_config (int *nhost, int *narch, struct hostinfo **hostp): proporciona información sobre la configuración de la máquina virtual int info = pvm_config( int *nhost, int *narch, - struct hostinfo **hostp):

Struct hostinfo { int hi_tid; char *hi_name; char *hi_arch; int hi_speed; }hostp;

8.3.5.5 Funciones de configuración de grupos

Las funciones de configuración de grupos son las siguientes:

• int pvm_joingroup (²mygroup²): devuelve el número de instancia del proceso en el grupo y le hace miembro del grupo llamado mygroup.

• int pvm_gsize (²mygroup²): devuelve el número de miembros del grupo.

• int pvm_gettid (²mygroup², inum): devuelve el tid del proceso que tiene el número de instancia inum en el grupo mygroup.

• int pvm_getinst (²mygroup², tid): devuelve el número de instancia que tiene la tarea tid en el grupo mygroup.

GVA–ELAI–UPM ® PFC 0084 - 2005 213

Page 224: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

• pvm_bcast (²mygroup²,...,..): emite un mensaje contenido en el buffer de emisión a todos los miembros del grupo salvo al emisor.

• int pvm joingroup (char *group): añade la tarea que la invoca al grupo de procesos identificado por group. En el caso de ser la primera tarea en unirse a él, la llamada crea el grupo. La función devuelve el número de instancia del proceso en el grupo, entero que puede adoptar valores entre 0 y el número de miembros del grupo menos uno. Por otra parte, una tarea puede formar parte de varios grupos. Si un proceso abandona un grupo y luego vuelve a él, puede obtener un número de instancia distinto, aunque siempre se asigna el menor número de instancia disponible a cualquier nueva tarea.

• int pvm_lvgroup (char *group): hace que la tarea que la invoca salga del grupo group.

• int pvm-gettid (char *group, int inum): devuelve el tid del proceso que tiene el número de instancia inum en el grupo group.

• int pvm-getinst (char *group, int tid): devuelve el número de instancia que tiene la tarea tid en el grupo group.

• int pvm-gsize (char *group): devuelve el número de miembros del grupo.

• int pvm-barrier (char *group, int count): bloquea el proceso que la invoca hasta que count procesos del grupo group hayan llamado a pvm_barrier. En general, count debería ser el número de componentes del grupo. Los procesos no pueden llamar a esta función usando como argumento un grupo al que no pertenecen. Además, en una sincronización de barrera dada, todos los procesos que llaman a esta función deberán usar el mismo valor para count.

214 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 225: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

8.3.5.6 Funciones de empaquetamiento de datos y control de buffers

Un mensaje antes de ser mandado hacia uno o varios destinatarios debe ser colocado en un buffer. Un buffer permite reservar la memoria poco a poco cuando se van empaquetando los datos.Las funciones de empaquetamiento de datos y control de buffers son las siguientes:

• int pvm-pk*(): es una familia de funciones que se emplean para empaquetar un vector de datos de un tipo dado en el buffer de envío. Pueden ser llamados varias veces para empaquetar un mensaje. Cada mensaje puede constar de varios vectores, cada uno de los cuales puede ser de un tipo distinto. No hay límite a la complejidad de los mensajes empaquetados, pero el receptor debe desempaquetarlos exactamente como los empaquetó el emisor. Las estructuras de C se deben enviar empaquetando sus componentes individuales. Cada función tiene un puntero al primer elemento a ser empaquetado, el número de elementos a empaquetar y la distancia o stride entre cada dos elementos consecutivos a empaquetar. La excepción la constituye pvm_pkstr, que empaqueta un array de caracteres terminado por un NULL.

• int pvm-initsend (int encoding): limpia el buffer de envío y crea uno nuevo, cuyo identificador devuelve, para empaquetar un nuevo mensaje. El esquema de codificación utilizado viene dado por encoding. Si se usa un solo buffer, que es lo habitual, debe llamarse a esta función antes de empaquetar un nuevo mensaje en el buffer pues, de otra forma, el nuevo mensaje se añadirá al anterior.

• int pvm-mkbuf (int encoding): crea un nuevo buffer de envío vacío, especificando el método de codificación usado para los mensajes, y devolviendo el identificador del buffer.

• int pvm-freebuf (int buf id): libera el buffer identificado por bufid. Debería hacerse tras enviar el mensaje que contiene, siempre y cuando no se vaya a necesitar en el futuro. Para usarlo debe haberse llamado antes a pvm_mkbuf para crear el buffer. No es necesario llamar a ninguna de estas dos funciones si se emplea pvm_initsend.

GVA–ELAI–UPM ® PFC 0084 - 2005 215

Page 226: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

• int pvm_getsbuf (): devuelve el identificador del buffer de envío activo.

• int pvm_getrbuf (): devuelve el identificador del buffer de recepción de activo.

• int pvm-setsbuf (int buf id): convierte al buffer identificado por bufid en el nuevo buffer de envío activo, guardando el estado del buffer anterior, cuyo identificador devuelve. Si bufid es 0, el buffer actual es guardado y no hay buffer activo.

• int pvm-setrbuf (int bufid): convierte al buffer identificado por bufid en el nuevo buffer de recepción activo, guardando el estado del buffer anterior, cuyo identificador devuelve. Si bufid es 0, el buffer actual es guardado y no hay buffer activo

8.3.5.7 Funciones de envío de mensajes

Las funciones de envío son las siguientes:

• int pvm-send (int tid, int msgtag): etiqueta con el identificador entero msgtag el mensaje que se encuentra en el buffer de envío y lo manda al proceso identificado por tid. Es muy importante tener en cuenta que esta rutina no bloquea al proceso que la llama, es decir, cuando una tarea envía datos puede seguir su ejecución normalmente, sin tener que esperar a que el destinatario reciba los datos ni a que éstos sean enviados de forma efectiva

• int pvm-mcast (int *tids, int ntask, int msgtag): etiqueta el mensaje con el identificador msgtag y lo difunde a todas las tareas especificadas en el vector tids de números enteros, cuya longitud viene dada por ntask.

216 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 227: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

8.3.5.8 Funciones de recepción de mensajes

Las funciones de recepción son las siguientes:

• int pvm_nrecv (int tid, int msgtag): devuelve 0, retornando inmediatamente, si no se ha recibido ningún mensaje etiquetado con el valor de msgtag procedente de la tarea tid, permitiéndose el uso del valor comodín (-1) en ambos casos. Si, por el contrario, se ha recibido un mensaje de esas características, lo sitúa en el buffer activo de recepción, que es creado por nrecv, y devuelve el identificador de dicho buffer. El buffer de recepción anterior es borrado, a no ser que se haya llamado a pvm_setrbuf.

• int pvm_recv (int tid, int msgta): es una rutina de recepción con bloqueo, es decir, que no devuelve el control a la rutina que la invoca hasta que recive un mensaje. El mensaje debe tener la etiqueta msgtag y proceder de la tarea identificad por tid.

• int pvm-upk: es la familia de funciones que realizan la tarea opuesta a la de las funciones pvm_pk*, es decir, desempaquetan los datos que se encuentran en el buffer de recepción activo. La lista completa de las funciones que conforman este grupo es la siguiente, en donde podemos encontrar las funciones complementarias a las de empaquetamiento en el mismo orden.

• int pvmjoingroup (): añade la tarea que la invoca al grupo de procesos identificado por group. En el caso de ser la primera tarea en unirse a él, la llamada crea el grupo. La función devuelve el número de instancia del proceso en el grupo, entero que puede adoptar valores entre 0 y el número de miembros del grupo menos uno. Por otra parte, una tarea puede formar parte de varios grupos. Si un proceso abandona un grupo y luego vuelve a él, puede obtener un número de instancia distinto, aunque siempre se asigna el menor número de instancia disponible a cualquier nueva tarea.

GVA–ELAI–UPM ® PFC 0084 - 2005 217

Page 228: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

8.4 PASOS PARA REALIZAR LA PARALELIZACIÓN DE UN PROGRAMA USANDO PVM. EJEMPLOS

Los pasos a seguir son los siguientes:

1. Incluir el programa en PVM e identificar el maestro.

2. Crear procesos esclavos y redireccionar su salida.

8.4.1 EJEMPLO 1: COMUNICACIÓN MAESTRO – ESCLAVO

En este programa, el maestro enviará una cadena al esclavo, a la cual el esclavo convertirá en mayúsculas y enviará de regreso al maestro. El maestro y el esclavo se muestran a continuación. Para compilar los programas, se teclea el comando make -f makefile.demo.

8.4.1.1 Programa Maestro

/* --------------------------------------------------------------------------- * * master_pvm.c * * * * Programa maestro para una simple demostración de PVM * * -------------------------------------------------------------------------- */ #include <stdio.h> #include <stdlib.h> #include <pvm3.h> #include <string.h> int main() { int mytid; /* nuesto ID de tarea */ int slave_tid; /* el ID del esclavo */ int result;

218 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 229: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

char message[] = "hello pvm"; /* nos incluimos al sistema PVM y obtenemos nuestro ID */ mytid = pvm_mytid(); /* creamos al esclavo */ result = pvm_spawn("slave_pvm", (char**)0, PvmTaskDefault, "", 1, &slave_tid); /* comprobamos que el esclavo se creo adecuadamente */ if(result != 1) { fprintf(stderr, "Error: Cannot spawn slave.\n"); /* salimos del sistema PVM*/ pvm_exit(); exit(EXIT_FAILURE); } /* se inicializa el buffer de datos para transmitir los datos al esclavo*/ pvm_initsend(PvmDataDefault); /* se "empaqueta'' la cadena dentro del buffer*/ pvm_pkstr(message); /* se envia la cadena al esclavo con una etiqueta de mensaje igual a 0 */ pvm_send(slave_tid, 0); /* se espera y recibe el resultado del esclavo*/ pvm_recv(slave_tid, 0); /* se "desempaca'' el resultado del esclavo */ pvm_upkstr(message); /* se muestra el resultado del esclavo*/ printf("Data from the slave : %s\n", message); /* salimos del sistema PVM*/ pvm_exit(); exit(EXIT_SUCCESS); } /* fin del main() */ /* fin del master_pvm.c */

GVA–ELAI–UPM ® PFC 0084 - 2005 219

Page 230: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

8.4.1.2 Programa esclavo /* ------------------------------------------------------------------------------------- * * slave_pvm.c * * * * Este es el program esclavo para una simple demostración de PVM * * ------------------------------------------------------------------------------------- */ #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <pvm3.h> #define MSG_LEN 20 void convert_to_upper(char*); int main() { int mytid; int parent_tid; char message[MSG_LEN]; /* nos incluimos dentro del sistema PVM */ mytid = pvm_mytid(); /* se obtiene el ID del maestro*/ parent_tid = pvm_parent(); /* se recibe la cadena origina del maestro */ pvm_recv(parent_tid, 0); pvm_upkstr(message); /* se convierte la cadena a mayúsculas*/ convert_to_upper(message); /* se envia la cadena convertida al maestro */ pvm_initsend(PvmDataDefault); pvm_pkstr(message); pvm_send(parent_tid, 0); /* se sale del sistema PVM*/ pvm_exit(); exit(EXIT_SUCCESS); } /* fin del main() */

220 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 231: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

/* funcion para convertir una cadena dada a mayúsculas */ void convert_to_upper(char* str) { while(*str != '\0') { *str = toupper(*str); str++; } } /* end convert_to_upper() */ /* fin del slave_pvm.c */

8.4.1.3 Archivo Makefile

# Make file para el programa de demostración de PVM .SILENT : # rutas para incluir archivos y librerías INCDIR=-I/usr/share/pvm3/include LIBDIR=-L/usr/share/pvm3/lib/LINUX # ligas a la librería de PVM LIBS=-lpvm3 CFLAGS=-Wall CC=gcc TARGET=all # este es el directorio donde se crearán los programas PVM_HOME=$(HOME)/pvm3/bin/LINUX all : $(PVM_HOME)/master_pvm $(PVM_HOME)/slave_pvm $(PVM_HOME)/master_pvm : master_pvm.c $(CC) -o $(PVM_HOME)/master_pvm master_pvm.c $(CFLAGS) $(LIBS) \ $(INCDIR) $(LIBDIR) $(PVM_HOME)/slave_pvm : slave_pvm.c $(CC) -o $(PVM_HOME)/slave_pvm slave_pvm.c $(CFLAGS) $(LIBS) \ $(INCDIR) $(LIBDIR)

GVA–ELAI–UPM ® PFC 0084 - 2005 221

Page 232: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

8.4.1.4 Explicación del programa anterior

A continuación vamos a ver como trabaja el programa anterior. Antes de nada, para usar las funciones PVM, necesitaremos incluir el archivo de cabecera pvm3.h en nuestro programa (#include <pvm3.h>, tanto en el programa maestro como en el esclavo). También al compilar los programas, necesitamos ligarlos con la librería PVM. Esto se hace especificando la opción -lpvm3 al compilador. Además, necesitamos especificar al compilador las rutas de los archivos cabecera y las librerias, como se hace en el makefile.

En el programa maestro, primero se obtiene el task ID del maestro haciendo una llamada a la función pvm_mytid (). El sistema PVM asigna a cada proceso un identificador único un entero de 32 bits llamado task ID de la misma manera que Linux asigna a cada proceso un identificador de proceso. De cualquier forma, el maestro no emplea este identificador (almacenado en mytid). Nuestra intención era solo llamar a la función pvm_mytid (). Esta función enlista al proceso dentro del sistema PVM y genera un identificador único. Si no se enlista explícitamente al proceso, PVM automáticamente agrega a nuestro proceso en la primera llamada de cualquier función PVM.

A continuación empleamos pvm_spawn () para crear al proceso esclavo. El primer parámetro de esta, "slave_pvm", es el nombre del ejecutable para el esclavo. El segundo son los argumentos que se desean pasar al esclavo (de manera similar al argv en C). Como no se quieren enviar argumentos, se establece este valor a 0. El tercer parámetro es una bandera con la cual podemos controlar como y donde PVM inicia el esclavo. Como solo tenemos una sola máquina, establecemos esta bandera a PvmTaskDefault, lo cual le indica a PVM que emplee el criterio por omisión para crear al esclavo. El cuarto parámetro es el nombre del host o arquitectura sobre el cual deseamos se ejecute el programa y en este caso se deja vacío. Solo se emplea cuando se usa una bandera diferente a PvmTaskDefault. El quinto parámetro establece el número de esclavos que se crearán y el sexto es un puntero a un arreglo en el cual se regresan los IDs de los esclavos. Esta función regresa el número de esclavos actualmente creados.

Un mensaje en PVM consiste básicamente de dos partes: el dato y una etiqueta que identifica el tipo de mensaje. La etiqueta nos ayuda a distinguir entre diferentes mensajes. Podemos asignar al mensaje para el valor intermedio una etiqueta que diga MSG_RESULT la cual se puede #define en cualquier archivo de cabecera y una etiqueta que diga MSG_ERROT para los mensajes que indiquen error. El maestro observará las etiquetas de los mensajes y determinará a que tipo pertenecen.

222 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 233: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

Para enviar un mensaje, primero se necesita "inicializar" el buffer. Esto se hace llamando a pvm_initsend (). El parámetro para esta función indica el esquema de "codificación" a emplear. Cuando intercambiamos datos entre máquinas de diferentes arquitecturas (por ejemplo, entre una máquina Pentium y una estación de trabajo SPARC) se necesita codificar el dato a enviar y decodificar el dato que se recibe de esta manera el dato es confiable. El parámetro para pvm_initsend () indica el esquema de codificación a emplear. El valor PvmDataDefault indica un esquema de codificación en el cual posibilita que el dato pueda ser intercambiado entre arquitecturas heterogéneas. Una vez que el buffer ha sido inicializado, necesitamos colocar el dato dentro del buffer y codificarlo. En nuestro caso, el dato es una cadena, así que empleamos la función pvm_pkstr () para "empaquetarlo" es decir codificarlo y colocarlo dentro del buffer. Si se requiere enviar un entero, existe la función pvm_pkint (). De forma similar, hay funciones para otros tipos de datos. Una vez que el dato es empaquetado, llamamos a pvm_send () para enviar el mensaje. El primer argumento es el ID del proceso al cual esta destinado el mensaje y el segundo es la etiqueta del mensaje. Como solo tenemos un tipo de mensaje, ponemos este valor a 0.

Una vez que el dato se envia al esclavo, el esclavo va a procesarlo y envia el resultado al maestro. Así que ahora llamamos pvm_recv () para recibir el datos del esclavo. De nuevo, el parámetro es le ID del proceso que estamos esperando el mensaje y la etiqueta del mensaje. Si el mensaje deseado aún no es enviado, esta función lo espera y no regresa. Por lo tanto, el maestro espera para que el esclavo procese el dato. Una vez que el mensaje llega, el dato se almacena en el buffer de recepción. Es necesario "desempacar" es decir decodificar para obtener el mensaje original. Esta decodificación se realiza mediante pvm_upkstr (). Por último desplegamos la cadena.

Antes que el programa termine, se debe indicar al sistema PVM que se deja este de esta manera los recursos ocupados por el proceso son liberados. Esto se realiza llamando a la función pvm_exit (). Después, el programa termina.

El programa esclavo es sencillo de comprender. Primero encontramos el ID del master (el cual es también su padre ya que el maestro creo al esclavo) llamando a la función pvm_parent (). Después recibe la cadena del maestro, la convierte a mayúscula y envia el resultado al maestro.

GVA–ELAI–UPM ® PFC 0084 - 2005 223

Page 234: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

8.4.2 EJEMPLO 2: PROGRAMA DE SUMA

En este caso tenemos un maestro y 4 esclavos. El maestro crea primero a los 4 esclavos y envia a cada uno de ellos su parte de los datos. El esclavo suma los datos y envia el resultado al maestro. Por lo que, se tienen dos tipos de mensajes: uno cuando el maestro envia un dato a los esclavos, para el cual emplearemos la etiqueta MSG_DATA y otro cuando el esclavo envia el resultado al maestro, para el cual usaremos la etiqueta MSG_RESULT. El programa maestro y esclavo se listan a continuación:

8.4.2.1 Cabeceras comunes /* -------------------------------------------------------------------- * * common.h * * * * Esta cabecera define algunas constantes comunes. * * -------------------------------------------------------------------- */ #ifndef COMMON_H #define COMMON_H #define NUM_SLAVES 4 /* número de esclavos */ #define SIZE 100 /* tamaño total del dato */ #define DATA_SIZE (SIZE/NUM_SLAVES) /* tamaño para cada esclavo */ #endif /* end common.h */ /* -------------------------------------------------------------------------------- * * tags.h * * * * Esta cabecera define las etiquetas empleadas por los mensajes. * * -------------------------------------------------------------------------------- */ #ifndef TAGS_H #define TAGS_H #define MSG_DATA 101 /* datos del maestro al esclavo*/ #define MSG_RESULT 102 /* resultado del esclavo al maestro*/ #endif /* end tags.h */

224 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 235: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

8.4.2.2 Programa maestro /* -------------------------------------------------------------------------------------- * * master_add.c * * * * Programa maestro para implementar la suma de los elementos de un * * arreglo usando PVM * * -------------------------------------------------------------------------------------- */ #include <stdio.h> #include <stdlib.h> #include <pvm3.h> /* PVM constantes y declaraciones */ #include "tags.h" /* etiquetas para los mensajes */ #include "common.h" /* constantes comunes */ int get_slave_no(int*, int); int main() { int mytid; int slaves[NUM_SLAVES]; /* arreglo para almacenar los task IDs de los esclavos */ int items[SIZE]; /* datos a ser procesados */ int result, i, sum; int results[NUM_SLAVES]; /* resultados de los esclavos */ /* nos enlistamos en el sistema PVM */ mytid = pvm_mytid(); /* inizilizacion del arreglo 'items' */ for(i = 0; i < SIZE; i++) items[i] = i; /* se crean los esclavos */ result = pvm_spawn("slave_add", (char**)0, PvmTaskDefault, "", NUM_SLAVES, slaves); /* se comprueba que los esclavos creados sean suficientes */ if(result != NUM_SLAVES) { fprintf(stderr, "Error: Cannot spawn slaves.\n"); pvm_exit(); exit(EXIT_FAILURE); } /* se distribuyen los datos a los esclavos */ for(i = 0; i < NUM_SLAVES; i++) { pvm_initsend(PvmDataDefault);

GVA–ELAI–UPM ® PFC 0084 - 2005 225

Page 236: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

pvm_pkint(items + i*DATA_SIZE, DATA_SIZE, 1); pvm_send(slaves[i], MSG_DATA); } /* se recibe el dato de los esclavos */ for(i = 0; i < NUM_SLAVES; i++) { int bufid, bytes, type, source; int slave_no; /* se recibe el mensaje de cualquiera de los esclavos */ bufid = pvm_recv(-1, MSG_RESULT); /* se obtiene información del buffer*/ pvm_bufinfo(bufid, &bytes, &type, &source); /* se obtiene el número del esclavo que envió el mensaje*/ slave_no = get_slave_no(slaves, source); /* se desempaca la información del esclavo*/ pvm_upkint(results + slave_no, 1, 1); } /* se obtiene el resultado final */ sum = 0; for(i = 0; i < NUM_SLAVES; i++) sum += results[i]; printf("The sum is %d\n", sum); /* se sale del sistema PVM */ pvm_exit(); exit(EXIT_SUCCESS); /* end main() */ /* función que regresa el numero del esclavo dado su task ID */ int get_slave_no(int* slaves, int task_id) { int i; for(i = 0; i < NUM_SLAVES; i++) if(slaves[i] == task_id) return i;

226 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 237: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

return -1; /* end get_slave_no() */ /* end master_add.c */

8.4.2.3 Programa esclavo /* -------------------------------------------------------------------------------- * * slave_add.c * * * * Programa esclavo para realizar la suma de los elementos de un * * arreglo usando PVM * * -------------------------------------------------------------------------------- */ #include <stdlib.h> #include <pvm3.h> #include "tags.h" #include "common.h" int main() { int mytid, parent_tid; int items[DATA_SIZE]; /* datos para enviar al maestro*/ int sum, i; /* nos enlistamos dentro del sistema PVM */ mytid = pvm_mytid(); /* se obtiene el identificador del maestro */ parent_tid = pvm_parent(); /* se reciben los datos del maestro */ pvm_recv(parent_tid, MSG_DATA); pvm_upkint(items, DATA_SIZE, 1); /* se encuentra la suma de los elementos*/ sum = 0; for(i = 0; i < DATA_SIZE; i++) sum = sum + items[i]; /* se envia el resultado al maestro */ pvm_initsend(PvmDataDefault); pvm_pkint(&sum, 1, 1); pvm_send(parent_tid, MSG_RESULT); /* se sale del PVM*/

GVA–ELAI–UPM ® PFC 0084 - 2005 227

Page 238: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

pvm_exit(); exit(EXIT_SUCCESS); /* end main() */

8.4.2.4 Archivo Makefile # Make file para el programa suma del PVM - makefile.add .SILENT : # rutas para los archivos include y librerias del PVM INCDIR=-I/usr/share/pvm3/include LIBDIR=-L/usr/share/pvm3/lib/LINUX # liga a la librería PVM LIBS=-lpvm3 CFLAGS=-Wall CC=gcc TARGET=all # el directorio donde se colocaran los ejecutables PVM_HOME=$(HOME)/pvm3/bin/LINUX all : $(PVM_HOME)/master_add $(PVM_HOME)/slave_add $(PVM_HOME)/master_add : master_add.c common.h tags.h $(CC) -o $(PVM_HOME)/master_add master_add.c $(CFLAGS) $(LIBS) \ $(INCDIR) $(LIBDIR) $(PVM_HOME)/slave_add : slave_add.c common.h tags.h $(CC) -o $(PVM_HOME)/slave_add slave_add.c $(CFLAGS) $(LIBS) \ $(INCDIR) $(LIBDIR)

8.4.2.5 Explicación del programa

En primer lugar vamos a analizar el programa esclavo. El esclavo recive los 25 elementos del arreglo del maestro en el arreglo items, obtiene su suma y envía el resultado al maestro con la etiqueta del mensaje MSG_RESULT.

A continuación analizamos al maestro. Definimos un arreglo slaves de tamaño igual a NUM_SLAVES el cual contiene los task ID's de los esclavos creados.

228 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 239: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

Existe otro arreglo results en el cual se almacenan los resultados de los esclavos. El maestro primero inicializa el arreglo items y después crea a los esclavos. Después distribuye los datos a los esclavos. En la llamada a la función pvm_pkint (), el primer parámetro es un puntero al arreglo en el cual los datos se almacenan, el segundo es el número de enteros a empacar y el tercero es el "stride". Stride significa cuantos elementos se saltan cuando se empaca. Cuando es 1, los elementos consecutivos son empacados. Cuando es 2, PVM va saltarse a los elementos 2 dando un paquete con los elementos pares (0, 2, 4...). De ahí que empleemos el 1.

Una vez que los datos han sido distribuidos a los esclavos, el maestro espera que los esclavos regresen el valor del resultado intermedio. Una posibilidad para obtener los resultados es que el maestro obtenga primero el resultado del esclavo 0 (es decir del esclavo cuyo ID esta almacenado en slave [0]), después del esclavo 1 y así sucesivamente.

En la llamada a pvm_recv (), sabemos que el primer parámetro es el task ID de la fuente del mensaje. Si este valor es -1, significa que los mensajes de cualquier proceso con la etiqueta de mensaje igual a MSG_RESULT van a ser recibidos por el maestro. El mensaje recibido junto con información de control se almacena en un buffer llamado active receive buffer. La llamada regresa un ID único para este buffer. Ahora necesitamos conocer quien envió el mensaje para poder almacenar el resultado en el apropiado elemento del arreglo results. La función pvm_bufinfo () regresa información acerca del mensaje en el buffer, como la etiqueta del mensaje, el número de bits y el task ID de quien lo envió. Una vez que se tiene el ID del remitente, se almacena el resultado enviado en su correcto elemento dentro del arreglo results.

8.5 EL PROCESAMIENTO DISTRIBUIDO EN C++ A TRAVÉS DEL ESTÁNDAR CORBA

Con anterioridad hemos visto una pequeña reseña de CORBA. En este apartado intentaremos dar una visión en mayor profundidad de la programación paralela y distribuida en C++ utilizando el estándar CORBA.

GVA–ELAI–UPM ® PFC 0084 - 2005 229

Page 240: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

8.5.1 INTRODUCCIÓN

CORBA es una arquitectura que facilita la interoperabilidad entre componentes distribuidos, desarrollados en diferentes lenguajes y que se ejecutan sobre distintas plataformas y sistemas operativos.

CORBA viene de Common Object Request Broker Architecture, que viene a significar algo así como "arquitectura común para gestores de solicitudes de objetos". Las especificaciones del estándar CORBA las desarrolla la OMG - Object Management Group -, que está conformado por un consorcio internacional de empresas, como pueden ser Sun, HP, DEC, IBM,....

El precursor del estándar CORBA fue el proyecto ANSA - Advanced Network Systems Architecture -, que fue desarrollado en el Reino Unido en el año 1985.

CORBA en sí no es una librería, un componente o una aplicación, sino un conjunto de especificaciones, es decir, de muchos documentos. Básicamente hay tres elementos principales:

• Un lenguaje de definición de interfaces llamado IDL (InterfaceDefinition Language).

• Un elemento que se encarga de facilitar la comunicación entre componentes llamado ORB (Object Request Broker).

• Un protocolo estándar existente en todos los ORB indistintamente del fabricante, llamado IIOP (Internet Inter-ORB Protocol).

El desarrollo de una aplicación CORBA, o la adaptación de una aplicación ya existente, comienza por la definición de las interfaces y módulos. Para ello se usa un lenguaje, llamado IDL, que es posteriormente convertido al lenguaje de implementación, que puede ser prácticamente cualquiera, desde COBOL y Visual Basic a C++, Delphi o Java.

230 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 241: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

En esta conversión, realizada con el compilador de IDL, se generan módulos de código que actúan como intérpretes en el cliente y en el servidor. Estos intérpretes, conocidos habitualmente como stub en el cliente y skeleton en el servidor, son los que se encargan de las tareas más complejas. El stub hace que el cliente CORBA crea estar usando un objeto local, facilitando la obtención de la referencia, preparación de parámetros para su transferencia y descodificación de valores de retorno. El skeleton se encarga del proceso complementario en la parte servidor.

Figura 8.2: Descripción de la arquitectura CORBA

Si IDL es el elemento de CORBA que facilita la independencia a la hora de trabajar con tipos de datos o definir interfaces, los ORB representan el otro pilar de CORBA. Los ORB forman parte de cliente y servidor, siendo los encargados de permitir la comunicación entre ambos componentes. Para ello usan el protocolo IIOP o algún otro derivado de GIOP, protocolos claramente documentados que permiten que ORBs de distintos fabricantes se comuniquen entre sí.

GVA–ELAI–UPM ® PFC 0084 - 2005 231

Page 242: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

Figura 8.3: Descripción de interfaces y objetos

Existen ORBs para la mayoría de los lenguajes y plataformas, aunque los más habituales se usan con C++, Java y COBOL. Son muchos los fabricantes que ofertan ORBs, aunque seguramente los productos más importantes y conocidos son Visibroker, de Inprise, y Orbix, de IONA.

Inprise Visibroker es un ORB integrado en las versiones superiores de Delphi, C++ Builder y JBuilder, lo cual supone una ventaja puesto que hay, en estas herramientas, asistentes que generan automáticamente el código para crear servidores y clientes CORBA.

Además de los ORBs y el protocolo de comunicación, una aplicación CORBA, concretamente un cliente, necesita algún mecanismo para localizar los objetos que necesita. Este mecanismo es un servicio de directorio distribuido, conocido habitualmente como smart agent, en el cual se registran todos aquellos servidores que están en funcionamiento. Estos servidores también pueden activarse bajo demanda, usando un OAD y un repositorio de interfaces que permita identificar el servidor que dispone de la interfaz solicitada.

8.5.2 OBJETIVOS DE CORBA

El objetivo inicial y primordial del grupo de gestión de objetos (OMG de Object Management Group) es crear una verdadera infraestructura abierta para la

232 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 243: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

distribución de objetos en vez de una aplicación comercial controlada por una compañía.

El secreto de su éxito ha sido que OMG ha creado las especificaciones de una interfaz, no el código. Las interfaces que especifica son siempre derivadas de una demostración tecnológica llevada a cabo por las compañías miembro. Las interfaces son escritas en un lenguaje de definición de interfaces (IDL) que define los límites de los componentes.

8.5.3 VENTAJAS DE CORBA

Las ventajas que presenta CORBA son:

• CORBA proporciona una infraestructura de comunicaciones para la colaboración entre objetos distribuidos heterogéneos (lenguaje de programación, arquitectura de la plataforma).

• Simplifica la interoperabilidad entre aplicaciones.

• Proporciona los mimbres para la colaboración entre objetos distribuidos.

• Pretende aportar a los sistemas distribuidos las ventajas que los lenguajes de programación mediante objetos aportan a la programación no distribuida, por ejemplo: encapsulación, herencia de interfaces, y manejo de excepciones.

8.5.4 DESARROLLOS CON CORBA

Los objetos distribuidos son piezas inteligentes de software que pueden intercambiar mensajes transparentemente en cualquier lugar en el mundo. El lenguaje y compilador que se usa para crear servidores de objetos distribuidos son totalmente transparentes a sus clientes, éstos no necesitan saber donde reside el objeto distribuido ni el sistema operativo en el que se ejecuta; y pueden estar en la misma maquina o bien en cualquier lugar de la red mundial.

GVA–ELAI–UPM ® PFC 0084 - 2005 233

Page 244: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

Además de esto podemos añadir que los objetos distribuidos por ser objetos gozan de todas las bondades que estos proveen, por lo que cualquier sistema de objetos proporciona las tres propiedades básicas: encapsulación, herencia y polimorfismo. Estas propiedades le permiten al objeto proporcionar sólo la interfaz deseada a sus clientes; reutilizar código y comportarse de distintas maneras.

Sin embargo el interés fundamental de los objetos distribuidos está en cómo esta tecnología puede ser extendida para enfrentarse con problemas complejos que son heredados al crear sistemas cliente/servidor robustos y de imagen simple, es decir como los objetos pueden trabajar juntos a través de una maquina y los limites de una red para crear soluciones cliente servidor. Nos encaminamos a los sistemas cliente servidor basados en objetos en donde se apreciara lo mejor de la grandeza y potencial de éstos.

8.5.5 EL ORB DE CORBA

Un ORB CORBA provee los mecanismos requeridos por los objetos para comunicarse con otros objetos a través de lenguajes heterogéneos, herramientas, plataformas y redes. También provee el entorno para manejar estos objetos, advertir su presencia y describir sus metadatos. Un ORB CORBA es un bus de objetos que se describe así mismo.

Usando un ORB, un objeto cliente puede invocar transparentemente un método en un objeto servidor, el cual puede estar en la misma máquina o a través de la red, el ORB intercepta la llamada y es responsable de encontrar el objeto que implemente la petición, pasarle los parámetros, invocar el método, y regresar los resultados. Los papeles de cliente/servidor son sólo usados ara controlar las interacciones entre los objetos, ya que los objetos en el ORB pueden actuar a la vez como cliente y como servidor.

8.5.5.1 Estructura de un ORB CORBA

En principio señalaremos lo que CORBA hace en el lado del cliente:

• Los fragmentos (stub) IDL del lado del cliente: proveen la interfaz estática de los servicios del cliente. Estos fragmentos de código precompilados definen como los clientes invocan los servicios correspondientes en los servidores. Estos servicios son definidos usando un IDL, y ambos son

234 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 245: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

generados por un compilador IDL. Un cliente debe tener un fragmento IDL para cada interfaz en el servidor. Este fragmento incluye código para realizar la comunicación y el paso de parámetros.

• La interfaz de invocación dinámica (DII): permite descubrir el método a ser invocado en tiempo de ejecución.

• Las APIs del repositorio de interfaces: permiten obtener y modificar la descripción de todas las interfaces componentes registradas, los métodos que soportan y los parámetros que requieren. Es un repositorio de metadatos dinámico para ORBs.

• La interfaz ORB: consiste en unas cuantas APIs de servicios locales que pueden ser de interés para una aplicación. Como por ejemplo el convertir la referencia de un objeto a una cadena.

El soporte de invocaciones cliente/servidor dinámicas y estáticas así como el repositorio de interfaces le dan a CORBA una ventaja sobre otros entornos de distribución de objetos. Las invocaciones estáticas son más rápidas y fáciles de programar. Las dinámicas proveen una máxima flexibilidad pero son difíciles de programar, aunque son útiles para las herramientas que requieren descubrir los servicios en tiempos de ejecución.

El lado del servidor no puede identificar la diferencia entre una invocación estática o dinámica; en ambos casos, el ORB localiza un adaptador del objetos del servidor, le transmite los parámetros, y le transfiere el control a la implementación del objeto a través del fragmente IDL del lado del servidor (esqueleto). A continuación se muestran los elementos de CORBA del lado del servidor.

• Los fragmentos IDL del lado del servidor: OMG los llama esqueletos, proveen la interfaz estática para cada servicio exportado por el servidor. Estos fragmentos, como los del lado del cliente son creados al usar un compilador IDL.

• La interfaz de esqueletos dinámica: proveen un mecanismo de unión en tiempo de ejecución para los servidores que necesitan gestionar las llamadas

GVA–ELAI–UPM ® PFC 0084 - 2005 235

Page 246: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

de métodos para componentes que no tiene un esqueleto base IDL compilado. Los esqueletos dinámicos son muy útiles para la implementación de puentes genéricos entre ORBs.

• El adaptador de objetos: provee el entorno en tiempo de ejecución para la instanciación de objetos servidores, pasándoles peticiones, y asignándoles una identificación de objeto (llamada referencia al objeto). El adaptador de objetos también registra las clases que soporta y sus instancias en tiempo de ejecución con el repositorio de implementación.

• El repositorio de implementación: provee un repositorio de información en tiempo de ejecución acerca de las clases que el servidor soporta, los objetos que están instanciados y sus identificadores. Guarda también información adicional relacionada con los ORBs.

• La interfaz ORB: consiste en unas cuantas APIs a servicios locales que son idénticas a los del lado del cliente.

8.5.5.2 Invocación de métodos CORBA. Estáticos contra Dinámicos

La interfaz estática es generada directamente en fragmentos por el precompilador IDL. Son ideales para programas que saben en tiempo de compilación las operaciones particulares que requerirán invocar. Tiene las siguientes ventajas sobre la invocación dinámica:

• Más fácil de programar.

• Provee un chequeo de tipos más robusto.

• Buen desempeño.

• Es autodocumentada.

Los pasos que involucran un llamado estático son los siguientes:

236 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 247: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

1. Definir las clases de objetos usando un lenguaje de definición de interfaces (IDL): Las IDLs son el medio por el cual los objetos le dicen a sus clientes potenciales que operaciones están disponibles y como deberían ser invocadas.

2. Ejecutar el fichero IDL a través de un precompilador del lenguaje: se procesa el fichero IDL y se producen los esqueletos para la implementación de clases servidoras.

3. Añadir el código de la implementación a los esqueletos: es decir crear las clases servidoras.

4. Compilar el código: se generan cuatro ficheros de salida que son: ficheros de importación que describen a los objetos en el repositorio de interfaces, fragmentos del cliente para los métodos en las IDLs definidas, fragmentos del servidor que llaman a los métodos en el servidor y el código que implementan las clases en el servidor.

5. Unir las definiciones de clases al repositorio de interfaces: para que se pueda acceder a ellas en tiempo de ejecución.

6. Instanciar los objetos en el servidor: al arrancar, un adaptador de objetos de un servidor debe instanciar los objetos servidor que sirven para la invocación de métodos remotos del cliente. Éstos son instancias de las clases de aplicación del servidor.

7. Registrar los objetos en tiempo de ejecución en el repositorio de implementación: el adaptador de objetos registra en el repositorio de implementación la referencia a un objeto y el tipo de cualquier objeto que se instancia en el servidor. El ORB usa esta información para localizar los objetos activos o para requerir la activación de objetos en un servidor particular.

En contraste la invocación de métodos dinámica provee un entorno de mayor flexibilidad, permite añadir nuevas clases al sistema sin requerir cambios en el código del cliente. Es muy útil para herramientas que descubren los servicios que son

GVA–ELAI–UPM ® PFC 0084 - 2005 237

Page 248: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

proveídos en tiempo de ejecución. Permiten escribir código genérico con APIs dinámicas.

Para invocar un método dinámico en un objeto, el cliente debe desempeñar los siguientes pasos:

1. Obtener la descripción del método del repositorio de interfaces.

2. Crear la lista de argumentos: la lista es creada usando la operación create_list y llamando add_arg tantas veces como se requiera para añadir cada argumento a la lista.

3. Crear la petición: la petición debe especificar la referencia al objeto, el nombre del método, y la lista de argumentos.

4. Invocar la petición: se puede invocar la petición de 3 maneras: 1) la llamada invocada envía la petición y obtiene los resultados; 2) la llamada enviada devuelve el control al programa, el cual debe emitir un get_response; 3) la llamada enviada puede ser definida de un sólo sentido.

Como se puede apreciar la invocación dinámica de un método requiere un cierto esfuerzo. Se cambia complejidad y desempeño por añadir flexibilidad.

238 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 249: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

Figura 8.4: Estructura cliente de CORBA

8.5.5.3 El lado del servidor de CORBA. El adaptador de objetos

Lo que una implementación de objetos necesita en el lado del servidor es una infraestructura servidora que registre las clases de la implementación, instancias a nuevos objetos, que les de un únicos identificador, que advierta su existencia, que invoque sus métodos en las peticiones de los clientes y que gestione peticiones concurrentes a sus servicios. La respuesta a quién desempeña este tipo de trabajo es el adaptador de objetos.

El adaptador de objetos es el mecanismo primario para que una implementación de un objeto pueda acceder a los servicios de un ORB. Aquí están algunos de los servicios que proporciona:

1. Registrar las clases del servidor en el repositorio de implementación.

2. Instancias los nuevos objetos en tiempo de ejecución.

GVA–ELAI–UPM ® PFC 0084 - 2005 239

Page 250: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

3. Generar y gestionar las referencias únicas a los objetos.

4. Anunciar la presencia de servidores de objetos y sus servicios.

5. Manipular las llamadas provenientes de clientes.

6. Enrutar la llamada hacia el método apropiado.

Un adaptador de objetos define como son activados los objetos. Esto lo puede hacer creando un nuevo proceso, creando un nuevo enlace dentro de un proceso existente o usando un enlace o proceso existente. Un servidor puede soportar una variedad de adaptadores de objetos para satisfacer diferentes tipos de peticiones, CORBA especifica un adaptador de objetos básico (BOA de Basic Object Adapter) que puede ser usado por la mayoría de los objetos del ORB y que puede servir como un estándar.

CORBA requiere que un adaptador BOA este disponible en cada ORB y necesita que las siguientes funciones sean proveídas por la implementación del BOA:

• Un repositorio de implementación que permita instalar y registrar la implementación de los objetos.

• Mecanismos para generar e interpretar las referencias a objetos.

• Un mecanismo para identificar al cliente que hace la llamada.

• Activación y desactivación de objetos implementados.

• Invocación de métodos a través de fragmentos

240 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 251: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

Un BOA soporta aplicaciones tradicionales y orientadas a objetos. No especifica como son localizados y empaquetados los métodos. Para obtener la más amplia cobertura de aplicación, CORBA define cuatro políticas de activación de objetos que son:

• Servidor compartido BOA: objetos múltiples pueden residir en el mismo programa. El BOA activa el servidor la primera vez que una petición es realizada sobre cualquier objeto implementado por aquel servidor. El servidor gestiona una petición a la vez y avisa cuando ha terminado para procesar la siguiente.

• Servidor no compartido BOA: cada objeto reside en un proceso de servidor diferente. Un nuevo servidor es activado la primera vez que una petición es solicitada en el objeto. Un nuevo servidor es iniciado cada vez que se hace una petición a un objeto que aún no esta activado, aunque un servidor para otro objeto con la misma implementación este activo.

• Servidor por método BOA: un nuevo servidor es comenzado cada vez que una petición es hecha. El servidor se ejecuta solo por el tiempo que dura el método particular. Varios procesos de servidor para el mismo objeto pueden estar activos concurrentemente.

• Servidor persistente BOA: los servidores son activados por medios externos al BOA. Un vez iniciado el BOA trata a todas las llamadas subsecuentes como llamadas a servidores compartidos; envía activaciones para objetos individuales y llamadas a métodos para un proceso individual.

GVA–ELAI–UPM ® PFC 0084 - 2005 241

Page 252: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

Figura 8.5: Estructura servidor de CORBA

8.5.5.4 Inicialización de CORBA

Las llamadas que un objeto debe seguir para inicializarse así mismo son:

1. Obtener la referencia al objeto de su ORB.

2. Obtener el puntero a su adaptador de objetos.

3. Descubrir que servicios iniciales están disponibles.

4. Obtener las referencias a los objetos de los servicios que se desean.

Para cada uno de los pasos anteriores se debe llamar el método apropiado. Un objeto puede inicializarse así mismo en más de un ORB.

242 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 253: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

8.5.6 IDL Y EL REPOSITORIO DE INTERFACES

Los metadatos es el ingrediente que permite crear sistemas cliente/servidor ágiles. Un sistema ágil es autodescriptible, dinámico, y reconfigurable. El sistema ayuda a los componentes a descubrirse unos a otros en tiempo de ejecución, y les provee información que le permite interoperar así como crear y gestionar componentes.

El lenguaje de metadatos de CORBA es el lenguaje de definición de interfaces (IDL) y el repositorio de metadatos de CORBA es el repositorio de interfaces que es una base de datos que se puede actualizar y cuestionar en tiempo de ejecución y que contiene la información generada por las IDLs.

8.5.6.1 IDL de CORBA y su estructura

El IDL de CORBA es un lenguajes neutral y totalmente declarativo. Provee interfaces independientes del lenguaje de programación y sistema operativo para todos los servicios y componentes que residen en el bus CORBA.

Un contrato IDL incluye una descripción de cualquier servicio que un componente servidor quiera exponer a sus clientes. Los componentes servidores deben soportar dos tipos de clientes: 1) clientes que invoquen sus servicios en tiempo de ejecución; y 2) desarrolladores que usan IDL para extender las funciones de sus componentes existentes por medio de herencia.

La gramática IDL es un subgrupo de C++ con palabras reservadas adicionales para soportar los conceptos de distribución, también soporta las características estándar de preprocesamiento de C++.

El repositorio de interfaces contiene metadatos que son idénticos a los componentes que se describen en la IDL. De hecho el repositorio de interfaces es simplemente una base de datos activa que contiene versiones compiladas de la información en metadatos capturada vía IDL.

GVA–ELAI–UPM ® PFC 0084 - 2005 243

Page 254: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

El compilador de IDL de CORBA genera stubs en el cliente y skeletons en el servidor. Los stubs y los skeletons, junto con el ORB, automatizan las siguientes actividades:

• Creación de proxies.

• Aplanamiento/Desaplanamiento de parámetros y resultados.

• Generación de clases de Implementación de la interfaz.

• Registro y activación de objetos.

• Localización y ligadura (binding) de objetos.

EL IDL de CORBA es un superconjunto de un subconjunto de C++. No es un lenguaje de programación, sólo sirve para definir interfaces. El IDL de CORBA ofrece:

• Describe operaciones y parámetros de cada interfaz.

• Lenguaje declarativo.

• Sintaxis similar al ANSI C++.

• Prepocesado como C++ (mas #pragma).

• Usa el código de caracteres ISO-Latin1.

244 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 255: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

Los principales elementos para construir un IDL CORBA son:

• Los Módulos proveen un namespace para agrupar a un conjunto de descripciones de clases, es decir agrupa varias clases.

• Las Interfaces definen un conjunto de métodos que los clientes pueden invocar en un objeto. Una interfaz puede tener atributos y puede declarar una o más excepciones.

• Las operaciones son el equivalente en CORBA de los métodos. Un parámetro tiene un modo que indica si un valor es pasado de el cliente al servidor (in), de el servidor al cliente (out), o en ambos (in/out).

• Los tipos de datos son usados para describir los valores aceptados de los parámetros, atributos, y valores de retorno de CORBA. Estos tipos de datos son llamados objetos de CORBA que son usados a través de lenguajes múltiples, sistemas operativos y ORBs. El tipo any es muy útil en situaciones dinámicas ya que representa a cualquier tipo de datos IDL posible.

CORBA define códigos de tipos que representan cada tipo de datos de la IDL definida. Se usan para crear datos autodescriptibles que puedas ser pasados a través de ORBs y repositorios de interfaces. Cada código de tipo tiene un ID de repositorio globalmente único. Son usados:

• Por interfaces de invocación dinámica.

• Por protocolos Inter-ORB.

• Por repositorios de interfaces.

• Por el tipo de datos any.

GVA–ELAI–UPM ® PFC 0084 - 2005 245

Page 256: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

La interfaz TypeCode de CORBA define un conjunto de métodos que permiten operar con códigos de tipos, compararlos y obtener sus descripciones.

Las diferencias más importantes entre IDL y C++ son, fundamentalmente:

1. No hay variables de estado en las clases.

2. No hay punteros.

3. No hay constructores/destructores.

4. No hay sobrecarga de métodos.

5. No existe el tipo int.

6. El IDL permite especificar modos en el paso de parámetros.

7. No hay templates.

8. No hay sentencias de control.

8.5.6.2 El repositorio de interfaces

Un repositorio de interfaces CORBA es una base de datos en línea de definiciones de objetos. Estas definiciones pueden ser capturadas directamente de un compilador IDL o a través de las nuevas funciones de escritura del repositorio de interfaces. La especificación de CORBA detalla como es organizada y recuperada la información del repositorio. Lo hace creativamente al especificar un conjunto de clases cuyas instancias representan la información que está en el repositorio. La jerarquía de clases refleja la especificación IDL.

246 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 257: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

Un ORB utiliza las definiciones de objetos en el repositorio para:

• Proveer un chequeo de tipos de las definiciones de métodos.

• Ayuda a conectar ORBs.

• Provee información en metadatos para clientes y herramientas.

• Proporciona objetos autodescriptibles.

Los repositorios de interfaces pueden ser mantenidos localmente o gestionados como recursos departamentales o empresariales. Sirven como una fuente valuable de información en la estructura de clases e interfaces de componentes. Un ORB puede tener acceso a múltiples repositorios de interfaces.

El repositorio de interfaces es implementado como un conjunto de objetos que representan la información en él. Estos objetos deben ser persistentes. CORBA agrupa los metadatos en módulos que representan el espacio de nombres. Los nombres de los objetos del repositorio son únicos dentro de un módulo. CORBA define una interfaz para cada uno de sus ocho estructuras IDL:

• ModuleDef.

• InterfaceDef.

• OperationDef.

• ParameterDef.

• AttributeDef.

GVA–ELAI–UPM ® PFC 0084 - 2005 247

Page 258: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

• ConstantDef.

• ExceptionDef.

• TypeDef.

Además de estas ocho interfaces, CORBA especifica una interfaz llamada Repository que sirve como raíz para todos los módulos contenidos en un namespace del repositorio. Cada repositorio de interfaces es representado por un objeto repository raíz global.

Además de estas jerarquías contenidas CORBA definió tres superclases abstractas llamadas IRObject, Contained, y Container. Todos los objetos del repositorio de interfaces heredan de la interfaz IRObject, la cual provee un método destroy. Los objetos que son contenedores heredan operaciones de navegación de la interfaz Container. La interfaz Contained define el comportamiento de los objetos que son contenidos en otros objetos. Todas las clases del repositorio son derivadas de Container, de Contained o de ambas a través de herencia múltiple. Este astuto esquema permite al repositorio de objetos comportarse de acuerdo a sus relaciones de contención.

Para acceder a los metadatos del repositorio de interfaces se invocan métodos polimorficamente en diferentes tipos de objetos. Es posible navegar y extraer información del los objetos del repositorio con tan sólo nueve métodos. Cinco de estos métodos son derivados de las clases antecesoras Container y Contained. Los otros cuatro métodos son específicos a las interfaces InterfaceDef y Repository.

A partir de CORBA se pueden crear federaciones mundiales de repositorios de interfaces que operen a través de ORBs múltiples. Para prevenir colisiones de nombres, estos repositorios asignan identificadores únicos a interfaces y operaciones globales. Para lograr esto se siguen los siguientes convencionalismos de nombrado:

• Nombres con alcance los cuales son hechos de uno o más identificadores separados por los caracteres ‘ : :’.

248 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 259: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

• Identificadores de repositorio que identifican globalmente módulos e interfaces. Son usados para sincronizar las definiciones a través de ORBs y repositorios, existen dos formatos para especificarlos: 1) usando nombres IDL con prefijos únicos y 2) usando identificadores únicos universales DCE.

8.5.6.3 El lenguaje IDL

Todo servicio precisa definir qué subrutinas forman parte de él. Al conjunto de signaturas de las subrutinas que forman parte de un servicio se le llama la interfaz de un servicio.

Un lenguaje de IDL especifica la sintaxis a utilizar para definir dicha lista de signaturas. Al mismo tiempo el lenguaje indica el tipo de estructuras de datos que pueden ser utilizados como parámetros.

La estructura del lenguaje indica las capacidades de manejo automático del paso de parámetros.

Con el fin de controlar la versión del servicio, se suele incluir la especificación del número de versión del servicio.

Finalmente, la definición incluye el nombre dado al servicio.

El IDL es procesado por un compilador de IDL. El compilador retorna Stubs y definiciones de estructuras de datos para (C). También retorna cabeceras para las subrutinas a definir en el servidor. Existe un Stub para el cliente y uno para el servidor.

Un Stub de cliente es una subrutina que toma los argumentos formales de un procedimiento remoto y se encarga de:

• Marshaling.

GVA–ELAI–UPM ® PFC 0084 - 2005 249

Page 260: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

• Efectuar el binding.

• Ejecutar el envío del mensaje.

• Esperar la respuesta.

• Efectuar el Unmarshaling de los parámetros de retorno.

• Devolver control al código de cliente: El stub de servidor en un sistema RPC típico es más simple que el de cliente. Puede ser visto como la imagen especular del stub del cliente.

• Recoge el mensaje de petición de servicio.

• Comprueba la compatibilidad de la versión

• Efectúa el unmarshal de los parámetros.

• Efectúa la invocación local de la subrutina del servidor.

• Efectúa el marshaling de los parámetros de retorno.

• Envía el mensaje de retorno a través del canal de comunicación establecido al recibir el mensaje de invocación.

En IDL, las estructuras de datos se definen con un lenguaje especial que refleja las restricciones de paso de parámetros. El compilador traduce dichas definiciones a estructuras de datos del lenguaje de programación (típicamente C, o C++).

250 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 261: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

Dichas traducciones quedan reflejadas en ficheros de cabecera que deben ser utilizados por los programas cliente y servidor. Al mismo tiempo el compilador general subrutinas que sirven para realizar el marshaling y unmarshaling de las estructuras de datos definidas.

Dichas subrutinas son adoptadas por los stubs para realizar el marshaling/unmarshaling. Las subrutinas emplean funciones de biblioteca especiales para llevar a cabo su función.

Los aspectos que debe cubrir un servicio de binding son:

• Encontrar el nodo más apropiado para el servicio.

• Establecer la compatibilidad del servicio pedido con el ofertado.

• Establecer un camino de comunicación entre el cliente y el servicio.

• Establecer un camino de acceso desde el cliente hasta la función del servidor: en ocasiones, el servicio de binding puede comenzar la ejecución del proceso servidor. Esta operación cara en términos de tiempo empleado aunque tan sólo ocurre una vez por par cliente/servidor.

En el caso del Binding para el Servidor el binder debe:

• Registrar el ejecutable del servidor, asociándolo con el nombre del servicio.

• Dependiendo del sistema concreto, registrar el número de puerto a utilizar por el servidor.

GVA–ELAI–UPM ® PFC 0084 - 2005 251

Page 262: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

• En algunos casos establecer un enlace de comunicaciones entre el cliente y el servidor.

• La última parte del binder corresponde al dispatcher. El dispatcher suele estar integrado en el servidor, a través de las funciones de biblioteca.

Para la implementación del Binding:

• El binder es el servicio del cual todos los demás dependen.

• Suele tener incorporado algún esquema de soporte de fallos.

• Encontrar el binder debe ser independiente del servicio de binder mismo.

• Generalmente disponible en una dirección bien conocida: bien en nodo local o en un puerto estándar.

8.5.6.4 Consideraciones acerca del Marshaling

1. La representación de números enteros depende de la CPU utilizada.

2. El alineamiento de datos en algunas arquitecturas, los datos deben alinearse en 32 (64) bits.

3. La representación de números en coma flotante puede diferir.

4. Los punteros, por sí mismos, no son transmisibles. En algunos casos, cuando el tipo apuntado esté claro, será posible efectuar una copia por

252 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 263: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

recorrido; esto dificulta la semántica de paso por referencia, tan común en llamadas a subrutinas en lenguajes procedurales.

5. La aproximación tomada es el copy-in, copy-out, con características totalmente diferentes en sistemas concurrentes.

6. Incompatibilidades en los tipos básicos de datos, por ejemplo, pasar enteros desde representaciones de 64 a 32 bits.

8.5.7 COMUNICACIÓN VÍA CORBA

Los pasos a seguir en la comunicación vía CORBA son:

1. El cliente invoca el método asociado en el stub que realiza el proceso de marshaling (Stub cliente).

2. El stub solicita del ORB la transmisión de la petición hacia el objeto servidor (ORB cliente).

3. El ORB del servidor toma la petición y la transmite el Adaptador de Objetos asociado, por lo general sólo hay uno (ORB servidor).

4. El Adaptador de Objetos resuelve cuál es el objeto invocado, y dentro de dicho objeto cuál es el método solicitado (Adaptador de Objetos).

5. El skeleton del servidor realiza el proceso de de-marshaling de los argumentos e invoca a la implementación del objeto (Skeleton servidor).

6. La implementación del objeto se ejecuta y los resultados y/o parámetros de salida se retornan al skeleton (Implementación del objeto).

GVA–ELAI–UPM ® PFC 0084 - 2005 253

Page 264: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

7. El proceso de retorno de los resultados es análogo.

Figura 8.6: Comunicación vía CORBA

8.5.8 IMPLEMENTACIÓN DE OBJETOS CORBA

El servicio de nombrado de objetos es el principal mecanismo para que los objetos en un ORB localicen otros objetos. El servicio de nombrado convierte los nombres humanos en referencias a objetos. Se puede opcionalmente asociar uno o más nombres con la referencia a un objeto.

Se puede referenciar un objeto CORBA usando una secuencia de nombres que forme un árbol de nombre jerárquico. Resolver un nombre significa encontrar el objeto asociado con el nombre en un contexto dado. Enlazar un nombre es crear una asociación nombre/objeto para un contexto particular.

Cada componente nombrado es una estructura con dos atributos: 1) un identificador que es el nombre del objeto; 2) el tipo que es una cadena en donde se puede poner una descripción del nombre del atributo.

Las interfaces NamingContext y BindingInterator implementan el servicio de nombrado. Se invoca el método bind en la interfaz NamingContext para asociar el

254 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 265: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

nombre de un objeto con un contexto enlazado. De esta forma es como se implementa una jerarquía de nombrado. El método list permite iterar a través de un conjunto de nombres (regresa un objeto BindingIterator). Se puede iterar invocando next_one y next_n en el objeto regresado BindingIterator.

En resumen, el servicio de nombrado de objetos define las interfaces que permiten gestionar el espacio de nombres para los objetos, consultar y navegar a través de ellos. Los objetos que proveen estas interfaces viven en el ORB.

8.5.9 EL SERVICIO DE CICLO DE VIDA DE OBJETOS DE CORBA

El servicio de ciclo de vida de objetos provee operaciones para crear, copiar, mover y borrar objetos. Todas estas operaciones pueden ahora soportar asociaciones entre grupos de objetos relacionados. Esto incluye relaciones de referencia y contenido. El servicio de ciclo de vida provee interfaces que son derivadas del servicio de relaciones.

Para crear un nuevo objeto, un cliente en principio debe encontrar una fábrica de objetos, ejecutar una petición de creación, y recibir de regreso una referencia a un objeto. Lo puede crear también haciendo una copia de uno ya existente. Cuando un objeto es copiado a través de varias máquinas, la fabrica de objetos en el nodo destino es involucrado.

La interfaz de LifeCycleObject define las operaciones de copiar, mover, y eliminar. La interfaz de FactoryFinder define un método para encontrar fabricas de objetos y la de GenericFactory simplemente define una operación de creado de objetos.

Las interfaces compuestas de ciclo de vida añaden una nueva interfaz llamada OperationsFactory, la cual crea objetos de la clase Operations. Ésta soporta los métodos copiar, mover y borrar y añade un método para destruir.

Las tres clases Node, Role, y Relationship son derivadas de las clases correspondientes en el servicio de relación. Éstas permiten definir relaciones entre objetos que no saben nada uno de otro. Para definir una relación, primero se debe asociar un papel con un objeto y entonces crear las relaciones entre estos papeles.

GVA–ELAI–UPM ® PFC 0084 - 2005 255

Page 266: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

8.5.9.1 El servicio de eventos de CORBA

El servicio de eventos permite a los objetos registrar y eliminar dinámicamente sus eventos específicos de interés. Un evento es una ocurrencia dentro de un objeto específico que puede ser de interés para uno o más objetos. Una notificación es un mensaje que un objeto envía a los grupos de interés para informarles que un evento específico ha ocurrido sin conocerles, ya que esto normalmente es gestionado por el servicio de eventos.

El servicio de eventos mantiene la comunicación entre objetos. El servicio define dos papeles para los objetos: proveedores que producen eventos y consumidores que los procesan a través de manejadores de eventos. Los eventos se comunican con llamadas estándar CORBA. En adición, hay dos modelos para la comunicación de eventos de datos: empujar (push) y tirar (pull). En el modelo empujar el proveedor de eventos toma la iniciativa e inicia la transferencia de datos a los consumidores. En el modelo tirar, el consumidor toma la iniciativa y requiere los datos de eventos de un proveedor.

Un canal de eventos es un objeto estándar CORBA que se coloca en el ORB y mantiene la comunicación entre los proveedores y consumidores. El canal de eventos de objetos genérico no comprende el contenido de los datos que pasan. En vez de esto, los productores y consumidores están de acuerdo en una semántica común de eventos.

La interfaz de eventos soporta múltiples niveles de servicios. Un almacenamiento persistente de eventos debe ser proveído por el canal persistente de objetos como parte de sus servicios.

El servicio de eventos es extremadamente útil; ya que provee las bases para la creación de un nuevo género de aplicaciones de objetos distribuidos.

256 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 267: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Procesamiento Distribuido con C++

GVA–ELAI–UPM ® PFC 0084 - 2005 257

Page 268: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Procesamiento Distribuido con C++ Miguel Hernández Vázquez

258 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 269: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

9 Conclusiones y líneas de mejora

En este capítulo veremos las conclusiones sobre la utilización de MPI y su aplicación en VTK, Matlab y ParaView. Finalmente se analizarán las posibles líneas de mejora.

GVA–ELAI–UPM ® PFC 0084 - 2005 259

Page 270: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Conclusiones y líneas de mejora Miguel Hernández Vázquez

9.1 CONCLUSIONES SOBRE MPI

Gracias a MPI conseguimos portabilidad, proveyendo una librería de paso de mensajes estándar independiente de la plataforma y de dominio público. La especificación de esta librería está en una forma independiente del lenguaje y proporciona funciones para ser usadas con C, C++ y Fortran. Abstrae los sistemas operativos y el hardware.

Existen implementaciones MPI para casi todas las máquinas y sistemas operativos, lo que significa que un programa paralelo escrito en C, C++ o Fortran, usando MPI para el paso de mensajes, puede funcionar en una gran variedad de hardware y sistemas operativos. Por estas razones MPI ha ganado gran aceptación dentro el mundillo de la computación paralela.

El usuario en MPI tiene que crear la máquina virtual decidiendo qué nodos del cluster usar para poner en funcionamiento sus aplicaciones cada vez que las arranca

La implementación del cluster es sencilla, pero resulta conveniente que todos los nodos que lo forman sean similares en cuanto a potencia y prestaciones, para facilitar la función de paralelización de los programas. Sí no se conocen bien las características del cluster puede realizarse una mala paralelización del programa, es decir, se puede conseguir el efecto contrario a lo deseado y obtener un programa más lento que el original.

9.2 MPI CON VTK Y PARAVIEW

VTK (Visualization Toolkit) son un conjunto de librerías destinadas a la visualización y el procesado de imágenes. Incluyen código abierto y software orientado a objetos. Son muy amplias y complejas, pero aún así, están diseñadas para ser sencillas de usar con cualquier lenguaje de programación orientado a objetos, como son C++, Java, Tcl, etc.

260 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 271: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Conclusiones y líneas de mejora

VTK dispone de una serie de clases preparadas para su aplicación en el procesamiento en paralelo. Estas clases están desarrolladas para que puedan hacer uso de la librería MPI. Las funciones de estas clases son muy parecidas, en cuanto a funcionamiento y sintaxis, a las originales para lenguaje C/C++, pero tienen la gran ventaja de que algunas de ellas (sobre todo funciones de envío y recepción) están configuradas para trabajar con estructuras complejas como son las imágenes.

Paraview es una aplicación que se utiliza para visualizar datos en dos o tres dimensiones. Esta aplicación puede ser utilizada en un solo puesto de trabajo o también en un cluster de ordenadores. Esto último permite a paraview ejecutar grandes cadenas de datos mediante la utilización de procesamiento distribuido.

Si compilamos ParaView para soportar MPI, ParaView se podrá lanzar como cualquier otra aplicación MPI. No es necesario paralelizar ningún tipo de código para trabajar en paralelo con ParaView, la aplicación ya está preparada para ello.

9.3 PROCESAMIENTO DISTRIBUIDO CON MATLAB

MatlabMPI es una implementación para Matlab de MPI (Message Passing Interface) que permite que cualquier programa creado bajo Matlab pueda ser ejecutado en múltiples procesadores. MatlabMPI consiste en un conjunto de instrucciones de Matlab que implementan un subconjunto de MPI, permitiendo que cualquier programa de Matlab pueda ser ejecutado en una computadora paralela. Además, MatlabMPI podrá ejecutarse en cualquier sistema de computadoras que soporten Matlab.

MATLAB MPI demuestra que el estándar propuesto para escritura de las aplicaciones paralelas en C y FORTRAN, es también válido en MATLAB. Además usando archivos de MATLAB de entrada/salida, es posible implementar completamente MATLAB MPI con el desarrollo de MATLAB, haciéndolo en seguida migrable a todas las computadoras en donde se ejecute MATLAB.

MATLAB MPI proporciona la mayor productividad posible en el desarrollo de aplicaciones paralelas.

GVA–ELAI–UPM ® PFC 0084 - 2005 261

Page 272: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Conclusiones y líneas de mejora Miguel Hernández Vázquez

La simplicidad y funcionalidad de MATLAB MPI lo hace una elección muy aconsejable para programadores que quieran acelerar sus códigos MATLAB en computadoras paralelas. El trabajo para el futuro será el de crear objetos de mayor rango (como, por ejemplo, matrices distribuidas). El resultado será la construcción de una capa de comunicaciones dentro de MATLAB MPI, que permita a un usuario lograr un aceptable desarrollo paralelo sin un aumento de las líneas de código.

9.4 PROCESAMIENTO DISTRIBUIDO CON C++

En este capítulo hemos visto una visión aproximada de tres de las implementaciones existentes para implementar el procesamiento distribuido en C++: MPI, PVM y CORBA.

La implementación con MPI está más desarrollada. Sin embargo, las otras dos implementaciones existentes, PVM y CORBA, no son tan conocidas y desarrolladas. Faltaría como conclusión el desarrollo más en profundidad de estas implementaciones, así como el desarrollo de diversos ejemplos.

9.5 LÍNEAS DE MEJORA

Son muchas las mejoras que se pueden hacer en torno a lo desarrollado a lo largo de este proyecto, algunas de las cuales son las siguientes:

• Realización e implementación de un cluster basado en el sistema operativo Linux.

• Utilización de otra implementación de MPI como puede ser LAM-MPI.

• Profundizar más en la utilización de MPI con Matlab, en especial en lo que se refiere a la hora del envío de datos entre procesadores, en especial de

262 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 273: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Conclusiones y líneas de mejora

imágenes. Estudiar las toolbox existentes de MPI para Matlab para elegir la más adecuada.

• Realización de un cluster amplio, cuyos nodos tengan características similares para poder obtener el mayor rendimiento posible.

• Estudiar la compatibilidad de MPI con otros lenguajes de programación, y con otras librerías de tratamiento de imágenes.

• Profundizar más en la utilización del procesamiento distribuido con el lenguaje de programación C++. Estudiar las implementaciones existentes del procesamiento paralelo para C++ PVM y CORBA.

GVA–ELAI–UPM ® PFC 0084 - 2005 263

Page 274: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Conclusiones y líneas de mejora Miguel Hernández Vázquez

264 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 275: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

10 Bibliografía

PROCESAMIENTO DISTRIBUIDO

• http://ib.cnea.gov.ar/~ipc/ Enzo A. Dari y Jorge O. Sofo. Febrero 2002.

• Los Clusters. Por Oscar Pino Morillas, Roberto Francisco Arroyo Moreno y Francisco Javier Nievas Muñoz.

GVA–ELAI–UPM ® PFC 0084 - 2005 265

Page 276: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Bibliografía Miguel Hernández Vázquez

• El Procesamiento Paralelo, Enfoque Cualitativo y Simulación. Por Leslie Murray. Escuela de Ingeniería Electrónica, Universidad Nacional de Rosario, Argentina. Mayo 26, 2000.

• Scalable Parallel Computing de Kai Hwang y Khiwei Xu.

MPI

• http://www.mcs.anl.gov/mpi/indexold.html

• www.mpiforum.orf/docs/mpi-11.ps Message Passing Interface Forum. MPI: A Message-Passing Interface Standard. 1995.

• Programación de aplicaciones paralelas con MPI (Message Passing Interface). Por José Miguel Alonso. Facultad de Informática UPV/EHU.

• MPI: a Message-Passing Interface Standard. Por ARPA, NSF y the National Science Foundation Science and Technology Center Cooperative. 1994.

• A User´s Guide to MPI. Por Peter S. Pacheco. Department of Mathematics. University of San Francisco. 1998.

MPICH

• Installation and User´s Guide to MPICH, by David Ashton, William Gropp, and Ewing Lusk

• http://www-unix.mcs.anl.gov/mpi/mpich/

266 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 277: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Bibliografía

PARAVIEW

• www.paraview.org

• http://www.teragrid.org/

• ParaView User´s Guide (Version 1.6)

CMAKE

• www.cmake.org

VTK

• www.vtk.org

• http://www.prashanthudupa.com/vtkdesigner/index.html

• Vtkgui.pdf

MATLAB / MATLABMPI

• http://www.mathtools.net/

• http://www.mathworks.com/

• http://www.mathworks.com/matlabcentral/fileexchange/loadCategory.do

GVA–ELAI–UPM ® PFC 0084 - 2005 267

Page 278: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Bibliografía Miguel Hernández Vázquez

• Cornell Multitask Toolbox for MATLAB http://www.tc.cornell.edu/Services/Software/CMTM/

• http://www.ll.mit.edu/MatlabMPI/

• Image Processing Toolbox for use with Matlab

• MatlabMPI. Por Jeremy Kepner. MIT Lincoln Laboratory. Department of Electrical Engineering. The Ohio State University. 2003.

RENDERIZACIÓN

• http://rnasa.tic.udc.es/gc/trabajos%202002-03/sombreado/Selec_metodo.htm

• 124.pdf

• bioIngEUITI-FI-UPM.pdf

• lect13.pdf

• pfcDiego.pdf

• Sombreado.pdf

268 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 279: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Bibliografía

C++, PVM y CORBA

• Parallel and Distributed Programming Using C++. Por Cameron Hughes y Tracey Hughes.

• http://www.ii.uam.es/~fjgomez/

• http://www.inforg.uniovi.es/CyP/PVM/

• http://es.tldp.org/Manuales-LuCAS/doc-cluster-computadoras/doc-cluster-computadoras-html/node43.html

• http://gsyc.escet.urjc.es/

• http://gsyc.escet.urjc.es/docencia/asignaturas/iti-arquit-distr-redes-heter/transpas/main.html

• www.cs.wustl.edu/_schmidt/

• http://www.netlib.org/pvm3/

• http://www.cs.wustl.edu/~schmidt/corba.html

• CORBA2EjemplosC++.pdf

• Developing Distributed Object Computing Applications with CORBA. Por Douglas C. Schmidt. Department of EECS. Vanderbilt University.

• Paper.corba.pdf

GVA–ELAI–UPM ® PFC 0084 - 2005 269

Page 280: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Bibliografía Miguel Hernández Vázquez

• Tema2_3a.pdf

• Proyecto de Fin de Carrera “Administración de sistemas en Windows NT y Linux. Latex e introducción a CORBA. Por Samuel Berrocoso Redondo.

• Prac10.pdf, Tema1_04_6p.pdf

• PVMTB.pdf

270 GVA-ELAI-UPM ® PFC 0084 - 2005

Page 281: El Procesamiento Distribuido y su aplicación al ... · procesamiento distribuido al tratamiento y procesado de imágenes; y por último, dar una introducción a las implementaciones

Miguel Hernández Vázquez Bibliografía

GVA–ELAI–UPM ® PFC 0084 - 2005 271