3.1. INTRODUCCIÓN. Figura 24. Jerarquía de los diversos componentes que componen PETSc.

Tamaño: px
Comenzar la demostración a partir de la página:

Download "3.1. INTRODUCCIÓN. Figura 24. Jerarquía de los diversos componentes que componen PETSc."

Transcripción

1 3. CÁLCULO NUMÉRICO EN PARALELO ASISTIDO POR LA LIBRERÍA DE CÁLCULO PETSC. 64

2 3.1. INTRODUCCIÓN. Hemos llegado a la parte central del proyecto, que consiste en hacer uso del cálculo numérico asistido por la librería PETSc para el Cálculo de Estructuras. Para llegar a entender esto, es necesario hacer una explicación más o menos detallada del funcionamiento de PETSc y de las posibilidades que ofrece. PETSc proporciona diversos paquetes software para la solución escalable (en paralelo) de sistemas algebraicos, provenientes de discretizaciones de ecuaciones diferenciales parciales (PDE s), así como bloques de construcción para la optimización y cálculo de autovalores. Se apoya en MPI para las operaciones de comunicación, pero esconde la interfaz de programación de MPI mediante un envoltorio que añade la propia PETSc. La librería PETSc está muy documentada, es de libre distribución y totalmente portable para las plataformas Cray, SGI, IBM, HP, Sun, Linux, Windows y Apple. Los lenguajes para escritura de código posibles son Fortran, C y C++. El origen de PETSc es el fruto de diversas investigaciones del Departamento de Energía de los Estados Unidos. Algunas de las herramientas que contiene la librería paralela son: diversas operaciones paralelas de manejo de vectores / arrays, numerosas operaciones y formatos de matrices paralelas y no paralelas, solucionadotes (solver) lineales y no lineales, algunos integradores de ecuaciones diferenciales ordinarias, gestión limitada de datos / rejillas paralelas, etc. La estructura de la librería PETSc se presenta en la figura 24. Figura 24. Jerarquía de los diversos componentes que componen PETSc. 65

3 3.2. MODELO DE PROGRAMACIÓN DE PETSC. PETSc utiliza la filosofía de la programación orientada a objetos (OOP) para construir las aplicaciones paralelas. El diseño de aplicaciones no se centra en los datos de los objetos, sino más bien en las operaciones que se pueden realizar sobre dichos datos. Por ejemplo, un vector no es un array de números de una dimensión, sino un objeto abstracto sobre el que se definen operaciones tales como el producto escalar o la suma. El modelo de programación con el que se trabaja presenta las siguientes características: Sistema de memoria distribuida, no compartida: solamente se requiere un compilador estándar, todas las operaciones de acceso a datos en máquinas remotas se realizan mediante MPI. Todos los detalles de las comunicaciones se esconden dentro de los objetos, de modo que el usuario no utiliza llamadas directas a MPI, sino que realiza las operaciones de comunicaciones desde un nivel más alto. No obstante, es posible realizar llamadas a rutinas de MPI desde cualquier parte del código. Se utiliza un modelo de programación SPMD (Simple Program Multiple Data), es decir, todos los nodos que pertenecen al cluster, dentro del cual ejecutamos nuestras aplicaciones paralelas, corren el mismo programa; sin embargo, cada proceso que se ejecuta en cada nodo tiene sus propias variables, distintas a las del resto de nodos, aun cuando se llamen igual. Esto hace que el resultado de ejecutar el mismo programa en diversos nodos sea distinto en cada uno. Lo que cabe ahora cuestionarse es cómo se bifurca el programa si todos los procesos ejecutan el mismo, de modo que cada proceso ejecute la parte del código paralelo que le corresponde. La forma de hacer esto es mediante la variable rank, que identifica el orden de cada proceso en el entorno de comunicaciones MPI. En función de esta variable se pueden poner en el código sentencias de control de flujo para ramificar el programa. Dentro de PETSc hay rutinas que son colectivas y otras que no lo son. Las operaciones colectivas se llevan a cabo mediante MPI y, en concreto, los comunicadores, que representan a todos aquellos procesos que tendrán que estarán involucrados en la computación. Los constructores de objetos PETSc son colectivos, y necesitan que se les pase un argumento que sea el nombre de un comunicador MPI para poder realizar su función. El comunicador que se utilizaba en MPI que involucraba a todos los procesos era MPI_COMM_WORLD, que ahora es sustituido por PETSC_COMM_WORLD. Si dentro del código existe una secuencia de órdenes colectivas, todos los procesos involucrados en las operaciones han de llamar a dichas operaciones en el mismo orden. En ningún momento hay que perder de vista que PETSc es solamente una librería de funciones (en C) y subrutinas (en Fortran), que proporcionan a nuestro código de aplicación la capacidad de ejecución de cálculo en paralelo mediante el soporte de otras librerías, como son MPI, BLAS y LAPACK. También destaca una ventaja importante de PETSc, y es que las interfaces de las funciones y subrutinas disponibles son las mismas para C, C++ y Fortran, con algún pequeño matiz que en su momento se comentará. 66

4 3.3. PANORÁMICA DE PETSC. PETSc está compuesta de un conjunto de librerías, de la misma forma que las clases en C++ o JAVA. Algunos de los módulos que se incluyen en PETSc son: Vectores. Matrices. Conjunto de índices. Arrays distribuidos. Métodos del subespacio de Krylov (solvers lineales). Precondicionadores. Solvers no lineales. Timesteppers para resolver PDE s dependientes del tiempo. La jerarquía a la que obedecen todas estas librerías se presenta en la figura 25. Figura 25. Librerías que componen PETSc. En la ruta donde se encuentra instalada PETSc, hay una estructura de subdirectorios que da una idea de la organización de PETSc. Los subdirectorios que dependen del directorio raíz son: 67

5 docs: aquí se encuentra toda la documentación de PETSc. El subdirectorio manualpages contiene un completo manual HTML de las rutinas PETSc. bin: utilidades para el uso con PETSc. bmake: directorio base de los makefiles necesarios para compilar código PETSc. Incluye subdirectorios para diferentes configuraciones. include: todos los ficheros de cabecera para incluir que son visibles por el usuario. include/finclude: ficheros de cabecera para usuario Fortran. include/private: ficheros privados que no deberían utilizarse para programas de aplicación. src: aquí se encuentra todo el código fuente para todas las librerías de PETSc, que incluye: - vec: vectores. is: conjuntos de índices. - mat: matrices. - dm: da: arrays distribuidos. ao: ordenaciones de aplicación. - ksp: ksp: aceleradores del Subespacio de Krylov. pc: precondicionadores. - snes: solvers no lineales. - ts: solvers de EDO s y timestepping. - sys: rutinas generales relacionadas con el sistema: plog: rutinas de profiling y registro de PETSc. draw: gráficos simples. - fortran: soporte para interfaces Fortran. - contrib: módulos anejos a PETSc, que no son parte oficial de la librería. examples: programas de ejemplo. interface: secuencias de llamada de interfaz abstracta. Este código no atiende a implementaciones particulares. impls: código fuente de algunas implementaciones. utils: rutinas de utilidad. Los nombres de directorio marcados en negrita, son aquellos que han sido de gran utilidad a la hora de comprender y utilizar la librería paralela PETSc en el proyecto que tenemos entre manos. 68

6 INICIO Y TERMINACIÓN DE UN PROGRAMA PETSC. Al igual que ocurría en el caso de MPI, a la hora de escribir programas utilizando PETSc, hay que llamar a una rutina de inicialización del entorno y a otra de terminación. Estas son, respectivamente: PetscInitialize(), que establece los servicios y datos estáticos e inicializa MPI si no se ha hecho antes ( PetscInitialize llama automáticamente a MPI_Init ). PetscFinalize(), que presenta el resumen de registro de eventos a lo largo del programa y cierra y libera los recursos utilizados. NOTA: Al igual que con MPI, hay un manual en formato HTML (al que se ha hecho referencia en el apartado anterior) donde se encuentra la definición detallada de todas y cada una de las funciones de PETSc. Es un manual muy completo y útil. También se ha hecho una copia, que se encuentra en el directorio unidadcd:\documentación\manual_web_funciones_petsc. A la hora de programar, se aconseja acudir antes al manual citado antes de utilizar cualquier función. Ya hemos dicho que todas las rutinas de comunicación colectiva de PETSc hacen uso de MPI. No es necesario utilizar rutinas de paso de mensajes de MPI directamente aunque, a veces, no queda otra salida, por ejemplo en el caso de MPI_BARRIER, ya que PETSc no tiene envoltorio para dicha rutina. Desde cualquier parte del código se puede invocar a cualquier rutina MPI, ya que el fichero de definiciones mpi.h se incluye dentro de los ficheros de cabecera de PETSc. No obstante, en general, se hace poco uso directo de rutinas MPI, más bien se utilizan las rutinas de envoltorio de PETSc, lo que nos sitúa en un nivel más alto de abstracción. Se puede llamar a la rutina MPI_Initialize antes de llamar a PetscInitialize (por cuenta del usuario o porque lo hace otro paquete externo a PETSc), pero si se hace así, al llamar a PetscFinalize al final del programa, habrá que llamar también a MPI_Initialize. Las librerías de PETSc se encargan de mapear todas las variables análogas a las de MPI; tal es el caso del comunicador PETSC_COMM_WORLD, ya citado, que se mapea al comunicador MPI_COMM_WORLD. Este comunicador hace referencia a todos los procesos que intervienen en la computación o en las comunicaciones. Si quisiéramos referirnos a un solo proceso, utilizaríamos el comunicador PETSC_COMM_SELF, que hace referencia al proceso llamante de la rutina PETSc actualmente llamada CHEQUEO DE ERRORES. Todas las rutinas PETSc, al igual que ocurría con MPI, devuelven un código de error (variable del tipo PestscErrorCode ). En el caso de C, el valor se devuelve como resultado de la función llamada; para Fortran, el código se devuelve dentro de una variable pasada como argumento a la subrutina. Ya se ha comentado la ventaja de que la interfaz de las funciones C y las subrutinas Fortran es la misma, con la pequeña diferencia de que las subrutinas Fortran necesitan un argumento más que es este código de error. El código de error es 0 si todo ha ido bien, y de valor distinto de 0 si ha habido algún problema. 69

7 Es un error muy común en códigos PETSc escritos en Fortran olvidarse del último argumento de las subrutinas, el código de error. La macro CHKERR(ierr) incluida con PETSc, verifica el valor del código de error devuelto por las rutinas. En el caso de códigos escritos en C, si hay algún error, esta rutina termina todos los procesos e imprime en pantalla una traza de errores detectados. En el caso de Fortran no ocurre igual; sí que se terminan todos los procesos, pero no se imprime una traza de errores porque no está soportado por las rutinas Fortran. No obstante, es fácil escribir un trozo de código que en función del valor del código de error imprima o no una traza de errores. Existe otra macro, SETERRQ, la cual puede lanzar códigos de error cuando el usuario la utilice. Como antes, en el caso de Fortran, a diferencia de C, esta macro tampoco imprime una traza de los errores encontrados OTROS ASPECTOS IMPORTANTES DE LOS PROGRAMAS PETSC FICHEROS DE CABECERA PETSC. Los ficheros de cabecera, correspondientes a los módulos PETSc que se desean utilizar en nuestro programa de aplicación, han de incluirse al principio del código. Para el caso de programación en lenguaje C o C++, las sentencias de inclusión son de la forma: #include petscksp.h En la sentencia de arriba, petscksp.h es el fichero de cabecera para el módulo PETSc correspondiente a la librería de solvers lineales, que utilizan métodos del Subespacio de Krylov. Como ya se ha visto, las distintas librerías que componen PETSc forman una jerarquía bien definida, que hace que las librerías de más alto nivel incluyan a las de niveles inferiores. Siendo esto así, cada vez que vayamos a crear un programa de aplicación, se habrá de incluir el fichero de cabecera del módulo PETSc de más alto nivel que vayamos a utilizar. El resto de módulos de más bajo nivel que se necesiten para la compilación serán automáticamente incluidos. Así, petscksp.h incluye petscmat.h (fichero de cabecera para matrices), este a petscvec.h (vectores) y este último a petsc.h (fichero base de la librería PETSc). Todos estos ficheros y los que no se han nombrado se encuentran en el subdirectorio include del directorio de instalación raíz de PETSc. El caso de Fortran es algo distinto. Los ficheros de cabecera se encuentran en el subdirectorio include/finclude, y la forma de incluirlos es la misma que en el caso de C/C++. El problema que se presenta al programar con Fortran es que los ficheros de cabecera no pueden ser incluidos más de una vez. Es por esta razón por la que se han de incluir los ficheros de cabecera de todos aquellos módulos PETSc que se necesiten, teniendo ahora en cuenta que los módulos de alto nivel no incluyen a los de bajo nivel (aunque sí que hacen uso de ellos). Otro punto importante a tener en cuenta al programar con Fortran, es que los ficheros de código fuente han de tener la extensión.f en vez de.f. Esto habilita el uso del preprocesador de C, de modo que se permite el uso de sentencias #include 70

8 dentro del código Fortran. Esto es necesario porque PETSc está escrita en C, y los ficheros de cabecera han de procesarse antes de enlazar las librerías con nuestro código Fortran de aplicación. Si a todo esto le añadimos que en vez de programar en Fortran 77 programamos en Fortran 90, por ejemplo, entonces la extensión de los ficheros será.f90 en lugar de.f, de modo que le indiquemos al compilador de Fortran ( g95 ) que el código escrito es Fortran 90 y no 77. NOTA: En el capítulo 11, del manual de usuario de PETSc incluido en la ruta unidadcd:\documentación\petsc, tienen lugar diversas discusiones sobre la utilización de Fortran con PETSc OPCIONES EN TIEMPO DE EJECUCIÓN. En el ANEXO I, donde se explica la implantación del sistema, se muestra la forma de ejecutar un programa paralelo por medio de utilidades que acompañan al paquete software de MPI. Si a la hora de lanzar un programa paralelo le pasamos como argumento en línea de comandos la opción -help, el programa imprimirá una lista con todas las opciones disponibles que se le pueden pasar como argumentos del programa. Estas opciones se denominan opciones en tiempo de ejecución, ya que se le pasan al programa una vez se está ejecutando. Estas mismas opciones se pueden especificar dentro del código fuente, de modo que se incluyen en el programa en tiempo de compilación. Cada programa PETSc, mantiene una base de datos con los nombres y valores de las opciones que se pueden escoger. Esta base de datos se crea al llamar a la rutina de inicialización PetscInitialize(). Es necesario ver la definición de la rutina en C/C++ y Fortran: C/C++: PetscInitialize(int *argc, char **args, const char *file, const char *help) Fortran: PetscInitialize(character file, integer ierr) En el caso de C/C++, argc y argv son las direcciones de los argumentos de línea de comandos pasados al programa, y file es el nombre de un fichero que contiene opciones adicionales. Además, se pueden especificar opciones al programar a través de la variable de entorno PETSC_OPTIONS. El orden de procesado de las opciones es: 1. Fichero. 2. Variable de entorno. 3. Línea de comandos. La formato habitual a la hora de especificar opciones es: -módulo_opción valor, por ejemplo -ksp_type richardson. Cualquier subrutina en un programa PETSc puede añadir registros a la base de datos por medio del comando PetscOptionsSetValue(char *name, char *value), aunque a penas se utiliza. Por el contrario, obtener opciones de la base de datos es muy común, y se realiza por medio de alguna de las siguientes rutinas, dependiendo del valor que queramos obtener: PetscOptionsHasName 71

9 PetscOptionsGetInt PetscOptionsGetReal PetscOptionsGetString PetscOptionsGetStringArray PetscOptionsGetIntArray PetscOptionsGetRealArray Si es necesario utilizar alguna de estas funciones, se aconseja mirar su interfaz en el manual HTML de PETSc ya comentado en apartados anteriores. Se aprovecha este momento para indicar que en PETSc, al igual que ocurría con MPI, hay unos tipos de variables definidos, que puede que no coincidan con los tipos de variables análogos de los lenguajes C o Fortran. Se pueden seguir utilizando los tipos de C o Fortran para escribir código, pero a la hora de llamar a las rutinas PETSc los argumentos han de ser de los tipos definidos por la librería, tales como PetscInt para enteros, PetscReal para números reales, PetscScalar para números reales de doble precisión, etc. No obstante, hay casos como el de PetscScalar, que se corresponde con un real de doble precisión de C/C++. Así mismo, PETSc proporciona rutinas tales como PetscPrintf, análoga a la función printf de C, con la diferencia de que la primera reconoce el formato de los datos de PETSc, y la segunda no. Esto es importante tenerlo en cuenta a la hora de implementar códigos de aplicación, pero estas funciones no se utilizan con frecuencia PROFILING. El término profile en términos informáticos, hace referencia al fichero de control de un programa, especialmente un fichero de texto leído automáticamente desde el directorio local de cada usuario, y pensado para ser fácilmente modificado por el usuario en orden a personalizar el comportamiento del programa. También se refiere a la acción de realizar un informe sobre las cantidades de tiempo consumidas por cada rutina, de forma que se puedan determinar los ajustes requeridos por el programa. PETSc permite el profiling de programas de forma fácil y sencilla. Las rutinas registran las actividades realizadas si se especifican ciertas opciones en tiempo de ejecución. Además, PETSc proporciona un mecanismo para imprimir información sobre operaciones de computación. Las opciones de profiling pasadas al programa como argumentos en tiempo de ejecución son las siguientes: -log_summary: -info [infofile]: imprime información sobre el funcionamiento del programa al término del mismo. Esta opción ha sido muy utilizada en la fase de pruebas del proyecto, y ha sido de gran ayuda a la hora de determinar el tiempo de ejecución del programa, los parámetros utilizados, etc. imprime información verbosa sobre el código a la salida estándar o a un fichero opcional. Esta opción proporciona detalles sobre algoritmos, estructuras de datos, etc. Esta opción, a diferencia de la anterior, supone una sobrecarga significativa, de modo que es mejor no utilizarla si lo que se quiere ver es el funcionamiento de la aplicación. 72

10 -log_trace [logfile]: traza el comienzo y el final de todos los eventos PETSc. Esta opción, que puede ser utilizada en combinación con la anterior, es útil para ver dónde se queda colgado un programa, sin acudir al depurador. Hay un paquete software denominado MPE (Multi-Processing Environment), que forma parte de la implementación MPICH de MPI. El Entorno Multi-Procesamiento (MPE), pretende proporcionar a los programadores un conjunto completo de herramientas para el análisis del funcionamiento de sus programas MPI. Estas herramientas incluyen: un conjunto de librerías de profiling, un conjunto de programas de utilidad y un conjunto de herramientas gráficas. Las librerías de profiling proporcionan una colección de rutinas que crean ficheros de log (de registro). Estos ficheros de log se pueden crear manualmente insertando llamadas MPE en el programa MPI o automáticamente, enlazando la aplicación con la librerías MPE requeridas. También es posible combinar ambos métodos. PETSc utiliza la opción en tiempo de ejecución log_mpe para crear un fichero de registro de eventos, apropiado para ser visualizado por Jumpshot, que es programa incluido con MPE para visualizar ficheros de log. La forma de indicar esta opción a PETSc en tiempo de ejecución es: -log_mpe [logfile] NOTA: En el apartado , del manual de usuario de PETSc, se habla un poco más sobre el registro de eventos particulares. PETSc registra automáticamente la creación de objetos, tiempos y contadores de punto flotante para las rutinas propias de las librerías. El usuario, por su parte, puede complementar esta información monitorizando sus códigos de aplicación. Las partes del código a ser monitorizadas son los denominados eventos. Las rutinas que utiliza PETSc para el registro de información (logging), se llaman PetscLogXxxx, y en particular, las rutinas que empiezan por PetscLogEventXxxx se dedican al registro de eventos. Para obtener información sobre la interfaz y el manejo de estas rutinas se aconseja dirigirse al ya referenciado manual HTML de rutinas PETSc PETSC CON UN SUBCONJUNTO DE PROCESOS. Hay veces las aplicaciones paralelas son muy grandes, y se requiere dividir el trabajo en partes, asignando alguna parte a un subconjunto de procesos, y no a todos los procesos en su totalidad. Otras veces, no esta la razón de utilizar un subconjunto de procesos, sino que nos puede interesar que un proceso maestro coordine el trabajo de otros procesos esclavos a él. Para lograr todo esto, habría que especificar un comunicador alternativo a PETSC_COMM_WORLD. La forma de hacerlo es mediante la rutina siguiente: PetscSetCommWorld(MPI_Comm comm) A esta rutina hay que llamarla antes que a PetscInitialize, pero después de MPI_Init. No es frecuente el uso de esta rutina, ya que en vez de hacer esto, una buena alternativa sería llamar varias veces a mpiexec de MPI (ver ANEXO I: mpiexec se encarga de ejecutar 73

11 programas en paralelo), y a cada llamada se le pasa un conjunto disjunto de procesos. Así sería fácil dividir el trabajo ESCRITURA, COMPILACIÓN Y EJECUCIÓN DE PROGRAMAS PETSC. Las herramientas utilizadas a la hora de crear aplicaciones paralelas son diversas. En nuestro caso, se ha escogido el editor emacs para la escritura del código fuente. Esta elección se debe simplemente a la familiarización con el editor. Los compiladores escogidos, más que nada por compatibilidad con las librerías, han sido gcc para compilar código escrito en C, g++ para código C++, y g95 para Fortran. Escoger los compiladores no fue tarea fácil, ya que al principio hubo problemas de compatibilidad de otros compiladores con las librerías PETSc y MPI. Una vez escritos y compilados los programas, se ejecutan mediante los scripts de ejecución paralela que proporciona la librería MPI. En concreto, el script mpiexec es el encargado de realizar tal operación. NOTA: En el capítulo 7 se habla un poco más sobre este tema. La compilación no se lleva a cabo llamando directamente a los compiladores, sería un poco descabellado, ya que hay que indicar varios nombres de librerías que se utilizan con frecuencia: PETSc, MPI, BLAS, LAPACK y las propias de la aplicación. Hay programas muy cómodos de utilizar como el Fortran Visual de Compaq, que automatizan el proceso de compilación y el posterior enlazado de librerías; sin embargo, a la hora de instalar MPI o PETSc no era viable utilizar este tipo de herramientas. Las fases de compilación y enlazado de código PETSc / MPI se realizan con la herramienta make, incluida dentro del paquete de Cygwin. Este comando hace uso de los denominados makefiles. El uso de esta herramienta facilita en gran medida el mantenimiento y depurado de programas. Para comprender la forma de utilizar los makefiles con PETSc, lo mejor es ver un ejemplo, el cual se presenta a continuación. CFLAGS = FFLAGS = CPPFLAGS = FPPFLAGS = LOCDIR = /home/josea/pruebas-petsc/pruebas_fortran EXAMPLESC = EXAMPLESF = struct.f90 diag_dom.f90 MANSEC = KSP include ${PETSC_DIR}/bmake/common/base struct: struct.o chkopts -${FLINKER} -o struct struct.o ${PETSC_MAT_LIB} ${RM} struct.o diag_dom: diag_dom.o chkopts -${FLINKER} -o diag_dom diag_dom.o ${PETSC_KSP_LIB} ${RM} diag_dom.o 74

12 cl: rm -f *.*~ rm -f *~ rm -f \#* En el código del makefile, vemos primeramente algunas variables bandera (flags), las cuales determinan cómo será compilado el código; de entre ellas la más importante es LOCDIR, que determina el directorio local donde se encuentran los ficheros de código fuente a compilar y enlazar. A continuación, viene una sentencia include muy importante, puesto que es la incluye otros makefiles, que son los que proporcionan las definiciones y reglas necesarias para la instalación PETSc básica para una arquitectura de sistema común. En estos makefiles se definen las variables que posteriormente el usuario utilizará para sus propios makefiles, como es el caso aquí mostrado. Estas variables son, por ejemplo, FLINKER, que define el linkador Fortran que se utilizará, PETSC_MAT_LIB, que define la ruta donde se encuentra el paquete de matrices de PETSc, y muchas otras. El último bloque de sentencias se utiliza para eliminar los ficheros intermedios creados en la fase de edición de código. En este makefile de ejemplo presentado, podemos observar que se definen dos objetivos para compilar dos ficheros: struct.f90 y diag_dom.f90. La forma de invocar al comando make para compilar y enlazar estos ficheros con las librerías de PETSc es simplemente la siguiente: nos colocamos en el directorio donde se encuentra el makefile y ejecutamos las siguientes sentencias: $ make struct $ make diag_dom La primera instrucción compila el fichero struct.f90 y la segunda el fichero diag_dom.f90. Notar que los argumentos que se le pasan al comando make son los objetivos definidos en el makefile, no el nombre de los ficheros. Por otro lado, si el makefile creado para compilar nuestras aplicaciones no tiene el nombre makefile, habrá que indicárselo a make con la opción f nombre_makefile. Para aprender más opciones sobre las formas de invocar make, se puede acudir al manual proporcionado con el paquete Cygwin, al cual se accede mediante la siguiente sentencia ejecutada en una consola de Cygwin: $ man make La mejor forma de aprender a utilizar estos makefiles, es viendo los ejemplos que se incluyen con la instalación de PETSc, o viendo los creados para las pruebas realizadas para el proyecto. No obstante, en el capítulo 15 del manual de usuario de PETSc se habla algo más sobre la construcción de estos ficheros de apoyo. 75

13 3.4. VECTORES INTRODUCCIÓN. Hasta ahora, lo que hemos visto a sido una descripción del entorno donde se desarrollan las aplicaciones PETSc, así como algunas características propias de la librería. Las siguientes grandes secciones, incluyendo la actual, se dedican a explicar en profundidad los principales módulos software que proporciona PETSc, y que han sido utilizados en la realización de aplicaciones paralelas para el Cálculo de Estructuras. Esta primera sección se dedica al tema de vectores, primer paquete de Álgebra lineal, que será la base para el entendimiento de las siguientes librerías que se explicarán. Ya dijimos que PETSc utiliza la filosofía de la Programación Orientada a Objetos (OOP), aun cuando C o Fortran no se ajustan a esta forma de programación (C++ sí, que también está soportado por PETSc). Pues bien, el objeto fundamental en la jerarquía de objetos de PETSc es el vector, denominado Vec en términos de la librería. Los vectores se utilizan para almacenar soluciones de problemas, la parte del lado derecho del sistema Ax=b, etc. En los siguientes apartados, veremos todo lo referente al manejo de este tipo de objetos, así como algunos paquetes software relacionados con los vectores, como son los índices o los arrays distribuidos CREACIÓN DE VECTORES. PETSc nos da la posibilidad de crear dos tipos de vectores, en función de nuestras necesidades y de si el sistema es mono o multi-procesador. Los dos tipos son: Vector secuencial: todas sus componentes (campos) pertenecen al mismo procesador. Vector paralelo: sus componentes se encuentran distribuidas a través de un conjunto de procesadores. El procedimiento de distribución de componentes sobre los distintos nodos del cluster, así como las distintas operaciones que se llevan a cabo sobre el vector, se realizan mediante MPI. Por esta razón, al vector paralelo también se le denomina vector MPI. PETSc soporta objetos con estructura de datos neutral, lo que permite un modelo de memoria distribuida, nada compartido, dentro de sistemas de procesadores individuales. El objeto vector de PETSc es un indicador (puntero) a las entradas del vector real; esto permite que el vector paralelo se pueda distribuir a través de muchos procesos, pero tiene como contrapartida que no se puede acceder al vector de forma directa, sino a través de unas rutinas específicas que esconden un complejo de llamadas a MPI. PETSc permite trabajar con el vector global, no sólo con la parte local del vector que pertenece a un proceso particular, pero de nuevo, a través de un conjunto de operaciones que especifica la librería paralela. Por otro lado, el acceder al vector a través unas rutinas definidas por PETSc ayuda a no preocuparse de la complejidad de las operaciones de comunicación entre procesos, que siempre es un tanto compleja. La creación de un vector se compone de tres fases: 76

14 1. La creación del vector, propiamente dicha, donde cada proceso crea su vector particular, en el caso de vectores secuenciales, o donde cada proceso crea su parte local del vector paralelo, en el caso de vectores MPI. Los vectores paralelos (MPI) están formados por vectores secuenciales, y cada uno pertenece a un proceso, de modo que el vector global paralelo es la unión de todos estos vectores locales a los procesos. 2. La inserción de valores. Tras la creación del objeto, cada proceso inserta valores en las partes del vector que considere necesarias, ya sean partes locales o no locales al proceso. 3. El ensamblado del vector. Esta es la fase que tiene lugar tras la inserción de valores en el vector. Aquí se realiza todo el paso de mensajes de las componentes del vector no-locales a los procesos. NOTA: No perder de vista que trabajamos con un modelo de programación paralela SPMD (Single Program, Multiple Data), es decir, todos los procesos ejecutan el mismo programa, aunque cada uno tiene su propios valores para las mismas variables, lo que da lugar a resultados distintos en cada nodo. Esto quiere decir que todos los procesos llaman a las mismas operaciones, y en el mismo orden; de modo que, en el caso particular de vectores, al crear, por ejemplo, un vector paralelo, todos los procesos lo crearán a la vez, y todos contribuirán con su parte local al vector MPI global. La definición de las interfaces de todas las rutinas se encuentran perfectamente detalladas en el manual HTML de PETSc, al que de nuevo se aconseja acudir cada vez que se requiera utilizar cualquier rutina. Las rutinas que proporciona PETSc para la creación de vectores son VecCreateSeq y VecCreateMPI para el caso de vectores secuenciales y paralelos, respectivamente. Ambas rutinas requieren el nombre de un comunicador como argumento, que en el caso de VecCreateSeq es PETSC_COMM_SELF, como no podría ser de otra manera. En el caso de la rutina para la creación de vectores MPI, se especifican dos dimensiones del vector, la local y la global. El usuario puede especificar ambas o una de las dos y la que resta dejar que la determine PETSc, indicando que dicha dimensión tenga el valor PETSC_DECIDE. De forma equivalente, se pueden sustituir las dos rutinas anteriores por el conjunto de las tres siguientes: VecCreate, para crear el vector y especificar el comunicador utilizado, VecSetSizes, para especificar las dimensiones (local y global) del vector, y VecSetFromOptions, para coger de la base de datos la opción que indica el tipo de vector a utilizar. Si en línea de comandos se indicó el argumento -vec_type mpi, el vector que determinará la rutina VecSetFromOptions será de tipo MPI, incluso en el caso uniproceso. A la creación de un vector le sigue la inserción de valores en el mismo. Esta fase se lleva a cabo mediante la rutina VecSet, para la inserción de un valor simple a todas las componentes del vector, o mediante VecSetValues, para la inserción de un conjunto de valores. Si la opción escogida es esta última, se puede llamar varias veces a dicha rutina en cualquiera o en todos los procesos, pero la fase de inserción no está completa. Por medio de la rutina VecSetValues, cualquier proceso puede insertar valores en cualquier componente del 77

15 vector global, aun siendo componentes no locales. Por esta razón, es necesario pasar a la tercera fase, la fase de ensamblado (si se utiliza la rutina VecSet, el ensamblado se puede omitir). Decir que PETSc no proporciona ninguna rutina llamada VecGetValues, sino que proporciona métodos alternativos tales como el acceso a un array local, copia del vector paralelo, u operaciones de dispersión (scatter) de valores entre procesos (rutinas basadas en MPI pero con una interfaz PETSc, que esconde la complejidad de las comunicaciones MPI). El ensamblado de un vector paralelo consiste en realizar todas las operaciones de comunicación interprocesos necesarias para distribuir los valores no locales previamente insertados. Las rutinas a las que hay que invocar para realizar el ensamblado son VecAssemblyBegin y VecAssemblyEnd, en medio de las cuales se pueden realizar operaciones de computación, de modo que se aproveche el tiempo en que se realizan las comunicaciones pertinentes. Si un proceso inserta valores en su parte local del vector paralelo, no es necesario realizar la fase de ensamblado, puesto que no hay que migrar valores a otros procesos. Uno de los parámetros a indicar en la llamada a la rutina VecSetValues es si se desea insertar o añadir (sumar) valores a las componentes del vector en cuestión. En el caso de la inserción, se indica mediante el valor INSERT_VALUES, y en el caso de la adición el valor es ADD_VALUES. Es importante hacer notar que la inserción y la adición no se pueden combinar. Para poder mezclar ambas acciones, serían necesarias fases distintas de inserción y adición, con llamadas entre medio a las rutinas de ensamblado. Esta forma de trabajar elimina la incertidumbre del caso en que un proceso inserte y otro añada valores a las mismas localizaciones dentro del vector. Una vez ensamblado el vector paralelo, un proceso puede obtener el tamaño de dicho vector llamando a VecGetSize. A su vez, si un proceso desea determinar el tamaño local de la parte que le corresponde del vector global, puede hacerlo mediante VecGetLocalSize. Es lógico querer visualizar los nuevos objetos de tipo vector creados. La librería PETSc, dispone de un módulo software para la creación de visualizadores (viewers), que son objetos utilizados para examinar, imprimir y guardar otros objetos. Existen diversas rutinas para trabajar con visualizadores, algunas de las cuales se presentan en la sección 14.3 del manual de usuario de PETSc. Incluso hay algunas para interactuar con MATLAB. En el caso concreto de vectores, la rutina VecView muestra en pantalla las componentes del vector pasado como argumento (de nuevo, se insta acudir al manual HTML de funciones PETSc). La creación de vectores está bien, pero si queremos obtener vectores con el mismo formato que el de uno recién creado, muchas veces interesaría más duplicarlos, así no habría que repetir las fases de creación, inserción de valores y ensamblado. Pues bien, PETSc suministra dos rutinas, VecDuplicate y VecDuplicateVecs, para el duplicado de un vector en otro o en otros, respectivamente. La gran ventaja de introducir sentencias de duplicado de vectores en el código fuente, es que dicho código no depende del formato de los vectores utilizados. Otras veces, por motivos implicados de una aplicación particular, puede ser útil crear vectores a partir de un array proporcionado por el usuario, cosa que se puede hacer con las rutinas VecCreateSeqWithArray y VecCreateMPIWithArray. En este caso, no se deja a PETSc la opción de alojar en memoria el espacio para el vector, sino que lo hace el propio usuario; esto implica que es el propio programador el encargado de especificar la dimensión 78

16 local del vector, teniendo cuidado de que el array sea lo suficientemente grande para contener los valores del vector local. Tras la utilización de un vector, la única salida que tiene, como objeto que es, es ser destruido. Esta operación de eliminación se lleva a cabo mediante VecDestroy, para un solo vector, o con VecDestroyVecs, para realizar lo mismo con un array de vectores OPERACIONES FUNDAMENTALES CON VECTORES. Algunas de las operaciones básicas con vectores proporcionadas por PETSc se presentan en la tabla 6, sacada del manual de usuario de PETSc. En la rutina VecNorm, el tipo de la norma del vector puede ser 1, 2 o infinito. RUTINA VecAXPY VecAYPX VecWAXPY VecAXPBY VecScale VecDot VecTDot VecNorm VecSum VecCopy VecSwap VecPointwiseMult VecPointwiseDivide VecMDot VecMTDot VecMAXPY VecMax VecMin VecAbs VecReciprocal VecShift VecSet OPERACIÓN REALIZADA y = y + a x y = x + a y w = a x + y y = a x + b y x = a x r = x*' y r = x' y r = x tipo r = xi y = x y = x mientras x = y wi = xi yi wi = xi / yi r[i] = x*' y[i] r[i] = x' y[i] y = y + i ai x[i] r = max xi r = min xi xi = xi xi = 1/xi xi = s + xi xi = Tabla 6. Operaciones básicas con vectores. La tabla anterior es auto explicativa, y si se desea realizar alguna de estas operaciones, no hay más que acudir al manual HTML de funciones para ver la interfaz y utilizarla. Siempre se aconseja ir al manual HTML porque, de la experiencia adquirida programando con PETSc, se ha llegado a la conclusión de que es el único sitio donde las interfaces de las rutinas están correctamente indicadas, sin errores. Hay una rutina muy importante y muy utilizada en las pruebas: VecGetOwnershipRange. La llamada a dicha rutina permite a cada proceso particular obtener, de un vector paralelo distribuido a través de todos los procesos, el rango local que le pertenece. El rango local se especifica con un índice inicial y un índice final, que 79

17 corresponden, respectivamente, a la primera y la última componente del vector global que pertenecen al proceso que invoca la rutina. Es importante hacer énfasis en el hecho de que los índices devueltos por esta rutina son índices globales, que indican la parte del vector paralelo que pertenece al proceso local que llama a la rutina. En la siguiente sección, se verán métodos adicionales para tratar con índices. La rutina VecGerOwnershipRange se suele utilizar en conjunción con VecSetValues, que también hace uso de índices globales. Es comprensible que sea un poco complicado asimilar todos estos conceptos de índices y rangos locales y globales, vector paralelo y secuencial, comunicador colectivo o individual, etc.; todos estos conceptos seguramente se aclararán y asentarán viendo los códigos de las pruebas realizadas. Una gran ventaja de PETSc, es que proporciona un código muy legible, debido a los nombres asignados a las rutinas, por lo que es fácil e intuitivo seguir el código fuente de las aplicaciones, que, a su vez, es la mejor forma de aprender a programar con PETSc (además de ir mirando el manual HTML de funciones). Ya dijimos que no había una rutina análoga a VecSetValues que extrajese valores de los vectores, cosa que muchas veces es necesaria. Para tal fin, PETSc proporciona dos rutinas: VecGetArray, que devuelve un puntero a los elementos locales (del vector global completo) que pertenecen al proceso llamante; y VecRestoreArray, que elimina el puntero cuando ya no es necesario acceder más al vector local. El array (puntero al array) devuelto, no es una copia del vector local, sino que es un acceso directo a los elementos del vector (la parte del vector global que pertenece a un proceso particular, se encuentran almacenada localmente). Esta forma de trabajar da lugar a un aumento de la eficiencia, ya que no hay que crear ni destruir copias de datos. Por último, puntualizar que hay rutinas con los nombres VecxxxBegin y VecxxxEnd que aumentan la eficiencia de las comunicaciones. Este tipo de rutinas aprovechan el hecho de que se vayan a realizar varias operaciones consecutivas que requieran comunicaciones y así unificarlas, manteniendo los cálculos implicados por separado. Sin embargo, al estar basadas en MPI-1, no están preparadas para solapar cálculos con comunicaciones, lo que se espera conseguir en un futuro al mejorar estas rutinas con MPI-2. Hasta aquí, la parte básica del paquete de vectores. En lo que resta de la sección, veremos algunos complementos del mismo paquete software, que servirán para facilitar la labor del programador ORDENACIÓN E INDEXADO (NUMERACIÓN). En muchos problemas científicos, se requiere un procesamiento previo de la información antes de pasar a la fase de computación. Este procesado hace referencia a cómo se ordenan y numeran los diversos elementos que componen un problema, que es la base para empezar a realizar operaciones sobre estos datos. Existen diversas situaciones en las que esto ha de tener lugar, tales como códigos paralelos de PDE s, en los que aparecen muchísimos vértices y grados de libertad. En nuestro caso, antes de realizar cálculos sobre una estructura concreta, es necesario realizar antes un mallado de la misma, y asignar a cada nodo resultante una identificación, para poder distinguir unos de otros. Tras realizar esto, es necesario numerarlos y ordenarlos de la forma que más convenga para nuestra aplicación. 80

18 A todo esto hay que añadir lo siguiente: como bien sabemos, los datos se distribuirán a través de los nodos del cluster de ordenadores. Pues bien, cada proceso tendrá su propia numeración local de los objetos de datos, frente a la numeración global del conjunto. Para toda esta casuística, PETSc suministra dos herramientas básicas, traducidas a paquetes software distintos: AO (Application Ordering Ordenación de la Aplicación) e IS (Index Set Batería de Indíces). AO permite mapear entre diferentes esquemas de numeración global, por ejemplo, entre la ordenación que utiliza PETSc y la que desearía utilizar un usuario para su aplicación; IS permite mapear entre numeración local (un proceso particular) y global (el conjunto de procesos). A continuación, veremos las dos herramientas por separado, las cuales trabajan juntas en un punto, el cual veremos ORDENACIONES DE UNA APLICACIÓN. Muchas veces es necesario, otras veces deseable, mantener diferentes formas de ordenar los elementos de un problema. Esto es una tarea complicada, debido a que es difícil que cada proceso mantenga información sobre el mapeado entre las distintas ordenaciones. En la figura 26, se presenta un ejemplo de lo comentado: tenemos una aplicación que mantiene una ordenación (natural) determinada para un array de 2D, mientras que PETSc utiliza una ordenación completamente distinta, que corresponde a la utilizada por las rutinas del Álgebra lineal. Cada bloque de datos pertenece a un proceso, los cuales utilizan una de las dos ordenaciones, según se le indique. Figura 26. Ordenaciones distintas para un mismo array de datos en 2D. Para crear una nueva ordenación de aplicación, basta con llamar a la rutina AOCreateBasic, la cual acepta dos arrays como argumentos, uno para especificar los valores de la ordenación que utiliza la aplicación, y otro para los valores de la ordenación que utiliza PETSc. Una vez creado el objeto AO, se pueden utilizar las rutinas AOPetscToApplication y AOApplicationToPetsc para mapear de una ordenación a otra. Si un conjunto de procesos llamó a la rutina AOCreateBasic, el mismo conjunto (no un subconjunto) ha de llamar a estas dos últimas rutinas, en el caso de que sea necesario, ya que la base datos que mantiene el mapeado entre ordenaciones es paralela, de modo que todos los procesos que la crearon han de mantenerla. La rutina AODestroy elimina el contexto de ordenaciones creado. Así mismo, AOView visualiza el objeto AO creado por las rutinas pertinentes. 81

19 CONJUNTOS DE ÍNDICES. Un conjunto de índices (IS) es una generalización de un conjunto de enteros, utilizado para definir dispersiones, recolecciones y operaciones similares sobre vectores y matrices. La rutina ISCreateGeneral, crea un conjunto de índices a partir de un array de enteros. Hay variantes de esta rutina, como es el caso de ISCreateStride, que crea un conjunto de índices que contiene una lista de enteros igualmente espaciados por un paso (stride), o como ISCreateBlock, que crea un conjunto de índices para un conjunto de bloques de enteros (mirar el manual HTML de funciones). Cuando no se necesita más un conjunto de índices, se puede destruir mediante la rutina ISDestroy. Hay una rutina, llamada AOCreateBasicIS, que crea una ordenación para una aplicación, no a partir de dos arrays de enteros (como así lo hacía la rutina AOCreateBasic ), sino a partir de dos conjuntos de índices. Posteriormente, de forma análoga a como ocurre con AOCreateBasic, se puede llamar a las rutinas AOPetscToApplicationIS y AOApplicationToPetscIS para mapear objetos IS entre las ordenaciones de aplicación y de PETSc. Con los objetos AO, se busca hallar un camino para mantener diferentes ordenaciones para los mismos datos de un problema. Por otro lado, con los objetos IS se busca acceder localmente a los recursos globales y viceversa. PETSc proporciona unas rutinas para mapear los índices desde un esquema de numeración local (el de un proceso individual) al esquema de numeración global de PETSc, y viceversa. Con las rutinas ISLocalToGlobalMappingCreate y ISLocalToGlobalMappingDestroy se crea y se destruye, respectivamente, una estructura de índices para mapear entre una numeración local y otra global. Tras la creación, las rutinas ISGlobalToLocalMappingApply y ISLocalToGlobalMappingApply realizan el mapeado entre índices globales y locales. En el caso de un vector paralelo, esto es muy interesante, ya que ofrece la posibilidad de insertar valores con una numeración local para el proceso llamante, sin preocuparse por la numeración global del vector paralelo completo. Ya vimos que la rutina VecSetValues utilizaba una numeración global para insertar valores en un vector paralelo. Ahora, haciendo uso de los conjuntos de índices, se pueden insertar valores mediante una numeración local. En concreto, la rutina VecSetLocalToGlobalMapping llamada tras ISLocalToGlobalMappingCreate, mapea los índices locales a índices globales para acceder al vector, de modo que mediante la rutina VecSetValuesLocal se puedan insertar valores utilizando índices locales, que automáticamente serán mapeados a los correspondientes índices globales, accediendo así al vector paralelo de forma correcta. Los índices locales seguirán una numeración propia de cada proceso, es decir, pertenecerán al rango de valores [0, size), donde size es el tamaño del vector local perteneciente al proceso (parte local del vector paralelo alojada en dicho proceso) DISEÑO DE DATOS PARALELOS Y VALORES DE CONTORNO (GHOST VALUES). Una situación típica en términos científicos, es la resolución de PDE s (ecuaciones en derivadas parciales). Gestionar bien el área de datos es la clave para obtener un buen rendimiento en las aplicaciones paralelas basadas en la resolución de este tipo de problemas. Respecto al área de datos, decir que se puede tratar como una malla (o rejilla) estructurada o no estructurada. PETSc proporciona dos tipos de objetos para tratar sendos casos: los arrays 82

20 distribuidos, para rejillas estructuradas, y los VecScatter (dispersión de vectores), para rejillas no estructuradas. Para evaluar las funciones que representan las PDE s, se requiere, en cada parte del proceso de resolución, obtener el valor del vector solución intermedio, el cual se encuentra distribuido entre los procesos que ejecutan la aplicación paralela. Cada proceso necesita los valores locales del vector paralelo que le corresponden, así como los valores de contorno (ghost values), que se encuentran almacenados en los procesos adyacentes. Este concepto se muestra en la figura 27. Figura 27. Concepto de valores ghost (valores de borde). En la resolución paralela del tipo de problemas que venimos comentando (problemas derivados de PDE s), intervienen cuatro puntos importantes a tener en cuenta: 1. Geometría de los datos: es importante identificar si los datos se presentan en forma de rejilla estructurada o no estructurada. 2. Creación de la estructura de soporte para los datos: tanto para los datos locales como para los valores ghost. 3. Actualización de valores ghost: cada proceso envía/recibe los correspondientes valores ghost a/de su vecino. 4. Fase de computación numérica local: cada proceso utiliza sus valores locales y los valores ghost para realizar las operaciones pertinentes. Existen dos tipos de representaciones de los datos que almacena cada proceso: la representación global y la local. En la global, cada proceso almacena un único conjunto local de nodos de la rejilla, y cada nodo pertenece a un único proceso. En la representación local, cada proceso almacena un único conjunto local de nodos de la rejilla, así como un conjunto de nodos ghost que pertenecen a los procesos adyacentes. Estas dos formas de representación se muestran en la figura 28. Las representaciones son las ya denominadas ordenaciones, las cuales se pueden manejar mediante los objetos AO que proporciona PETSc. A continuación, pasaremos a ver los métodos que utiliza PETSc para tratar con rejillas, que ya se han comentado: arrays distribuidos y VecScatter. 83

21 Figura 28. Representación global y local de los nodos pertenecientes a un proceso REJILLAS ESTRUCTURADAS: ARRAYS DISTRIBUIDOS Los arrays distribuidos (DA), son un paquete software de PETSc independiente al módulo de vectores, pero ambos funcionan en conjunto para trabajar con rejillas lógicas de datos regulares y rectangulares, a la hora de distribuir datos no locales entre los distintos procesos. Los arrays distribuidos de PETSc, están diseñados para el único caso en que se pueda pensar que los datos están almacenados en un array lógico multidimensional estándar. Por esta razón, los DA s no están pensados para paralelizar rejillas de datos no estructuradas. Los datos de la aplicación paralela se almacenan en objetos de tipo vector, de tamaño apropiado. Los objetos DA sólo contienen la información del esquema de datos paralelos y la información de la comunicación de valores ghost, aunque se pueden utilizar para crear vectores y matrices con un diseño apropiado. Al trabajar con DA s, el primer paso a realizar es la creación de estos objetos. Se puede crear una estructura de datos de comunicación de un DA mediante las rutinas DACreate1d, DACreate2d o DACreate3d, dependiendo de si la estructura de la rejilla estructurada regular es de 1D, 2D o 3D, respectivamente. Hay dos parámetros importantes a pasar como argumentos a estas rutinas: el número de puntos de rejilla y el número de procesos, ambos especificados para cada dirección. Otro parámetro a indicar es el tipo de estructura del array distribuido; los tipos disponibles son dos: estructura de tipo caja y de tipo estrella. Ambos se muestran en la figura 29. Esta definición del tipo de estructura del DA determinará los valores ghost que se utilizarán. Figura 29. Patrón de la estructura de datos para los valores ghost. Ya hemos dicho que los objetos DA, sólo contienen información sobre la estructura de datos paralela y las comunicaciones. Los datos se almacenarán en vectores. Y este es el siguiente paso, crear los vectores que contengan la información sobre los datos (incluidos los valores ghost). 84

22 Cada objeto DA define el diseño de dos vectores: un vector global distribuido y un vector local que incluye espacio para los puntos ghost pertinentes. Cada proceso almacena una única porción del vector global, y cada proceso almacena su vector local completo más el alojamiento necesario para los valores ghost. El objeto DA informa sobre el tamaño y el esquema de sendos vectores, pero no aloja espacio para los valores de dichos vectores. La forma de trabajar es creando los dos vectores a partir de la información proporcionada por el objeto DA. Las rutinas que realizan esto son DACreateGlobalVector y DACreateLocalVector. A partir de que se crean los objetos vector, se pueden utilizar todas las rutinas del módulo de vectores. Cuando dentro de una aplicación un proceso necesita los valores ghost para realizar ciertas operaciones, hemos de conseguirlos mediante operaciones de dispersión (scatter) de dichos valores desde los procesos adyacentes al proceso local. Esto es, hemos de realizar una dispersión de algunos valores del vector global al vector local. PETSc suministra dos rutinas para realizar la operación de dispersión en dos pasos: DAGlobalToLocalBegin y DAGlobalToLocalEnd. En medio de estas dos rutinas, las cuales realizan un entramado de comunicaciones, se pueden realizar operaciones de computación, de modo que podamos aumentar el rendimiento de nuestra aplicación. Al término de dichas operaciones, se dispone del vector local con los valores ghost actualizados, momento en el que se pueden llevar a cabo las operaciones necesarias. Una vez terminado el procesado del vector local, se pueden enviar los nuevos valores de dicho vector al vector global mediante una operación de dispersión, la cual realiza la rutina DALocalToGlobal. Por último, señalar que existen dos rutinas, DaLocalToLocalBegin y DALocalToLocalEnd, que se utilizan para copiar de un vector local que contiene puntos ghost no actualizados a otro vector local, el cual, ahora sí, contendrá los correspondientes valores ghost actualizados. La única cosa a tener en cuenta al realizar esta operación, es que ambos vectores locales han de tener el mismo diseño paralelo, es decir, han de ser compatibles con el mismo DA (generados por el mismo objeto DA, si cabe). Realmente, de los dos vectores, el global y el local, se trabaja con el local a la hora de realizar operaciones de computación, puesto que es el que contiene los valores ghost. Ya hemos visto cómo crear ambos vectores, así como la forma de actualizar los valores ghost. Sin embargo, esta forma de actualizar los valores de contorno es poco eficiente. PETSc provee las siguientes rutinas: DAGetLocalVector que, como su propio nombre indica, obtiene el vector local correspondiente (con los valores ghost correctos), tras lo cual se realizan las operaciones necesarias en el proceso actual; y DARestoreLocalVector, que libera el vector de trabajo local cuando ya no se necesita. Estas dos rutinas apenas requieren tiempo de CPU para su funcionamiento. Tras realizar todas estas fases de creación de diseño paralelo de vectores mediante objetos DA, creación de los vectores correspondientes a los diseños realizados, etc., lo que resta es insertar valores en dichos vectores. Las rutinas destinadas a tal fin son dos, DAVecGetArray para obtener un array en el que insertaremos los valores generados en nuestro programa de aplicación, y DAVecRestoreArray para restaurar el array y mapear los valores al vector distribuido. A la primera rutina, se le puede especificar que el vector al cual queremos insertar valores sea el global o el local, pero una vez que obtengamos el array, sólo podremos acceder a los valores locales y a los valores ghost, el resto de valores estarán indefinidos. La forma de acceder al array es utilizando una indexación global, como si estuviéramos accediendo al vector global de forma directa (aunque sabemos que eso no es posible si no es a través de rutinas que utilizan arrays intermedios). 85

23 Decir que existen otras rutinas, como DAGetCorners y DAGetGhostCorners, empleadas para obtener información sobre la estructura de la rejilla datos, en concreto el valor de los índices de la esquina inferior izquierda de la parte local correspondiente al objeto DA en cuestión. Como última aplicación de los arrays distribuidos, puntualizar que es posible mapear entre las ordenaciones de aplicación y de PETSc utilizadas para gestionar las rejillas regulares rectangulares. En su momento vimos que el paquete software de objetos AO era el encargado de gestionar el tema de las ordenaciones de datos. A su vez, también vimos cómo PETSc utiliza una ordenación de los datos distinta a la ordenación natural de la que hace uso una aplicación particular (apartado , figura 26). Pues existen rutinas, pertenecientes al módulo de objetos DA, que complementan su funcionamiento con las rutinas del módulo de objetos AO. Por ejemplo, la rutina DAGetAO obtiene el contexto de ordenación de datos de la estructura paralela representada por un array distribuido particular REJILLAS NO ESTRUCTURADAS: VECSCATTER. Establecer los patrones de comunicación en rejillas no estructuradas es mucho más complejo que en el caso de rejillas estructuradas, debido a la dependencia con la malla y con la discretización. En el apartado , se hizo una breve descripción del paquete de conjuntos índices (IS). PETSc utiliza este tipo de objetos para facilitar las dispersiones y recolecciones (scatters & gathers) utilizadas para actualizar los puntos ghost de problemas definidos sobre rejillas de datos no estructuradas. Así mismo, es muy probable que sea necesario utilizar los objetos AO (Application Ordering) para mapear entre el esquema de ordenación de nuestra aplicación y el de PETSc, de modo que consigamos que los valores situados en procesos adyacentes sean numerados de forma secuencial (así facilitar el manejo de los valores ghost). La librería paralela PETSc proporciona, dentro del módulo de vectores, soporte completo para las operaciones de dispersión y recolección. En términos de PETSc, se hace referencia a estas operaciones como dispersiones generalizadas, aunque en la actualidad son una combinación de dispersiones y recolecciones. El programador puede seleccionar cualquier subconjunto de las componentes de un vector e insertarlas o añadirlas a cualquier subconjunto de las componentes de otro vector. Para tal fin, PETSc utiliza un término denominado contexto de dispersión, que es un objeto del tipo VecScatter, utilizado para referirse a un entorno de comunicaciones concreto. La razón de utilizar los contextos es que podemos diferenciar entre distintas operaciones de dispersión con vectores. La rutina VecScatterCreate es la encargada de crear el contexto de dispersión, y hay que indicarle los vectores que intervendrán en la operación (pueden ser paralelos o secuenciales), así como el subconjunto de un vector que se copiará a otro subconjunto igual o distinto al del otro vector. El número de elementos de ambos subconjuntos ha de ser idéntico. VecScatterDestroy se encarga de eliminar los datos creados por la rutina anterior. La dispersión se lleva a cabo a través de VecScatterBegin y VecScatterEnd, con una característica peculiar: una operación de dispersión puede realizarse a la inversa. Esto último se indica mediante un argumento pasado a estas dos rutinas, el cual puede tomar el valor SCATTER_FORWARD (dispersión del vector global al local) o SCATTER_REVERSE (dispersión del vector local al global). Las operaciones de dispersión son colectivas, lo que implica que todos los procesos que sean propietarios de un vector paralelo, sobre el que se realiza una dispersión, han de llamar a las rutinas de dispersión. 86

24 Antes de pasar al siguiente punto, veamos dos características importantes de las dispersiones. La primera es que cualquier pareja de vectores que tenga el diseño paralelo conveniente (mismo número de elementos en cada proceso), puede utilizar el objeto VecScatter creado con la rutina VecScatterCreate. No importa que los vectores utilizados para la dispersión no hayan intervenido en la llamada a dicha rutina si, como ya se ha comentado, tienen el mismo esquema paralelo que el de los vectores utilizados en la llamada. Esto es una ventaja, ya que se puede reutilizar el contexto de dispersión, de modo que se reducen las comunicaciones y, por ende, aumenta el rendimiento de nuestra aplicación. La segunda característica a comentar, es que no existe una rutina que realice la función inversa a VecSetValues (esto ya se ha apuntado en otra ocasión). Es decir, se pueden insertar valores en un vector paralelo con VecSetValues y después ensamblar el vector con las rutinas correspondientes, pero no existe rutina alguna para obtener de la misma forma los valores. En su defecto, con PETSc se trabaja de forma que primero se realiza una dispersión de valores a un vector creado al efecto, y posteriormente se llama a la rutina VecGetArray para mapear los valores del vector a un array pasado como argumento. Al final, es necesario llamar a VecRestoreArray devolver al sistema el array empleado. Al igual que ocurría en el caso de rejillas estructuradas, en rejillas no estructuradas también es importante el uso de valores ghost (valores que se encuentran en los procesos inmediatamente adyacentes al proceso local, y que son fundamentales para realizar diversas operaciones de computación). Sin embargo, la forma de trabajar es algo distinta al caso de rejillas estructuradas. El método consiste en dos etapas de dispersión. Primeramente, se realiza una dispersión de valores desde el vector paralelo a los vectores locales de trabajo, que contienen espacio para valores ghost ( SCATTER_FORWARD ). A continuación se realiza la computación requerida utilizando los vectores locales. Por último, se lleva a cabo una dispersión hacia atrás para introducir el resultado en el vector solución global ( SCATTER_REVERSE ). Antes de terminar, veamos una última cuestión relacionada con el tratamiento que ofrece PETSc para rejillas no estructuradas. Todo lo que se ha hablado hasta ahora en este apartado presenta dos inconvenientes: es necesario memoria adicional para almacenar los vectores locales de trabajo (partes locales del vector global que incluyen espacio para los valores ghost), y además se necesita tiempo suplementario para copiar los valores del vector global a los vectores locales. PETSc tiene en cuenta estos inconvenientes, y proporciona rutinas para alojar espacio para los vectores globales con prealojamiento de memoria para los valores ghost. Estas rutinas son VecCreateGhost y VecCreateGhostWithArray ; a ambas se les pasa como argumento un array que contendrá las posiciones donde se encuentran los valores ghost dentro del vector global. La rutina VecGhostGetLocalForm es la encargada de mapear el vector global paralelo al vector secuencial correspondiente, que incluirá los valores ghost. Este vector secuencial comparte el mismo espacio de memoria que el vector paralelo. Al vector MPI (paralelo) se accede mediante una numeración global y, al secuencial, con una numeración local (también para los valores ghost). La rutina complementaria a la anterior es VecGhostRestoreLocalForm, que produce el mismo efecto que el uso de VecRestoreArray tras VecGetArray. En el caso de rejillas no estructuradas, las rutinas VecGhostUpdateBegin y VecGhostUpdateEnd cumplen la misma función que la que realizaban VecScatterBegin y VecScatterEnd en rejillas estructuradas, salvo por una salvedad, que en este caso no se necesitan copiar los valores locales al proceso, sólo los valores ghost, ya que los valores del vector local comparten el mismo array que los valores del vector global. 87

25 3.5. MATRICES INTRODUCCIÓN. Una vez visto el módulo de vectores, primer paquete de Álgebra Lineal proporcionado por PETSc y fundamental para entender los posteriores paquetes, pasemos a ver el módulo de matrices, segundo paquete de Álgebra Lineal. Las matrices son los objetos fundamentales que almacenan operadores lineales, como es el caso de los Jacobianos. A lo largo de esta sección, veremos cómo trata PETSc las matrices y qué posibilidades ofrece. La forma de gestionar los objetos de tipo matriz es la misma que en el caso de vectores: primero se crea una matriz, se insertan valores, se utiliza para varias operaciones de computación y, finalmente, se destruye. En este sentido, es útil pensar en matrices como conjunto de vectores, al menos en un principio, para así abordar el enrevesado tema de la paralelización. PETSc proporciona alrededor de unos cincuenta formatos de matrices distintas, tanto para funcionamiento en sistemas uniprocesador como en paralelo. Sin embargo, los dos formatos principales son la matriz densa y la matriz de fila dispersa comprimida (compressed sparse row), también llamada matriz AIJ. Está última es la que más fomenta PETSc a la hora de realizar programas de aplicación, y así lo demuestra al realizar más rutinas que trabajan con este tipo de matrices que con otras. Una gran ventaja que proporciona PETSc, es que el código de las aplicaciones no depende del tipo de matrices utilizado CREACIÓN DE MATRICES. Veamos ahora, de forma general sin particularizar el tipo de matriz empleado, las operaciones básicas para crear, ensamblar e insertar valores en una matriz genérica. Para tal fin, PETSc facilita una rutina denominada MatCreate, la cual crea un objeto de tipo matriz. Esta matriz será secuencial si el programa se ejecuta en un sistema uniprocesador o paralela si se ejecuta en un sistema multiproceso. El tipo de matriz se especifica en tiempo de ejecución a través de la ya comentada base de datos que mantiene el programa de aplicación con la rutina MatSetFromOptions, o lo especifica el propio programa a través de la rutina MatSetType. Los tipos de matrices disponibles más comunes son: Matriz dispersa (AIJ): MPIAIJ (paralela), SEQAIJ (secuencial). Matriz dispersa en bloque: MPIBAIJ, SEQBAIJ. Matriz dispersa en bloque simétrica: MPISBAIJ, SEQSBAIJ. Matriz diagonal en bloque: MPIBDIAG, SEQBDIAG. Matriz densa: MPIDENSE, SEQDENSE. Matriz libre. Etcétera. La razón de que haya tantos tipos de matrices distintos, se debe a que ninguna estructura de datos general es apropiada para todos los tipos de problemas. Comentar que los formatos de matrices en bloque y diagonales proporcionan beneficios de rendimiento significantes. Además, aparte de la gran selección de formatos de matrices que proporciona PETSc, decir también que es relativamente fácil extender la librería añadiendo nuevas estructuras de datos (aunque esto aquí no lo veremos). En el caso de matrices paralelas, al igual que ocurría con vectores, cada proceso aporta su parte de la nueva matriz MPI que se creará. PETSc particiona las matrices por filas no por 88

26 columnas, esto es, cada proceso aporta una submatriz de un número cualquier de filas y de N columnas. Todos los procesos tienen las mismas columnas (partición por filas). Esto se aclara en la figura 30. La suma de las filas de cada proceso dará lugar a la dimensión (primera) global de la matriz total. La segunda dimensión es N. La descomposición en filas consecutivas a través de los procesos, en el caso de matrices dispersas (AIJ), es un procedimiento sencillo, y resulta más fácil trabajar con otros códigos de otras aplicaciones. Supongamos por un momento, que no queremos descomponer nuestra matriz en conjunto de filas, sino en otro tipo de conjunto, por ejemplo, por grupos de columnas. Por otro lado, sabemos que PETSc siempre descompone en conjunto de filas. La pregunta es cómo hacer lo primero teniendo en cuenta lo segundo. Y la respuesta se puede obtener fácilmente si recordamos el paquete de objetos AO que proporciona PETSc. Estos objetos se encargan de mapear entre la ordenación de aplicación y la de PETSc. Si ordenamos los índices de la matriz de nuestra aplicación por columnas, y mapeamos a los índices que utiliza PETSc (ordenados por filas), tendremos resuelto el problema. Todo esto está muy bien si lo que buscamos es dividir nuestra matriz por columnas (no es dividir, es simplemente una vista de la matriz, como si estuviera descompuesta por columnas), porque así lo requiera nuestro problema. Sin embargo, esto presenta claros problemas de eficiencia, debido a que PETSc distribuye a través de los procesos los grupos de filas y, si ahora ordenamos por columnas, cada columna estará distribuida a través de todos los procesos, no son locales a los mismos. De modo que, al realizar cualquier cálculo local con una columna, sería necesario realizar varias operaciones de comunicación desde todos los procesos al proceso local para obtener la columna completa. Esto disminuye en gran medida el rendimiento, por eso no es aconsejable en absoluto. Figura 30. Contribución de 3 procesos para formar una matriz paralela. Con la llamada a MatSetSizes, se especifican las dimensiones globales y locales de la matriz, esto es, cada proceso será poseedor de una parte de la matriz global, y cada parte de cada proceso tendrá sus propias dimensiones, cuyas sumas correspondientes serán las dimensiones de la matriz global. En general, el usuario especifica las dimensiones locales o las globales, no ambas. Esto hace que PETSc sea la que decida las dimensiones no especificadas por el usuario, de modo que sea la librería la que controle el alojamiento de espacio en memoria para la matriz. Esto se verá posteriormente con más detalle. MatGetOwnershipRange se encarga de devolver las filas que pertenecen al proceso que llama a dicha rutina. Una vez creada la matriz, tiene lugar la fase de inserción de valores, la cual se lleva a cabo mediante la rutina MatSetValues, accediendo a las posiciones de la matriz mediante una indexación global. Esta rutina inserta (INSERT_VALUES) o añade (ADD_VALUES) en la matriz un bloque de valores de dimensiones m x n. Ya se apuntó en su momento, que PETSc estaba escrita en C. Esto hace que, aunque escribamos código en Fortran, los índices para acceder a las filas y a las columnas de la matriz global empiezan por cero, que es la convención que sigue el lenguaje C (en Fortran empiezan por uno). Por otro lado, a la rutina indicada, se le pasa un array bidimensional que contiene los valores a insertar. Dicha rutina 89

27 trata el array como si los valores estuvieran almacenados por filas (convención de C, opuesta al almacenamiento por columnas que utiliza Fortran); esto es, al insertar un valor en la posición (i,j), el elemento a obtener del array se encontrará en la posición [i * n + j], siendo n el número de columnas del bloque de valores a insertar. No obstante, es posible indicarle a la rutina que los valores del array están almacenados por columnas a través de la rutina MatSetOption. Además, con esta rutina se puede especificar también si la matriz es simétrica, hermítica, etc. Hay algunos formatos de matriz que almacenan los valores por bloques. En estos casos, es más eficiente llamar a la rutina MatSetValuesBlocked que a MatSetValues. Esto último da lugar a la siguiente afirmación: una matriz es definida por su interfaz (las operaciones que se pueden realizar sobre ella), no por su estructura de datos. Si nos acordamos de la fase que venía a continuación al trabajar con vectores, veremos que es la misma que viene ahora al trabajar con matrices: fase de ensamblado. Esta etapa es necesaria para colocar en sus lugares correspondientes los valores no locales a los procesos, ya que estos últimos pueden insertar valores en cualquier posición de la matriz global (aunque, por razones de eficiencia, se aconseja que cada proceso genere valores para las posiciones locales al mismo). Las rutinas de ensamblado pertinentes son MatAssemblyBegin y MatAssemblyEnd. De nuevo, es posible realizar operaciones de computación en medio de las dos llamadas a las rutinas anteriores, de modo que podamos aumentar el rendimiento de nuestra aplicación. Como en el caso de vectores, no se pueden mezclar fases de inserción y adición de valores sin intercalar rutinas de ensamblado. Ante este escenario, PETSc permite en la fase de ensamblado final, pasar un argumento a las rutinas anteriores denominado MAT_FINAL_ASSEMBLY y, durante las fases de ensamblado intermedias, un argumento llamado MAT_FLUSH_ASSEMBLY. Con esto se evita que se realicen ciertas operaciones del ensamblado total que se realiza en la fase final. Respecto a lo anterior, decir que para las matrices dispersas, las filas son comprimidas una vez terminada la fase de ensamblado final. A partir de este momento se pueden realizar operaciones de multiplicación, transposición, etc., con las matrices. Una operación que no es aconsejable, es insertar valores una vez terminada la fase final de ensamblado, ya que esto requiere copias de valores y, posiblemente, alojamiento adicional de memoria (sólo almacenan los valores distintos de cero). No obstante, puede que nuestro problema necesite cambiar valores y, por tanto, requiera varias fases de ensamblado. En esta situación, si nuestra matriz mantiene las mismas posiciones de valores distintos de cero, es posible llamar a la rutina MatSetOption con el valor MAT_NO_NEW_NONZERO_LOCATIONS. Así, se reutiliza la estructura de datos, con el fin de aumentar la eficiencia de nuestra aplicación. A esta última rutina, hay que invocarla después del ensamblado completo de la primera matriz. En la introducción a esta sección, se expuso que los dos formatos principales de matrices que suministra PETSc son la matriz densa y la matriz de fila dispersa comprimida (o matriz AIJ). En los dos siguientes apartados, veremos ambos tipos por separado MATRICES DISPERSAS. Las matrices dispersas (sparse), también llamadas matrices AIJ o CSR (fila dispersa comprimida), son el tipo de matriz que utiliza PETSc por defecto en sus códigos de aplicación. También es el tipo de matriz que se ha utilizado en las pruebas realizadas en el proyecto presente. 90

28 En este tipo de matrices, PETSc almacena los elementos distintos de cero por filas, junto con un array indicando las posiciones (columnas) donde se encuentran los elementos dentro de una fila, así como un array de indicadores que apunten al comienzo de cada fila de la matriz. La técnica utilizada, cuando es posible, para almacenar las matrices AIJ, tanto secuenciales como paralelas, es la de nodos-i (nodos idénticos). Este método se basa en asignar un número de nodo a cada fila de la matriz, y se almacenan sólo aquellas filas (nodos) que sean distintas a las demás. Filas idénticas tendrán el mismo número de nodo, pero sólo uno de ellos se alojará en memoria. NOTA: En alguna ocasión, se ha comentado ya que Fortran utiliza la convención de indexar los arrays empezando por 1, mientras que C empieza por 0, que es la opción por defecto utilizada por PETSc (ya que la librería está escrita en C). Cada vez que se llama a una rutina PETSc, es inevitable utilizar la indexación empezando por 0. Sin embargo, hay veces que interesa utilizar paquetes externos a PETSc escritos en Fortran, y que utilizan la indexación comenzando por 1. Para tales situaciones, PETSc permite indicar por línea de comandos con la opción mat_aij_oneindex, que las rutinas que no son de PETSc utilizan indexación basada en 1 para acceder a las matrices creadas por la librería paralela. Al igual que en el caso de vectores, las matrices pueden ser secuenciales o paralelas. Veamos por separado ambos tipos, de los que se pueden esperar algunas características ya vistas en el tema de vectores; sin embargo, otras peculiaridades que se verán son propias de los objetos de tipo matriz. MATRICES AIJ SECUENCIALES. La rutina encargada de crear una matriz AIJ secuencial es MatCreateSeqAIJ. Esta rutina equivale a llamar a las rutinas MatCreate, MatSetFromOptions (o MatSetType ) y MatSetSizes en conjunto y en este orden. A esta rutina se le puede especificar el número de elementos distintos de cero en cada fila de la matriz. Esto es una forma de realizar el prealojamiento de espacio en memoria para la matriz. PETSc también permite no especificar este argumento que indica los elementos no ceros, lo que implica que sea la librería la que realice el prealojamiento de espacio. Sin embargo, realizar prealojamiento dinámico de memoria, disminuye enormemente la eficiencia del programa, de modo que ha de ser el usuario quien realice semejante operación en grandes problemas de computación. Como se acaba de comentar, PETSc permite especificar los elementos distintos de cero de la matriz. Para tal fin, la librería permite indicar los elementos no ceros para todas las filas (si todas tienen prácticamente el mismo número de no ceros) mediante un escalar o, por el contrario, pasar a la rutina un array de dimensión igual al número de filas de la matriz, que contenga los elementos no ceros para cada fila, aproximadamente. En ambos casos, cuanto más exactos seamos en la aproximación, menor número de prealojamientos dinámicos tendrá que hacer la librería y, en consecuencia, mayor rendimiento tendrá nuestra aplicación. Si a priori no se conocen los elementos distintos de cero de la matriz, es usual realizar un pequeño trozo de código antes del prealojamiento de espacio de la matriz, para computar el número de elementos no cero. Esto requerirá una sobrecarga adicional, pero ni mucho menos 91

29 comparable a la necesaria en el caso de no realizar el prealojamiento por parte del usuario, dejando a la librería que sea la que lo realice de forma dinámica. Esta es la forma más eficiente de trabajar en aquellos casos en que nos dan una matriz, por ejemplo la correspondiente a una estructura, y hemos de realizar el prealojamiento de espacio en memoria para nuestra aplicación. Una vez creada la matriz y realizado el prealojamiento de memoria (ambas fases se realizan mediante la misma subrutina), se insertan valores en las correspondientes posiciones (estos valores pueden ser generados por nuestra aplicación o recogidos de entidades externas, como puede ser un fichero). Tras la inserción de valores, se lleva a cabo la fase de ensamblado, explicada en la introducción del apartado de matrices. MATRICES AIJ PARALELAS. MatCreateMPIAIJ es la rutina proporcionada por PETSc para crear una matriz dispersa paralela. En este momento se requiere un poco de atención adicional, pues siempre los temas de objetos paralelos son un poco más complejos de entender. En el caso de vectores, vimos que dichos objetos eran distribuidos a través de todos los procesos que intervenían en el proceso de computación paralela, cada proceso poseía una parte del vector. El número de filas (componentes) del vector que pertenecían a un proceso las podía especificar el usuario o, por el contrario, podía ser PETSc la que las repartiera de una forma más o menos equitativa entre los procesos. Ahora, en el caso de las matrices, ocurre algo similar, sólo que en dos dimensiones en vez de en una. Esto complica un poco el esquema (mental) que previamente ha de realizarse antes de nada. Partimos de que PETSc distribuye las matrices por filas a través de los procesos, y esto es algo inamovible. Lo que sí puede indicar el usuario es el número de filas que pertenecen a un proceso particular. Y esta es la base de todo, aunque se puede exprimir bastante. Pensemos que, en general, uno de los fines de nuestra aplicación será obtener el resultado de una matriz por un vector (el caso de matriz por matriz es fácilmente extensible), o la solución del sistema Ax=b. En cualquier caso, aparece una multiplicación de una matriz A por un vector x. La segunda dimensión global de la matriz A (número de columnas) ha de ser idéntica a la dimensión global del vector x. Respecto a esto, existe un problema, que la matriz y el vector se encuentran distribuidos a través del conjunto de procesadores implicados en la aplicación paralela. En este sentido, hemos de tener en cuenta que la segunda dimensión local de la matriz (número de columnas locales) a de ser idéntica a la dimensión local del vector x en cada proceso. Así mismo, en cada proceso, la primera dimensión local de la matriz (número de filas locales) ha de ser la misma que la dimensión local del vector solución b. La rutina MatCreateMPIAIJ permite que se le indiquen las dimensiones locales y globales de la matriz a crear. PETSc da la opción de que sea la misma librería la que especifique la dimensión global o la local (no ambas). La forma de hacerlo es dando el valor PETSC_DECIDE a los argumentos de la dimensiones en cuestión (globales o locales). La dimensión que no especifique PETSc ha de indicarla obligatoriamente el usuario (el usuario también puede especificar las dos, aunque ha de tener en cuenta la coherencia que ha de tener lugar entre las dimensiones globales y la suma de las dimensiones locales de cada proceso). Si el valor PETSC_DECIDE no se utiliza para las dimensiones locales, el programador ha de 92

30 tener en cuenta la discusión anterior sobre la compatibilidad de las dimensiones locales con las dimensiones de la matriz A y de los vectores x y b. Un tema importante a tratar, es el asunto del prealojamiento de espacio en memoria para la matriz paralela. El caso ahora es distinto al de matrices secuenciales. Primeramente, empecemos definiendo el concepto de submatriz diagonal de un proceso. Sabemos que la matriz se distribuye por grupos de filas a través de los procesos que intervendrán en la ejecución de la aplicación paralela. El número de filas que pertenecen a un proceso, es la dimensión principal de la submatriz local; de modo que la matriz global es la unión de las submatrices almacenadas en cada proceso (todas las submatrices tendrán, lógicamente, el mismo número de columnas, pues la matriz se distribuye por filas completas). En este supuesto, la submatriz diagonal de un proceso es la correspondiente a la parte de la submatriz total, almacenada en dicho proceso, que es cuadrada (misma dimensión principal y secundaria) y, además, dicho bloque se encuentra en la diagonal de la matriz global. Para aclarar todo esto se presenta la figura 31. Figura 31. Distribución de una matriz paralela a lo largo de los procesos en grupos de filas. Concepto de submatriz diagonal y offset en cada proceso. La submatriz offset es la parte de la submatriz local, perteneciente a un proceso, que no pertenece a la submatriz diagonal. Si existen varios bloques offset, la submatriz offset total es la unión de estos bloques. La figura 31 es, de nuevo, bastante aclaratoria. Una vez definido lo que es la submatriz diagonal y offset de un proceso, podemos abordar el asunto del prealojamiento de memoria para matrices AIJ paralelas. La forma de realizar el prealojamiento es indicando a la rutina MatCreateMPIAIJ el número de elementos distintos de cero de la submatriz diagonal y de la submatriz offset, por separado. Al igual que en el caso de matrices AIJ secuenciales, ahora también se le puede indicar a la rutina en cuestión, el número de no ceros para todas las filas (mediante un escalar) o el número de no ceros para cada fila (mediante un array). La única diferencia es que aquí habrá dos escalares o dos arrays, uno para la submatriz diagonal y otro para la submatriz offset, ambas locales al proceso. Si se especifica el número de no ceros de alguna submatriz mediante un array, se 93

4.1. INTRODUCCIÓN. 102

4.1. INTRODUCCIÓN. 102 4. PRUEBAS. 101 4.1. INTRODUCCIÓN. En este capítulo se presentan dos secciones claramente diferenciadas. La primera es una descripción breve de algunos de los ficheros de ejemplo de vectores y matrices,

Más detalles

Lógica: Algoritmo: Archivo: Base de datos: Bit:

Lógica: Algoritmo: Archivo: Base de datos: Bit: Lógica: Algoritmo: Archivo: Base de datos: Bit: 1 LÓGICA: Es una secuencia de operaciones realizadas por el hardware o por el software. Lógica del hardware, Son los circuitos y Chips que realizan las operaciones

Más detalles

TEMA 7. ARRAYS (LISTAS Y TABLAS).

TEMA 7. ARRAYS (LISTAS Y TABLAS). TEMA 7. ARRAYS (LISTAS Y TABLAS). En capítulos anteriores se han descrito las características de los tipos de datos básicos o simples (carácter, entero y coma flotante). Asimismo, se ha aprendido a definir

Más detalles

Metodología y Tecnología de la Programación. I.T. Informática de Gestión

Metodología y Tecnología de la Programación. I.T. Informática de Gestión ESCUELA POLITÉCNICA SUPERIOR DE CÓRDOBA PROGRAMAS, MÉTODOS Y CRITERIOS DE EVALUACIÓN A APLICAR DURANTE EL PROCESO DE EXTINCIÓN DEL PLAN 1999 Metodología y Tecnología de la Programación I.T. Informática

Más detalles

ANÁLISIS SEMÁNTICO LA TABLA DE SÍMBOLOS

ANÁLISIS SEMÁNTICO LA TABLA DE SÍMBOLOS Todos los derechos de propiedad intelectual de esta obra pertenecen en exclusiva a la Universidad Europea de Madrid, S.L.U. Queda terminantemente prohibida la reproducción, puesta a disposición del público

Más detalles

Tema 2 Conceptos básicos de programación. Fundamentos de Informática

Tema 2 Conceptos básicos de programación. Fundamentos de Informática Tema 2 Conceptos básicos de programación Fundamentos de Informática Índice Metodología de la programación Programación estructurada 2 Pasos a seguir para el desarrollo de un programa (fases): Análisis

Más detalles

CAPÍTULO 3 ESTRUCTURAS DE DATOS ESTÁTICAS

CAPÍTULO 3 ESTRUCTURAS DE DATOS ESTÁTICAS CAPÍTULO 3 ESTRUCTURAS DE DATOS ESTÁTICAS Capítulo 3 Estructuras de datos estáticas 1/37 1. INTRODUCCIÓN Las estructuras de datos se utilizan, generalmente, para procesar una colección de valores que están

Más detalles

PROGRAMACIÓN PARALELA. Modelos de programación paralela Paradigmas de programación paralela

PROGRAMACIÓN PARALELA. Modelos de programación paralela Paradigmas de programación paralela PROGRAMACIÓN PARALELA Modelos de programación paralela Paradigmas de programación paralela Tipos de paralelismo Paso de mensajes Paralelismo de datos Memoria compartida Paradigmas de programación paralela

Más detalles

Evolución del software y su situación actual

Evolución del software y su situación actual Evolución del software y su situación actual El software es el conjunto de programas que permite emplear la PC, es decir, es el medio de comunicación con la computadora, el control de sus funciones y su

Más detalles

Programación Orientada a Objetos

Programación Orientada a Objetos Programación Orientada a Objetos PROGRAMACIÓN ORIENTADA A OBJETOS 1 Sesión No. 8 Nombre: El Modelo de diseño con UML Contextualización Los modelos que podemos crear con UML son varios, por lo que debemos

Más detalles

Índice general 7. Presentación 15

Índice general 7. Presentación 15 ÍNDICE GENERAL Índice general 7 Presentación 15 1. Introducción 19 1.1. Antecedentes históricos de la computación................... 19 1.2. Definiciones previas............................... 24 1.3.

Más detalles

El fichero <X11/X.h> se incluye cuando se utiliza el <X11/Xlib.h>, por tanto, cuando este último sea incluido, el primero no es necesario hacerlo.

El fichero <X11/X.h> se incluye cuando se utiliza el <X11/Xlib.h>, por tanto, cuando este último sea incluido, el primero no es necesario hacerlo. PRÁCTICAS DE ENTORNOS DE USUARIO Parte II: Programación en X-Window Ficheros cabecera Al realizar un programa X-Window, se han de incluir los siguientes ficheros cabecera, además de los ficheros cabecera

Más detalles

FICHEROS Y BASES DE DATOS (E44) 3º INGENIERÍA EN INFORMÁTICA. Tema 4. Técnicas de Dispersión. Definición y Manejo.

FICHEROS Y BASES DE DATOS (E44) 3º INGENIERÍA EN INFORMÁTICA. Tema 4. Técnicas de Dispersión. Definición y Manejo. FICHEROS Y BASES DE DATOS (E44) 3º INGENIERÍA EN INFORMÁTICA Tema 4. Técnicas de Dispersión. Definición y Manejo. 1.- Introducción. 2.- Funciones de Dispersión. 3.- Saturación Progresiva. 4.- Empaquetado

Más detalles

Algoritmo. Programa. Lenguaje algorítmico

Algoritmo. Programa. Lenguaje algorítmico ESCUELA DE EDUCACION SECUNDARIA TECNICA N 3 LENGUAJE ELECTRONICO PROFESOR: PAOLO, MARCOS GERMAN TEMA: ALGORITMOS Algoritmo Es un conjunto prescrito de instrucciones o reglas bien definidas, ordenadas y

Más detalles

Programación Orientada a Objetos. Sesión 6: El Elemento adicional del lenguaje orientado a objetos

Programación Orientada a Objetos. Sesión 6: El Elemento adicional del lenguaje orientado a objetos Programación Orientada a Objetos Sesión 6: El Elemento adicional del lenguaje orientado a objetos Contextualización Los lenguajes de programación siempre cuentan con elementos adicionales que pueden funcionar

Más detalles

Programación en Entornos Paralelos: MPI

Programación en Entornos Paralelos: MPI 1-11 Marzo de 2017 FACET -UNT Programación en Entornos Paralelos: MPI Graciela Molina mgracielamolina@gmailcom TRADICIONALMENTE Procesamiento secuencial 2 TRADICIONALMENTE Procesamiento secuencial Si ya

Más detalles

USO DE MAKE CON CLIP

USO DE MAKE CON CLIP USO DE MAKE CON CLIP SACL a882sacl@yahoo.com.ar Grupo Clip clip-castellano@gruposyahoo.com.ar Versión 0.1-12/06/2005 Revisiones: INTRODUCCION Como ya sabemos, compilar un prg no presenta ningún problema

Más detalles

Funciones Definición de función

Funciones Definición de función Funciones Definición de función Una función es un bloque de código que realiza una tarea específica. Una función es una porción de programa, identificable mediante un nombre, que realiza determinadas tareas

Más detalles

TAREA 1. INTRODUCCIÓN A LOS SISTEMAS OPERATIVOS.

TAREA 1. INTRODUCCIÓN A LOS SISTEMAS OPERATIVOS. 1 TAREA 1. INTRODUCCIÓN A LOS SISTEMAS OPERATIVOS. 1- Cuáles son las principales funciones de un sistema operativo? Los Sistemas Operativos tienen como objetivos o funciones principales lo siguiente; Comodidad;

Más detalles

La última versión disponible cuando se redactó este manual era la 5 Beta (versión ), y sobre ella versa este manual.

La última versión disponible cuando se redactó este manual era la 5 Beta (versión ), y sobre ella versa este manual. Manual de Dev-C++ 4.9.9.2 Página 1 de 11 Introducción Dev-C++ es un IDE (entorno de desarrollo integrado) que facilita herramientas para la creación y depuración de programas en C y en C++. Además, la

Más detalles

Estructuras dinámicas lineales (i)

Estructuras dinámicas lineales (i) Estructuras dinámicas lineales (i) Introducción En la lección anterior se explicaron los conceptos de dinámicas y puntero; vimos la forma en que se implementan dichas tanto en la notación algorítmica como

Más detalles

Unidad V. Ya veremos qué poner en "algunas_palabras" y "algo_más", por ahora sigamos un poco más.

Unidad V. Ya veremos qué poner en algunas_palabras y algo_más, por ahora sigamos un poco más. Implementación Orientada a Objetos. Unidad V 5.1 Estructura de una clase. Una clase consiste en: algunas_palabras class nombre_de_la_clase [algo_más] { [lista_de_atributos] [lista_de_métodos] Lo que está

Más detalles

Sistema electrónico digital (binario) que procesa datos siguiendo unas instrucciones almacenadas en su memoria

Sistema electrónico digital (binario) que procesa datos siguiendo unas instrucciones almacenadas en su memoria 1.2. Jerarquía de niveles de un computador Qué es un computador? Sistema electrónico digital (binario) que procesa datos siguiendo unas instrucciones almacenadas en su memoria Es un sistema tan complejo

Más detalles

UNIDAD I. Universidad del Zulia Costa Oriental del Lago. Conceptos Básicos

UNIDAD I. Universidad del Zulia Costa Oriental del Lago. Conceptos Básicos Costa Oriental del Lago UNIDAD I Conceptos Básicos Comandos internos y externos. Estructura básicas: entidad, atributo, base de datos, clave primaria y secundaria, registro y archivo de datos empresas

Más detalles

Cristian Blanco

Cristian Blanco UNIDAD DIDÁCTICA 8. ANÁLISIS Y DISEÑO ORIENTADO A OBJETOS. DIAGRAMAS DE COMPORTAMIENTO En el siguiente enlace tienes una descripción y algunos ejemplos de todos los diagramas UML.: http://jms32.eresmas.net/tacticos/uml/umlindex.html

Más detalles

Semana Lenguajes 7de programación Tipos de lenguajes de programación

Semana Lenguajes 7de programación Tipos de lenguajes de programación Semana Lenguajes 7de programación Semana 6 Empecemos! Estimados participantes, bienvenidos a esta nueva semana, en la que estudiaremos los lenguajes de programación más utilizados. No olvides repasar los

Más detalles

Una función es un miniprograma dentro de un programa. Las funciones contienen varias

Una función es un miniprograma dentro de un programa. Las funciones contienen varias TEMA 6. FUNCIONES. Una función es un miniprograma dentro de un programa. Las funciones contienen varias sentencias bajo un solo nombre, que un programa puede utilizar una o más veces para ejecutar dichas

Más detalles

FUNCIONES JAVASCRIPT. CONCEPTO. PARÁMETROS O ARGUMENTOS Y TIPOS. PASO POR VALOR. RETURN. EJEMPLOS. (CU01122E)

FUNCIONES JAVASCRIPT. CONCEPTO. PARÁMETROS O ARGUMENTOS Y TIPOS. PASO POR VALOR. RETURN. EJEMPLOS. (CU01122E) APRENDERAPROGRAMAR.COM FUNCIONES JAVASCRIPT. CONCEPTO. PARÁMETROS O ARGUMENTOS Y TIPOS. PASO POR VALOR. RETURN. EJEMPLOS. (CU01122E) Sección: Cursos Categoría: Tutorial básico del programador web: JavaScript

Más detalles

Capítulo 3. Introducción a la programación. Continuar

Capítulo 3. Introducción a la programación. Continuar Capítulo 3 Introducción a la programación Continuar Introducción Java es un lenguaje que tiene muchas ventajas frente a otros lenguajes de programación: es open source (código abierto), esto permite ver

Más detalles

DOMÓTICA: PROTOCOLO UPNP Y HOGAR DIGITAL V. HERRAMIENTAS INTEL PARA EL USO Y DESARROLLO DE LA TECNOLOGÍA UPNP

DOMÓTICA: PROTOCOLO UPNP Y HOGAR DIGITAL V. HERRAMIENTAS INTEL PARA EL USO Y DESARROLLO DE LA TECNOLOGÍA UPNP V. HERRAMIENTAS INTEL PARA EL USO Y DESARROLLO DE LA TECNOLOGÍA UPNP Desde 1999, la empresa Intel Corporation trabaja con la tecnología UPnP con la finalidad de conseguir llevar a cabo un entorno de red

Más detalles

roducción a la programación con el lenguaje C usando el entorno de trabajo Dev-C. Nociones básicas de programación

roducción a la programación con el lenguaje C usando el entorno de trabajo Dev-C. Nociones básicas de programación There are no translations available. Introducción a la programación con el lenguaje C usando el entorno de trabajo Dev-C. roducción a la programación con el lenguaje C usando el entorno de trabajo Dev-C.

Más detalles

Mapeo de datos adquiridos en variables de MATLAB

Mapeo de datos adquiridos en variables de MATLAB Mapeo de datos adquiridos en variables de MATLAB María del Mar Sanz Lluch Borja Bordel Sánchez Marina Pérez Jiménez MATLAB aplicado a la instrumentación electrónica Departamento de Electrónica Física (UPM)

Más detalles

Tema 2 Introducción a la Programación en C.

Tema 2 Introducción a la Programación en C. Tema 2 Introducción a la Programación en C. Contenidos 1. Conceptos Básicos 1.1 Definiciones. 1.2 El Proceso de Desarrollo de Software. 2. Lenguajes de Programación. 2.1 Definición y Tipos de Lenguajes

Más detalles

Programación MODULAR: Subalgoritmos - funciones y procedimientos

Programación MODULAR: Subalgoritmos - funciones y procedimientos Programación MODULAR: Subalgoritmos - funciones y procedimientos Uno de los métodos fundamentales para resolver un problema es dividirlo en problemas más pequeños, llamados subproblemas. Estos problemas

Más detalles

Como utilizar MODULES en Fortran 90

Como utilizar MODULES en Fortran 90 Como utilizar MODULES en Fortran 90 Seminario de computación 2009 Qué es un MODULE? Los modules son una forma eficiente de intercambiar información entre diferentes programas y subprogramas. También permiten

Más detalles

Como utilizar MODULES en Fortran 90. Seminario de computación 2009

Como utilizar MODULES en Fortran 90. Seminario de computación 2009 Como utilizar MODULES en Fortran 90 Seminario de computación 2009 Qué es un MODULE? Los modules son una forma eficiente de intercambiar información entre diferentes programas y subprogramas. También permiten

Más detalles

CAPÍTULO 5 DESARROLLO DEL SISTEMA

CAPÍTULO 5 DESARROLLO DEL SISTEMA DESARROLLO DEL SISTEMA CAPÍTULO 5 DESARROLLO DEL SISTEMA 5.1 IMPLEMENTACIÓN DE BASE DE DATOS La implementación de la base de datos se realizó usando el manejador de Bases de datos Microsoft SQL Server

Más detalles

TEMA 3: El proceso de compilación, del código fuente al código máquina

TEMA 3: El proceso de compilación, del código fuente al código máquina TEMA 3: El proceso de compilación, del código fuente al código máquina 3.1 Fase de compilación y linkado (link, montado o enlace) Un programa escrito en un lenguaje de alto nivel, no puede ser ejecutado

Más detalles

1 Introducción a los algoritmos y a la programación de computadoras... 1

1 Introducción a los algoritmos y a la programación de computadoras... 1 Contenido - IX Contenido 1 Introducción a los algoritmos y a la programación de computadoras... 1 1.1 Introducción... 2 1.2 Concepto de algoritmo... 2 1.2.1 Definición de algoritmo y problema... 2 1.2.2

Más detalles

JavaScript Avanzado (I)

JavaScript Avanzado (I) Programación Web Tema 3.3 Java Script Avanzado Miguel Ángel Manso Emerson Castañeda Ramón Alcarria ETSI en Topografía, Geodesia y Cartografía - UPM JavaScript Avanzado (I) Conceptos sobre Objetos En JavaScript

Más detalles

Herramientas para el estudio de prestaciones en clusters de computación científica, aplicación en el Laboratorio de Computación Paralela

Herramientas para el estudio de prestaciones en clusters de computación científica, aplicación en el Laboratorio de Computación Paralela Introducción Herramientas Estudio Conclusiones Herramientas para el estudio de prestaciones en clusters de computación científica, aplicación en el Laboratorio de Computación Paralela Ingeniería en Informática

Más detalles

INTRODUCCIÓN A LA POO EN C++

INTRODUCCIÓN A LA POO EN C++ INTRODUCCIÓN A LA POO EN C++ ÍNDICE DEL TEMA 1.- Introducción 2.- Diferencias C/C++ 3.- Programación orientada a objetos 4.- Aspectos avanzados C++ 1 1. Introducción Lenguaje C Lenguaje de propósito general

Más detalles

Arreglos Estructura (struct)

Arreglos Estructura (struct) Universidad Rafael Urdaneta Escuela de Ingeniería de Computación Arreglos Estructura (struct) MSc Jaime Soto Una estructura de datos es una colección de datos que pueden ser caracterizados por su organización

Más detalles

Diseño de compiladores. Organización de memoria. Organización de memoria. Organización de memoria. Zona de código 04/05/2014 ORGANIZACIÓN DE MEMORIA

Diseño de compiladores. Organización de memoria. Organización de memoria. Organización de memoria. Zona de código 04/05/2014 ORGANIZACIÓN DE MEMORIA Diseño de compiladores Gestión de la memoria / Generación de código ORGANIZACIÓN DE MEMORIA Organización de memoria Depende del tipo de lenguaje (declarativos, imperativos), del compilador y del sistema

Más detalles

SISTEMAS PARALELOS Y DISTRIBUIDOS. 3º GIC. PRÁCTICA 9 Departamento de Arquitectura y Tecnología de Computadores Universidad de Sevilla

SISTEMAS PARALELOS Y DISTRIBUIDOS. 3º GIC. PRÁCTICA 9 Departamento de Arquitectura y Tecnología de Computadores Universidad de Sevilla SISTEMAS PARALELOS Y DISTRIBUIDOS. 3º GIC. PRÁCTICA 9 Departamento de Arquitectura y Tecnología de Computadores Universidad de Sevilla PROGRAMACIÓN DE COMPUTADORES DE MEMORIA DISTRIBUIDA USANDO MPI. PREPARACIÓN

Más detalles

Práctica 1 Parte 2: Masa-Muelle y ODEs (Bloque OPCIONAL) (Asignación 19 de Febrero; Entrega 25 de Febrero a las 23:59)

Práctica 1 Parte 2: Masa-Muelle y ODEs (Bloque OPCIONAL) (Asignación 19 de Febrero; Entrega 25 de Febrero a las 23:59) Práctica 1 Parte 2: Masa-Muelle y ODEs (Bloque OPCIONAL) (Asignación 19 de Febrero; Entrega 25 de Febrero a las 23:59) Cómo entregar la práctica? Enviar una copia de los ficheros ExercisePoint.cpp y ExerciseSpring.cpp

Más detalles

Message Passing Interface (MPI)

Message Passing Interface (MPI) Message Passing Interface (MPI) INTRODUCCIÓN MPI (Message Passing Interface) como es un interfaz estandarizada para la realización de aplicaciones paralelas basadas en pasaje de mensajes. El modelo de

Más detalles

UD2 Instalación y uso de

UD2 Instalación y uso de UD2 Instalación y uso de entornos de desarrollo Índice 1. Entornos de desarrollo 1.1. Introducción 1.2. Componentes 2. Instalación de entornos de desarrollo 2.1. Programación 2.2. Bases de datos 2.3. Otros

Más detalles

Programación Orientada a Objetos en C++

Programación Orientada a Objetos en C++ Unidad I Programación Orientada a Objetos en C++ Programación Orientada a Objetos en C++ Programación I - 0416202 Contenido Esta lección abarca los siguientes temas: Estructura y declaración de una clase

Más detalles

Análisis y escritura de las estructuras de control

Análisis y escritura de las estructuras de control Análisis y escritura de las estructuras de control por Iván Cruz En esta lectura se abordarán las estructuras de control del lenguaje de programación C, estas estructuras. Permiten al programador comunicarse

Más detalles

Introducción a Java. Dr. (c) Noé Alejandro Castro Sánchez

Introducción a Java. Dr. (c) Noé Alejandro Castro Sánchez Introducción a Java Dr. (c) Noé Alejandro Castro Sánchez Programas Java Applets Pueden correr en navegadores Web Agregan funcionalidad a páginas Web Se llega a restringir su funcionalidad (e. g., no pueden:

Más detalles

TEMA 8. ESTRUCTURAS Y UNIONES.

TEMA 8. ESTRUCTURAS Y UNIONES. TEMA 8. ESTRUCTURAS Y UNIONES. Este capítulo examina estructuras, uniones, enumeraciones y s definidos por el usuario que permite a un programador crear nuevos s de datos. La capacidad para crear nuevos

Más detalles

Procesadores de lenguaje Tema 5 Comprobación de tipos

Procesadores de lenguaje Tema 5 Comprobación de tipos Procesadores de lenguaje Tema 5 Comprobación de tipos Departamento de Ciencias de la Computación Universidad de Alcalá Resumen Sistemas de tipos. Expresiones de tipo. Equivalencia de tipos. Sobrecarga,

Más detalles

PARADIGMA y LENGUAJES DE PROGRAMACIÓN

PARADIGMA y LENGUAJES DE PROGRAMACIÓN CATEDRA CARRERA: PARADIGMA y LENGUAJES DE PROGRAMACIÓN LICENCIATURA EN SISTEMAS DE INFORMACION FACULTAD DE CIENCIAS EXACTAS QUIMICAS Y NATURALES UNIVERSIDAD NACIONAL DE MISIONES Año 2017 2do Cuatrimestre

Más detalles

Presentación de Open MPI

Presentación de Open MPI Presentación de Open MPI Qué es Open MPI? Se trata de una API de código abierto desarrollada para facilitar la programación paralela y/o distribuida que: Implementa el estándar MPI. Permite la distribución

Más detalles

FICHEROS Y BASES DE DATOS (E44) 3º INGENIERÍA EN INFORMÁTICA. Tema 3. Estructuras de Almacenamiento. Básicas. Definición y Manejo.

FICHEROS Y BASES DE DATOS (E44) 3º INGENIERÍA EN INFORMÁTICA. Tema 3. Estructuras de Almacenamiento. Básicas. Definición y Manejo. FICHEROS Y BASES DE DATOS (E44) 3º INGENIERÍA EN INFORMÁTICA Tema 3. Estructuras de Almacenamiento Básicas. Definición y Manejo. 1.- Búsqueda de Información. Definición de Clave. 2.- Definición y Manejo

Más detalles

Fundamentos de Informática 3. Construcción de Software

Fundamentos de Informática 3. Construcción de Software 2 Contenidos Fundamentos de Informática 3. Construcción de Software - Introducción - - - Diseño -Algoritmos -Diagramas de Flujo -Pseudocódigos - Codificación - Pruebas - Mantenimiento Fundamentos de Informática

Más detalles

FUNDACIÓN EDUCATIVA OBRERA FUNEDO TÉCNICO EN SECRETARIADO EJECUTIVO SISTEMATIZADO. Conceptos básicos de Access 2013

FUNDACIÓN EDUCATIVA OBRERA FUNEDO TÉCNICO EN SECRETARIADO EJECUTIVO SISTEMATIZADO. Conceptos básicos de Access 2013 Base de datos: Conceptos básicos de Access 2013 Una base de datos es un conjunto de datos que están organizados para un uso determinado y el conjunto de los programas que permiten gestionar estos datos

Más detalles

INTRODUCCIÓN A COMPILADORES Y LENGUAJES FORMALES FUNDAMENTOS DE COMPILADORES

INTRODUCCIÓN A COMPILADORES Y LENGUAJES FORMALES FUNDAMENTOS DE COMPILADORES Todos los derechos de propiedad intelectual de esta obra pertenecen en exclusiva a la Universidad Europea de Madrid, S.L.U. Queda terminantemente prohibida la reproducción, puesta a disposición del público

Más detalles

Introducción a Sistemas Operativos: Ficheros

Introducción a Sistemas Operativos: Ficheros Introducción a Sistemas Operativos: Ficheros Clips Fr ancisco J Ballesteros 1. Entrada/Salida Es importante saber cómo utilizar ficheros. En UNIX, es aún más importante dado que gran parte de los recursos,

Más detalles

Computación Aplicada. Universidad de Las Américas. Aula virtual de Computación Aplicada. Módulo de Excel 2013 LIBRO 6

Computación Aplicada. Universidad de Las Américas. Aula virtual de Computación Aplicada. Módulo de Excel 2013 LIBRO 6 Computación Aplicada Universidad de Las Américas Aula virtual de Computación Aplicada Módulo de Excel 2013 LIBRO 6 Contenido FORMA DE HACER CÁLCULOS... 3 QUÉ SON LAS FÓRMULAS Y QUÉ LAS FUNCIONES?... 4

Más detalles

Diagrama de despliegue

Diagrama de despliegue Diagrama de despliegue Definición.- Los Diagramas de Despliegue muestran las relaciones físicas de los distintos nodos que componen un sistema y el reparto de los componentes sobre dichos nodos. La vista

Más detalles

PROCEDIMIENTOS ALMACENADOS

PROCEDIMIENTOS ALMACENADOS Modelado de Base de Datos PROCEDIMIENTOS ALMACENADOS Universidad Politecnica de los Llanos Procedimiento Almacenado Un Procedimiento almacenado es un Objeto de Base de Datos que puede encapsular logica

Más detalles

Programación Orientada a Objetos

Programación Orientada a Objetos Programación Orientada a Objetos PROGRAMACIÓN ORIENTADA A OBJETOS 1 Sesión No. 6 Nombre: Elementos adicionales del lenguaje orientado a objetos Contextualización Los lenguajes de programación siempre cuentan

Más detalles

Entorno de Programación Visual C++ 6.0

Entorno de Programación Visual C++ 6.0 Entorno de Programación Visual C++ 6.0 Informática II Fundamentos de Programación 18 de Febrero de 2002 1 Visual C++ 6.0 Es un IDE (Entorno de desarrollo integrado). Tiene editor, compilador, enlazador,

Más detalles

INTRODUCCIÓN...9 CAPÍTULO 1. ELEMENTOS DE UN PROGRAMA INFORMÁTICO...11

INTRODUCCIÓN...9 CAPÍTULO 1. ELEMENTOS DE UN PROGRAMA INFORMÁTICO...11 Índice INTRODUCCIÓN...9 CAPÍTULO 1. ELEMENTOS DE UN PROGRAMA INFORMÁTICO...11 1.1 PROGRAMA Y LENGUAJESDE PROGRAMACIÓN...12 1.1.1 EL LENGUAJE JAVA...13 1.1.2 EL JDK...15 1.1.3 LOS PROGRAMAS EN JAVA...16

Más detalles

Microsoft Visual Studio está basado en.net framework. Definiciones de.net Framework:

Microsoft Visual Studio está basado en.net framework. Definiciones de.net Framework: 1) CONCEPTO La palabra "Visual" hace referencia al método que se utiliza para crear la interfaz gráfica de usuario (GUI). En lugar de escribir numerosas líneas de código para describir la apariencia y

Más detalles

Contenido: Nº Tema Imagen Descripción 1 Capas de la arquitectura de un ordenador

Contenido: Nº Tema Imagen Descripción 1 Capas de la arquitectura de un ordenador Contenido: 1. Capas de la arquitectura de un ordenador 2. Diagramas de flujo 3. Ciclo de vida del software 4. Compilado de programas y lincado de librerías 5. Interfaz gráfico de Scratch 1.4 6. Programando

Más detalles

LENGUAJE FORTRAN. FUNCIONES Y SUBRUTINAS

LENGUAJE FORTRAN. FUNCIONES Y SUBRUTINAS LENGUAJE FORTRAN. FUNCIONES Y SUBRUTINAS Programación en Fortran Valentín Moreno ÍNDICE 1. Subprogramas 2. Funciones 3. Subrutinas 2 3 1. SUBPROGRAMAS 1. SUBPROGRAMAS Si necesitamos usar con frecuencia

Más detalles

Es un conjunto de palabras y símbolos que permiten al usuario generar comandos e instrucciones para que la computadora los ejecute.

Es un conjunto de palabras y símbolos que permiten al usuario generar comandos e instrucciones para que la computadora los ejecute. Los problemas que se plantean en la vida diaria suelen ser resueltos mediante el uso de la capacidad intelectual y la habilidad manual del ser humano. La utilización de la computadora en la resolución

Más detalles

ALGORITMOS Y PROGRAMACIÓN I Unidad 3

ALGORITMOS Y PROGRAMACIÓN I Unidad 3 ALGORITMOS Y PROGRAMACIÓN I Unidad 3 Tipos de Datos Estructurados Prof. Jaime Soto Sección (007) Material original de Prof. AURELY LEAL Introducción a las Estructuras de Datos Una estructura de datos es

Más detalles

Capítulo 3. Subprogramas. 3.1 Subprogramas FUNCTION

Capítulo 3. Subprogramas. 3.1 Subprogramas FUNCTION Capítulo 3 Subprogramas Con lo explicado hasta aquí se pueden escribir programas sencillos y no demasiado largos. Pero varias razones justifican la necesidad de disponer de otro tipo de recursos. Por una

Más detalles

Paralelismo _Arquitectura de Computadoras IS603

Paralelismo _Arquitectura de Computadoras IS603 Paralelismo _Arquitectura de Computadoras IS603 INTRODUCCION El objetivo de esta investigación, es conceptualizar las diferentes tipos de paralelismo referente al área de Arquitectura de Computadoras,

Más detalles

ALGORÍTMICA. Dpto. Ingeniería de Sistemas y Automática Facultad de Ciencias Universidad de Valladolid.

ALGORÍTMICA. Dpto. Ingeniería de Sistemas y Automática Facultad de Ciencias Universidad de Valladolid. ALGORÍTMICA Dpto. Ingeniería de Sistemas y Automática Facultad de Ciencias Universidad de Valladolid. Indíce Algoritmo Elementos de un algoritmo: Variables, Constantes, Expresiones Datos: Definición y

Más detalles

Declaración de variables en pseudocódigo. Ambito global o local programación. (CU00205A)

Declaración de variables en pseudocódigo. Ambito global o local programación. (CU00205A) aprenderaprogramar.com Declaración de variables en pseudocódigo. Ambito global o local programación. (CU00205A) Sección: Cursos Categoría: Curso Bases de la programación Nivel II Fecha revisión: 2024 Autor:

Más detalles

Conclusiones y recomendaciones

Conclusiones y recomendaciones Conclusiones y recomendaciones El MD5C otorga, al grupo de desarrollo, 3 vistas claramente definidas en base a: a. Los tipos de presentación y subpresentación que tiene la aplicación. b. Las 5 capas que

Más detalles

Programación de Ordenadores

Programación de Ordenadores Programación de Ordenadores Ingeniería Química David Pelta Depto de Ciencias de la Computación e I.A. Universidad de Granada Índice Resolución de Problemas con Ordenadores Algoritmo Metodología de la programación

Más detalles

U.A.B.C. Facultad de Ingeniería Programación Estructurada UNIDAD III

U.A.B.C. Facultad de Ingeniería Programación Estructurada UNIDAD III UNIDAD III Funciones 3.1 Forma general de una función. C fué diseñado como un lenguaje de programación estructurado, también llamado programación modular. Por esta razón, para escribir un programa se divide

Más detalles

TIPOS DE SOFTWARE. A grandes rasgos, se puede decir que existen tres tipos de software:

TIPOS DE SOFTWARE. A grandes rasgos, se puede decir que existen tres tipos de software: SOFTWARE Software es un término informático que hace referencia a un programa o conjunto de programas de cómputo que incluye datos, procedimientos y pautas que permiten realizar distintas tareas en un

Más detalles

Explicación de los criterios heurísticos

Explicación de los criterios heurísticos Explicación de los criterios heurísticos 1. Claridad de los objetivos El Sitio Web debe comunicar de manera inmediata su propósito, objetivo y funciones. 1. El propósito u objetivo de la página Web es

Más detalles

Estructura de Datos Unidad 1: Repaso del Lenguaje Java

Estructura de Datos Unidad 1: Repaso del Lenguaje Java Estructura de Datos Unidad 1: Repaso del Lenguaje Java Introducción Java es un lenguaje de programación orientado a objetos, desarrollado por Sun Microsystems a principios de 1991, con el que se van a

Más detalles

Paralelismo. MPI Paso de mensajes. Francisco García Sánchez Departamento de Informática y Sistemas

Paralelismo. MPI Paso de mensajes. Francisco García Sánchez Departamento de Informática y Sistemas Paralelismo MPI Paso de mensajes Francisco García Sánchez Departamento de Informática y Sistemas Contenido Introducción 1) Uso de MPI 2) Multiplicación de matrices 3) Ordenación por mezcla 4) Programación

Más detalles

MICROSOFT EXCEL 2013 (COMPLETO)

MICROSOFT EXCEL 2013 (COMPLETO) MICROSOFT EXCEL 2013 (COMPLETO) Curso para aprender a utilizar la hoja de cálculo Microsoft Excel 2013, perteneciente a la suite ofimática Microsoft Office 2013, explicando todas las funciones que la aplicación

Más detalles

Tema: Programación Orientada a Objetos

Tema: Programación Orientada a Objetos Estructura de datos y Programación / Programación I Tema: Programación Orientada a Objetos Ing. Analia Méndez Ing. Raquel Zarco Año: 2012 Qué es Programación Orientada a Objetos (POO)? Es un paradigma

Más detalles

Introducción a la programación

Introducción a la programación Introducción a la programación PROGRAMACION I Grado en Matematicas Informática Programación I - 2015/2016 Introducción 1 Introducción a la programación Computador: aparato electrónico capaz de interpretar

Más detalles

Un sistema de bases de datos sirve para integrar los datos. Lo componen los siguientes elementos:

Un sistema de bases de datos sirve para integrar los datos. Lo componen los siguientes elementos: Qué es una base de datos? El problema de los datos Todas las empresas requieren almacenar información. Desde siempre lo han hecho. La información puede ser de todo tipo. Cada elemento informativo (nombre,

Más detalles

Tema 4g: Proceso Unificado: Implementación

Tema 4g: Proceso Unificado: Implementación Tema 4g: Proceso Unificado: Implementación Marcos López Sanz Índice Visión general Artefactos Componentes Subsistemas de implementación Interfaces Descripción de la arquitectura (vista del modelo de implementación)

Más detalles

Universidad Autónoma del Estado de México Facultad de Medicina

Universidad Autónoma del Estado de México Facultad de Medicina Universidad Autónoma del Estado de México Facultad de Medicina Licenciatura en Bioingeniería Médica Unidad de Aprendizaje: Algoritmos y programación básica Unidad 3: Estructuras de control de flujo en

Más detalles

LOS BENEFICIOS DE UTILIZAR R SOFTWARE

LOS BENEFICIOS DE UTILIZAR R SOFTWARE Máster de Estadística Aplicada con R software LOS BENEFICIOS DE UTILIZAR R SOFTWARE Máxima Formación Numerosas empresas y universidades utilizan R para los análisis estadísticos y realización de gráficos

Más detalles

TEMA 5: Subprogramas, programación modular

TEMA 5: Subprogramas, programación modular TEMA 5: Subprogramas, programación modular 5.1.-Definición de módulo. Programación modular La programación modular está basada en la técnica de diseño descendente, que como ya vimos consiste en dividir

Más detalles

Tema 6: Clases. Índice

Tema 6: Clases. Índice Tema 6: Clases Antonio J. Sierra Índice 1. Fundamentos. 2. Declaración de objetos. 3. Asignación de objetos a variables referencia. 4. Métodos. 5. Constructores. 6. this. 7. Recogida de basura. 8. Modelado

Más detalles

Ingeniería de Software: Y eso qué es?

Ingeniería de Software: Y eso qué es? Ingeniería de Software: Y eso qué es? Definición: Estrategia para desarrollar software de alta calidad. A qué se le denomina Software de alta calidad? Al software que sea: Util (al cliente). Portable.

Más detalles

Ingeniera de Sistemas: Luz Esperanza Espitia Tutora de Estructura de datos.

Ingeniera de Sistemas: Luz Esperanza Espitia Tutora de Estructura de datos. Ingeniera de Sistemas: Luz Esperanza Espitia Tutora de Estructura de datos. Con relación a la Estructura LISTA Indicar objetos reales que se puedan modelar con dicha estructura. Listas de Ordenes de visitas

Más detalles

Lenguajes de Cuarta Generación

Lenguajes de Cuarta Generación Lenguajes de Cuarta Generación Diana Marcela SánchezS http://www.csi.map.es/csi/metrica3/index.html www.csi.map.es/csi/metrica3/ /metrica3/index.htmlindex.html Que es un programa? La unión de una secuencia

Más detalles

PROCESADOR DE TEXTOS: WRITER

PROCESADOR DE TEXTOS: WRITER PROCESADOR DE TEXTOS: WRITER Profesor: José María González Centro: I.E.S. AZAHAR - ( Antas Almería ) Teoría OpenOffice Writer Capítulo I: Formato Documento Nivel de Dificultad: Medio 1. Creación y eliminación

Más detalles

ASIGNATURA: (TIS-106) Estructuras de Datos II DOCENTE: Ing. Freddy Melgar Algarañaz TEMA 4. Montículos binarios (heaps)

ASIGNATURA: (TIS-106) Estructuras de Datos II DOCENTE: Ing. Freddy Melgar Algarañaz TEMA 4. Montículos binarios (heaps) TEMA 4. Montículos binarios (heaps) Veamos otro tipo especial de árbol binario, los llamados heaps (montículos), que se pueden representar eficazmente con un vector. Definición: un montículo de máximos

Más detalles

ALGORITMOS II PSEUDOCODIGOS INTRODUCCION AL PSEINT CORPODICES VICTOR ANDRES OCHOA CORREA

ALGORITMOS II PSEUDOCODIGOS INTRODUCCION AL PSEINT CORPODICES VICTOR ANDRES OCHOA CORREA ALGORITMOS II PSEUDOCODIGOS INTRODUCCION AL PSEINT CORPODICES VICTOR ANDRES OCHOA CORREA CONTENIDOS Definición de un algoritmo Tipos de datos Representaciones de un algoritmo Lenguaje natural Pseudocódigo

Más detalles

CAPITULO I INTRODUCCIÓN

CAPITULO I INTRODUCCIÓN CAPITULO I INTRODUCCIÓN MATLAB es un entorno de programación y ejecución en el cual se permiten construir herramientas propias según los requerimientos del programador, fácilmente se crean funciones y

Más detalles