source: utilities.f

Last change on this file was 3fbbfbb, checked in by Jan Meinke <j.meinke@…>, 14 years ago

Move to doxygen comments and smmp_p.

Doxygen comments in Fortran are !> ... !! ... !<. I'm planning move the API documentation from the
lyx file into the code. This should make it easier to get documentation for all the common block
variables as well.

Use import smmp_p to indicate the parallel version of the Python bindings.

  • Property mode set to 100644
File size: 6.4 KB
Line 
1! *********************************************************************
2! This file contains distributeWorkLoad, fileNameMP
3!
4! Copyright 2007 Frank Eisenmenger, U.H.E. Hansmann,
5! Jan H. Meinke, Sandipan Mohanty
6!
7! *********************************************************************
8
9!> Calculate the best way to distribute the work load across processors.
10!! It calculates the average number of interactions and then tries to
11!! assign a number of interactions to each processor that is as close
12!! as possible to the average. The routine should be called once for
13!! every molecule in the system.
14!!
15!! @param num_ppr Number of processors per replica
16!! @param nml index of molecule or zero.
17!!
18!! @author Jan H. Meinke
19!<
20 subroutine distributeWorkLoad(num_ppr,nml)
21
22 include 'INCL.H'
23
24 integer i1ms, io, iv, i2ms, ms
25
26 integer num_ppr, nml
27 integer idxOfFirstVariable, idxOfLastVariable
28 integer at, atct, ivw, i, j, isum, i14
29 integer totalct, irank, itarget
30 double precision ipps
31
32 if (nml.eq.0) then
33 idxOfFirstVariable = ivrml1(1)
34 idxOfLastVariable = ivrml1(ntlml) + nvrml(ntlml) -1
35 i1ms = imsml1(ntlml)+ nmsml(ntlml)
36 do i = 0, MAX_PROC
37 do j = 1, mxml
38 workPerProcessor(j, i) = 0
39 end do
40 end do
41 else
42 idxOfFirstVariable = ivrml1(nml)
43 idxOfLastVariable = ivrml1(nml) + nvrml(nml) - 1
44 i1ms = imsml1(nml)+ nmsml(nml)
45 do i = 0, MAX_PROC
46 workPerProcessor(nml, i) = 0
47 end do
48 end if
49
50 isum = 0
51 do io = idxOfLastVariable, idxOfFirstVariable, - 1
52 iv = iorvr(io)
53 i2ms = i1ms - 1
54 i1ms = imsvr1(iv)
55 do ms = i1ms, i2ms
56 do at = latms1(ms), latms2(ms)
57 do ivw=ivwat1(at),ivwat2(at)
58 do j=lvwat1(ivw),lvwat2(ivw)
59 isum = isum + 1
60 end do
61 end do
62 do i14=i14at1(at),i14at2(at)
63 isum = isum + 1
64 end do
65 end do
66 end do
67 end do
68 ipps = isum / num_ppr
69 write (logString, *) "Total number of interactions:", isum
70 write (logString, *) "Average # of interactions per processor",
71 & ipps
72
73 totalct = 0
74 irank = 1
75 itarget = int(irank * ipps)
76 if (nml.eq.0) then
77 i1ms = imsml1(ntlml)+ nmsml(ntlml)
78 else
79 i1ms = imsml1(nml)+ nmsml(nml)
80 end if
81 do io = idxOfLastVariable, idxOfFirstVariable, - 1
82 isum = 0
83 iv = iorvr(io)
84 i2ms = i1ms - 1
85 i1ms = imsvr1(iv)
86 do ms = i1ms, i2ms
87 do at = latms1(ms), latms2(ms)
88 atct = atct + 1
89 do ivw=ivwat1(at),ivwat2(at)
90 do j=lvwat1(ivw),lvwat2(ivw)
91 isum = isum + 1
92 end do
93 end do
94 do i14=i14at1(at),i14at2(at)
95 isum = isum + 1
96 end do
97 end do
98 end do
99 if ((totalct + isum).gt.itarget) then
100 if((.not.irank.eq.num_ppr)
101 & .and.
102 & (abs(totalct-itarget)
103 & .lt.abs(totalct + isum - itarget))) then
104 workPerProcessor(nml, irank) = io + 1
105! write (logString, *) io + 1, totalct, itarget
106 else
107 workPerProcessor(nml, irank) = io
108! write (logString, *) io, totalct + isum, itarget
109 end if
110 irank = irank + 1
111 itarget = int(irank * ipps)
112 end if
113 totalct = totalct + isum
114 end do
115 workPerProcessor(nml, 0) = idxOfLastVariable + 1
116 workPerProcessor(nml, num_ppr) = ivrml1(nml)
117
118 end subroutine distributeWorkLoad
119
120!>
121!! The function fileNameMP takes a template of a file name in the
122!! variable base. The position of the first and last character that
123!! may be replaced by rank in the string are given in i1 (first) and
124!! i2 (last).
125!! The function returns an empty string if the rank would need more
126!! characters than is allowed by the template.
127!! For example,
128!! \code
129!! rank = 11
130!! fileName = fileNameMP('base_0000.dat', 6, 9, rank)
131!! write (logString, *), fileName
132!! \endcode
133!! will output base_0011.dat.
134!!
135!! @param base the base file name, e.g., base_0000.dat.
136!! @param i1 index of the first character that may be replaced
137!! @param i2 index of the last character that may be replaced
138!! @param rank the number that should be inserted into the file name.
139!!
140!! @return file name for rank
141!<
142 character*80 function fileNameMP(base, i1, i2, rank)
143
144 character*(*) base
145! i1, i2: Index of first and last character that can be replaced
146! rank: rank of node
147 integer i1, i2, rank
148
149 fileNameMP = base
150 if ((i2 - i1 + 1).le.log10(1.0 * rank)) then
151 print *,'too few characters available to label '
152 print *,'filenames with rank = ',rank
153 stop
154 endif
155
156! TODO: Allow arbitrary rank
157
158 if (rank.lt.10) then
159 write(fileNameMP(i2:i2), '(i1)') rank
160 elseif (rank.lt.100) then
161 write(fileNameMP(i2-1:i2), '(i2)') rank
162 elseif (rank.lt.1000) then
163 write(fileNameMP(i2-2:i2), '(i3)') rank
164 elseif (rank.lt.10000) then
165 write(fileNameMP(i2-3:i2), '(i4)') rank
166 elseif (rank.lt.100000) then
167 write(fileNameMP(i2-4:i2), '(i5)') rank
168 elseif (rank.lt.1000000) then
169 write(fileNameMP(i2-5:i2), '(i6)') rank
170 endif
171 end function fileNameMP
172! End fileNameMP
173
174
175!>
176!! Add messages to log. This routine takes the log (debugging) mes-
177!! sages and writes them to the log file if the log level is less or
178!! equal to the maximum log level given by the global variable
179!! MAXLOGLEVEL.
180!!
181!! @author Jan H. Meinke
182!!
183!! @param loglevel level at which this message should be added to
184!! the log.
185!! @param message message to be written to the log.
186!! @param rank global rank of this node if running an MPI job zero
187!! otherwise.
188!<
189 subroutine addLogMessage(loglevel, message, rank)
190
191 integer MAXLOGLEVEL, LOGFILEUNIT
192 common /log/MAXLOGLEVEL, LOGFILEUNIT
193
194 integer :: loglevel, rank
195 character(LEN=*) :: message
196
197 if (loglevel <= MAXLOGLEVEL) then
198 write(LOGFILEUNIT, *) message
199 end if
200
201 end subroutine addLogMessage
Note: See TracBrowser for help on using the repository browser.