Archive for the '6149' Category

Introducción a AjProcessor (Parte 1)

Thursday, April 23rd, 2009

En marzo, estuve trabajando en el código de AjProcessor, parte de mi proyecto de Code Kata en Google:

http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjProcessor

La idea es la evolución de código experimental que hice con AjMessages y otros ejemplos. Quiero tener una aplicación, basada en el pasaje de mensajes, que pueda ejecutar en una grilla de máquinas heterogéneas. La aplicación podría ser dividida en pasos, y cada paso podría ejecutar en la misma máquina, para prueba local, o en distintas máquinas. El despliegue de la aplicación en distintas máquinas debería ser transparente a la escritura del código de la aplicación.

Alguno de esos objetivos fueron alcanzados con AjMessages, pero esta vez, quiero partir de una base más limpia, basada en las lecciones aprendidas en los anteriores intentos.

Primero, quiero pasar en limpio algunas ideas básicas, para explicar la motivación del código que está apareciendo en el proyecto. La idea básica es tener lo que llamo processors, procesadores, código que recibe un mensaje y lo procesa.

El mensaje tiene un payload, contenido, que puede ser un objeto arbitrario, un string, o cualquier otra cosa, y propiedades adicionales, en forma de pares clave/valor.

Otro ladrillo esencial en esta aplicación tipo lego, es el elemento que publica mensajes. Hay entonces un publisher:

El mensaje saliente puede ser recibido por cualquier otro código. El mismo mensaje puede ser procesado por más de otro Processor:

Es como el patrón publish/subscribe. Otro patrón a tomar en cuenta, es un componente tipo router. Dependiendo de algo del mensaje (propiedad, contenido), o del entorno (balanceo de carga), envía el mensaje a diferentes destinos.

Muchas veces, un componente implementará ambos roles, de de Message Processor y el de Message Publisher. Para facilitar la llamada a objetos .NET comunes, sería bueno tener un procesador que reciba un mensaje, toma una parte del mismo (por ejemplo, el contenido), y lo envía como parámetro a un método del objeto .NET. El valor de retorno podría ser tomado como contenido de un nuevo mensaje saliente.

Los componentes pueden ser dispuestos en cadena, implementando una especie de pipeline/tubería donde procesar un mensaje:

Una disposición más compleja sería recibir un mensaje, y reenviarlo a diferentes pipelines, según el contenido o propiedad del mensaje entrante. Y tomar los mensajes salientes de los pipelines, para reenviarlos al próximo paso.

(este concepto podría ser mapeado al concepto de Application en AjMessages, pero sin la idea de procesacimiento distribuido). Una idea más interesante es ejecutar una especie de ruteadores a pipelines, pero en varias máquinas

La infraestructura de AjProcessor estaría a cargo de la serialización, deserialización y ruteo de mensajes entre distintas máquinas anfitrionas. Podría enviar mensajes usando Windows Communication Foundation (WCF), o cualquier otra tecnología. La idea es tener un trasporte que se pueda agregar o definir, en configuración, sin afectar al funcionamiento de la aplicación.

Bien, todas estas son las ideas iniciales que forman el fundameto el proyecto. En un próximo espero explicar algo del código actual (apenas algunas interfaces, clases de implementación y tests).

Angel “Java” Lopez
http://www.ajlopez.com/en
http://twitter.com/ajlopez

Seminario gratuito: Programación Paralela, Programación Distribuida, High Performance Computing

Monday, December 29th, 2008

Desde fines del 2006, estoy trabajando con programación distribuida, usando CCR/DSS, WCF y otras tecnologías, como Message Passing Interface. En estas últimas semanas, comencé a trabajar con High Performance Computing Windows HPC Server 2008.

Ahora, en Enero, daremos con Sebastián Renzi  (@SebaRenzi) un seminario gratuito en el Microsoft User Group:

SEMINARIO GRATUITO “Programación Paralela, Programación Distribuida, High Performance Computing”.
Thursday, January 15, 2009
Lugar: Auditorio del MUG, Rivadavia 1479 1º A, Ciudad de Buenos Aires.

Ahí está el abstract:

Hay aplicaciones que necesitan procesar gran cantidad de información, o que tienen requerimientos de velocidad exigente.
Exploraremos en la charla algunas tecnologías y estrategías que tenemos disponibles como:
– Programación Paralela: usando múltiples threads, TPL (Task Parallel Library).
– Programación Distribuida: enviando el trabajo a realizar a distintas máquinas, usando WCF o DSS/CCR
– High Performance Computing: ejecutando jobs, tasks, y programas

HPC Server 2008 es el producto de Microsoft que permite armar un cluster de máquinas, pudiendo llegar a tener cientos de nodos.
Es la tendencia actual en supercomputación.

Mostraremos ejemplos de código de cada uno.

Las vacantes son limitadas.

La idea es explorar algunas ideas de AjMessages, grid computing, Task Parallel Library, MPI, MPI.NET y programación HPC. También mostrar código andando, esperamos poder llevar un cluster virtualizado andando, para mostrarlo en la charla.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com/
http://twitter.com/ajlopez

Realidad aumentada con Windows HPC

Monday, December 1st, 2008

En estos días estoy trabajando con Windows High Performance Computing Server 2008. Investigando sobre el tema en la red (en especial en Twitter), encuentro esta demostración:

[View:http://www.youtube.com/watch?v=JksDWFQwOOM]

[youtube:JksDWFQwOOM]

[View:http://www.youtube.com/watch?v=WEfr9WmCtgg]

[youtube:WEfr9WmCtgg]

Es un trabajo de la gente del High Performance Computing Center de Stuttgart (HLRS)

Se llama realidad aumentada a un tipo de realidad virtual que combina imágenes reales e imaginarias. Por ejemplo, usando un “headset” transparente podríamos ver cómo una mesa se vería en nuestra sala, o ver un esquema en 3D de un motor mientras lo estamos reparando. La gente de HLRS está trabajando con el Microsoft Technical Computing Initiative en cosas como Augmented Reality in the automotive industry

Pueden ver algunas fotos de las instalaciones que tienen en

Microsoft HPC Institute – HLRS – University of Stuttgart

Igualito al hardware que tengo en mi casa…. 🙂

Encontré estos videos en

Augmented Reality mit Windows HPC

Hay más videos sobre HPC, y depuración MPI, en

HLRS

Algo más de información sobre Augmented Reality

What Is the Metaverse and Should HPC Care?
Augmented reality – Wikipedia, the free encyclopedia
Mixed reality – Wikipedia, the free encyclopedia

International Symposium on Mixed and Augmented Reality (ISMAR)

http://www.augmented.org/
How Augmented Reality Will Work

Llegaremos a tener nuestro Holodek?

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com/
http://twitter.com/ajlopez

Grid as a Service

Tuesday, November 11th, 2008

Desde el último año, estuve trabajando con tecnologías relacionados con computación distribuida. Actualmente, mi trabajo está relacionado con Windows HPC (High Performance Computing). Pero también estuve en contacto con DSS/CCR de Microsoft Robotics, WCF (Windows Communication Foundation), y examiné algunas implementaciones de Java, como GridGain. Mencioné el concepto de Grid as a Service como una idea para implementar en mi posts Grid Computing Programming, Programando para una Grid,Más programando para una grid.

Un Grid as a Service es algo que podría ser implementado sobre diferentes tecnologías de base. Supongo que debe haber alguna implementación de estas ideas. Ésta es la idea que tengo en mente:

– Una grilla de computadoras, heterogéneas, de línea

– Software para distribuir una o varias tareas en la grilla

– API y front end Web, para definir y subir una aplicación en grilla.

– API e interface Web interface, para lanzar la ejecución de esa aplicación

La aplicación en grilla podría contener:

– Ejecutables, como .exe, .dlls (si está basado en Windows) o .jar (en Java).

– Un manifiesto, describiendo las características de la aplicación: parámetros necesarios, salida esperada (archivo, base de datos, XML,…)

Para lanzar una tarea, el usuario provee los parámetros de entrada, para enviar a ejecutar una aplicación ya cargada y definida en la grilla. Al final de la ejecución, recibiría una notificación, posiblemente una URL con el resultado calculado.

Mi trabajo con AjMessages, AjAgents, está, de alguna manera, orientado a este objetivo de grid as a service.

La grilla de soporte podría ser expandida para tomar más poder y capacidad de otras grillas. Esto es, la misma API que el desarrollador de aplicaciones usaría, podría ser consumida por otras grillas para sus aplicaciones.

Las máquinas podrían ser provistas por data centers (cada año que pase habrá más data centers disponibles, a costo razonables), como los que actualmente proveen servicios en el “cloud” o máquinas virtuales.

Habría varios detalles a discutir, como el monitoreo, nivel de servicio, temas de seguridad. Una alternativa es programar en una “sandbox”, o en un lenguaje dedicado orientado a grilla o computación en paralelo. Computación en paralelo no es lo mismo que computación en grilla: en mi opinión, grid computing es más flexible, una aplicación en grilla podría enviar mensajes a cualquier nodo en la grilla, en cualquier momento, en cambio, la computación en paralelo está más orientada a algoritmos como map reduce, y tecnologías más sincronizadas como MPI (Message-passing interface).

Otros enlaces relacionados:

Recursos de Grid Computing
Recursos de Windows High Performance Computing (HPC) y Programación
http://delicious.com/ajlopez/gridcomputing
http://delicious.com/ajlopez/hpc

Angel “Java” Lopez
http://www.ajlopez.com/
http://twitter.com/ajlopez

Recursos de Windows High Performance Computing (HPC) y Programación

Saturday, November 8th, 2008

Desde el último año, estuve investigando sobre computación distribuida y en grilla. Encontré bastantes recursos útiles, información, que fui agregando a mi delicious. Uno de los tópicos que encontré es la implementación de Microsoft de High Performance Computing (HPC). Este post es una lista de los recursos más relevantes que estoy usando.

Primero, hay que ver la página de Windows HPC Server 2008:

http://www.microsoft.com/hpc

El primer video para mirar es el de último PDC 2008, la sesión de HPC:

HPC Session at last PDC
http://channel9.msdn.com/pdc2008/ES13/

Excelente presentación, cubriendo el nuevo Windows HPC Server 2008, nodos, tareas, trabajos, herramientas de programación, formas de programar, programación MPI (Message Passing Interface) y MPI.NET, computer go en HPC (hermosa idea, jugar al go en cluster), toda la presentación merece un post aparte.

Me gustó también un video corto pero interesante, que muestra la consola de administración en:

http://channel9.msdn.com/shows/The+HPC+Show/Five-Minute-Intro-to-the-HPC-Server-2008-Management-Console/

EL blog a leer es Windows HPC survival guide

Un post como ejemplo: No scientist left behind with CRAY Supercomputer running Windows HPC Server 2008

Hay una colección de recursos en HPC Resource Kit

Todos los videos de HPC:

HPC | Tags | Channel 9

(tópicos interesantes: WCF y programación HPC, HPC Basic Profile: servicios web para invocar desde Java y otros lenguajes)

Hay un sitio de comunidad dedicado a Windows HPC:

http://www.windowshpc.net/

con archivos, recursos, código fuente y ejemplos. 

Software para usar

Para iniciarse en la programación para HPC, hay que instalar Microsoft HPC Pack (Windows). Lo bajé desde:

HPC Pack 2008 SDK download

(no hace falta un HPC Server para los primeros pasos)

Luego, instalé MPI.NET Software

(Instalé el MPI.NET SDK.msi pero también expandí el MPI.NET-1.0.0.zip: éste tiene mejores ejemplos, ya armados como soluciones de Visual Studio)

Un excelente tutorial, sobre programación secuencial, en paralelo, y luego usando HPC 2008, en:

Learning Parallel Programming — from shared-memory multi-threading to distributed-memory multi-processing

Enlaces adicionales

Si quieren explorar las posibilidades de programación de HPC, hay algunos temas a investigar:

HPC

http://www.hpccommunity.org/ Comunidad HPC
http://www.hpcwire.com/ High Productivity Computing
http://www.ddj.com/hpc-high-performance-computing/
YouTube – An Overview of High Performance Computing and Challenges for the Future
http://en.wikipedia.org/wiki/High-performance_computing

MPI

MPI (Message Passing Interface) está soportado en Windows HPC. Hay una implementación de Microsoft:

Microsoft MPI (Windows)

que puede ser invocada desde C++.

Hay una implementacíón .NET sobre esa de Microsoft MPI:

MPI.NET: High-Performance C# Library for Message Passing

Tiene código fuente de ejemplo.

(una anterior implementación en Codeplex:  MPI .Net – Home)

Ya había escrito sobre otra implementación en .NET:

MPI Message Passing Interface in .NET

Más sobre MPI

MPI 2.0 Report
MPI Tutorials
Microsoft Messaging Passing Interface – Wikipedia, the free encyclopedia
Pure Mpi.NET

Programación en paralelo

Introduction to Parallel Computing introducción muy completa (gracias a jgarcia por el enlace)
Microsoft Innovation Day – November 5, 2006 están presentando algo relacionado con DryadLINQ
Multithreading and Concurrency in .NET una lista completa de tecnologías disponibles en .NET
http://www.microsoft.com/ccrdss Ahora, CCR/DSS como paquete separado (antes venían sólo en Microsoft Robotics)
Adobe Press – 9780321603944 – Software Pipelines: The Key to Capitalizing on the Multi-core Revolution
Burton Smith: On General Purpose Super Computing and the History and Future of Parallelism | Going Deep | Channel 9
Welcome to Hadoop!
Dryad – Home Un interesante proyecto de Microsoft research
YouTube – Dryad: A general-purpose distributed execution platform Presentación en Google Talks
Concurrency: What Every Dev Must Know About Multithreaded Apps
Overview of concurrency in .NET Framework 3.5 | Igor Ostrovsky Blogging
Parallel Programming with .NET
Parallel Computing Developer Center de Microsoft
Parallel Virtual Machine – Wikipedia, the free encyclopedia
http://msdn.microsoft.com/msdnmag/issues/07/10/PLINQ/default.aspx Parallel LINQ

Map Reduce

Writing An Hadoop MapReduce Program In Python
Dryad: Distributed Data-Parallel Programs from Sequential Building Blocks
Google Research Publication: MapReduce

Delicious

En mis enlaces en delicious sobre HPC, MPI, Parallel programming, Grid Computing, algoritmos Map Reduce, CCR/DSS:

http://delicious.com/ajlopez/hpc
http://delicious.com/ajlopez/mpi
http://delicious.com/ajlopez/parallel
http://delicious.com/ajlopez/gridcomputing
http://delicious.com/ajlopez/mapreduce
http://delicious.com/ajlopez/ccr
http://delicious.com/ajlopez/dss

En el PDC 2008, Windows HPC fue mostrado con un ejemplo de Computer Go, el programa campeón del mundo ManyFacesOfGo (http://www.smart-games.com) . Computer Go es un tópico fascinante:

http://delicious.com/ajlopez/computergo

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Agentes Distribuidos y Fractales usando DSS/VPL

Monday, June 23rd, 2008

La semana pasada escribí una aplicación de base para agentes distribuidos usando DSS/VPL, agentes que intercambian mensajes arbitrarios e implementan un balanceo de carga rudimentario. Pueden leer los detalles en:

Agentes Distribuidos usando DSS/VPL
Distributed Agents using DSS/VPL

Ayer, extendí el ejemplo con un nuevo proyecto, Fractal:

Pueden bajarlo desde mi Skydrive.

Tiene dos DSS Service Components, uno es el Calculator: calcula un sector del fractal de Mandelbrot. El otro componente es el Renderer, que tiene un formulario para controlar y mostrar los resultados del cálculo. El mensaje que transporta la información del sector a calcular es:

public class SectorInfo : MessagePayload { public double RealMinimum { get; set; } public double ImgMinimum { get; set; } public double Delta { get; set; } public int FromX { get; set; } public int FromY { get; set; } public int Width { get; set; } public int Height { get; set; } public int MaxIterations { get; set; } public int MaxValue { get; set; } }

Otra clase es el mensaje que retorna el cálculo:

public class Sector : MessagePayload { public int FromX { get; set; } public int FromY { get; set; } public int Width { get; set; } public int Height { get; set; } public int[] Values { get; set; } }

El Calculator divide el sector a calcular, si lo considera demasiado grade. Podría calcularlo en un solo paso, pero me parece interesante esta solución, para repartir el trabajo entre varios nodos:

 

private void Calculate(AgentMessage msg) { LogInfo("Entering Calculator with Action: " + msg.Action); SectorInfo sectorInfo = (SectorInfo) msg.Payload; LogInfo(String.Format("X {0} Y {1} Width {2} Height {3}", sectorInfo.FromX, sectorInfo.FromY, sectorInfo.Width, sectorInfo.Height)); if (sectorInfo.Width > 100 && sectorInfo.Height > 100) SplitSector(sectorInfo); else CalculateSector(sectorInfo); }

Como en el ejemplo de la semana pasada, podemos ejecutar este ejemplo desde un diagrama VPL, que se llama FractalVpl1:

Acá hay un solo Renderer, y dos agentes Calculator. Si lanzamos este programa VPL, aparece una ventana. Esta es su apariencia (luego de presionar el botón Calculate):

Podemos arrastrar el mouse para seleccionar una nueva región, o usar los botones de Zoom In y Zoom Out. El botón de Reset vuelve a la posición y colores iniciales. El botón Reset Colors vuelve a los colores iniciales, que pueden ser cambiados al azar con el botón New Colors.

Hay otro programa VPL, llamado FractalVpl2, que puede ser usado para ejecutar el mismo ejemplo de forma distribuida. Tiene un diagrama con dos AgentHosts:

y dos nodos:

Debemos compilar el ejemplo VPL y pedir de ejecutar sus nodos en forma distribuida, usando el rundeployer.cmd (para más detalles, ver mi anterior post, mencionado al principio).

Estos son algunos de los gráficos que produce el sistema:

 

(Este post es una traducción del original en “Anglish”:

Distributed Agents and Fractals using DSS/VPL

)

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com

Agentes Distribuidos usando DSS/VPL

Friday, June 20th, 2008

En este post, exploraremos algunas ideas para implementar agentes distribuidos, aprovechando las capacidades que nos brindan Decentrilized Software Services (DSS) y el Visual Programming Language (VPL), includos en el Microsoft Robotics Developer Studio (estoy trabajando con la versión CTP 2.0, con VS 2008). Pueden bajarse el código desde mi Skydrive:

AjDssAgents-0.1.zip

En un anterior post:

Web Crawler example using DSS (Decentralized Software Services)
Ejemplo de Web Crawler usando DSS (Decentralized Software Services)

escribí algunos componentes DSS orquestados desde VPL, para implementar un web crawler. En ese ejemplo, hay un Dispatcher, un Resolver, un Downloader, y un Harvester. Pueden leer ahí el detalle de sus funciones.

Pero supongamos que ahora tenemos varias máquinas para poder ejecutar el proceso de web crawling. Queremos instalar y ejecutar varios Downloaders y Harvesters, en una grilla de máquinas, usando load balancing automático. El problema con la orquestación desde VPL es que no soporta conceptos como load balancing, por lo menos no directamente. Entonces, escribí este ejemplo donde los componentes se comunican entre sí, como agentes, usando mensajes especiales.

Un agente, en este ejemplo, es un DSS service component, capaz de recibir y procesar mensajes que les envían los otros agentes. Puede enviar mensajes a otros componentes. En vez de indicar a cuál agente va dirigido un mensaje, se especifica el tipo lógico de agente al que va destinado, por ejemplo “WebCrawler/Harvester”.

Otro componente especializado, el AgentHost, se encargar de recibir esos mensajes a enviar, y los destina a un agente local o remoto, que corresponda al tipo lógico especificado.

La solución

La solución .NET tiene tres proyectos:

AjDssAgents contiene el contrato genérico de un agente, y sus tipos, y la implementación concreta del AgentHost.

DecrementAgent and WebCrawler son simples agentes a usar en el ejemplo. El web crawler implementado es similar al de mi anterior post, mencionado arriba.

El mensaje

Los agentes intercambian mensajes, objetos del tipo AgentMessage:

[DataContract] public class AgentMessage { [DataMember] public string From { get; set; } [DataMember] public string To { get; set; } [DataMember] public string Action { get; set; } [DataMember] public object Payload { get; set; } }

El campo From indica el origen del mensaje (no estoy usando ese campo todavía) El campo To es la dirección física (dirección DSSP) del agente destino, o su tipo lógico. En el ejemplo de este post, solamente estoy usando los tipos lógicos. ¿Por qué usar un tipo lógico? Así, si un mensaje tiene como To el valor “WebCrawler/Dispatcher”, será enviado a un agente que corresponda a ese tipo lógico.

¿Cómo un agente conoce cuáles otros agentes están siendo ejecutados, y cuáles son sus tipos lógicos? Pues bien, no lo sabe. El componente que mantiene esa información es el AgenHost local, único en cada DssHost activo. Cada agente envía sus mensajes salientes a su AgentHost local, y éste los reenvía a los agentes locales o remotos apropiados.

Los agentes

Cada agente es un DSS service component, con una dirección asignada cuando es creado. Durante el comienzo de su ejecucuón, el agente envía a su AgentHost local un mensaje DSS, indicando su dirección y su tipo lógico (p.ej. WebCrawler/Dispatcher). Esta es la forma por la que el AgentHost conoce los agentes que estan ejecutándose localmente, en su DssHost. Veamos el código de inicio de un agente Dispatcher del ejemplo WebCrawler:

 

protected override void Start() { base.Start(); // Add service specific initialization here. _state.AgentType = "WebCrawler/Dispatcher"; host.NewNode newNode = new host.NewNode(new host.AgentInfo() { Address = this.ServiceInfo.Service, AgentType = _state.AgentType }); _hostPort.Post(newNode); }

El tipo del agente es mantenido en su estado.

Este es un código típico, de un agente, en este caso un Dispatcher, mostrando el tratamiento de un mensaje entrante y la producción de mensajes salientes:

 

[ServiceHandler(ServiceHandlerBehavior.Concurrent)] public IEnumerator<ITask> PostMessageHandler(generic.PostMessage postMessage) { if (postMessage.Body.Action.Equals("Dispatch")) Dispatch(postMessage.Body); else if (postMessage.Body.Action.Equals("Resolve")) Resolve(postMessage.Body); postMessage.ResponsePort.Post(DefaultSubmitResponseType.Instance); yield break; } private void Dispatch(AgentMessage msg) { LogInfo("Entering Dispatcher with Action: " + msg.Action); LogInfo("URL: " + msg.Payload); DownloadTarget target = new DownloadTarget(); target.Uri = (string) msg.Payload; target.Depth = 1; AgentMessage postmsg = new AgentMessage() { Action = "Resolve", To = _state.AgentType, Payload = target }; host.PostMessage post = new host.PostMessage(postmsg); _hostPort.Post(post); } private void Resolve(AgentMessage msg) { LogInfo("Entering Dispatcher with Action: " + msg.Action); DownloadTarget downloadtarget = (DownloadTarget)msg.Payload; LogInfo("URL: " + downloadtarget.Uri + ", Depth: " + downloadtarget.Depth); DownloadTarget target = ProcessUrl(downloadtarget); if (target != null) { AgentMessage agentmsg = new AgentMessage() { To = "WebCrawler/Downloader", Action="Download", Payload = downloadtarget }; host.PostMessage postmsg = new host.PostMessage(agentmsg); _hostPort.Post(postmsg); } }

El AgentHost

Hay uno y sólo uno por DssHost en ejecución. El AgentHost recibe la información de los nuevos agentes que se crean (su dirección y tipo lógico), y mantiene esa información en su propio estado.

Recibe mensajes de sus agentes locales, y los reenvía a otros agentes locales o a un AgentHost remoto. En este último caso, serializa el contenido del mensaje en un string, usando serialización XML (no podemos enviar un objeto genérico, debido a limitaciones en el Proxy que usa DSS). Esta es la estructura de un mensaje remoto:

 

[DataContract] public class RemoteAgentMessage { [DataMember] public string From { get; set; } [DataMember] public string To { get; set; } [DataMember] public string Action { get; set; } [DataMember] public string PayloadTypeName { get; set; } [DataMember] public string Payload { get; set; } }

Notemos que el mensaje remote tiene un string Payload, que es la serialización XML del contenido original, y también tiene su tipo calificado, así el host destino podrá deserializarlo a su tipo correspondiente al objeto original.

Un AgentHost soporta subscripciones. Otros AgentHosts pueden subscribirse a recibir información de sus nuevos agentes. En general, si tenemos tres máquinas, debemos susbcribir a los tres AgentHosts entre ellos, así tendrán toda la información de los agentes que se encuentre corriendo, en las distintas máquinas.

Un ejemplo de Web Crawler con VPL

El ejemplo WebCrawlerVpl2 en VPL contiene dos diagramas, el primero:

Hay un Dispatcher, dos Downloaders y dos agentes Harvesters. El Dispatcher lanza la URL inicial a procesar, y mantiene una lista de URLs ya procesadas. El Downloader obtiene el contenido de cada página en proceso. El Harvester examina el contenido y obtiene los nuevos links a procesar.

Notemos que hay dos AgentHosts, y ellos se relacionan por notificaciones para informar sus nuevos agentes al otro.

Todos estos agentes y componentes se distribuyen en dos nodos:

El nodo Windows ejecutará en localhost:50000/50001, y el nodo Windows0 usar localhost:50002/50003 como dirección. Podemos modificar estos parámetros, agregar más agentes y nodos, sin cambiar el código de la aplicación.

Para ejecutar la distribución en forma distribuida, debemos compilarlar usando Build -> Compile as a Service en el menú de VPL. Deberá cambiar las propiedades de VPL, ahora en el ejemplo están apuntando a directorios locales en mi máquina de desarrollo:

Al compilar, VPL mostrará su avance:

Luego de la compilación, ir a la consola de DOS de MRDS, cambiar al directorio bin y lanzar el comando rundeployer.cmd:

Yo ejecuto el deployer en mi máquina local. Uds. pueden ejecutar el ejemplo en otras máquinas remotas, iniciando el deployer en cada una de ellas.

Ahora, estamos listos para ejecutar el web crawler. Seleccionamos la opción Run -> Run on distributed nodes , y la aplicación comenzará a ejecutar. Un ventana de diálogo nos pedirár la URL inicial. La ingresamos, y el proceso comienza a recuperar las páginas de ese sitio. Pueden ver el estado del primer AgentHost (ejemplo) en:

http://localhost:50000/agenthost

Hay tres agentes locales y dos agentes remotos.

En el otro DssHost, hay otro AgentHost:

http://localhost:50002/agenthost0

Vemos la diferencia: aquí hay dos nodos locales y tres remotos.

Para ver el avance del proceso, pedir en el navegador

http://localhost:50000/console/output

Conclusiones

Con estas ideas, podemos implementar aplicaciones tipo grilla, ejecutándose en varios nodos físicos. Perdemos la orquestación de VPL, no podemos dibujar el camino de los mensajes. Pero ganamos en balanceo de carga y deploying dinámico. Con algo de esfuerzo adicional, podemos escribir un servicio que inicia e instale el sistema en una nueva máquina remota, en el medio de un proceso en ejecución. La serialización de objetos arbitrarios es posible, ahora está usando serialización XML, podemos cambiarla por serialización “custom” o binaria.

Podría agregar subscripción a mensajes, en una futura versión. Un agente podría recibir mensajes que no estaban destinados a él, especificando algún criterio de subscripción. Esos criterios se mantendrían en los AgentHosts. Cuando un AgentHost rutea un mensaje saliente, podría reenviar una copia del mismo a cualquier agente interesando, ya sea local o remoto.

Tienen la versión original de este post en “Anglish”:

http://ajlopez.wordpress.com/2008/06/15/distributed-agents-using-dssvpl

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com/en

Recursos de Grid Computing

Saturday, May 10th, 2008

Desde el año pasado, y más en estas últimas semanas, he estado investigando sobre Grid Computing, buscando enlaces, recursos, “papers”, implementaciones. Este post es el resultado de esa investigación.

Como siempre, un artículo de la Wikipedia:

http://en.wikipedia.org/wiki/Grid_computing

Si Ud. se está iniciando en el mundo de Grid Computing, estas son buenas introducciones

New to Grid Computing

Grid Computing according IBM

The anatomy of the grid

The physiology of the grid  

Interesante lista de lecturas para desarrolladores en Grid

Recommended reading list for grid developers

Grid Café tiene varios artículos y recursos

Grid Cafe Grid Projects in the world  

Grid Cafe The place for everybody to learn about the Grid  

What is “the Grid”?  

Grid @ CERN 

Sobre el estado de la industria:

http://www.gridtoday.com/ (un poco demasiado abarcativo, no es sólo sobre grid computing)

http://www.gridblog.com/

La lista completa de enlaces que mantengo, en:

http://del.icio.us/ajlopez/gridcomputing

Algunos productos para examinar:

http://www.gridgain.com
http://www.digipede.net algo más sobre Digipede en http://dotnetjunkies.com/WebLog/stefandemetz/archive/2006/12/09/Free_Grid_Computing_software.aspx
http://www.gridgistics.net/

http://sourceforge.net/projects/ngrid/

Algo relacionado, que comienza a “estar de moda”:

http://en.wikipedia.org/wiki/Cloud_computing

He escrito artículos en este blog sobre Grid Computing:

http://msmvps.com/blogs/lopez/archive/tags/Grid+Computing/default.aspx

y en “Anglish”, Angel’s English:

http://ajlopez.wordpress.com/category/grid-computing/

donde hay algunas implementaciones sencillas de ideas a seguir explorando, como AjAgents, y AjMessages.

Esta lista de recursos, en Anglish, desde:

Grid Computing Resources

Angel “Java” Lopez
http://www.ajlopez.com

Agentes en Grid

Thursday, May 8th, 2008

El año pasado participé del desarrollo de una aplicación que se ejecuta en una grilla de máquinas sin disco. Este año, estoy volviendo a actualizar el proyecto, espero poder bloggear sobre el resultado dentro de un mes. Mientras, quisiera escribir sobre algunas ideas a explorar.

En este post, uso el término “agente”, de una forma algo libre. No definiré precisamente el concepto, quiero usarlo como término base a refinar en el futuro (llegando en algún momento a tratar el tema de agentes autónomos, que me parece más interesante). Por ahora, exploremos algunas ideas básicas (¿ingenuas?) para entender mejor los problemas relacionados con agentes y aplicaciones en grid. Algunas de las ideas acá presentadas pueden ser vistas como ingenuas, pero siento que es un ejercicio necesario, para aprehender los conceptos clave y los problemas a ser resueltos en este tipo de aplicaciones. Al final de este post, presentaré algunas sugerencias de implementación.

He descripto algunas aplicaciones para ejecutar en una grid en mis anteriores post:

Grid Computing Programming

Más programando para una grid

Programando para una Grid

Conceptos de Agentes

En este post, un agente es una pieza de software, con conducta y estado. Se ejecuta en un host de agentes, una aplicación que provee los servicios de base para que el agente pueda “vivir” y trabajar. Representaremos al agente con esta figura:

Patrones de comunicación de agentes

Hay mucha literatura sobre comunicación de agentes, desde simples técnicas hasta elaborados contratos, negociaciones, y más. Podemos tener agentes con creencias, deseos e intenciones. En este post, un agente es más simple: sólo tiene estado, puede enviar y recibir mensajes. Puede recibir estímulos de otros agentes y desde el ambiente de su host.

El más simple patrón de comunicación es un agente enviando un mensaje a otro agente:

Algunas notas:

– El agente enviador conoce al agente receptor. Quiero decir, alguna forma de identidada debe ser implementada. El mensaje no es enviado a cualquiera: el que envía intenta enviar el mensaje a un determinado agente.

– El mensaje transporta datos, y debe ser entendido por el receptor, posiblemente procesado por uno de sus métodos de implementación.

– En enviador no espera por una respuesta. No está interesado en un mensaje de respuesta inmediato.

– Los agentes pueden residir en diferentes máquinas en la grila, y la comunicación se produce tanto local como remota.

Durante su vida un agente puede enviar muchos mensajes a distintos agentes, que debe conocer de alguna manera:

Algunas veces, el agente enviador recibirá un mensaje desde el agente receptor, notificando algun trabajo hecho, o enviando algún dato procesado. Dependiendo de la aplicación, el mensaje de respuesta podría acarrear información para identificar al mensaje original:

En este caso, el enviador original debe estar preparado para recibir la respuesta de una manera asincrónica. Esto podría ser un interesante problema a resolver: un agente puede enviar varios mensajes, y sería mejora si puede seguir ejecutando sin recibir todas las respuestas a tiempo. Por ejemplo, en una aplicación de un juego de tablero, un agente puede delegar la exploración de un árbol de jugadas a otros agentes, y, luedo de un tiempo, sería posible tomar una decisión, con sólo algunas respuestas recibidas.

Nubes (“clouds”) en el cielo de la grilla

Otro caso: un agente puede estar interesado en enviar un mensaje, pero no a un receptor determinado. Al contrario, quiere enviarlo a una “nube” de agentes, así cualquiera interesado en el mensaje tendría la oportunidad de procesarlo.

Esta característica puede ser implementada usando estas estrategias:

– Un agente envía un mensaje a un sistema de pizarra (blackboard), que otros agentes están vigilando.

– Una agente enviaría una mensaje a la aplicación host, indicando un tópico (como en una cola de mensajes), así cualquier agente subscripto recibirá el mensaje. Una variante: sólo algunos subscriptores reciben el mensaje, dependiendo de parámetros de aplicación.

– Un agente podría enviar un mensaje dirigido a alguna definición de proveedor de servicio. Un proveedor de servicio es un agente, que declara al comienzo de su vida, sus capacidades y los servicios que puede proveer. 

Un ejemplo, tomemos una aplicación de un juego de tablero, ajedrez o go. Un agente en esa aplicación puede enviar un mensaje reclamando resolver cierta posición de ataque. En un sistema de pizarra, publicará el pedido. En un sistema de tópicos, lo enviaría al tópico “ataques”. En una estrategia de proveedor de servicio, envía el mensaje a uno o más de los proveedores del servicio AttackResolver.

Como en el patrón anterior, un agente puede recibir una respuesta asincrónica, ahora desde “la nube”:

 

Duplicación de agentes

Un agente tiene conducta y estado. Si el agente puede dividir su trabajo, podría tomar el camino de duplicarse a sí mismo:

Es algo extraño, pero podría ser útil, dependiendo de la aplicación a desarrollar.

Agentes y la Grilla

Cada agente puede ser albergado en un nodo de la grilla. El mecanismo de envío de mensajes debe ser capaz de enviar un mensaje a otro nodo. La aplicación host mantiene una lista de agentes por identidad, y conoce cúal  es local o remoto. Una prueba ácida: una aplicación de grilla con agentes debe ser capaz de correr en una sola máquina, o en una grilla, sin cambiar el código o el algoritmo.

 

Como en otras implementaciones de grilla (discutidos en los post que mencioné al principio), un servidor central está a cargo de la distribución de las tareas entre los nodos de la grilla. “Grid as a Service” es una nueva frase que podemos aplicar a esta situación.

Moviendo al Agente

Un agente puede iniciar sus actividades en un node. Pero en algún momento, puede decidir de continuar su trabajo en otro nodo (la aplicación host que lo alberga también puede tomar esa decisión, independientemente del agente). Entonces, su estado sería enviado de un nodo a otro (otro caso: podría querer duplicarse y que su clon siga el trabajo en otra máquina).

Noten que la conducta del agente (que puede estar compilada o puede estar escrita en un lenguaje dinámico o de agente), no viaja. Pero bien podría ser que viaje, incluso, que haya agentes que vayan adaptando su conducta en el tiempo.

Inyectando conducta

La conducta de cada agente podría ser expresada en código compilado (archivos .jar en Java, assemblies en .NET). Otras alternativas son posibles: la conducta podría ser especificada en un lenguaje de scripting dedicado a agentes (pienso en una adaptación del AjBasic, por ejemplo).

Si la conducta se expresa en forma compilada, uno o varios servers puede tomar la responsabilidad de almacenar y distribuir esos componentes:

Ideas de implementación

Muchas de estas ideas pueden ser implementadas en cualquier lenguaje/tecnología apropiada, como Java y .NET, que soporte múltiples threads, invocación remota, serialización de mensajes, etc…

En los últimos tiempos estuve trabajando en mis projectos AjMessages y AjAgents, más información enestos post:

AjMessages: a message processor

Agents using Concurrency and Coordination Runtime (CCR)

AjMessages- hacia un procesador de mensajes

Agentes usando Concurrency and Coordination Runtime (CCR)

Algoritmos Genéticos con AjAgents y Concurrency and Coordination Runtime (CCR)

Genetic Algorithms with AjAgents and Concurrency and Coordination Runtime (CCR)

(Tengo otro proyecto, AjGrid, no publicado aún). Para este post, creo que el AjAgents podría ser una implementación de esas ideas. AjMessages tiene ahora soporte de ejecución remota, pero está más orientado a un proceso tubería (“pipeline”): es más difícil de implementar en semejante sistemas las ideas de este post.

Estoy agregando algunas características a AjAgents (ahora, AjAgents trabaja sólo en local):

Configuración: Carga y creación de agentes en ejecución, según alguna información de configuración, ya sea al inicio o en el medio de la ejecución.

Assembly remoto: Así un nodo de grilla pueder ser inyectado con nuevos agentes.

Identificación de Agente: Para identificar al agente de manera única (un UID debería bastar).

Transporte de mensaje: Windows Communication Foundation es un candidato, otro podría ser DSSP.

Un posible camino es tomar Decentralized System Services (DSS) del Microsoft Robotics Developer Studio. Un agente podría ser implementado como un servicio de DSS, ejecutando en un host DSS. La comunicación entre máquinas puede ser implementada usando DSSP como protocolo.

“Stay tuned”, vendrá más código.

(Esta es una actualización y traducción de mi post en “Anglish”, Angel’s English:

Agents in a Grid

)

Angel “Java” Lopez
http://www.ajlopez.com/en

Message Passing Interface, CCR, DSS, y Pure MPI.NET

Wednesday, April 16th, 2008

En estos días, estuve investigando algo sobre grid computing y Microsoft Robotics Studio, usando DSS y CCR. Encontré un interesante documento:

High Performance Multi-Paradigm Messaging Runtime Integrating Grids and Multicore Systems

Los autores son Xiaohong Qiu, Geoffrey C. Fox, Huapeng Yuan, Seung-Hee Bae, de la Indiana University de Bloomington, y George Chrysanthakopoulos, Henrik Frystyk Nielsen, de Microsoft Research. Nielsen y Chrysanthakopoulos son los “creadores” del Concurrency and Coordination Runtime (CCR) y de Decentralized Software Services (DSS), tecnologías que son pilares de Microsoft Robotics Studio, y que pueden ser usandas más allá de robótica. Más información sobre estas tecnologías en:

http://www.microsoft.com/robotics

El “abstract” del documento dice:

eScience applications need to use distributed Grid environments where each component is an individual or cluster of multicore machines. These are expected to have 64-128 cores 5 years from now and need to support scalable parallelism. Users will want to compose heterogeneous components into single jobs and run seamlessly in both distributed fashion and on a future “Grid on a chip” with different subsets of cores supporting individual components. We support this with a simple programming model made up of two layers supporting traditional parallel and Grid programming paradigms (workflow) respectively. We examine for a parallel clustering application, the Concurrency and Coordination Runtime CCR from Microsoft as a multi-paradigm runtime that integrates the two layers. Our work uses managed code (C#) and for AMD and Intel processors shows around a factor of 5 better performance than Java. CCR has MPI pattern and dynamic threading latencies of a few microseconds that are competitive with the performance of standard MPI for C.

¿Que es MPI? Son las siglas de Message Passing Interface. Según la Wikipedia:

Message Passing Interface (MPI) is both a computer specification and is an implementation that allows many computers to communicate with one another. It is used in computer clusters.

Hay una There is a implementación de Microsoft:

Microsoft Message Passing Interface (MS MPI) is an implementation of the MPI2 specification by Microsoft for use in Windows Compute Cluster Server to interconnect and communicate (via messages) between High performance computing nodes. It is mostly compatible with the MPICH2 reference implementation, with some exceptions for job launch and management. MS MPI includes bindings for C and FORTRAN languages. It supports using the Microsoft Visual Studio for debugging purposes.

Gua! FORTRAN….. Esos buenos viejos días! ;-). Recuerdo haber trabajado con la implementación de Lisp en Fortran del bueno de Gregory Chaitin, en el siglo pasado. Pero no hay vuelta atrás, parafraseando a David Hilbert: Nadie nos expulsará del paraiso que Java y .NET han creado para nosotros…. ;-). Pueden leer la cita original en este interesante thread.

Pero estoy divagando. Volvamos al tema.

Los principales sitios sobre MPI son:

http://www.mpi-forum.org/
http://www.open-mpi.org/
http://www.lam-mpi.org/

Yo estaba pensando en implementar algo de las ideas de MPI en .NET o Java, cuando encuentro:

http://www.purempi.net/

PureMpi.NET is a completely managed implementation of the message passing interface. The object-oriented API is simple, and easy to use for parallel programming. It has been developed based on the latest .NET technologies, including Windows Communication Foundation (WCF). This allows you to declaratively specify the binding and endpoint configuration for your environment, and performance needs. When using the SDK, a programmer will definitely see the MPI’ness of the interfaces come through, and will enjoy taking full advantage of .NET features – including generics, delegates, asynchronous results, exception handling, and extensibility points.

PureMpi.NET allows you to create high performance production quality parallel systems, with all the benefits of in .NET

Es una implementación lista para bajar y usar, con VS 2005 o VS 2008. Usa generics para implementar canales tipados en MPI.

Me bajé la librería, y la instalé en una máquina con Visual Studio 2008. El programa de instalación agregó un nuevo template de proyecto, Mpi.NET:

Cree un proyecto, que aparece:

Modifiqué el Program.cs a:

 

using System; using System.Collections.Generic; using System.Linq; using System.Text; using Mpi; namespace Mpi.NET1 { class Program { static void Main(string[] args) { ProcessorGroup.Process("MPIEnvironment", delegate(IDictionary<string, Comm> comms) { Comm comm = comms["MPI_COMM_WORLD"]; Console.WriteLine(comm.Rank); IAsyncResult result = comm.BeginSend<string>(0, "", "Rank: " + comm.Rank, TimeSpan.FromSeconds(30), null, null); if (comm.Rank == 0) { for (int i = 0; i < comm.Size; i++) { string receivedMsg = comm.Receive<string>(i, Constants.AnyTag, TimeSpan.FromSeconds(30)); Console.WriteLine(receivedMsg); } } comm.EndSend<string>(result); }); } } }

La clase ProcessGroup se encarga de los procesos a ejecutar. Notar el uso de delegados para especificar el proceso. Un proceso MPI recibe un diccionario de objetos Comm, que son los canales para comunicarse con otros procesos MPI.

La clase ProcessGroup tiene esta estructura (según la información de metadata):

 

namespace Mpi { public class ProcessorGroup : IDisposable { public ProcessorGroup(Environment environment, Processor processor); public ProcessorGroup(string environment, Processor processor); public Environment Environment { get; } public ICollection<IAsyncResult> Results { get; } public void Dispose(); protected virtual void Dispose(bool disposing); public static void Process(string environmentConfigName, Processor processor); public void Start(); public void WaitForCompletion(); } }

El número y configuración de procesadores puede ser definida en el archivo App.config:

 

<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="Mpi" type="Mpi.ConfigurationSection, Mpi"/> </configSections> <Mpi> <Environments> <Environment name="MPIEnvironment"> <Hosts> <Host comms="MPI_COMM_WORLD" client="MpiClient1" service="MpiService1" /> <Host comms="MPI_COMM_WORLD" client="MpiClient2" service="MpiService2"/> <Host comms="MPI_COMM_WORLD" client="MpiClient3" service="MpiService3"/> </Hosts> </Environment> </Environments> </Mpi> <system.serviceModel> <client> <endpoint address="net.tcp://localhost:8080/MpiService" binding="netTcpBinding" bindingConfiguration="" contract="Mpi.IMpiService" name="MpiClient1"> <identity> <userPrincipalName value="" /> </identity> </endpoint> <endpoint address="net.tcp://localhost:8081/MpiService" binding="netTcpBinding" bindingConfiguration="" contract="Mpi.IMpiService" name="MpiClient2"> <identity> <userPrincipalName value="" /> </identity> </endpoint> <endpoint address="net.tcp://localhost:8082/MpiService" binding="netTcpBinding" bindingConfiguration="" contract="Mpi.IMpiService" name="MpiClient3"> <identity> <userPrincipalName value="" /> </identity> </endpoint> </client> <behaviors> <serviceBehaviors> <behavior name="MpiServiceBehavior"> <serviceDebug httpHelpPageEnabled="false" httpsHelpPageEnabled="false" includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="MpiServiceBehavior" name="MpiService1"> <endpoint address="net.tcp://localhost:8080/MpiService" binding="netTcpBinding" bindingConfiguration="" name="MpiServiceEndpoint" contract="Mpi.IMpiService" /> </service> <service behaviorConfiguration="MpiServiceBehavior" name="MpiService2"> <endpoint address="net.tcp://localhost:8081/MpiService" binding="netTcpBinding" bindingConfiguration="" name="MpiServiceEndpoint" contract="Mpi.IMpiService" /> </service> <service behaviorConfiguration="MpiServiceBehavior" name="MpiService3"> <endpoint address="net.tcp://localhost:8082/MpiService" binding="netTcpBinding" bindingConfiguration="" name="MpiServiceEndpoint" contract="Mpi.IMpiService" /> </service> </services> </system.serviceModel> <system.runtime.serialization> <dataContractSerializer> <declaredTypes> </declaredTypes> </dataContractSerializer> </system.runtime.serialization> </configuration>

Jeje, usan <host..>…  Me recuerda a AjMessages… 😉

La ejecución de programa produce:

Bueno, no vamos a decir “Huy, que bruto que programa”, pero es mi primer programa MPI. Hay 3 “ranks”, porque así esta configurado en el archivo de arriba.

Encontran varios ejemplos ejecutables en la distribución de Pure MPI.NET. En mi opinión, es una interesante implementación de ideas de MPI, con algunas vueltas de tuerca adaptadas al mundo .NET: generics y delegates , bienvenidos.

¿Grid y MPI? Puede ser. Tengo que estudiar las referencias mencionadas en el “paper” que nombré al principio. Aunque ese trabajo está dedicado a cuestiones de alto rendimiento, tiene un buen resumen conceptual de los modelos de ejecución, y las relaciones posibles entre MPI, CCR, y DSS.

(Había publicado este artículo en “anglish”, Angel’s English, en:
Message Passing Interface, CCR, DSS, and Pure MPI.NET
)

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com