Raspberry Fields Forever

Depuis sa sortie, je suis en admiration devant les raspberry Pi, ça sert à tout, c'est pas très cher et linux fonctionne dessus. Dans des temps anciens, j'ai étudié le calcul parallèle , notamment MPI et PVM. C'était marrant, mais je n'en ai pas fait mon métié. En fouillant un peu l'internet, j'ai vu qu'il était relativement simple de monter des raspberry en cluster, d'ou l'idée de faire le mien: un petit cluster Pi pédagogique.
Le Hardware
Pour se faire, Amazon est ton ami: les bestiolles: https://www.amazon.fr/gp/product/B01CCOXV34/ , j'en ai pris 6 Le 'mini' rack: https://www.amazon.fr/gp/product/B01COU8Z1O/ L'alimentation: https://www.amazon.fr/gp/product/B00YTJ45HM/ Les cables d'alimentation: https://www.amazon.fr/gp/product/B00OOOHPN8/ Le switch: https://www.amazon.fr/gp/product/B00A33BYRC/ Les RJ45 de 30 cm: https://www.amazon.fr/gp/product/B00DCWFZO4/ Les MicroSD: https://www.amazon.fr/gp/product/B0162YQG2I/
Le Software
Le système d'exploitation
Sans surprise une raspbian. J'ai fais une seule installation propre:
  1. Serveur SSH
  2. Montage NFS sur un synology pour les datas communes 192.168.1.7:/volume1/nfscpi /usr/local nfs defaults 0 0
Activation du service rpcbin pour nfs
systemctl enable rpcbind
Editer le fichier /etc/hosts ou utilisé votre dns privé.
127.0.0.1    localhost
::1     localhost ip6-localhost ip6-loopback
ff02::1     ip6-allnodes
ff02::2     ip6-allrouters
192.168.1.50    cpi1.andytoys.fr cpi1
192.168.1.51    cpi2.andytoys.fr cpi2
192.168.1.52    cpi3.andytoys.fr cpi3
192.168.1.53    cpi4.andytoys.fr cpi4
192.168.1.54    cpi5.andytoys.fr cpi5
192.168.1.55    cpi6.andytoys.fr cpi6
127.0.1.1   raspberrypi
Puis j'ai mounté ma carte sd sur mon pc de bureau:
dd if=/dev/sdi of=image_cpi bs=2048
et cloné l'image sur chaque carte sd:
dd if=image_cpi of=/dev/sdi bs=2048
Ensuite, il suffit de changer la conf (ip, nom réseau, etc ...) spécifique à chaque noeud.
Manager le tout
Pour faire des installations en parallèle sur les nœuds du cluster PI, j'ai utilisé clusterssh sur mon poste de travail.
apt install clusterssh
Il fait une copie de ce que l'utilisateur tape au clavier sur tous les nœuds. Depuis la machine ou cssh est lancé, il faut copié votre clé publique ssh sur tous les noeuds et créer le fichier /etc/clusters
 clusterpi cpi1 cpi2 cpi3 cpi4 cpi5 cpi6 
Et lancer
cssh user@clusterpi
MPI
Via cssh:
apt install mpi-default-dev
apt install mpi-default-bin
Sur un des nœuds: J'ai récupéré un fichier example du calcul de pi :cpi.c sur le site de MPI.
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
 *  (C) 2001 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

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

double f(double);

double f(double a)
{
    return (4.0 / (1.0 + a*a));
}

int main(int argc,char *argv[])
{
    int    n, myid, numprocs, i;
    double PI25DT = 3.141592653589793238462643;
    double mypi, pi, h, sum, x;
    double startwtime = 0.0, endwtime;
    int    namelen;
    char   processor_name[MPI_MAX_PROCESSOR_NAME];

    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
    MPI_Get_processor_name(processor_name,&namelen);

    fprintf(stdout,"Process %d of %d is on %s\n",
        myid, numprocs, processor_name);
    fflush(stdout);

    n = 2000000000;         /* default # of rectangles */
    if (myid == 0)
    startwtime = MPI_Wtime();

    MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);

    h   = 1.0 / (double) n;
    sum = 0.0;
    /* A slightly better approach starts from large i and works back */
    for (i = myid + 1; i <= n; i += numprocs)
    {
    x = h * ((double)i - 0.5);
    sum += f(x);
    }
    mypi = h * sum;

    MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

    if (myid == 0) {
    endwtime = MPI_Wtime();
        printf("pi is approximately %.16f, Error is %.16f\n",
           pi, fabs(pi - PI25DT));
    printf("wall clock time = %f\n", endwtime-startwtime);           
    fflush(stdout);
    }

MPI_Finalize();
return 0;
}
J'ai fixé n = 2000000000 Créé un fichier ~/machine qui contient le nom de vos noeuds:
cpi1
cpi2
cpi3
cpi4
cpi5
cpi6
Compilation:
mpicc -g -O3 cpi.c  -o /usr/local/cpi  -lm
Execution:
mpiexec -machinefile machine  -n <nombre de process>  /usr/local/cpi
Les resultats
Raspberry Pi:
model name   : ARMv7 Processor rev 4 (v7l)
BogoMIPS    : 38.40
Sur 1 noeud à 4 coeurs:
mpiexec   -n 4 /usr/local/cpi
pi is approximately 3.1415926535898393, Error is 0.0000000000000462
wall clock time = 37.888490
Sur l'ensemble du cluster 6*4 coeurs:
 mpiexec -machinefile machine  -n 24 /usr/local/cpi
 pi is approximately 3.1415926535898175, Error is 0.0000000000000244
 wall clock time = 6.369657
ça a le mérite de fonctionner, niveau perf c'est pas top ! vu la puissance d'un raspberry PI. A titre indicatif, sur mon pc de bureau:
model name   : Intel(R) Core(TM) i5-3350P CPU @ 3.10GHz
stepping    : 9
cpu MHz     : 3112.109
cache size  : 6144 KB
bogomips    : 6186.28


mpiexec -n 4 ./cpi
pi is approximately 3.1415926535898393, Error is 0.0000000000000462
wall clock time = 2.342589
C'était juste pour m'amuser un peu. Joyeuses fêtes à tous.
comments powered by Disqus