C > PVM

TitrePVM
Postée le19-10-2008
Affichée780
Mini-lien
Description

Eliminiation de Gauss

EtatNe contient pas d'erreurs. Ne contient pas d'erreurs.
Code d'insertion
Options
Afficher les numéros de lignes  Mettre la source en plein ecran  Selectionner la source  Partager sur Facebook 
Téléchargement Telecharger en format txt  Telecharger en format pdf  Telecharger en format c
Plein ecran
#include <stdio.h>
#include <sys/types.h>
#include "pvm3.h"

#define GRPNAME "tokenring"

void main(int argc, char ** argv) {
    int NPROC = 8;              /* default nb of proc */
    int mytid;                  /* my task id */
    int *tids;                  /* array of task id */
    int me;                     /* my process number */
    int i;
       
        int N;
        char nom[255];
        char nomsortie[255];
       
        //vérification du nombre d'argument
        if (argc != 4){
                printf ("Usage: %s <matrix size><matrix name><matrix name out>\n", argv[0]);
                exit (-1);
        }
        // taille de la ligne de la matrice
        N = atoi ( argv[1] );

        //localité de la matrice
        strcpy(nom, argv[2]);

        strcpy(nomsortie, argv[3]);

    /* enroll in pvm */
    mytid = pvm_mytid();

    /* determine the size of my sibling list */
    NPROC = pvm_siblings(&tids);

    /* WARNING: tids are in order of spawning, which is different from
       the task index JOINING the group */


    me = pvm_joingroup( GRPNAME ); /* me: task index in the group */
    pvm_barrier( GRPNAME, NPROC );
    pvm_freezegroup ( GRPNAME, NPROC );
    for ( i = 0; i < NPROC; i++) tids[i] = pvm_gettid ( GRPNAME, i);

/*--------------------------------------------------------------------------*/
/*           all the tasks are equivalent at that point                     */
       
     dowork( me, tids, NPROC, nom, N, nomsortie);

     pvm_lvgroup( GRPNAME );
     pvm_exit();
}


void matrix_load ( char nom[], double *tab, int N, int nproc, int tids[]) {
        FILE *f;
        int i,j;
        double buf[N];
        double toto;
        int num_envoi;
        int ligne_courant=0;

        if ((f = fopen (nom, "r")) == NULL) { perror ("matrix_load : fopen "); }


  for (i=0; i<N; i++) {
        if(i%nproc == 0){
                for (j=0; j<N; j++) {
                        fscanf (f, "%lf ", &toto);
                        *(tab+ligne_courant*N+j) = toto;
                        //printf ("%lf ",*(tab+ligne_courant*N+j));
                }
                ligne_courant ++;
        }else{
                num_envoi = i%nproc;
                for (j=0; j<N; j++) {
                        fscanf (f, "%lf ", &buf[j] );
                }
                pvm_initsend(PvmDataDefault);
                pvm_pkdouble(buf,N,1);
                pvm_send(tids[num_envoi], 0);
        }
  }
  fclose (f);
}




void matrix_save ( char nom[], double *tab, int N , int nproc, int tids[]) {
  FILE *f;
  int i,j;
  double buf;

  if ((f = fopen (nom, "w")) == NULL) { perror ("matrix_save : fopen "); }

  for (i=0; i<N; i++) {
        if(i%nproc == 0){
                for (j=0; j<N; j++){
                        fprintf (f,"%8.2f", *(tab + i*(N/nproc)+j));
                }
                fprintf (f, "\n");
        }else {
                pvm_recv(tids[i%nproc],-1);
                       
                for (j=0; j<N; j++) {
                        pvm_upkdouble(&buf,1,1);
                        fprintf (f,"%8.2f", buf);
                }
                fprintf (f, "\n");
        }

  }
fprintf (f, "\n");
fclose (f);
}

void matrix_display ( double *tab,int  N ) {
  int i,j;

  for (i=0; i<N; i++) {
    for (j=0; j<N; j++) {
      printf ("%8.2f ", *(tab+i*N+j) );
    }
    printf ("\n");
  }

}

void gauss ( double * tab, int N, int nproc, int me, int tids[] ) {
  int i,j,k,l;
  double pivot;
  double buffer[N];
  double buf;
  int decalage = 0;

  for(k=0;k<(N-1);k++)
        {
                //le processeur a le pivot en cour
                if(k%nproc==me)
                {
                        for(j=k; j < N ;j++){
                                buffer[j] = *(tab + ((k/nproc)*N) + j);
                        }
                        //envoi de la ligne
                        pvm_initsend(PvmDataDefault);
                        pvm_pkdouble(&buffer[k],N-k,1);
                        for(l=0; l<nproc;l++){
                                if(l != me){
                                        pvm_send(tids[l], 0);
                                }
                        }
                }
                else
                {
                        pvm_recv(tids[k%nproc],-1);
                        pvm_upkdouble(&buffer[k],N-k,1);
                       
                }

                if(me>(k%nproc)){
                        decalage=(k/nproc);
                }else{
                        decalage=(k/nproc) + 1;
                }

                for(i=decalage;i<(N/nproc);i++)
                {
                        pivot = (*(tab + i * N + k)/buffer[k]);
                        for(j=k;j<N;j++)
                        {
                                *(tab + i * N +j) = *(tab + i * N + j) - pivot*buffer[j];
                        }
                }
        }
}

/* Simple example passes a token around a ring */

dowork( int me, int tids[], int nproc, char nom[255], int N, char nomsortie[255]) {
        FILE *f;
        struct timeval tv1, tv2;        /* for timing */
        int duree;
        double *tab, pivot;
        int i,j,k = 0,l;
        double buf;
        double buffer[N];
        int num_envoi;
        int decalage = 0;
        int ligne_courant = 0;
        double coeff;

        if ( (tab = malloc(N*(N/(nproc))*sizeof(double))) == NULL ) {
                printf ("Cant malloc %d bytes\n", N*N*sizeof(double));
                exit (-1);
        }

        if(me == 0)
        {
                gettimeofday( &tv1, (struct timezone*)0 );
                matrix_load ( nom , tab, N, nproc, tids );
                gettimeofday( &tv2, (struct timezone*)0 );
                duree = (tv2.tv_sec - tv1.tv_sec) * 1000000 + tv2.tv_usec - tv1.tv_usec;
                printf ("me : %d, loading time: %10.8f sec.\n", me, duree/1000000.0 );

        }else{
                for(i=0; i<(N/nproc);i++){
                        pvm_recv(-1,-1);
                        for (j=0; j<N; j++) {
                                pvm_upkdouble(&buf,1,1);
                                *(tab + i*N + j) = buf;
                        }
                }
               
        }
        pvm_barrier( GRPNAME, nproc );
        if (me == 0){
                gettimeofday( &tv1, (struct timezone*)0 );
        }
        gauss (tab,N,nproc,me,tids);
        if (me ==0){
                gettimeofday( &tv2, (struct timezone*)0 );
                duree = (tv2.tv_sec - tv1.tv_sec) * 1000000 + tv2.tv_usec - tv1.tv_usec;
                printf ("me : %d, calcul time: %10.8f sec.\n", me, duree/1000000.0 );
        }
        pvm_barrier( GRPNAME, nproc );
        ligne_courant = 0;
        if(me == 0)
        {
                gettimeofday( &tv1, (struct timezone*)0 );
                matrix_save (nomsortie, tab, N, nproc, tids);
                gettimeofday( &tv2, (struct timezone*)0 );
                duree = (tv2.tv_sec - tv1.tv_sec) * 1000000 + tv2.tv_usec - tv1.tv_usec;
                printf ("me : %d, save time: %10.8f sec.\n", me, duree/1000000.0 );
               
               
        }else{
                //num_envoi = i%nproc;
                for (i=0; i < N/(nproc); i++) {
                        for (j=0; j < N; j++) {
                                buffer[j] = *(tab + N*i + j);
                        }
                        pvm_initsend(PvmDataDefault);
                        pvm_pkdouble(buffer,N,1);
                        pvm_send(tids[0], 0);
                        ligne_courant++;
                }
        }
        free(tab);
}