mpi mnozenje matrica
22.01.2014. u 14:38 · pre 155 meseci
#1
Radim neki mali projekat iz mpi-a i imam nekih problema. Pa ako mozete pomoci.
Kod je dolje ispod. Radi se o mnozenju matrica.
Ovo je tekst projekta
Pojašnjenje za MPI: Samo jedan čvor (master, npr. broj 0) ima matrice A i B (jer se one unose samo na jednom mjestu, to što se popunjavaju konstantama je stavljeno da se pojednostavi kod za vas, u stvarnom slučaju se uzimaju iz fajlova koji ne moraju biti dostupni svim čvorovima, itd) koje treba da dostavi (cijele ili dijelove) svim čvorovima koji množe matrice, a nakon množenja treba da na masteru rekonstruiše matricu C na osnovu parcijalnih rješenja sa svih čvorova. Kad se matrica C kompletira, saberu se svi elementi i dobije suma (ovo sabiranje je samo za provjeru, nas interesuje cijela matrica C).
Kad kompajliram kod kaze da je greska u scatterv. I ako mozete da pojasnite kako radi scatterv? Ja sam to pokusao nekako ali ne ide.
Kod je dolje ispod. Radi se o mnozenju matrica.
Ovo je tekst projekta
Pojašnjenje za MPI: Samo jedan čvor (master, npr. broj 0) ima matrice A i B (jer se one unose samo na jednom mjestu, to što se popunjavaju konstantama je stavljeno da se pojednostavi kod za vas, u stvarnom slučaju se uzimaju iz fajlova koji ne moraju biti dostupni svim čvorovima, itd) koje treba da dostavi (cijele ili dijelove) svim čvorovima koji množe matrice, a nakon množenja treba da na masteru rekonstruiše matricu C na osnovu parcijalnih rješenja sa svih čvorova. Kad se matrica C kompletira, saberu se svi elementi i dobije suma (ovo sabiranje je samo za provjeru, nas interesuje cijela matrica C).
Kad kompajliram kod kaze da je greska u scatterv. I ako mozete da pojasnite kako radi scatterv? Ja sam to pokusao nekako ali ne ide.
Code:
/* File taken from http://www.hp-see.eu/hp-see-computing-challenge */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#include "mpi.h"
void ispis(long N, double *x)
{
long i, j;
for(i = 0; i < N; i ++)
{
for(j = 0; j < N; j ++){
printf(" %lf",x[i * N + j]);
}
printf("\n");
}
}
double gettime(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + 1e-6 * tv.tv_usec;
}
void matfill(long N, double *mat, double val) {
long i, j;
for(i = 0; i < N; i ++)
for(j = 0; j < N; j ++)
mat[i * N + j] = val;
}
void matmul(long N, double *a, double *b, double *c) {
long i, j, k;
int brojcvorova, suma=0;
MPI_Comm_size(MPI_COMM_WORLD,&brojcvorova);
int *temp=(int *) malloc(N * sizeof(int));
int *temp2=(int *) malloc(N * sizeof(int));
for(i=0;i<N;i++)
{
temp2[i]=suma+1;
temp[i]=(N*N)/brojcvorova;
suma+=temp[i];
}
temp2[0]=0;
temp[brojcvorova-1]+=(N*N)%brojcvorova;
MPI_Scatterv(a,temp2,temp,MPI_DOUBLE,c,N,MPI_DOUBLE,0,MPI_COMM_WORLD);
for (i = 0; i < N; i ++)
for (j = 0; j < N; j ++)
for (k = 0; k < N; k ++)
c[i * N + j] += a[i * N + k] * b[k * N + j];
}
int main(int argc, char **argv) {
long N;
double *A, *B, *C, t;
int brojProcesa, ukupno,cvor;
int provjera=MPI_Init(&argc, &argv);
if (provjera!=MPI_SUCCESS) { //provjera da li je doslo do greske pri pokretanju mpi programa
printf("Greska pri pokretanju MPI programa.\n");
MPI_Abort(MPI_COMM_WORLD, provjera);
}
MPI_Comm_size(MPI_COMM_WORLD, &brojProcesa);
MPI_Comm_rank(MPI_COMM_WORLD, &cvor);
if(argc!=2)
{
if(cvor==0) printf("Netacan broj parametara!!\n");
MPI_Finalize();
return 1;
}
printf("Ukupan broj procesa %d Moj broj %d\n", brojProcesa,cvor);
MPI_Barrier(MPI_COMM_WORLD); //cekamo da svi dodju na isto mjesto
N = atoi(argv[1]);
double *bufer=(double *) malloc(N * N * sizeof(double));
A = (double *) malloc(N * N * sizeof(double));
B = (double *) malloc(N * N * sizeof(double));
C = (double *) malloc(N * N * sizeof(double));
if(cvor==0)
{
matfill(N, A, 1.0);
matfill(N, B, 2.0);
matfill(N, C, 0.0);
}
else { sleep(5); }
MPI_Barrier(MPI_COMM_WORLD);
MPI_Bcast(B,N*N,MPI_DOUBLE,0,MPI_COMM_WORLD);
MPI_Bcast(bufer,N*N,MPI_DOUBLE,0,MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
t = gettime();
matmul(N, A, B, bufer);
t = gettime() - t;
MPI_Gather(bufer,N,MPI_DOUBLE,C,N,MPI_DOUBLE,0,MPI_COMM_WORLD);
ispis(N,C);
//fprintf(stdout, "%ld\t%le\t%le\n", N, t, (2 * N - 1) * N * N / t);
//fflush(stdout);
free(A);
free(B);
free(C);
MPI_Finalize();
return EXIT_SUCCESS;
}
/* File taken from http://www.hp-see.eu/hp-see-computing-challenge */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#include "mpi.h"
void ispis(long N, double *x)
{
long i, j;
for(i = 0; i < N; i ++)
{
for(j = 0; j < N; j ++){
printf(" %lf",x[i * N + j]);
}
printf("\n");
}
}
double gettime(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + 1e-6 * tv.tv_usec;
}
void matfill(long N, double *mat, double val) {
long i, j;
for(i = 0; i < N; i ++)
for(j = 0; j < N; j ++)
mat[i * N + j] = val;
}
void matmul(long N, double *a, double *b, double *c) {
long i, j, k;
int brojcvorova, suma=0;
MPI_Comm_size(MPI_COMM_WORLD,&brojcvorova);
int *temp=(int *) malloc(N * sizeof(int));
int *temp2=(int *) malloc(N * sizeof(int));
for(i=0;i<N;i++)
{
temp2[i]=suma+1;
temp[i]=(N*N)/brojcvorova;
suma+=temp[i];
}
temp2[0]=0;
temp[brojcvorova-1]+=(N*N)%brojcvorova;
MPI_Scatterv(a,temp2,temp,MPI_DOUBLE,c,N,MPI_DOUBLE,0,MPI_COMM_WORLD);
for (i = 0; i < N; i ++)
for (j = 0; j < N; j ++)
for (k = 0; k < N; k ++)
c[i * N + j] += a[i * N + k] * b[k * N + j];
}
int main(int argc, char **argv) {
long N;
double *A, *B, *C, t;
int brojProcesa, ukupno,cvor;
int provjera=MPI_Init(&argc, &argv);
if (provjera!=MPI_SUCCESS) { //provjera da li je doslo do greske pri pokretanju mpi programa
printf("Greska pri pokretanju MPI programa.\n");
MPI_Abort(MPI_COMM_WORLD, provjera);
}
MPI_Comm_size(MPI_COMM_WORLD, &brojProcesa);
MPI_Comm_rank(MPI_COMM_WORLD, &cvor);
if(argc!=2)
{
if(cvor==0) printf("Netacan broj parametara!!\n");
MPI_Finalize();
return 1;
}
printf("Ukupan broj procesa %d Moj broj %d\n", brojProcesa,cvor);
MPI_Barrier(MPI_COMM_WORLD); //cekamo da svi dodju na isto mjesto
N = atoi(argv[1]);
double *bufer=(double *) malloc(N * N * sizeof(double));
A = (double *) malloc(N * N * sizeof(double));
B = (double *) malloc(N * N * sizeof(double));
C = (double *) malloc(N * N * sizeof(double));
if(cvor==0)
{
matfill(N, A, 1.0);
matfill(N, B, 2.0);
matfill(N, C, 0.0);
}
else { sleep(5); }
MPI_Barrier(MPI_COMM_WORLD);
MPI_Bcast(B,N*N,MPI_DOUBLE,0,MPI_COMM_WORLD);
MPI_Bcast(bufer,N*N,MPI_DOUBLE,0,MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
t = gettime();
matmul(N, A, B, bufer);
t = gettime() - t;
MPI_Gather(bufer,N,MPI_DOUBLE,C,N,MPI_DOUBLE,0,MPI_COMM_WORLD);
ispis(N,C);
//fprintf(stdout, "%ld\t%le\t%le\n", N, t, (2 * N - 1) * N * N / t);
//fflush(stdout);
free(A);
free(B);
free(C);
MPI_Finalize();
return EXIT_SUCCESS;
}
