Raspberry Fields Forever

Par Ghislain 20 July 2018
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 [email protected]
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