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; }
# 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[] ) { int id; // rank int n; // liczba punktow dla kazdego wezla int p; // size double x_max; double x_min; MPI_Comm parentcomm; MPI_Status status; MPI_Init ( &argc, &argv ); MPI_Comm_rank ( MPI_COMM_WORLD, &id ); MPI_Comm_size ( MPI_COMM_WORLD, &p ); MPI_Comm_get_parent(&parentcomm); MPI_Recv ( &x_min, 1, MPI_DOUBLE, 0, 1, parentcomm, &status ); MPI_Recv ( &x_max, 1, MPI_DOUBLE, 0, 2, parentcomm, &status ); MPI_Recv ( &n, 1, MPI_INT, 0, 3, parentcomm, &status ); //MPI_Barrier(MPI_COMM_WORLD); heat_part ( n, p, id, x_min, x_max ); // obliczenia dla pojedynczego wezla MPI_Finalize ( ); return 0; } /******************************************************************************/ // 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 ) { MPI_Send ( &h[1], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD ); } if ( id < p - 1 ) { 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 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 int np = 8; // liczba procesow double x_max; double x_min; MPI_Comm komunikator; int *errcodes; MPI_Init ( &argc, &argv ); //MPI_Comm_rank ( MPI_COMM_WORLD, &id ); //MPI_Comm_size ( MPI_COMM_WORLD, &p ); MPI_Comm_spawn("dziecko", MPI_ARGV_NULL, np, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &komunikator, errcodes); n = 12; // liczba punktow dla kazdego wezla int j; for(j=0;j<np;j++){ i = 0; // poczatkowa chwila czasu // wspolrzedna lewego punktu dla wezla id x_min = ( ( double )( np * n + 1 - j * n - i ) * a + ( double )( j * n + i ) * b ) / ( double ) ( np * n + 1 ); i = n + 1; // wspolrzedna prawego punktu dla wezla id x_max = ( ( double )( np * n + 1 - j * n - i ) * a + ( double )( j * n + i ) * b ) / ( double )( np * n + 1 ); MPI_Send ( &x_min, 1, MPI_DOUBLE, j, 1, komunikator ); MPI_Send ( &x_max, 1, MPI_DOUBLE, j, 2, komunikator ); MPI_Send ( &n, 1, MPI_INT, j, 3, komunikator ); } MPI_Finalize ( ); return 0; } void* bufor = (void *)malloc(rozmiar); MPI_Recv ( bufor, rozmiar, MPI_PACKED, 0, 1, parentcomm, &status ); MPI_Unpack(bufor, rozmiar, &pozycja, &wys.x_min, 1, MPI_DOUBLE, MPI_COMM_WORLD); MPI_Unpack(bufor, rozmiar, &pozycja, &wys.x_max, 1, MPI_DOUBLE, MPI_COMM_WORLD); MPI_Unpack(bufor, rozmiar, &pozycja, &wys.n, 1, MPI_INT, MPI_COMM_WORLD);