V3FIT
bmw_parallel_context.f
Go to the documentation of this file.
1 !*******************************************************************************
4 !
5 ! Note separating the Doxygen comment block here so detailed decription is
6 ! found in the Module not the file.
7 !
10 !*******************************************************************************
12  USE mpi_inc
13  USE profiler
14 
15  IMPLICIT NONE
16 
17 !*******************************************************************************
18 ! DERIVED-TYPE DECLARATIONS
19 ! 1) bmw parallel context base class
20 !
21 !*******************************************************************************
22 !-------------------------------------------------------------------------------
25 !-------------------------------------------------------------------------------
28  INTEGER :: offset
30  INTEGER :: stride
31 
33  INTEGER :: num_threads
34 
35 #if defined (mpi_opt)
39  INTEGER :: comm = mpi_comm_null
40 #endif
41  END TYPE
42 
43 !*******************************************************************************
44 ! INTERFACE BLOCKS
45 !*******************************************************************************
46 !-------------------------------------------------------------------------------
48 !-------------------------------------------------------------------------------
50  MODULE PROCEDURE bmw_parallel_context_reduce1, &
54  END INTERFACE
55 
56  CONTAINS
57 
58 !*******************************************************************************
59 ! CONSTRUCTION SUBROUTINES
60 !*******************************************************************************
61 !-------------------------------------------------------------------------------
69 !-------------------------------------------------------------------------------
71 #if defined (MPI_OPT)
72  & comm &
73 #endif
74  & )
75 
76  IMPLICIT NONE
77 
78 ! Declare Arguments
79  TYPE (bmw_parallel_context_class), POINTER :: &
81 #if defined (MPI_OPT)
82  INTEGER, INTENT(in) :: comm
83 #endif
84 
85 ! local variables
86 #if defined (MPI_OPT)
87  LOGICAL :: isinit
88  INTEGER :: status
89 #endif
90  REAL (rprec) :: start_time
91 
92 ! Start of executable code
93  start_time = profiler_get_start_time()
94 
96 
97 #if defined (MPI_OPT)
98  CALL mpi_initialized(isinit, status)
99 
100  IF (.not.isinit) THEN
101  CALL mpi_init(status)
102  END IF
103 
105  CALL mpi_comm_rank(bmw_parallel_context_construct%comm, &
107  & status)
108  CALL mpi_comm_size(bmw_parallel_context_construct%comm, &
110  & status)
111 
112 #else
115 #endif
116 
117 ! Configure the number of threads to use.
118  bmw_parallel_context_construct%num_threads = 1
119 
120  CALL profiler_set_stop_time('bmw_parallel_context_construct', &
121  & start_time)
122 
123  END FUNCTION
124 
125 !*******************************************************************************
126 ! DESTRUCTION SUBROUTINES
127 !*******************************************************************************
128 !-------------------------------------------------------------------------------
137 !-------------------------------------------------------------------------------
138  SUBROUTINE bmw_parallel_context_destruct(this &
139 #if defined(MPI_OPT)
140  & ,finalize &
141 #endif
142  & )
143 
144  IMPLICIT NONE
145 
146 ! Declare Arguments
147  TYPE (bmw_parallel_context_class), POINTER :: this
148 #if defined (MPI_OPT)
149  LOGICAL, INTENT(in) :: finalize
150 
151 ! local variables
152  INTEGER :: status
153 #endif
154 
155 ! Start of executable code
156  DEALLOCATE(this)
157 
158 #if defined (MPI_OPT)
159  IF (finalize) THEN
160  CALL mpi_finalize(status)
161  END IF
162 #endif
163 
164  END SUBROUTINE
165 
166 !*******************************************************************************
167 ! DESTRUCTION SUBROUTINES
168 !*******************************************************************************
169 !-------------------------------------------------------------------------------
175 !-------------------------------------------------------------------------------
176  SUBROUTINE bmw_parallel_context_abort(status)
177 
178  IMPLICIT NONE
179 
180 ! Declare Arguments
181  INTEGER, INTENT(in) :: status
182 
183 ! Start of executable code
184 #if defined (MPI_OPT)
185  CALL mpi_abort(mpi_comm_world, status, status)
186 #else
187  CALL exit(status)
188 #endif
189 
190  END SUBROUTINE
191 
192 !*******************************************************************************
193 ! SETTER SUBROUTINES
194 !*******************************************************************************
195 !-------------------------------------------------------------------------------
202 !-------------------------------------------------------------------------------
203  SUBROUTINE bmw_parallel_context_set_threads(this, num_threads)
204 !$ USE omp_lib
205 
206  IMPLICIT NONE
207 
208 ! Declare Arguments
209  TYPE (bmw_parallel_context_class), INTENT(inout) :: this
210  INTEGER, INTENT(in) :: num_threads
211 
212 ! local variables
213  REAL (rprec) :: start_time
214 
215 ! Start of executable code
216  start_time = profiler_get_start_time()
217 
218 ! Configure the number of threads to use.
219  this%num_threads = num_threads
220 
221 !$ IF (this%num_threads .gt. 0) THEN
222 !$ CALL OMP_SET_NUM_THREADS(this%num_threads)
223 !$ END IF
224 !$OMP PARALLEL
225 !$ this%num_threads = OMP_GET_MAX_THREADS()
226 !$OMP END PARALLEL
227 
228  CALL profiler_set_stop_time('bmw_parallel_context_set_threads', &
229  & start_time)
230 
231  END SUBROUTINE
232 
233 !*******************************************************************************
234 ! UTILITY SUBROUTINES
235 !*******************************************************************************
236 !-------------------------------------------------------------------------------
244 !-------------------------------------------------------------------------------
245  SUBROUTINE bmw_parallel_context_report(this, io_unit)
246 
247  IMPLICIT NONE
248 
249 ! Declare Arguments
250  TYPE (bmw_parallel_context_class), INTENT(inout) :: this
251  INTEGER, INTENT(in) :: io_unit
252 
253 ! local variables
254  REAL (rprec) :: start_time
255 
256 ! Start of executable code
257  start_time = profiler_get_start_time()
258 
259  IF (this%offset .eq. 0) THEN
260 #if defined(MPI_OPT)
261  WRITE (io_unit,1000) this%stride
262 #endif
263  WRITE (io_unit,1001) this%num_threads
264  END IF
265 
266  CALL profiler_set_stop_time('bmw_parallel_context_report', &
267  & start_time)
268 
269 1000 FORMAT('Using ',i4,' processes.')
270 #if defined (MPI_OPT)
271 1001 FORMAT('Using ',i4,' threads per process.')
272 #else
273 1001 FORMAT('Using ',i4,' threads.')
274 #endif
275 
276  END SUBROUTINE
277 
278 !-------------------------------------------------------------------------------
286 !-------------------------------------------------------------------------------
287  SUBROUTINE bmw_parallel_context_reduce1(this, buffer)
288  USE stel_kinds, ONLY: rprec
289 
290  IMPLICIT NONE
291 
292 ! Declare Arguments
293  TYPE (bmw_parallel_context_class), INTENT(in) :: this
294  REAL (rprec), DIMENSION(:), INTENT(inout) :: buffer
295 
296 ! local variables
297  REAL (rprec) :: start_time
298  INTEGER :: status
299 
300 ! Start of executable code
301  start_time = profiler_get_start_time()
302 
303 #if defined (MPI_OPT)
304  CALL mpi_allreduce(mpi_in_place, buffer, SIZE(buffer), mpi_real8, &
305  & mpi_sum, this%comm, status)
306 #endif
307 
308  CALL profiler_set_stop_time('bmw_parallel_context_reduce1', &
309  & start_time)
310 
311  END SUBROUTINE
312 
313 !-------------------------------------------------------------------------------
321 !-------------------------------------------------------------------------------
322  SUBROUTINE bmw_parallel_context_reduce2(this, buffer)
323  USE stel_kinds, ONLY: rprec
324 
325  IMPLICIT NONE
326 
327 ! Declare Arguments
328  TYPE (bmw_parallel_context_class), INTENT(in) :: this
329  REAL (rprec), DIMENSION(:,:), INTENT(inout) :: buffer
330 
331 ! local variables
332  REAL (rprec) :: start_time
333  INTEGER :: status
334 
335 ! Start of executable code
336  start_time = profiler_get_start_time()
337 
338 #if defined (MPI_OPT)
339  CALL mpi_allreduce(mpi_in_place, buffer, SIZE(buffer), mpi_real8, &
340  & mpi_sum, this%comm, status)
341 #endif
342 
343  CALL profiler_set_stop_time('bmw_parallel_context_reduce2', &
344  & start_time)
345 
346  END SUBROUTINE
347 
348 !-------------------------------------------------------------------------------
356 !-------------------------------------------------------------------------------
357  SUBROUTINE bmw_parallel_context_reduce3(this, buffer)
358  USE stel_kinds, ONLY: rprec
359 
360  IMPLICIT NONE
361 
362 ! Declare Arguments
363  TYPE (bmw_parallel_context_class), INTENT(in) :: this
364  REAL (rprec), DIMENSION(:,:,:), INTENT(inout) :: buffer
365 
366 ! local variables
367  REAL (rprec) :: start_time
368  INTEGER :: status
369 
370 ! Start of executable code
371  start_time = profiler_get_start_time()
372 
373 #if defined (MPI_OPT)
374  CALL mpi_allreduce(mpi_in_place, buffer, SIZE(buffer), mpi_real8, &
375  & mpi_sum, this%comm, status)
376 #endif
377 
378  CALL profiler_set_stop_time('bmw_parallel_context_reduce3', &
379  & start_time)
380 
381  END SUBROUTINE
382 
383 !-------------------------------------------------------------------------------
391 !-------------------------------------------------------------------------------
392  SUBROUTINE bmw_parallel_context_reduce4(this, buffer)
393  USE stel_kinds, ONLY: rprec
394 
395  IMPLICIT NONE
396 
397 ! Declare Arguments
398  TYPE (bmw_parallel_context_class), INTENT(in) :: this
399  REAL (rprec), DIMENSION(:,:,:,:), INTENT(inout) :: buffer
400 
401 ! local variables
402  REAL (rprec) :: start_time
403  INTEGER :: status
404 
405 ! Start of executable code
406  start_time = profiler_get_start_time()
407 
408 #if defined (MPI_OPT)
409  CALL mpi_allreduce(mpi_in_place, buffer, SIZE(buffer), mpi_real8, &
410  & mpi_sum, this%comm, status)
411 #endif
412 
413  CALL profiler_set_stop_time('bmw_parallel_context_reduce4', &
414  & start_time)
415 
416  END SUBROUTINE
417 
418 !-------------------------------------------------------------------------------
427 !-------------------------------------------------------------------------------
428  PURE FUNCTION bmw_parallel_context_start(this, total)
429 
430  IMPLICIT NONE
431 
432 ! Declare Arguments
433  INTEGER :: bmw_parallel_context_start
434  TYPE (bmw_parallel_context_class), INTENT(in) :: this
435  INTEGER, INTENT(in) :: total
436 
437 ! local variables
438  INTEGER :: n_per_process
439  INTEGER :: n_left
440 
441 ! Start of executable code
442 ! Need to divide the problem space evenly by the number of processes.
443  n_per_process = total/this%stride
444 
445 ! The number of items may not evenly divide by the number of processes.
446  n_left = mod(total, this%stride)
447 
448  bmw_parallel_context_start = 1 + this%offset*n_per_process
449 
450 ! Acound for the remaining elements in the first n_left processes.
451  IF (this%offset .lt. n_left) THEN
453  & + this%offset
454  ELSE
456  & + n_left
457  END IF
458 
459  END FUNCTION
460 
461 !-------------------------------------------------------------------------------
470 !-------------------------------------------------------------------------------
471  PURE FUNCTION bmw_parallel_context_end(this, total)
472 
473  IMPLICIT NONE
474 
475 ! Declare Arguments
476  INTEGER :: bmw_parallel_context_end
477  TYPE (bmw_parallel_context_class), INTENT(in) :: this
478  INTEGER, INTENT(in) :: total
479 
480 ! local variables
481  INTEGER :: n_per_process
482  INTEGER :: n_left
483 
484 ! Start of executable code
485 ! Need to divide the problem space evenly by the number of processes.
486  n_per_process = total/this%stride
487 
488 ! The number of items may not evenly divide by the number of processes.
489  n_left = mod(total, this%stride)
490 
491  bmw_parallel_context_end = (this%offset + 1)*n_per_process
492 
493 ! Acound for the remaining elements in the first n_left processes.
494  IF (this%offset .lt. n_left) THEN
496  & + this%offset + 1
497  ELSE
499  & + n_left
500  END IF
501 
502  END FUNCTION
503 
504 !-------------------------------------------------------------------------------
513 !-------------------------------------------------------------------------------
514  PURE FUNCTION bmw_parallel_context_i(index, num_i)
515 
516  IMPLICIT NONE
517 
518 ! Declare Arguments
519  INTEGER :: bmw_parallel_context_i
520  INTEGER, INTENT(in) :: index
521  INTEGER, INTENT(in) :: num_i
522 
523 ! Start of executable code
524  bmw_parallel_context_i = mod(index - 1, num_i) + 1
525 
526  END FUNCTION
527 
528 !-------------------------------------------------------------------------------
538 !-------------------------------------------------------------------------------
539  PURE FUNCTION bmw_parallel_context_j(index, num_i, num_j)
540 
541  IMPLICIT NONE
542 
543 ! Declare Arguments
544  INTEGER :: bmw_parallel_context_j
545  INTEGER, INTENT(in) :: index
546  INTEGER, INTENT(in) :: num_i
547  INTEGER, INTENT(in) :: num_j
548 
549 ! Start of executable code
550  bmw_parallel_context_j = mod((index - 1)/num_i, num_j) + 1
551 
552  END FUNCTION
553 
554 !-------------------------------------------------------------------------------
564 !-------------------------------------------------------------------------------
565  PURE FUNCTION bmw_parallel_context_k(index, num_i, num_j)
566 
567  IMPLICIT NONE
568 
569 ! Declare Arguments
570  INTEGER :: bmw_parallel_context_k
571  INTEGER, INTENT(in) :: index
572  INTEGER, INTENT(in) :: num_i
573  INTEGER, INTENT(in) :: num_j
574 
575 ! Start of executable code
576  bmw_parallel_context_k = (index - 1)/(num_j*num_i) + 1
577 
578  END FUNCTION
579 
580  END MODULE
bmw_parallel_context::bmw_parallel_context_reduce4
subroutine bmw_parallel_context_reduce4(this, buffer)
Reduce parallel buffers.
Definition: bmw_parallel_context.f:393
profiler
Defines functions for measuring an tabulating performance of function and subroutine calls....
Definition: profiler.f:13
bmw_parallel_context::bmw_parallel_context_k
pure integer function bmw_parallel_context_k(index, num_i, num_j)
Compute the k index of a flat array.
Definition: bmw_parallel_context.f:566
bmw_parallel_context::bmw_parallel_context_start
pure integer function bmw_parallel_context_start(this, total)
Compute the start index of a flat array.
Definition: bmw_parallel_context.f:429
bmw_parallel_context
Defines the base class of the type bmw_parallel_context_class. This contains the state variables need...
Definition: bmw_parallel_context.f:11
mpi_inc
Umbrella module avoid multiple inlcudes of the mpif.h header.
Definition: mpi_inc.f:11
bmw_parallel_context::bmw_parallel_context_report
subroutine bmw_parallel_context_report(this, io_unit)
Report the number of parallel processes and threads.
Definition: bmw_parallel_context.f:246
bmw_parallel_context::bmw_parallel_context_i
pure integer function bmw_parallel_context_i(index, num_i)
Compute the i index of a flat array.
Definition: bmw_parallel_context.f:515
profiler::profiler_get_start_time
real(rprec) function profiler_get_start_time()
Gets the start time of profiled function.
Definition: profiler.f:194
bmw_parallel_context::bmw_parallel_context_destruct
subroutine bmw_parallel_context_destruct(this, finalize)
Deconstruct a bmw_parallel_context_class object.
Definition: bmw_parallel_context.f:143
bmw_parallel_context::bmw_parallel_context_reduce3
subroutine bmw_parallel_context_reduce3(this, buffer)
Reduce parallel buffers.
Definition: bmw_parallel_context.f:358
bmw_parallel_context::bmw_parallel_context_j
pure integer function bmw_parallel_context_j(index, num_i, num_j)
Compute the j index of a flat array.
Definition: bmw_parallel_context.f:540
bmw_parallel_context::bmw_parallel_context_abort
subroutine bmw_parallel_context_abort(status)
Abort the entire program.
Definition: bmw_parallel_context.f:177
bmw_parallel_context::bmw_parallel_context_reduce1
subroutine bmw_parallel_context_reduce1(this, buffer)
Reduce parallel buffers.
Definition: bmw_parallel_context.f:288
bmw_parallel_context::bmw_parallel_context_reduce
Interface for the buffer reduction.
Definition: bmw_parallel_context.f:49
profiler::profiler_set_stop_time
subroutine profiler_set_stop_time(symbol_name, start_time)
Gets the end time of profiled function.
Definition: profiler.f:121
bmw_parallel_context::bmw_parallel_context_set_threads
subroutine bmw_parallel_context_set_threads(this, num_threads)
Set the number of threads.
Definition: bmw_parallel_context.f:204
bmw_parallel_context::bmw_parallel_context_class
Base class representing a bmw parallel context. This contains all memory needed parameters needed to ...
Definition: bmw_parallel_context.f:26
bmw_parallel_context::bmw_parallel_context_end
pure integer function bmw_parallel_context_end(this, total)
Compute the end index of a flat array.
Definition: bmw_parallel_context.f:472
bmw_parallel_context::bmw_parallel_context_construct
type(bmw_parallel_context_class) function, pointer bmw_parallel_context_construct(comm)
Construct a bmw_context_class object.
Definition: bmw_parallel_context.f:75
bmw_parallel_context::bmw_parallel_context_reduce2
subroutine bmw_parallel_context_reduce2(this, buffer)
Reduce parallel buffers.
Definition: bmw_parallel_context.f:323