1.* Mise à jour des dépendances pour fortran90: 2 outils* * *makedepf90* - creates Makefile dependency list for Fortran source files. Sur zephir, le binaire se trouve sous /usr/local/bin man pages: http://personal.inet.fi/private/erikedelmann/makedepf90/manpage.html makedependf90 va créer un fichier contenant les dépendances qui sera inclu dans le Makefile. Une bonne méthode est d'ajouter une cible depend dans le Makefile qui aura pour règle la création de ce fichier. Regarder l'exemple sur la page man que je vous ai fournie, c'est très clair. * sfmakedepend: vous pouvez trouver de l'info sur le web mais par expérience, le premier outil fonctionne mieux. Ce que je rajoutais dans le Makefile SRC_EX1: sources de EX1 # Mise a jour des dependances pour fortran90 # ------------------------------------------- depend: /kora/home/install/viry/f90/tools/maketools/tests/sfmakedepend -s -g $(SRCS_EX1) 2. *Utilisation des modules pour structurer le code:* Je vous mets en attaché deux modules utilisés dans la parallélisation d'une méthode de Jacobi. L'exemple fournit n'utilise pas les topologies cartésiennes pour des raisons de simplification, je vous conseille de mettre dans le module mpi_module, les infos sur la topolgie cartésienne construite ainsi que les routines qui la définisse. 3. *Méthode SOR: * créer un compte sur le Webct du ncsa*: http://ci-tutor.ncsa.uiuc.edu/login.php Dans le cours introduction MPI, vous avez le traitement de la méthode de Jacobi et l'utilisation de la méthode SOR pour accélérer la convergence de la méthode, vous avez également des références * je vous ai photocopié le chapitre d'un livre "Elliptic Problem in two Dimension: Solution of Laplace 's Equation by finite Difference. Vous pouvez venir le chercher dans mon bureau ////////////////////////////////////////////////////////////////////// MODULE types_module IMPLICIT NONE INTEGER, PARAMETER :: real4 = selected_real_kind(6,37) INTEGER, PARAMETER :: real8 = selected_real_kind(15,307) PUBLIC END MODULE types_module ////////////////////////////////////////////////////////////////////// MODULE jacobi_module USE types_module IMPLICIT NONE REAL(real8), DIMENSION(:,:), ALLOCATABLE :: vnew REAL(real8), DIMENSION(:,:), ALLOCATABLE, TARGET :: v ! solution array REAL(real8) :: tol=1.d-4, del, gdel=1.0d0 REAL(real4) :: start_time, end_time INCLUDE "mpif.h" !! This brings in pre-defined MPI constants, ... INTEGER :: p, ierr,below, above, k, m, mp, iter=0 PUBLIC CONTAINS SUBROUTINE bc(v, m, mp, k, p) ! PDE: Laplacian u = 0; 0<=x<=1; 0<=y<=1 ! B.C.: u(x,0)=sin(pi*x); u(x,1)=sin(pi*x)*exp(-pi); u(0,y)=u(1,y)=0 ! SOLUTION: u(x,y)=sin(pi*x)*exp(-pi*y) IMPLICIT NONE INTEGER m, mp, k, p, j REAL(real8), DIMENSION(0:m+1,0:mp+1) :: v REAL(real8), DIMENSION(0:m+1) :: y0 y0 = sin(3.141593*(/(j,j=0,m+1)/)/(m+1)) IF(p > 1) THEN v = 0.0d0 IF (k == 0 ) v(:, 0) = y0 IF (k == p-1) v(:,mp+1) = y0*exp(-3.141593) ELSE v = 0.0d0 v(:,0) = y0 v(:,m+1) = y0*exp(-3.141593) END IF RETURN END SUBROUTINE bc SUBROUTINE borders(k,below, above, p) IMPLICIT NONE INTEGER :: k,below, above, p IF(k == 0) THEN below = -1 ! tells MPI not to perform send/recv above = k+1 ELSE IF(k == p-1) THEN below = k-1 above = -1 ! tells MPI not to perform send/recv ELSE below = k-1 above = k+1 ENDIF RETURN END SUBROUTINE borders SUBROUTINE update_bc_2( v, m, mp, k, below, above ) INCLUDE "mpif.h" INTEGER :: m, mp, k,below, above, ierr REAL(real8), dimension(0:m+1,0:mp+1) :: v INTEGER status(MPI_STATUS_SIZE) CALL MPI_SENDRECV( & v(1,mp ), m, MPI_DOUBLE_PRECISION, above, 0, & v(1, 0), m, MPI_DOUBLE_PRECISION, below, 0, & MPI_COMM_WORLD, status, ierr ) CALL MPI_SENDRECV( & v(1, 1), m, MPI_DOUBLE_PRECISION, below, 1, & v(1,mp+1), m, MPI_DOUBLE_PRECISION, above, 1, & MPI_COMM_WORLD, status, ierr ) RETURN END SUBROUTINE update_bc_2 SUBROUTINE update_bc_1(v, m, mp, k, below, above) IMPLICIT NONE INCLUDE 'mpif.h' INTEGER :: m, mp, k, ierr, below, above REAL(real8), DIMENSION(0:m+1,0:mp+1) :: v INTEGER status(MPI_STATUS_SIZE) ! Select 2nd index for domain decomposition to have stride 1 ! Use odd/even scheme to reduce contention in message passing IF(mod(k,2) == 0) THEN ! even numbered processes CALL MPI_Send( v(1,mp ), m, MPI_DOUBLE_PRECISION, above, 0, & MPI_COMM_WORLD, ierr) CALL MPI_Recv( v(1,0 ), m, MPI_DOUBLE_PRECISION, below, 0, & MPI_COMM_WORLD, status, ierr) CALL MPI_Send( v(1,1 ), m, MPI_DOUBLE_PRECISION, below, 1, & MPI_COMM_WORLD, ierr) CALL MPI_Recv( v(1,mp+1), m, MPI_DOUBLE_PRECISION, above, 1, & MPI_COMM_WORLD, status, ierr) ELSE ! odd numbered processes CALL MPI_Recv( v(1,0 ), m, MPI_DOUBLE_PRECISION, below, 0, & MPI_COMM_WORLD, status, ierr) CALL MPI_Send( v(1,mp ), m, MPI_DOUBLE_PRECISION, above, 0, & MPI_COMM_WORLD, ierr) CALL MPI_Recv( v(1,mp+1), m, MPI_DOUBLE_PRECISION, above, 1, & MPI_COMM_WORLD, status, ierr) CALL MPI_Send( v(1,1 ), m, MPI_DOUBLE_PRECISION, below, 1, & MPI_COMM_WORLD, ierr) ENDIF RETURN END SUBROUTINE update_bc_1 SUBROUTINE print_mesh(v,m,mp,k,iter) IMPLICIT NONE INTEGER :: m, mp, k, iter, i, out REAL(real8), DIMENSION(0:m+1,0:mp+1) :: v out = 20 + k do i=0,m+1 write(out,"(2i3,i5,' => ',4f10.3)")k,i,iter,v(i,:) enddo write(out,*)'+++++++++++++++++++++++++++++++++++++++++++++++++++++++' RETURN END SUBROUTINE print_mesh END MODULE jacobi_module ////////////////////////////////////////////////////////////////////// MODULE mpi_module USE types_module IMPLICIT NONE INCLUDE "mpif.h" !! This brings in pre-defined MPI constants, ... PUBLIC CONTAINS SUBROUTINE update_bc_2( v, m, mp, k, below, above ) INCLUDE "mpif.h" INTEGER :: m, mp, k, below, above, ierr REAL(real8), dimension(0:m+1,0:mp+1) :: v INTEGER status(MPI_STATUS_SIZE) CALL MPI_SENDRECV( & v(1,mp ), m, MPI_DOUBLE_PRECISION, above, 0, & v(1, 0), m, MPI_DOUBLE_PRECISION, below, 0, & MPI_COMM_WORLD, status, ierr ) CALL MPI_SENDRECV( & v(1, 1), m, MPI_DOUBLE_PRECISION, below, 1, & v(1,mp+1), m, MPI_DOUBLE_PRECISION, above, 1, & MPI_COMM_WORLD, status, ierr ) RETURN END SUBROUTINE update_bc_2 SUBROUTINE update_bc_1(v, m, mp, k, below, above) IMPLICIT NONE INCLUDE 'mpif.h' INTEGER :: m, mp, k, ierr, below, above REAL(real8), DIMENSION(0:m+1,0:mp+1) :: v INTEGER status(MPI_STATUS_SIZE) ! Select 2nd index for domain decomposition to have stride 1 ! Use odd/even scheme to reduce contention in message passing IF(mod(k,2) == 0) THEN ! even numbered processes CALL MPI_Send( v(1,mp ), m, MPI_DOUBLE_PRECISION, above, 0, & MPI_COMM_WORLD, ierr) CALL MPI_Recv( v(1,0 ), m, MPI_DOUBLE_PRECISION, below, 0, & MPI_COMM_WORLD, status, ierr) CALL MPI_Send( v(1,1 ), m, MPI_DOUBLE_PRECISION, below, 1, & MPI_COMM_WORLD, ierr) CALL MPI_Recv( v(1,mp+1), m, MPI_DOUBLE_PRECISION, above, 1, & MPI_COMM_WORLD, status, ierr) ELSE ! odd numbered processes CALL MPI_Recv( v(1,0 ), m, MPI_DOUBLE_PRECISION, below, 0, & MPI_COMM_WORLD, status, ierr) CALL MPI_Send( v(1,mp ), m, MPI_DOUBLE_PRECISION, above, 0, & MPI_COMM_WORLD, ierr) CALL MPI_Recv( v(1,mp+1), m, MPI_DOUBLE_PRECISION, above, 1, & MPI_COMM_WORLD, status, ierr) CALL MPI_Send( v(1,1 ), m, MPI_DOUBLE_PRECISION, below, 1, & MPI_COMM_WORLD, ierr) ENDIF RETURN END SUBROUTINE update_bc_1 END MODULE mpi_module ////////////////////////////////////////////////////////////////////// Lorsque vous envisagez l'algorithme de schwarz pour améliorer la convergence, attention aux conditions limites appliquées aux bords. ////////////////////////////////////////////////////////////////////// Petit rappel sur lequel on n'est pas revenu cette semaine. Il serait utile avant de faire le choix d'un algorithme de décomposition de domaine de *faire le point sur les schémas en temps et en espace qui vont nécessité ce type de méthode.* C'est indispensable pour les choix qui seront fait. Différences finies: schéma en espace seul => système à résoudre => (gradient conjugué / algorithme itératif) schéma en temps implicit => système à résoudre => (gradient conjugué / algorithme itératif) schéma en temps explicit =>juste une décomposition du maillage et une communication des ghosts points entre processus on se revoit la semaine prochaine pour faire le point à ce sujet laurence Viry