Ir al contenido principal

This is my blog, more about me at marianoguerra.github.io

🦋 @marianoguerra.org 🐘 @marianoguerra@hachyderm.io 🐦 @warianoguerra

Resolviendo ejercicios de MPI (y tambien en erlang) Parte 2

enunciado del ejercicio 2

Write a program that reads an integer value from the terminal and distributes the value to all of the MPI processes. Each process should print out its rank and the value it received. Values should be read until a negative integer is given as input.

lo resolvi ahi nomas con MPI, lo corri y todo andaba bien excepto que los procesos no imprimian (excepto el rank 0), pelee, toque, agregue fflush(stdout) y printf's por todos lados (clasica estrategia de debugger artesanal de C :D) y nada, copie el ejercicio resuelto de la pagina y le pasa lo mismo, asi que asumo que es algo relacionado con que mi notebook no es un cluster y encima tiene un solo core. aunque no sirva de mucho, aca esta la resolucion en C:

#include <stdio.h>
#include <mpi.h>

int main (int argc, char** argv) {
int rank, size, value, i;
MPI_Status status;

MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
printf("process %d of %d\n", rank, size);

do {
if(rank == 0) {
printf("give me a value: ");
scanf("%d", &value);
MPI_Bcast(&value, 1, MPI_INT, 0, MPI_COMM_WORLD);
}
else {
MPI_Recv(&value, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
printf("process %d received %d\n", rank, value);
fflush(stdout);
}
} while(value >= 0);
printf("negative value, closing\n");

MPI_Finalize();
return 0;
}


el programa compila y corre, por el hecho de que me pida los valores sucesivos asumo que los procesos estan recibiendo los valores (si no se colgaria en el broadcast) pero de todas formas no imprime.

bueno, pase a la resolucion en erlang, aca esta el codigo:

-module(ej2).
-export([run/1]).

run(Total) ->
Pids = spawn_listeners(Total),
get_values(Pids).

spawn_listeners(Count) -> spawn_listeners(Count, []).

spawn_listeners(0, Pids) -> Pids;
spawn_listeners(Count, Pids) ->
Pid = spawn(fun() -> listener() end),
spawn_listeners(Count - 1, [Pid|Pids]).

listener() ->
receive
Number ->
io:format("process ~p received ~p~n", [self(), Number]),
if
Number >= 0 -> listener();
true ->
io:format("negative value, closing ~p~n", [self()])
end
end.

get_values(Pids) ->
case io:get_line("give me a value (negative to quit): ") of
{error, Reason} ->
io:format("error reading value (~p)~n", [Reason]);
eof ->
io:format("error reading value~n");
Value ->
case string:to_integer(Value) of
{error, Reason} ->
io:format("invalid value (~p)~n", [Reason]),
get_values(Pids);
{IntValue, _Rest} ->
send_values(IntValue, Pids),
if
IntValue >= 0 -> get_values(Pids);
true -> io:format("negative value, closing~n")
end
end
end.

send_values(Value, Pids) ->
lists:foreach(fun(Pid) -> Pid ! Value end, Pids).



algunas observaciones, en este programa se pueden crear multiples grupos que escuchen a multiples entradas y de tamaños variables sin cambiar el codigo.
Una observacion sobre erlang es lo raro que es la convencion de los delimitadores, por ejemplo:

  • Si es la ultima sentencia de una funcion va con punto (a excepcion de que este haciendo pattern matching en cuyo caso todos menos la ultima son con punto y coma)
  • Si es una sentencia comun dentro de una funcion termina en coma, a excepcion de que sea la ultima de la funcion (en cuyo caso punto o punto y coma como vimos arriba) pero tambien a excepcion de que sea la ultima de un if, case, receive en cuyo caso es ;, pero no si es la ultima del ultimo statement en cuyo caso no lleva nada.
estas son algunas nomas, no me costo mucho entenderlas pero lleva un tiempo acostumbrarse y por ahi le erras, mas si moves codigo o agregas statements en cuyo caso tenes que revisar los terminadores.

ejemplo de la salida del de erlang (probando enteros positivos, negativos y valores invalidos):



$ erl
Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.6.5 (abort with ^G)
1> c(ej2).
{ok,ej2}
2> ej2:run(4).
give me a value (negative to quit): 42
process received 42
process received 42
process received 42
process received 42
give me a value (negative to quit): 7
process received 7
process received 7
process received 7
process received 7
give me a value (negative to quit): -1
negative value, closing
process received -1
process received -1
process received -1
process received -1
negative value, closing
negative value, closing
negative value, closing
negative value, closing
ok
3> ej2:run(4).
give me a value (negative to quit): asd
invalid value (no_integer)
give me a value (negative to quit): -1
negative value, closing
process received -1
process received -1
process received -1
process received -1
negative value, closing
negative value, closing
negative value, closing
negative value, closing
ok
4>

Resolviendo ejercicios de MPI(y tambien en erlang)

Como tarea en un grupo de la facultad del que formo parte tenemos que resolver ejercicios de MPI, como yo algo de idea de MPI tengo decidí también resolverlos en erlang para seguir aprendiendo mas de este lenguaje, acá van los enunciados del primer ejercicio y las resoluciones de ambos.

Write a program that uses MPI and has each MPI process print

Hello world from process i of n
using the rank in MPI_COMM_WORLD for i and the size of MPI_COMM_WORLD for n. You can assume that all processes support output for this example.

el ejercicio en C lo pueden ver en el post anterior así que acá pego el de erlang nomas

-module(ej1).
-export([run/1]).

run(Total, Total) -> ok;
run(Count, Total) ->
spawn(fun() -> salute(Total) end),
run(Count + 1, Total).

run(Total) -> run(0, Total).

salute(Total) ->
io:format("Hello world from ~p of ~p~n", [self(), Total]).


como en erlang no hay una forma de saber cuantos procesos totales hay dando vueltas (o al menos no es tan estatico como MPI) decidi pasarle el total y imprimir el PID.

para correrlo y ver la salida la forma facil es:

$ erl ej1.erl
Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.6.5 (abort with ^G)
1> c(ej1).
{ok,ej1}
2> ej1:run(4).
Hello world from of 4
Hello world from of 4
Hello world from of 4
Hello world from of 4
ok
3>

todo en orden, vamos a por el segundo

como nota al margen, donde hice el pattern matching de

run(Total, Total) -> ok;

podria haber hecho

run(0, _Total) -> ok;

y contar al reves en

run(Count + 1, Total).

por

run(Count - 1, Total).

pero me parecio mas simpatico contar para adelante :P

mpi en ubuntu

como instalar y usar mpi en ubuntu para programar?

sudo aptitude install mpich-bin libmpich1.0-dev ssh

iniciamos el servidor ssh:

sudo /etc/init.d/ssh start

creamos un archivo hello.c


/* C Example */
#include <stdio.h>
#include <mpi.h>

int main (int argc, char** argv)
{
int rank, size;

MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
printf( "Hello world from process %d of %d\n", rank, size );
MPI_Finalize();
return 0;
}


compilamos el ejemplo:

mpicc hello.c -o hellompi

corremos el ejemplo con 4 procesos:

mpirun -np 4 ./hellompi

para que no nos pida el password por cada proceso hacemos lo siguiente

generamos las claves para el ssh

ssh-keygen -t dsa

y agregamos la clave a la lista autorizada (si ya tenes ~/.ssh/authorized_keys agrega la clave al final)

cp ~/.ssh/id_dsa.pub ~/.ssh/authorized_keys

y volia!

mariano@ganesha:~$ mpirun -np 4 ./hellompi
Hello world from process 0 of 4
Hello world from process 2 of 4
Hello world from process 1 of 4
Hello world from process 3 of 4

PD: yo ya tenia instalado build-essential, si no lo instala hay que instalarlo a mano
PD2: esto funciona en debian y derivados, en fedora supongo que hay que cambiar aptitude por yum y sale andando

Frase interesante

hoy leí esta frase:

Typesafe languages eliminate these problems by design. Instead of just exhorting programmers to be more careful, typesafe languages put mechanisms in place which guarantee that they cannot happen.

y mi cerebro pensó que esta buena la frase para aplicarla mas genéricamente:

Thing X eliminate these problems by design. Instead of just exhorting Users to be more careful, Thing X put mechanisms in place which guarantee that they cannot happen.

esto me paso después de leer sobre NewSqueak y Limbo en los cuales algunos problemas de la programacion concurrente no existen por cuestion de diseño. Pase a pensar en como se puede diseñar algo para que los problemas no puedan suceder.

quotequotequote

soy adicto a los quotes :)

The cheapest, fastest, and most reliable components are those that aren't there.

-- Gordon Bell

One of my most productive days was throwing away 1000 lines of code.

-- Ken Thompson

Deleted code is debugged code.

-- Jeff Sickel

The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.

-- Brian W. Kernighan, in the paper Unix for Beginners (1979)

Beauty is more important in computing than anywhere else in technology because software is so complicated. Beauty is the ultimate defence against complexity.

-- David Gelernter

UNIX was not designed to stop its users from doing stupid things, as that would also stop them from doing clever things.

-- Doug Gwyn

If you're willing to restrict the flexibility of your approach, you can almost always do something better.

-- John Carmack

All software sucks, be it open-source [or] proprietary. The only question is what can be done with particular instance of suckage, and that's where having the source matters.

-- viro [http://www.ussg.iu.edu/hypermail/linux/kernel/0404.3/1344.html]

It's not that perl programmers are idiots, it's that the language rewards idiotic behavior in a way that no other language or tool has ever done.

-- Erik Naggum, comp.lang.lisp

Simplicity is prerequisite for reliability.

-- Edsger W. Dijkstra

Beware of "the real world". A speaker's apeal to it is always an invitation not to challenge his tacit assumptions.

-- Edsger W. Dijkstra

Unix is a junk OS designed by a committee of PhDs

-- Dave Cutler

Forward thinking was just the thing that made multics what it is today.

-- Erik Quanstrom

I remarked to Dennis [Ritchie] that easily half the code I was writing in Multics was error recovery code. He said, "We left all that stuff out [of Unix]. If there's an error, we have this routine called panic, and when it is called, the machine crashes, and you holler down the hall, 'Hey, reboot it.'"

-- Tom Van Vleck [http://www.multicians.org/unix.html]

The key to performance is elegance, not battalions of special cases.

-- Jon Bentley and Doug McIlroy

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

   -- Bill Gates

Haskell is faster than C++, more concise than Perl, more regular than Python, more flexible than Ruby, more typeful than C#, more robust than Java, and has absolutely nothing in common with PHP.

-- Autrijus Tang

Object-oriented design is the roman numerals of computing.

-- Rob Pike

{ajh} I always viewed HURD development like the Special Olympics of free software.


We have persistant(sic) objects, they're called files.

-- Ken Thompson

Simplicity is the ultimate sophistication.

   -- Leonardo da Vinci

Increasingly, people seem to misinterpret complexity as sophistication, which is baffling---the incomprehensible should cause suspicion rather than admiration. Possibly this trend results from a mistaken belief that using a somewhat mysterious device confers an aura of power on the user.

-- Niklaus Wirth

y como cierre para divertirse un buen rato:

http://harmful.cat-v.org/software/java
http://harmful.cat-v.org/software/c++/

Anathema @ Bs As

Flor de recital el de Anathema en el ND Ateneo, si no escuchaste la banda te lo recomiendo encarecidamente por el bien de las focas bebes (?)


fui con mi hermano, nos pegamos un paseo de un dia por bs as y sali corriendo del recital un tema antes que terminara para llegar justo a tomarme el colectivo que me depositaria 12 horas despues en la silla del trabajo :D.

El sonido, la puesta en escena y las canciones estuvieron geniales.

Unas fotos sacadas por mi hermano( http://flickr.com/ignacioguerra)




Instalando archivos faltantes de paquetes en debian

Como seguro me pasa de nuevo y mi memoria es debil voy a documentar que hice aca asi la proxima me autoleo

luego de correr el script anterior copiamos los .deb culpables buscando con

dpkg -S /ruta/completa/al/archivo/faltante

a una carpeta, luego instalamos binutils para tener el comando ar que se usa para descomprimir los .deb

(Los .deb estan en /var/cache/apt/archives si no hiciste apt-get clean)

ar x archivo.deb

nos deja varios archivos, hacemos

tar -xvzf data.tar.gz

y despues

cp ./ruta/completa/al/archivo/faltante /ruta/completa/al/archivo/faltante

(notece que el primero tiene un "." adelante

bueno, esto fue el daytona USA para sega saturn, espero que lo hayan disfrutado y seguimos con mas nivel X (?)

Esto podria ser muy facil de automatizar, pero como no creo que le pase a alguien en el planeta mas de una vez lo dejo como ejercicio para el lector.

bash <3

por alguna razon un server que tengo no me esta instalando todos los archivos de unos paquetes, en varias instalaciones anteriores si lo habia hecho y no importa cuanto purge, rm -rf, locate y demases nunca se instalan todos los archivos, por eso necesitaba listar los archivos no instalados de un conjunto de paquetes con un patron de nombre comun. El script quedo asi.

for i in $(dpkg -L $(dpkg --get-selections | grep gforge | awk '{print $1}')); do [ ! -e $i ] && echo $i; done

ahora a usar ar e instalar a mano los archivos faltantes, por alguna razon son todos los scripts de cron y un archivo de configuracion en etc... vaya uno a saber que magia negra hace que no se instalen..

Hint: cambien gforge en el grep por el patron a matchear (aunque no creo que mucha gente necesite algo asi :P

Querida AFIP

window.navigate no anda en firefox ni safari, por favor use window.location asi no tengo que levantar firebug para escribir la direccion a mano para poder validar mi domicilio.

atte.
el pueblo oprimido

PD: le mande el mail, esperemos su respuesta..