Sumowanie elementów szeregu zbieżnego

    -- Sebastian Pawlak, 2000.



Kod źródłowy pliku "main.c":

/* Program sumuje `MAX' elementow szeregu zbieznego przy uzyciu MPI_Reduce.
 * Program dziala w trybie point-to-point
 * s1222, 2000.03.19
 *
 * Wykorzystane zostaly funkcje tworzace komunikator.
 * Proces 0 (master) zostanie wylaczony z MPI_COMM_WORLD i w ten
 * sposob zostanie wylaczony z obliczen (bedzie oczekiwal na wyniki
 * obliczen slave`ow).
 *
 * MPI_Reduce zbiera ze wszystkich procesow bufory dokonujac zadanej
 * operacji arytmetycznej / logicznej na odpowiadajacych sobie elementach
 * tych buforow - wynik operacji jest zwracany do bufora docelowego.
 * Funkcja uzywa algorytmu drzewiastego do zbierania wynikow.
 *
 * schemat zrownoleglenia laczenia buforow (wraz z wykonaniem zadanej
 * operacji arytmetycznej) za pomoca MPI_Reduce
 *
 *   0     1     2     3     4     5     6     7
 *   |     |     |     |     |     |     |     |
 *   |<----|     |<----|     |<----|     |<----|
 *   |op   |     |op   |     |op   |     |op   |
 *   |     |     |     |     |     |     |     |
 *   |<----------|     |     |<----------|     |
 *   |op   |     |     |     |op   |     |     |
 *   |     |     |     |     |     |     |     |
 *   |<----------------------|     |     |     |
 *   |op   |     |     |     |     |     |     |
 *
 * zakladajac ze proces 0 posiada bufor[5] = { 5, 7, 2 ,1 ,0 }, natomiast
 *               proces 1 posiada bufor[5] = { 2, 0, 5, 2, 8 },
 *               to proces 0 (root), dla zadanej operacji MPI_SUM
 *                    bedzie mail wynik[5] = { 7, 7, 7, 3, 8 };
 * dostepne operacje:
 * MPI_MAX    - Maximum,               MPI_MIN  - Minimum,
 * MPI_SUM    - Sum,                   MPI_PROD - Product (mnozenie),
 * MPI_LAND   - Logical AND,           MPI_BAND - Bitwise AND,
 * MPI_LOR    - Logica OR,             MPI_BOR  - Bitwise OR,
 * MPI_LXOR   - Logical Exclusive OR,  MPI_BXOR - Bitwise Exclusive OR,
 * MPI_MAXLOC - Maximum and Location of Maximum,
 * MPI_MINLOC - Minimum and Location of Minimum.
 */
#include <stdio.h>
#include "mpi.h"

#define MAX 3000000

int main(int argc, char **argv)
{
    int rank, size;
    int i, xx, yy;
    MPI_Status status;
    double wynik, suma = 0;
    double startTime, endTime;

    MPI_Group staraGrupa, nowaGrupa;
    MPI_Comm nowyKomunikator;
    int procesWykluczany[] = { 0 }; /* master */
 
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    /**************************
     * tworzenie komunikatora *
     **************************/
    /* pobranie procesor nalezacych do grupy identyfikowanej przez komunikator MPI_COMM_WORLD */
    MPI_Comm_group(MPI_COMM_WORLD, &staraGrupa);
    
    /* wykluczenie z otrzymanej grupy procesu numer 0 */
    MPI_Group_excl(staraGrupa, 1, procesWykluczany, &nowaGrupa);
    
    /* tworzenie komunikatora na podstawie wyznaczonej nowej grupy */
    MPI_Comm_create(MPI_COMM_WORLD, nowaGrupa, &nowyKomunikator);

    MPI_Comm_size(nowyKomunikator, &size);
    MPI_Comm_rank(nowyKomunikator, &rank);

    printf("rank: %d  \n", rank);

    if(rank != 0 && rank != MPI_UNDEFINED) {  /* nie master */
        xx = (rank - 1) * (MAX / (size - 1));
        yy = (rank) * (MAX / (size - 1));
    
        for(i = xx; i < yy ; i++)
            suma += (1 / (double)(1 + i));
        printf("suma czesciowa z procesu nr %d: %f\n", rank, suma);

        MPI_Reduce(&suma, &wynik, 1, MPI_DOUBLE, MPI_SUM, 0,
                   nowyKomunikator);   /* przesylanie `sum', wraz z dodawaniem,
                                        * do `wynik' w procesie 0
                                        */
    } else if(rank != MPI_UNDEFINED) {

        startTime = MPI_Wtime();
        suma = 0;
        MPI_Reduce(&suma, &wynik, 1, MPI_DOUBLE, MPI_SUM, 0,
                   nowyKomunikator);   /* zbieranie wynikow od slaveow ;
                                        * master juz nie wysyla danych !!!
                                        */
        endTime = MPI_Wtime();

        printf("wynik: %f\n", wynik);
        printf("czas %f sek.\n", endTime - startTime);
    }

/*  MPI_Comm_free(nowyKomunikator);
    MPI_Group_free(&nowaGrupa);
    MPI_Group_free(&staraGrupa);
  */
    MPI_Finalize();
    return 0;
}
w3cw3c
automatyka przemysłowa