To jest stara wersja strony!
# kompilator c CCOMP = mpicc # konsolidator LINK = mpicc MPIRUN = /usr/lib64/openmpi/bin/mpiexec # opcje optymalizacji: # wersja do debugowania # OPT = -g -DDEBUG -p # wersja zoptymalizowana do mierzenia czasu # OPT = -O3 -fopenmp -p # pliki naglowkowe #INC = -I../pomiar_czasu # biblioteki #LIB = -L../pomiar_czasu -lm LIB = -lm # zaleznosci i komendy heat: heat.o $(LINK) $(OPT) heat.o -o heat $(LIB) heat.o: heat.c $(CCOMP) -c $(OPT) heat.c $(INC) run: $(MPIRUN) -np 8 ./heat clean: rm -f *.o
# include <stdlib.h> # include <stdio.h> # include <math.h> # include "mpi.h" int main ( int argc, char *argv[] ); void heat_part ( int n, int p, int id, double x_min, double x_max ); /******************************************************************************/ int main ( int argc, char *argv[] ) { double a = 0.0; // lewy brzeg przedzialu double b = 1.0; // prawy brzeg przedzialu int i; int id; // rank int n; // liczba punktow dla kazdego wezla int p; // size double x_max; double x_min; MPI_Init ( &argc, &argv ); MPI_Comm_rank ( MPI_COMM_WORLD, &id ); MPI_Comm_size ( MPI_COMM_WORLD, &p ); n = 12; // liczba punktow dla kazdego wezla i = 0; // poczatkowa chwila czasu // wspolrzedna lewego punktu dla wezla id x_min = ( ( double )( p * n + 1 - id * n - i ) * a + ( double )( id * n + i ) * b ) / ( double ) ( p * n + 1 ); i = n + 1; // wspolrzedna prawego punktu dla wezla id x_max = ( ( double )( p * n + 1 - id * n - i ) * a + ( double )( id * n + i ) * b ) / ( double )( p * n + 1 ); heat_part ( n, p, id, x_min, x_max ); // obliczenia dla pojedynczego wezla MPI_Finalize ( ); } /******************************************************************************/ // obliczenia dla pojedynczego wezla - pojedynczego podobszaru /******************************************************************************/ void heat_part ( int n, int p, int id, double x_min, double x_max ) { double cfl; double *h; double *h_new; int i; int ierr; int j; int j_max; int j_min; double k; MPI_Status status; double t; double t_del; double t_max; double t_min; int tag; double wtime; double *x; double x_del; h = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // rozwiazanie dla t_i h_new = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // rozwiazanie dla t_i+1 x = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // wspolrzedne punktow k = 0.002 / ( double ) p; // przewodniosc cieplna j_min = 0; // indeksy krokow czasowych - min i max j_max = 100; t_min = 0.0; // chwile czasu - min i max t_max = 10.0; t_del = ( t_max - t_min ) / ( double ) ( j_max - j_min ); // krok czasowy Delta t x_del = ( x_max - x_min ) / ( double ) ( n + 1 ); // odstep miedzy punktami for ( i = 0; i <= n + 1; i++ ) { x[i] = ( ( double ) ( i ) * x_max + ( double ) ( n + 1 - i ) * x_min ) / ( double ) ( n + 1 ); } // ustawienie warunku poczatkowego for ( i = 0; i <= n + 1; i++ ) { h[i] = 95.0; } // sprawdzenie stabilnosci schematu cfl = k * t_del / x_del / x_del; if ( 0.5 <= cfl ) { printf ( " CFL condition failed.\n" ); exit ( 1 ); } wtime = MPI_Wtime ( ); //poczatek pomiaru czasu for ( j = 1; j <= j_max; j++ ) { // wymiana informacji z wezlami sasiednimi tag = 1; if ( id < p - 1 ) { MPI_Send ( &h[n], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD ); } if ( 0 < id ) { MPI_Recv ( &h[0], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD, &status ); } tag = 2; if ( 0 < id ) { // DO UZUPELNIENIA MPI_Send ( &h[1], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD ); } if ( id < p - 1 ) { // DO UZUPELNIENIA MPI_Recv ( &h[n+1], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD, &status ); } // implementacja wzoru roznicowego for ( i = 1; i <= n; i++ ) { h_new[i] = h[i] + t_del * ( k * ( h[i-1] - 2.0 * h[i] + h[i+1] ) / x_del / x_del + 2.0 * sin ( x[i] * t ) ); } // nowa chwila czasu t = ( ( double ) ( j - j_min ) * t_max + ( double ) ( j_max - j ) * t_min ) / ( double ) ( j_max - j_min ); // przygotowanie do nastepnego kroku czasowego for ( i = 1; i < n + 1; i++ ) { h[i] = h_new[i]; } if ( 0 == id ) h[0] = 100.0 + 10.0 * sin ( t ); if ( id == p - 1 ) h[n+1] = 75; } // koncowa wymiana informacji z wezlami sasiednimi tag = 11; if ( id < p - 1 ) { MPI_Send ( &h[n], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD ); } if ( 0 < id ) { MPI_Recv ( &h[0], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD, &status ); } tag = 12; if ( 0 < id ) { // DO UZUPELNIENIA MPI_Send ( &h[1], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD ); } if ( id < p - 1 ) { // DO UZUPELNIENIA MPI_Recv ( &h[n+1], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD, &status ); } wtime = MPI_Wtime ( ) - wtime; if ( id == 0 ) { printf ( "\n" ); printf ( " Wall clock elapsed seconds = %f\n", wtime ); } // wydruk wyniku printf ( "%2d T= %f\n", id, t ); printf ( "%2d X= ", id ); for ( i = 0; i <= n + 1; i++ ) { printf ( "%7.2f", x[i] ); } printf ( "\n" ); printf ( "%2d H= ", id ); for ( i = 0; i <= n + 1; i++ ) { printf ( "%7.2f", h[i] ); } printf ( "\n" ); free ( h ); free ( h_new ); free ( x ); return; }
# include <stdlib.h> # include <stdio.h> # include <math.h> # include "mpi.h" int main ( int argc, char *argv[] ); void heat_part ( int n, int p, int id, double x_min, double x_max ); /******************************************************************************/ int main ( int argc, char *argv[] ) { double a = 0.0; // lewy brzeg przedzialu double b = 1000000.0; // prawy brzeg przedzialu int i; int id; // rank int n; // liczba punktow dla kazdego wezla int p; // size double x_max; double x_min; MPI_Init ( &argc, &argv ); MPI_Comm_rank ( MPI_COMM_WORLD, &id ); MPI_Comm_size ( MPI_COMM_WORLD, &p ); n = 1000000; // liczba punktow dla kazdego wezla i = 0; // poczatkowa chwila czasu // wspolrzedna lewego punktu dla wezla id x_min = ( ( double )( p * n + 1 - id * n - i ) * a + ( double )( id * n + i ) * b ) / ( double ) ( p * n + 1 ); i = n + 1; // wspolrzedna prawego punktu dla wezla id x_max = ( ( double )( p * n + 1 - id * n - i ) * a + ( double )( id * n + i ) * b ) / ( double )( p * n + 1 ); heat_part ( n, p, id, x_min, x_max ); // obliczenia dla pojedynczego wezla MPI_Finalize ( ); } /******************************************************************************/ // obliczenia dla pojedynczego wezla - pojedynczego podobszaru /******************************************************************************/ void heat_part ( int n, int p, int id, double x_min, double x_max ) { double cfl; double *h; double *h_new; int i; int ierr; int j; int j_max; int j_min; double k; MPI_Status status; double t; double t_del; double t_max; double t_min; int tag; double wtime; double *x; double x_del; MPI_Request req1, req2, req3, req4; MPI_Status stat1, stat2, stat3, stat4; h = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // rozwiazanie dla t_i h_new = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // rozwiazanie dla t_i+1 x = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // wspolrzedne punktow k = 0.002 / ( double ) p; // przewodniosc cieplna j_min = 0; // indeksy krokow czasowych - min i max j_max = 100; t_min = 0.0; // chwile czasu - min i max t_max = 10.0; t_del = ( t_max - t_min ) / ( double ) ( j_max - j_min ); // krok czasowy Delta t x_del = ( x_max - x_min ) / ( double ) ( n + 1 ); // odstep miedzy punktami for ( i = 0; i <= n + 1; i++ ) { x[i] = ( ( double ) ( i ) * x_max + ( double ) ( n + 1 - i ) * x_min ) / ( double ) ( n + 1 ); } // ustawienie warunku poczatkowego for ( i = 0; i <= n + 1; i++ ) { h[i] = 95.0; } // sprawdzenie stabilnosci schematu cfl = k * t_del / x_del / x_del; if ( 0.5 <= cfl ) { printf ( " CFL condition failed.\n" ); exit ( 1 ); } wtime = MPI_Wtime ( ); //poczatek pomiaru czasu for ( j = 1; j <= j_max; j++ ) { // wymiana informacji z wezlami sasiednimi ///NON BLOCK if ( id > 0 ) { MPI_Irecv ( &h[0], 1, MPI_DOUBLE, id-1, 1, MPI_COMM_WORLD, &req1 ); } if ( id < p - 1 ) { MPI_Irecv ( &h[n+1], 1, MPI_DOUBLE, id+1, 2, MPI_COMM_WORLD, &req2 ); } ///END NON BLOCK if ( id > 0 ) { MPI_Isend ( &h[1], 1, MPI_DOUBLE, id-1, 2, MPI_COMM_WORLD, &req3 ); } if ( id < p - 1 ) { MPI_Isend ( &h[n], 1, MPI_DOUBLE, id+1, 1, MPI_COMM_WORLD, &req4 ); } // implementacja wzoru roznicowego for ( i = 2; i <= n-1; i++ ) { h_new[i] = h[i] + t_del * ( k * ( h[i-1] - 2.0 * h[i] + h[i+1] ) / x_del / x_del + 2.0 * sin ( x[i] * t ) ); } ///NON BLOCK ///WAIT FOR RECEIVE if ( id > 0 ) { MPI_Wait(&req1, &stat1); } if ( id < p - 1 ) { MPI_Wait(&req2, &stat2); } int tmp = 1; h_new[tmp] = h[tmp] + t_del * ( k * ( h[tmp-1] - 2.0 * h[tmp] + h[tmp+1] ) / x_del / x_del + 2.0 * sin ( x[tmp] * t ) ); tmp = n; h_new[tmp] = h[tmp] + t_del * ( k * ( h[tmp-1] - 2.0 * h[tmp] + h[tmp+1] ) / x_del / x_del + 2.0 * sin ( x[tmp] * t ) ); ///WAIT FOR SEND if ( id > 0 ) { MPI_Wait(&req3, &stat3); } if ( id < p - 1 ) { MPI_Wait(&req4, &stat4); } ///END NON BLOCK // nowa chwila czasu t = ( ( double ) ( j - j_min ) * t_max + ( double ) ( j_max - j ) * t_min ) / ( double ) ( j_max - j_min ); // przygotowanie do nastepnego kroku czasowego for ( i = 1; i < n + 1; i++ ) { h[i] = h_new[i]; } if ( 0 == id ) h[0] = 100.0 + 10.0 * sin ( t ); if ( id == p - 1 ) h[n+1] = 75; } // koncowa wymiana informacji z wezlami sasiednimi tag = 11; if ( id < p - 1 ) { MPI_Send ( &h[n], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD ); } if ( 0 < id ) { MPI_Recv ( &h[0], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD, &status ); } tag = 12; if ( 0 < id ) { // DO UZUPELNIENIA MPI_Send ( &h[1], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD ); } if ( id < p - 1 ) { // DO UZUPELNIENIA MPI_Recv ( &h[n+1], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD, &status ); } wtime = MPI_Wtime ( ) - wtime; if ( id == 0 ) { printf ( "\n" ); printf ( " Wall clock elapsed seconds = %f\n", wtime ); } // wydruk wyniku /*printf ( "%2d T= %f\n", id, t ); printf ( "%2d X= ", id ); for ( i = 0; i <= n + 1; i++ ) { printf ( "%7.2f", x[i] ); } printf ( "\n" ); printf ( "%2d H= ", id ); for ( i = 0; i <= n + 1; i++ ) { printf ( "%7.2f", h[i] ); } printf ( "\n" ); */ free ( h ); free ( h_new ); free ( x ); return; }
MPI_Status status;
double a = 0.0; // lewy brzeg przedzialu
double b = 1.0; // prawy brzeg przedzialu
int i;
int id; // rank
int n; // liczba punktow dla kazdego wezla
int p; // size
double x_max;
double x_min;
MPI_Init ( &argc, &argv );
MPI_Comm_get_parent(&parentcomm);
if (parentcomm == MPI_COMM_NULL) {
//rodzic
}
else{
//dziecko
printf("Proces dzidzia\n");
MPI_Comm_rank ( MPI_COMM_WORLD, &id );
MPI_Comm_size ( MPI_COMM_WORLD, &p );
//double
MPI_Recv(&n, 1, MPI_INT, 0, 1, parentcomm, &status);
MPI_Recv(&x_min, 1, MPI_DOUBLE, 0, 2, parentcomm, &status);
MPI_Recv(&x_max, 1, MPI_DOUBLE, 0, 3, parentcomm, &status);
// printf("xmin: %lf, xmax: %lf\n",x_min, x_max);
heat_part ( n, p, id, x_min, x_max ); // obliczenia dla pojedynczego wezla
}
MPI_Finalize ( );
// return p;
}
/******************************************************************************/
// obliczenia dla pojedynczego wezla - pojedynczego podobszaru
/******************************************************************************/
void heat_part ( int n, int p, int id, double x_min, double x_max )
{
double cfl;
double *h;
double *h_new;
int i;
int ierr;
int j;
int j_max;
int j_min;
double k;
MPI_Status status;
double t;
double t_del;
double t_max;
double t_min;
int tag;
double wtime;
double *x;
double x_del;
h = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // rozwiazanie dla t_i
h_new = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // rozwiazanie dla t_i+1
x = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // wspolrzedne punktow
k = 0.002 / ( double ) p; // przewodniosc cieplna
j_min = 0; // indeksy krokow czasowych - min i max
j_max = 100;
t_min = 0.0; // chwile czasu - min i max
t_max = 10.0;
t_del = ( t_max - t_min ) / ( double ) ( j_max - j_min ); // krok czasowy Delta t
x_del = ( x_max - x_min ) / ( double ) ( n + 1 ); // odstep miedzy punktami
for ( i = 0; i <= n + 1; i++ )
{
x[i] = ( ( double ) ( i ) * x_max
+ ( double ) ( n + 1 - i ) * x_min )
/ ( double ) ( n + 1 );
}
// ustawienie warunku poczatkowego
for ( i = 0; i <= n + 1; i++ )
{
h[i] = 95.0;
}
// sprawdzenie stabilnosci schematu
cfl = k * t_del / x_del / x_del;
if ( 0.5 <= cfl )
{
printf ( " CFL condition failed.\n" );
exit ( 1 );
}
wtime = MPI_Wtime ( ); //poczatek pomiaru czasu
for ( j = 1; j <= j_max; j++ )
{
// wymiana informacji z wezlami sasiednimi
tag = 1;
if ( id < p - 1 )
{
MPI_Send ( &h[n], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD );
}
if ( 0 < id )
{
MPI_Recv ( &h[0], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD, &status );
}
tag = 2;
if ( 0 < id )
{
// DO UZUPELNIENIA
MPI_Send ( &h[1], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD );
}
if ( id < p - 1 )
{
// DO UZUPELNIENIA
MPI_Recv ( &h[n+1], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD, &status );
}
// implementacja wzoru roznicowego
for ( i = 1; i <= n; i++ )
{
h_new[i] = h[i] + t_del * (
k * ( h[i-1] - 2.0 * h[i] + h[i+1] ) / x_del / x_del
+ 2.0 * sin ( x[i] * t ) );
}
// nowa chwila czasu
t = ( ( double ) ( j - j_min ) * t_max
+ ( double ) ( j_max - j ) * t_min )
/ ( double ) ( j_max - j_min );
// przygotowanie do nastepnego kroku czasowego
for ( i = 1; i < n + 1; i++ )
{
h[i] = h_new[i];
}
if ( 0 == id ) h[0] = 100.0 + 10.0 * sin ( t );
if ( id == p - 1 ) h[n+1] = 75;
}
// koncowa wymiana informacji z wezlami sasiednimi
tag = 11;
if ( id < p - 1 ) {
MPI_Send ( &h[n], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD );
}
if ( 0 < id ) {
MPI_Recv ( &h[0], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD, &status );
}
tag = 12;
if ( 0 < id ) {
// DO UZUPELNIENIA
MPI_Send ( &h[1], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD );
}
if ( id < p - 1 ) {
// DO UZUPELNIENIA
MPI_Recv ( &h[n+1], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD, &status );
}
wtime = MPI_Wtime ( ) - wtime;
if ( id == 0 )
{
printf ( "\n" );
printf ( " Wall clock elapsed seconds = %f\n", wtime );
}
// wydruk wyniku
printf ( "%2d T= %f\n", id, t );
printf ( "%2d X= ", id );
for ( i = 0; i <= n + 1; i++ )
{
printf ( "%7.2f", x[i] );
}
printf ( "\n" );
printf ( "%2d H= ", id );
for ( i = 0; i <= n + 1; i++ )
{
printf ( "%7.2f", h[i] );
}
printf ( "\n" );
free ( h );
free ( h_new );
free ( x );
return;
}
# include <stdlib.h>
# include <stdio.h>
# include <math.h>
# include "mpi.h"
/******************************************************************************/
int main ( int argc, char *argv[] )
{
int np = 8;
int errcodes[8];
MPI_Comm parentcomm, intercomm;
double a = 0.0; // lewy brzeg przedzialu
double b = 1.0; // prawy brzeg przedzialu
int i;
int id; // rank
int n; // liczba punktow dla kazdego wezla
int p; // size
double x_max;
double x_min;
MPI_Init ( &argc, &argv );
MPI_Comm_get_parent(&parentcomm);
if (parentcomm == MPI_COMM_NULL) {
//rodzic
MPI_Comm_spawn("heat", MPI_ARGV_NULL, np,MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm, errcodes );
printf("Proces rodzic\n");
//MPI_Comm_rank ( MPI_COMM_WORLD, &id );
//MPI_Comm_size ( MPI_COMM_WORLD, &p );
int p = np;
int j=0;
for(j=0; j<p; j++){
n = 12; // liczba punktow dla kazdego wezla
i = 0; // poczatkowa chwila czasu
// wspolrzedna lewego punktu dla wezla id
x_min = ( ( double )( p * n + 1 - j * n - i ) * a
+ ( double )( j * n + i ) * b )
/ ( double ) ( p * n + 1 );
i = n + 1;
// wspolrzedna prawego punktu dla wezla id
x_max = ( ( double )( p * n + 1 - j * n - i ) * a
+ ( double )( j * n + i ) * b )
/ ( double )( p * n + 1 );
//printf("x_min %d , x_max %d\n",x_min, x_max);
//heat_part ( n, p, id, x_min, x_max ); // obliczenia dla pojedynczego wezla
MPI_Send ( &n, 1, MPI_INT, j, 1, intercomm );
MPI_Send ( &x_min, 1, MPI_DOUBLE, j , 2, intercomm );
MPI_Send ( &x_max, 1, MPI_DOUBLE, j, 3, intercomm );
} }
else{
//dziecko
printf("Proces dzidzia\n");
}
MPI_Finalize ( );
// return p;
}
/******************************************************************************/
// obliczenia dla pojedynczego wezla - pojedynczego podobszaru
/******************************************************************************/
# include <stdlib.h> # include <stdio.h> # include <math.h> # include "mpi.h" #define NUM_SPAWNS 1 int main ( int argc, char *argv[] ); /******************************************************************************/ int main ( int argc, char *argv[] ) { int np = NUM_SPAWNS; int errcodes[NUM_SPAWNS]; MPI_Comm parentcomm, intercomm; MPI_Init(&argc, &argv); MPI_Comm_get_parent(&parentcomm); if (parentcomm == MPI_COMM_NULL) { MPI_Comm_spawn("root_proc", MPI_ARGV_NULL, np, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm, errcodes); printf("proces rodzic 1\n"); } else { printf("Proces dziecko 1\n"); } fflush(stdout); MPI_Finalize(); }