V3FIT
de_mpi.f
1  SUBROUTINE de_mpi(np, fcn, funcval)
2  USE de_mod
3  USE mpi_params
4  USE mpi_inc
5  IMPLICIT NONE
6  INTEGER :: np
7  REAL(rprec) :: funcval(np)
8  EXTERNAL fcn
9 
10 #if defined(MPI_OPT)
11  INTEGER :: status(MPI_STATUS_size) !mpi stuff
12  INTEGER :: i, j, iflag !mpi stuff
13  INTEGER :: numsent, sender, ierr !mpi stuff
14  INTEGER :: anstype, column !mpi stuff
15  REAL(rprec), DIMENSION(n_free) :: x
16  REAL(rprec), DIMENSION(nopt) :: fvec
17 
18 !******************************************
19 !
20 ! mpi : set barrier so ALL processors get here before starting
21 !
22  CALL mpi_barrier(mpi_comm_world, ierr) !mpi stuff
23 
24 !******************************************
25 !
26 ! ****Master node controls this portion of the code****
27 !
28  IF (myid .eq. master) THEN
29  numsent = 0 !numsent is a counter used to track how many
30  !jobs have been sent to workers
31 c
32 c SEND forward difference displacements from master to each
33 c worker process. Tag with these with the column number.
34 c
35  DO j = 1,min(numprocs-1,np)
36  x(:) = ui_xc(j,:)
37  CALL mpi_send(x, n_free, mpi_real8, j,
38  1 j, mpi_comm_world, ierr)
39  IF (ierr .ne. 0) stop 'MPI_SEND error(1) in de_mpi'
40  numsent = numsent+1
41  END DO !j = 1,MIN(numprocs-1,n)
42 c
43 c Looping through the columns, collect answers from the workers.
44 c As answers are received, new uncalculated columns are sent
45 c out to these same workers.
46 c
47  DO j = 1,np
48  CALL mpi_recv(fvec, nopt, mpi_real8,
49  1 mpi_any_source, mpi_any_tag,
50  2 mpi_comm_world, status, ierr)
51  IF (ierr .ne. 0) stop 'MPI_RECV error(1) in de_mpi'
52  sender = status(mpi_source)
53  anstype = status(mpi_tag) ! column is tag value
54  IF (anstype .gt. np) stop 'ANSTYPE > NP IN de_mpi'
55 
56  funcval(anstype) = sum(fvec(:nopt)**2)
57 c WRITE(6,'(a,1pe10.3,a,i3,a,i3)')' FUNCVAL = ',
58 c 1 funcval(anstype),
59 c 2 ' for iteration ', anstype+nfev,' processor = ', sender
60 
61 c
62 c If more columns are left, then send another column to the worker(sender)
63 c that just sent in an answer
64 c
65  IF (numsent .lt. np) THEN
66  numsent = numsent+1
67  x(:) = ui_xc(numsent,:)
68 
69  CALL mpi_send(x, n_free, mpi_real8,
70  1 sender, numsent, mpi_comm_world, ierr)
71  IF (ierr .ne. 0) stop 'MPI_SEND error(2) in de_mpi'
72 
73  ELSE ! Tell worker that there is no more work to DO
74 
75  CALL mpi_send(mpi_bottom, 0, mpi_real8,
76  1 sender, 0, mpi_comm_world, ierr)
77  IF (ierr .ne. 0) stop 'MPI_end error(3) in de_mpi'
78  ENDIF ! IF( myid .eq. master ) THEN
79  END DO ! DO j = 1,n
80 c
81 c ****Worker portion of the code****
82 c Skip this when processor id exceeds work to be done
83 c
84  ELSE IF (myid .le. np) THEN !!IF( myid .ne. master )
85 c
86 c Otherwise accept the next available column, check the tag,
87 c and IF the tag is non-zero CALL SUBROUTINE fcn.
88 c If the tag is zero, there are no more columns
89 c and worker skips to the END.
90 c
91  90 CALL mpi_recv(x, n_free, mpi_real8, master,
92  1 mpi_any_tag, mpi_comm_world, status, ierr)
93  IF (ierr .ne. 0) stop 'MPI_RECV error(2) in de_mpi'
94 
95  column = status(mpi_tag) !!ID of pseudo-processor issuing this message
96  IF (column .eq. 0) THEN
97  GOTO 200
98  ELSE
99  iflag = column
100 c CALL the chisq fcn for the portion of displacement vector which
101 c was just received. Note that WA stores the local fvec_min array
102 
103  CALL fcn(nopt, n_free, x, fvec, iflag, nfev)
104  IF (iflag.ne.0) GOTO 300
105 c
106 c Send this function evaluation back to the master process tagged
107 c with the column number so the master knows where to put it
108 c
109  CALL mpi_send(fvec, nopt, mpi_real8, master,
110  1 column, mpi_comm_world, ierr)
111  IF (ierr .ne. 0) stop 'MPI_SEND error(4) in de_mpi'
112  GOTO 90 !Return to 90 and check IF master process has sent any more jobs
113  END IF
114  200 CONTINUE
115  ENDIF ! IF( myid .ne. master )
116 
117 !
118 ! Broadcast the funcval array to all processors FROM master
119 !
120  CALL mpi_bcast(funcval, np, mpi_real8, master,
121  1 mpi_comm_world, ierr)
122  IF (ierr .ne. 0) GOTO 100
123 
124  RETURN
125 
126  100 CONTINUE
127  print *,' MPI_BCAST error in de_mpi: IERR=', ierr
128 
129  RETURN
130 
131  300 CONTINUE
132  print *,' IFLAG = ', iflag, ' in de_mpi CALL to fcn'
133  stop
134 #endif
135  END SUBROUTINE de_mpi
mpi_inc
Umbrella module avoid multiple inlcudes of the mpif.h header.
Definition: mpi_inc.f:11