Вопрос о командах MPI_SEND и MPI_RECV - PullRequest
0 голосов
/ 27 апреля 2020

Я изменил свой код и поместил MPI_RECV перед MPI_SEND. На этот раз я не получил никакого сообщения об ошибке; однако казалось, что код все еще находится в тупике. Причина в том, что я открыл некоторые файлы (UNIT = 11, 12, 13,14) перед командами MPI_RECV и MPI_SEND; затем я собрал данные с помощью этих двух команд и записал их в эти файлы, но в эти файлы не было записано никаких данных. Я вставляю мой модифицированный код ниже. Не могли бы вы взглянуть на это и дать мне несколько советов? Большое вам спасибо.

PROGRAM MAIN
USE MPI
USE CAL
IMPLICIT NONE
INTEGER                       :: nb                   !Number of valence band
DOUBLE PRECISION              :: me                   !Minimum eigen value
DOUBLE COMPLEX, ALLOCATABLE   :: u_s1(:,:)            !Array to store the contribution of each eigen state to the total spin orbit torque
DOUBLE COMPLEX, ALLOCATABLE   :: u_s2(:,:)            !Array to store the contribution of each eigen state to the total spin orbit torque
DOUBLE COMPLEX, ALLOCATABLE   :: u_t1(:,:)            !Array to collect the contribution of each eigen state to the total spin orbit torque from all processors
DOUBLE COMPLEX, ALLOCATABLE   :: u_t2(:,:)            !Array to collect the contribution of each eigen state to the total spin orbit torque from all processors
DOUBLE COMPLEX                :: sr1                  !Sum of Femri surface part for spin orbit torque on all km(1) k points
DOUBLE COMPLEX                :: sr2                  !Sum of Femri surface part for spin orbit torque on all km(1) k points
DOUBLE PRECISION, ALLOCATABLE, TARGET :: nme(:)       !Array to store the minimum eigen value
INTEGER, ALLOCATABLE, TARGET          :: nnb(:)       !Array to store the number of valence band
INTEGER                       :: world_size           !MPI
INTEGER                       :: world_rank, ierr     !MPI
INTEGER                       :: irank, j0            !MPI
!
!Initializing MPI
CALL MPI_Init(ierr)
CALL MPI_Comm_size(MPI_COMM_WORLD, world_size, ierr)
CALL MPI_Comm_rank(MPI_COMM_WORLD, world_rank, ierr)
!
!Opening file that stores the total spin orbit torque value for the Fermi surface part
OPEN (UNIT=11, FILE='SOT_Surface.dat', STATUS='UNKNOWN')
!

!Opening file that stores the spin orbit torque for the Fermi surface part versus energy
OPEN (UNIT=12, FILE='SOT_Surface_sve_xz.dat', STATUS='UNKNOWN')
OPEN (UNIT=13, FILE='SOT_Surface_sve_yz.dat', STATUS='UNKNOWN')
!

!Opening file that stores the minimum eigen value and number of valence band
OPEN (UNIT=14, FILE='SOT_mineig_numval.dat', STATUS='UNKNOWN')
!
!Allocating the array used to store the contribution of each eigen state to the total spin orbit torque
ALLOCATE (u_s1(2,nu_wa*km(1)))
ALLOCATE (u_s2(2,nu_wa*km(1)))
!

!Allocating array to collect the contribution of each eigen state to the total spin orbit torque from all processors
IF (world_rank .EQ. 0) THEN
    ALLOCATE (u_t1(2,nu_wa*km(1)*km(2)))
    ALLOCATE (u_t2(2,nu_wa*km(1)*km(2)))
END IF
u_t1 = CMPLX(0.0d0, 0.0d0)
u_t2 = CMPLX(0.0d0, 0.0d0)
!

!Allocating array to collect the number of valence band and the minimum eigen value
IF (world_rank .EQ. 0) THEN
    ALLOCATE (nme(km(2)))
    ALLOCATE (nnb(km(2)))
END IF
nme = 0.0d0
nnb = 0
!
!Allocating array to collect the contribution of each eigen state to the total spin orbit torque from all processors
IF (world_rank .EQ. 0) THEN
    ALLOCATE (u_t1(2,nu_wa*km(1)*km(2)))
    ALLOCATE (u_t2(2,nu_wa*km(1)*km(2)))
END IF
u_t1 = CMPLX(0.0d0, 0.0d0)
u_t2 = CMPLX(0.0d0, 0.0d0)
!

!Allocating array to collect the number of valence band and the minimum eigen value
IF (world_rank .EQ. 0) THEN
    ALLOCATE (nme(km(2)))
    ALLOCATE (nnb(km(2)))
END IF
nme = 0.0d0
nnb = 0
!

!opening test files
open (unit=21,file='normalisedprefactor.dat',status='unknown')
open (unit=22,file='gd.dat',status='unknown')
open (unit=23,file='con.dat',status='unknown')
open (unit=24,file='par.dat',status='unknown')
open (unit=25,file='grga.dat',status='unknown')
open (unit=26,file='nfdk.dat',status='unknown')
!Reading the Cartesian coordinates of k-point mesh
DO j = 1, km(2), 1
   IF (mod(j-1, world_size) .NE. world_rank) CYCLE
   DO k = 1, km(1), 1
      kp(k,:) = ka(j,k,:)
   END DO
   !Building up Hamiltonian matrix on k points and diagonalising the matrix to obtain Eigen vectors and values
   CALL HAMSUR(vd,kp,nu_wa,nu_nr,km(1),nd1,nd2,nd3,nd4,nd5,hr1,hr2,hr3,hr4,hr5,tb,ec,ev,fermi,an,wf,bv,dk,u_s1,u_s2,sr1,sr2,nb,me)
   !
   CALL MPI_Barrier(MPI_COMM_WORLD, ierr)
   IF (WORLD_RANK .EQ. 0) THEN
      u_t1(1:2,1+nu_wa*km(1)*(j-1):nu_wa*km(1)*j) = u_s1
      u_t2(1:2,1+nu_wa*km(1)*(j-1):nu_wa*km(1)*j) = u_s2
      DO k = 1, WORLD_SIZE-1, 1
         IF (j-1+k .EQ. km(2)) EXIT
         l = k + 101
         n = k + 102
         CALL MPI_RECV(u_t1(1,1+nu_wa*km(1)*(j-1+k)), 2*nu_wa*km(1), MPI_DOUBLE_COMPLEX, k,l, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr)
         CALL MPI_RECV(u_t2(1,1+nu_wa*km(1)*(j-1+k)), 2*nu_wa*km(1), MPI_DOUBLE_COMPLEX, k,n, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr)
      END DO
   ELSE
      l = WORLD_RANK + 101
      n = WORLD_RANK + 102
      CALL MPI_SEND(u_s1,2*nu_wa*km(1), MPI_DOUBLE_COMPLEX, 0, l, MPI_COMM_WORLD, ierr)
      CALL MPI_SEND(u_s2,2*nu_wa*km(1), MPI_DOUBLE_COMPLEX, 0, n, MPI_COMM_WORLD, ierr)
   END IF
   crr1 = crr1 + sr1
   crr2 = crr2 + sr2
   IF (WORLD_RANK .EQ. 0) THEN
      nme(j-1) = me
      nnb(j-1) = nb
      DO k = 1, WORLD_SIZE-1, 1
         IF (j-1+k .EQ. km(2)) EXIT
         l = k + 103
         n = k + 104
         CALL MPI_RECV(nme(j-1+k), 1, MPI_DOUBLE, k,l, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr)
         CALL MPI_RECV(nnb(j-1+k), 1, MPI_INT, k,n, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr)
      END DO
   ELSE
      l = WORLD_RANK + 103
      n = WORLD_RANK + 104
      CALL MPI_SEND(me, 1, MPI_DOUBLE, 0, l, MPI_COMM_WORLD, ierr)
      CALL MPI_SEND(nb, 1, MPI_INT, 0, n, MPI_COMM_WORLD, ierr)
   END IF
END DO
!

CALL MPI_Barrier(MPI_COMM_WORLD, ierr)
IF (world_rank .EQ. 0) THEN
    ALLOCATE (crr1_all(world_size))
    ALLOCATE (crr2_all(world_size))
END IF
crr1_all = CMPLX(0.0d0, 0.0d0)
crr2_all = CMPLX(0.0d0, 0.0d0)
CALL MPI_Gather(crr1, 1, MPI_double_complex, crr1_all, 1, MPI_double_complex, 0, MPI_COMM_WORLD, ierr)
CALL MPI_Gather(crr2, 1, MPI_double_complex, crr2_all, 1, MPI_double_complex, 0, MPI_COMM_WORLD, ierr)

!Writing total conductivity value into the file
IF (world_rank .EQ. 0) THEN
    crr1_total = CMPLX(0.0d0, 0.0d0)
    crr2_total = CMPLX(0.0d0, 0.0d0)
    DO i = 1, world_size, 1
       crr1_total = crr1_total + crr1_all(i)
       crr2_total = crr2_total + crr2_all(i)
    END DO
    !Finding the minimum eigen value
    NULLIFY (p1, p2)
    p1 => nme(1)
    p2 => nnb(1)
    DO i = 2, km(2), 1
       IF (p1 .GE. nme(i)) THEN
          p1 => nme(i)
       END IF
       IF (p2 .LE. nnb(i)) THEN
          p2 => nnb(i)
       END IF
    END DO
    WRITE (UNIT=14, FMT='(A27,$)') 'The minimum eigen value is:'
    WRITE (UNIT=14, FMT=*) p1
    WRITE (UNIT=14, FMT='(A30,$)') 'The number of valence band is:'
    WRITE (UNIT=14, FMT=*) p2
    !
    !Constant for the coefficient
    pi = DACOS(-1.0d0)
    hb = 1.054571817d-34 !(unit - J)
    es = 1.602176634d-19 !(unit - J*s)
    !
    WRITE (UNIT=11, FMT='(A55,$)') 'Spin Orbit Torque without coeffieicnt within x-z plane:'
    WRITE (UNIT=11, FMT=*) crr1_total
    WRITE (UNIT=11, FMT='(A52,$)') 'Spin Orbit Torque with coefficient within x-z plane:'
    WRITE (UNIT=11, FMT=*) crr1_total * es ** 2 * hb / 4.0d0 / pi
    WRITE (UNIT=11, FMT='(A55,$)') 'Spin Orbit Torque without coeffieicnt within y-z plane:'
    WRITE (UNIT=11, FMT=*) crr2_total
    WRITE (UNIT=11, FMT='(A52,$)') 'Spin Orbit Torque with coefficient within y-z plane:'
    WRITE (UNIT=11, FMT=*) crr2_total * es ** 2 * hb / 4.0d0 / pi
    DO i = 1, nu_wa*km(1)*km(2), 1
       WRITE (UNIT=12, FMT=*) u_t1(1:2,i)
       WRITE (UNIT=13, FMT=*) u_t2(1:2,i)
    END DO
END IF
!
!Finalising MPI
CALL MPI_Finalize(ierr)
!
!Deallocating array that sotres and collect the fermi-surface-part contribution of each eigen state to the total spin orbit torque
DEALLOCATE (u_s1)
DEALLOCATE (u_s2)
DEALLOCATE (u_t1)
DEALLOCATE (u_t2)
!
STOP
END PROGRAM MAIN
...