PartMC  2.6.1
mpi.F90
Go to the documentation of this file.
1 ! Copyright (C) 2007-2015 Matthew West
2 ! Licensed under the GNU General Public License version 2 or (at your
3 ! option) any later version. See the file COPYING for details.
4 
5 !> \file
6 !> The pmc_mpi module.
7 
8 !> Wrapper functions for MPI.
9 !!
10 !! All of these functions can be called irrespective of whether MPI
11 !! support was compiled in or not. If MPI support is not enabled then
12 !! they do the obvious trivial thing (normally nothing).
13 module pmc_mpi
14 
15  use pmc_util
16 
17 #ifdef PMC_USE_MPI
18  use mpi
19 #endif
20 
21 contains
22 
23 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
24 
25  !> Whether MPI support is compiled in.
26  logical function pmc_mpi_support()
27 
28 #ifdef PMC_USE_MPI
29  pmc_mpi_support = .true.
30 #else
31  pmc_mpi_support = .false.
32 #endif
33 
34  end function pmc_mpi_support
35 
36 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
37 
38  !> Dies if \c ierr is not ok.
39  subroutine pmc_mpi_check_ierr(ierr)
40 
41  !> MPI status code.
42  integer, intent(in) :: ierr
43 
44 #ifdef PMC_USE_MPI
45  if (ierr /= mpi_success) then
46  call pmc_mpi_abort(1)
47  end if
48 #endif
49 
50  end subroutine pmc_mpi_check_ierr
51 
52 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
53 
54  !> Initialize MPI.
55  subroutine pmc_mpi_init()
56 
57 #ifdef PMC_USE_MPI
58  integer :: ierr
59 
60  call mpi_init(ierr)
61  call pmc_mpi_check_ierr(ierr)
62  call pmc_mpi_test()
63 #endif
64 
65  end subroutine pmc_mpi_init
66 
67 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
68 
69  !> Abort the program.
70  subroutine pmc_mpi_abort(status)
71 
72  !> Status flag to abort with.
73  integer, intent(in) :: status
74 
75 #ifdef PMC_USE_MPI
76  integer :: ierr
77 
78  call mpi_abort(mpi_comm_world, status, ierr)
79 #else
80  call die(status)
81 #endif
82 
83  end subroutine pmc_mpi_abort
84 
85 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
86 
87  !> Shut down MPI.
88  subroutine pmc_mpi_finalize()
89 
90 #ifdef PMC_USE_MPI
91  integer :: ierr
92 
93  call mpi_finalize(ierr)
94  call pmc_mpi_check_ierr(ierr)
95 #endif
96 
97  end subroutine pmc_mpi_finalize
98 
99 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
100 
101  !> Synchronize all processes.
102  subroutine pmc_mpi_barrier()
103 
104 #ifdef PMC_USE_MPI
105  integer :: ierr
106 
107  call mpi_barrier(mpi_comm_world, ierr)
108  call pmc_mpi_check_ierr(ierr)
109 #endif
110 
111  end subroutine pmc_mpi_barrier
112 
113 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
114 
115  !> Returns the rank of the current process.
116  integer function pmc_mpi_rank()
117 
118 #ifdef PMC_USE_MPI
119  integer :: rank, ierr
120 
121  call mpi_comm_rank(mpi_comm_world, rank, ierr)
122  call pmc_mpi_check_ierr(ierr)
123  pmc_mpi_rank = rank
124 #else
125  pmc_mpi_rank = 0
126 #endif
127 
128  end function pmc_mpi_rank
129 
130 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
131 
132  !> Returns the total number of processes.
133  integer function pmc_mpi_size()
134 
135 #ifdef PMC_USE_MPI
136  integer :: size, ierr
137 
138  call mpi_comm_size(mpi_comm_world, size, ierr)
139  call pmc_mpi_check_ierr(ierr)
140  pmc_mpi_size = size
141 #else
142  pmc_mpi_size = 1
143 #endif
144 
145  end function pmc_mpi_size
146 
147 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
148 
149  !> Perform basic sanity checks on send/receive.
150  subroutine pmc_mpi_test()
151 
152 #ifdef PMC_USE_MPI
153  real(kind=dp), parameter :: test_real = 2.718281828459d0
154  complex(kind=dc), parameter :: test_complex &
155  = (0.707106781187d0, 1.4142135624d0)
156  logical, parameter :: test_logical = .true.
157  character(len=100), parameter :: test_string &
158  = "a truth universally acknowledged"
159  integer, parameter :: test_integer = 314159
160 
161  character, allocatable :: buffer(:)
162  integer :: buffer_size, max_buffer_size, position
163  real(kind=dp) :: send_real, recv_real
164  complex(kind=dc) :: send_complex, recv_complex
165  logical :: send_logical, recv_logical
166  character(len=100) :: send_string, recv_string
167  integer :: send_integer, recv_integer
168  real(kind=dp), allocatable :: send_real_array(:)
169  real(kind=dp), allocatable :: recv_real_array(:)
170 
171  if (pmc_mpi_rank() == 0) then
172  send_real = test_real
173  send_complex = test_complex
174  send_logical = test_logical
175  send_string = test_string
176  send_integer = test_integer
177  allocate(send_real_array(2))
178  send_real_array(1) = real(test_complex)
179  send_real_array(2) = aimag(test_complex)
180 
181  max_buffer_size = 0
182  max_buffer_size = max_buffer_size &
183  + pmc_mpi_pack_size_integer(send_integer)
184  max_buffer_size = max_buffer_size &
185  + pmc_mpi_pack_size_real(send_real)
186  max_buffer_size = max_buffer_size &
187  + pmc_mpi_pack_size_complex(send_complex)
188  max_buffer_size = max_buffer_size &
189  + pmc_mpi_pack_size_logical(send_logical)
190  max_buffer_size = max_buffer_size &
191  + pmc_mpi_pack_size_string(send_string)
192  max_buffer_size = max_buffer_size &
193  + pmc_mpi_pack_size_real_array(send_real_array)
194 
195  allocate(buffer(max_buffer_size))
196 
197  position = 0
198  call pmc_mpi_pack_real(buffer, position, send_real)
199  call pmc_mpi_pack_complex(buffer, position, send_complex)
200  call pmc_mpi_pack_logical(buffer, position, send_logical)
201  call pmc_mpi_pack_string(buffer, position, send_string)
202  call pmc_mpi_pack_integer(buffer, position, send_integer)
203  call pmc_mpi_pack_real_array(buffer, position, send_real_array)
204  call assert_msg(350740830, position <= max_buffer_size, &
205  "MPI test failure: pack position " &
206  // trim(integer_to_string(position)) &
207  // " greater than max_buffer_size " &
208  // trim(integer_to_string(max_buffer_size)))
209  buffer_size = position ! might be less than we allocated
210  end if
211 
212  call pmc_mpi_bcast_integer(buffer_size)
213 
214  if (pmc_mpi_rank() /= 0) then
215  allocate(buffer(buffer_size))
216  end if
217 
218  call pmc_mpi_bcast_packed(buffer)
219 
220  if (pmc_mpi_rank() /= 0) then
221  position = 0
222  call pmc_mpi_unpack_real(buffer, position, recv_real)
223  call pmc_mpi_unpack_complex(buffer, position, recv_complex)
224  call pmc_mpi_unpack_logical(buffer, position, recv_logical)
225  call pmc_mpi_unpack_string(buffer, position, recv_string)
226  call pmc_mpi_unpack_integer(buffer, position, recv_integer)
227  call pmc_mpi_unpack_real_array(buffer, position, recv_real_array)
228  call assert_msg(787677020, position == buffer_size, &
229  "MPI test failure: unpack position " &
230  // trim(integer_to_string(position)) &
231  // " not equal to buffer_size " &
232  // trim(integer_to_string(buffer_size)))
233  end if
234 
235  deallocate(buffer)
236 
237  if (pmc_mpi_rank() /= 0) then
238  call assert_msg(567548916, recv_real == test_real, &
239  "MPI test failure: real recv " &
240  // trim(real_to_string(recv_real)) &
241  // " not equal to " &
242  // trim(real_to_string(test_real)))
243  call assert_msg(653908509, recv_complex == test_complex, &
244  "MPI test failure: complex recv " &
245  // trim(complex_to_string(recv_complex)) &
246  // " not equal to " &
247  // trim(complex_to_string(test_complex)))
248  call assert_msg(307746296, recv_logical .eqv. test_logical, &
249  "MPI test failure: logical recv " &
250  // trim(logical_to_string(recv_logical)) &
251  // " not equal to " &
252  // trim(logical_to_string(test_logical)))
253  call assert_msg(155693492, recv_string == test_string, &
254  "MPI test failure: string recv '" &
255  // trim(recv_string) &
256  // "' not equal to '" &
257  // trim(test_string) // "'")
258  call assert_msg(875699427, recv_integer == test_integer, &
259  "MPI test failure: integer recv " &
260  // trim(integer_to_string(recv_integer)) &
261  // " not equal to " &
262  // trim(integer_to_string(test_integer)))
263  call assert_msg(326982363, size(recv_real_array) == 2, &
264  "MPI test failure: real array recv size " &
265  // trim(integer_to_string(size(recv_real_array))) &
266  // " not equal to 2")
267  call assert_msg(744394323, &
268  recv_real_array(1) == real(test_complex), &
269  "MPI test failure: real array recv index 1 " &
270  // trim(real_to_string(recv_real_array(1))) &
271  // " not equal to " &
272  // trim(real_to_string(real(test_complex))))
273  call assert_msg(858902527, &
274  recv_real_array(2) == aimag(test_complex), &
275  "MPI test failure: real array recv index 2 " &
276  // trim(real_to_string(recv_real_array(2))) &
277  // " not equal to " &
278  // trim(real_to_string(aimag(test_complex))))
279  end if
280 #endif
281 
282  end subroutine pmc_mpi_test
283 
284 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
285 
286  !> Broadcast the given value from process 0 to all other processes.
287  subroutine pmc_mpi_bcast_integer(val)
288 
289  !> Value to broadcast.
290  integer, intent(inout) :: val
291 
292 #ifdef PMC_USE_MPI
293  integer :: root, ierr
294 
295  root = 0 ! source of data to broadcast
296  call mpi_bcast(val, 1, mpi_integer, root, &
297  mpi_comm_world, ierr)
298  call pmc_mpi_check_ierr(ierr)
299 #endif
300 
301  end subroutine pmc_mpi_bcast_integer
302 
303 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
304 
305  !> Broadcast the given value from process 0 to all other processes.
306  subroutine pmc_mpi_bcast_string(val)
307 
308  !> Value to broadcast.
309  character(len=*), intent(inout) :: val
310 
311 #ifdef PMC_USE_MPI
312  integer :: root, ierr
313 
314  root = 0 ! source of data to broadcast
315  call mpi_bcast(val, len(val), mpi_character, root, &
316  mpi_comm_world, ierr)
317  call pmc_mpi_check_ierr(ierr)
318 #endif
319 
320  end subroutine pmc_mpi_bcast_string
321 
322 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
323 
324  !> Broadcast the given value from process 0 to all other processes.
325  subroutine pmc_mpi_bcast_packed(val)
326 
327  !> Value to broadcast.
328  character, intent(inout) :: val(:)
329 
330 #ifdef PMC_USE_MPI
331  integer :: root, ierr
332 
333  root = 0 ! source of data to broadcast
334  call mpi_bcast(val, size(val), mpi_character, root, &
335  mpi_comm_world, ierr)
336  call pmc_mpi_check_ierr(ierr)
337 #endif
338 
339  end subroutine pmc_mpi_bcast_packed
340 
341 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
342 
343  !> Determines the number of bytes required to pack the given value.
344  integer function pmc_mpi_pack_size_integer(val)
345 
346  !> Value to pack.
347  integer, intent(in) :: val
348 
349  integer :: ierr
350 
351 #ifdef PMC_USE_MPI
352  call mpi_pack_size(1, mpi_integer, mpi_comm_world, &
354  call pmc_mpi_check_ierr(ierr)
355 #else
357 #endif
358 
359  end function pmc_mpi_pack_size_integer
360 
361 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
362 
363  !> Determines the number of bytes required to pack the given value.
364  integer function pmc_mpi_pack_size_real(val)
365 
366  !> Value to pack.
367  real(kind=dp), intent(in) :: val
368 
369  integer :: ierr
370 
371 #ifdef PMC_USE_MPI
372  call mpi_pack_size(1, mpi_double_precision, mpi_comm_world, &
374  call pmc_mpi_check_ierr(ierr)
375 #else
377 #endif
378 
379  end function pmc_mpi_pack_size_real
380 
381 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
382 
383  !> Determines the number of bytes required to pack the given value.
384  integer function pmc_mpi_pack_size_string(val)
385 
386  !> Value to pack.
387  character(len=*), intent(in) :: val
388 
389  integer :: ierr
390 
391 #ifdef PMC_USE_MPI
392  call mpi_pack_size(len_trim(val), mpi_character, mpi_comm_world, &
394  call pmc_mpi_check_ierr(ierr)
396  + pmc_mpi_pack_size_integer(len_trim(val))
397 #else
399 #endif
400 
401  end function pmc_mpi_pack_size_string
402 
403 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
404 
405  !> Determines the number of bytes required to pack the given value.
406  integer function pmc_mpi_pack_size_logical(val)
407 
408  !> Value to pack.
409  logical, intent(in) :: val
410 
411  integer :: ierr
412 
413 #ifdef PMC_USE_MPI
414  call mpi_pack_size(1, mpi_logical, mpi_comm_world, &
416  call pmc_mpi_check_ierr(ierr)
417 #else
419 #endif
420 
421  end function pmc_mpi_pack_size_logical
422 
423 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
424 
425  !> Determines the number of bytes required to pack the given value.
426  integer function pmc_mpi_pack_size_complex(val)
427 
428  !> Value to pack.
429  complex(kind=dc), intent(in) :: val
430 
431  integer :: ierr
432 
433 #ifdef PMC_USE_MPI
434  call mpi_pack_size(1, mpi_double_complex, mpi_comm_world, &
436  call pmc_mpi_check_ierr(ierr)
437 #else
439 #endif
440 
441  end function pmc_mpi_pack_size_complex
442 
443 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
444 
445  !> Determines the number of bytes required to pack the given value.
446  integer function pmc_mpi_pack_size_integer_array(val)
447 
448  !> Value to pack.
449  integer, allocatable, intent(in) :: val(:)
450 
451  integer :: total_size, ierr
452 
453 #ifdef PMC_USE_MPI
454  logical :: is_allocated
455 
456  total_size = 0
457  is_allocated = allocated(val)
458  if (is_allocated) then
459  call mpi_pack_size(size(val), mpi_integer, mpi_comm_world, &
460  total_size, ierr)
461  call pmc_mpi_check_ierr(ierr)
462  total_size = total_size + pmc_mpi_pack_size_integer(size(val))
463  end if
464  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
465 #else
466  total_size = 0
467 #endif
468 
470 
472 
473 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
474 
475  !> Determines the number of bytes required to pack the given value.
476  integer function pmc_mpi_pack_size_real_array(val)
477 
478  !> Value to pack.
479  real(kind=dp), allocatable, intent(in) :: val(:)
480 
481  integer :: total_size, ierr
482 
483 #ifdef PMC_USE_MPI
484  logical :: is_allocated
485 
486  total_size = 0
487  is_allocated = allocated(val)
488  if (is_allocated) then
489  call mpi_pack_size(size(val), mpi_double_precision, mpi_comm_world, &
490  total_size, ierr)
491  call pmc_mpi_check_ierr(ierr)
492  total_size = total_size + pmc_mpi_pack_size_integer(size(val))
493  end if
494  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
495 #else
496  total_size = 0
497 #endif
498 
499  pmc_mpi_pack_size_real_array = total_size
500 
501  end function pmc_mpi_pack_size_real_array
502 
503 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
504 
505  !> Determines the number of bytes required to pack the given value.
506  integer function pmc_mpi_pack_size_string_array(val)
507 
508  !> Value to pack.
509  character(len=*), allocatable, intent(in) :: val(:)
510 
511  integer :: i, total_size
512  logical :: is_allocated
513 
514  is_allocated = allocated(val)
515  if (is_allocated) then
516  total_size = pmc_mpi_pack_size_integer(size(val))
517  do i = 1,size(val)
518  total_size = total_size + pmc_mpi_pack_size_string(val(i))
519  end do
520  end if
521  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
522  pmc_mpi_pack_size_string_array = total_size
523 
524  end function pmc_mpi_pack_size_string_array
525 
526 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
527 
528  !> Determines the number of bytes required to pack the given value.
529  integer function pmc_mpi_pack_size_real_array_2d(val)
530 
531  !> Value to pack.
532  real(kind=dp), allocatable, intent(in) :: val(:,:)
533 
534  integer :: total_size, ierr
535 
536 #ifdef PMC_USE_MPI
537  logical :: is_allocated
538 
539  total_size = 0
540  is_allocated = allocated(val)
541  if (is_allocated) then
542  call mpi_pack_size(size(val), mpi_double_precision, mpi_comm_world, &
543  total_size, ierr)
544  call pmc_mpi_check_ierr(ierr)
545  total_size = total_size + pmc_mpi_pack_size_integer(size(val,1)) &
546  + pmc_mpi_pack_size_integer(size(val,2))
547  end if
548  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
549 #else
550  total_size = 0
551 #endif
552 
554 
556 
557 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
558 
559  !> Packs the given value into the buffer, advancing position.
560  subroutine pmc_mpi_pack_integer(buffer, position, val)
561 
562  !> Memory buffer.
563  character, intent(inout) :: buffer(:)
564  !> Current buffer position.
565  integer, intent(inout) :: position
566  !> Value to pack.
567  integer, intent(in) :: val
568 
569 #ifdef PMC_USE_MPI
570  integer :: prev_position, ierr
571 
572  prev_position = position
573  call mpi_pack(val, 1, mpi_integer, buffer, size(buffer), &
574  position, mpi_comm_world, ierr)
575  call pmc_mpi_check_ierr(ierr)
576  call assert(913495993, &
577  position - prev_position <= pmc_mpi_pack_size_integer(val))
578 #endif
579 
580  end subroutine pmc_mpi_pack_integer
581 
582 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
583 
584  !> Packs the given value into the buffer, advancing position.
585  subroutine pmc_mpi_pack_real(buffer, position, val)
586 
587  !> Memory buffer.
588  character, intent(inout) :: buffer(:)
589  !> Current buffer position.
590  integer, intent(inout) :: position
591  !> Value to pack.
592  real(kind=dp), intent(in) :: val
593 
594 #ifdef PMC_USE_MPI
595  integer :: prev_position, ierr
596 
597  prev_position = position
598  call mpi_pack(val, 1, mpi_double_precision, buffer, size(buffer), &
599  position, mpi_comm_world, ierr)
600  call pmc_mpi_check_ierr(ierr)
601  call assert(395354132, &
602  position - prev_position <= pmc_mpi_pack_size_real(val))
603 #endif
604 
605  end subroutine pmc_mpi_pack_real
606 
607 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
608 
609  !> Packs the given value into the buffer, advancing position.
610  subroutine pmc_mpi_pack_string(buffer, position, val)
611 
612  !> Memory buffer.
613  character, intent(inout) :: buffer(:)
614  !> Current buffer position.
615  integer, intent(inout) :: position
616  !> Value to pack.
617  character(len=*), intent(in) :: val
618 
619 #ifdef PMC_USE_MPI
620  integer :: prev_position, length, ierr
621 
622  prev_position = position
623  length = len_trim(val)
624  call pmc_mpi_pack_integer(buffer, position, length)
625  call mpi_pack(val, length, mpi_character, buffer, size(buffer), &
626  position, mpi_comm_world, ierr)
627  call pmc_mpi_check_ierr(ierr)
628  call assert(607212018, &
629  position - prev_position <= pmc_mpi_pack_size_string(val))
630 #endif
631 
632  end subroutine pmc_mpi_pack_string
633 
634 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
635 
636  !> Packs the given value into the buffer, advancing position.
637  subroutine pmc_mpi_pack_logical(buffer, position, val)
638 
639  !> Memory buffer.
640  character, intent(inout) :: buffer(:)
641  !> Current buffer position.
642  integer, intent(inout) :: position
643  !> Value to pack.
644  logical, intent(in) :: val
645 
646 #ifdef PMC_USE_MPI
647  integer :: prev_position, ierr
648 
649  prev_position = position
650  call mpi_pack(val, 1, mpi_logical, buffer, size(buffer), &
651  position, mpi_comm_world, ierr)
652  call pmc_mpi_check_ierr(ierr)
653  call assert(104535200, &
654  position - prev_position <= pmc_mpi_pack_size_logical(val))
655 #endif
656 
657  end subroutine pmc_mpi_pack_logical
658 
659 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
660 
661  !> Packs the given value into the buffer, advancing position.
662  subroutine pmc_mpi_pack_complex(buffer, position, val)
663 
664  !> Memory buffer.
665  character, intent(inout) :: buffer(:)
666  !> Current buffer position.
667  integer, intent(inout) :: position
668  !> Value to pack.
669  complex(kind=dc), intent(in) :: val
670 
671 #ifdef PMC_USE_MPI
672  integer :: prev_position, ierr
673 
674  prev_position = position
675  call mpi_pack(val, 1, mpi_double_complex, buffer, size(buffer), &
676  position, mpi_comm_world, ierr)
677  call pmc_mpi_check_ierr(ierr)
678  call assert(640416372, &
679  position - prev_position <= pmc_mpi_pack_size_complex(val))
680 #endif
681 
682  end subroutine pmc_mpi_pack_complex
683 
684 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
685 
686  !> Packs the given value into the buffer, advancing position.
687  subroutine pmc_mpi_pack_integer_array(buffer, position, val)
688 
689  !> Memory buffer.
690  character, intent(inout) :: buffer(:)
691  !> Current buffer position.
692  integer, intent(inout) :: position
693  !> Value to pack.
694  integer, allocatable, intent(in) :: val(:)
695 
696 #ifdef PMC_USE_MPI
697  integer :: prev_position, n, ierr
698  logical :: is_allocated
699 
700  prev_position = position
701  is_allocated = allocated(val)
702  call pmc_mpi_pack_logical(buffer, position, is_allocated)
703  if (is_allocated) then
704  n = size(val)
705  call pmc_mpi_pack_integer(buffer, position, n)
706  call mpi_pack(val, n, mpi_integer, buffer, size(buffer), &
707  position, mpi_comm_world, ierr)
708  call pmc_mpi_check_ierr(ierr)
709  end if
710  call assert(698601296, &
711  position - prev_position <= pmc_mpi_pack_size_integer_array(val))
712 #endif
713 
714  end subroutine pmc_mpi_pack_integer_array
715 
716 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
717 
718  !> Packs the given value into the buffer, advancing position.
719  subroutine pmc_mpi_pack_real_array(buffer, position, val)
720 
721  !> Memory buffer.
722  character, intent(inout) :: buffer(:)
723  !> Current buffer position.
724  integer, intent(inout) :: position
725  !> Value to pack.
726  real(kind=dp), allocatable, intent(in) :: val(:)
727 
728 #ifdef PMC_USE_MPI
729  integer :: prev_position, n, ierr
730  logical :: is_allocated
731 
732  prev_position = position
733  is_allocated = allocated(val)
734  call pmc_mpi_pack_logical(buffer, position, is_allocated)
735  if (is_allocated) then
736  n = size(val)
737  call pmc_mpi_pack_integer(buffer, position, n)
738  call mpi_pack(val, n, mpi_double_precision, buffer, size(buffer), &
739  position, mpi_comm_world, ierr)
740  call pmc_mpi_check_ierr(ierr)
741  end if
742  call assert(825718791, &
743  position - prev_position <= pmc_mpi_pack_size_real_array(val))
744 #endif
745 
746  end subroutine pmc_mpi_pack_real_array
747 
748 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
749 
750  !> Packs the given value into the buffer, advancing position.
751  subroutine pmc_mpi_pack_string_array(buffer, position, val)
752 
753  !> Memory buffer.
754  character, intent(inout) :: buffer(:)
755  !> Current buffer position.
756  integer, intent(inout) :: position
757  !> Value to pack.
758  character(len=*), allocatable, intent(in) :: val(:)
759 
760 #ifdef PMC_USE_MPI
761  integer :: prev_position, i, n
762  logical :: is_allocated
763 
764  prev_position = position
765  is_allocated = allocated(val)
766  call pmc_mpi_pack_logical(buffer, position, is_allocated)
767  if (is_allocated) then
768  n = size(val)
769  call pmc_mpi_pack_integer(buffer, position, n)
770  do i = 1,n
771  call pmc_mpi_pack_string(buffer, position, val(i))
772  end do
773  end if
774  call assert(630900704, &
775  position - prev_position <= pmc_mpi_pack_size_string_array(val))
776 #endif
777 
778  end subroutine pmc_mpi_pack_string_array
779 
780 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
781 
782  !> Packs the given value into the buffer, advancing position.
783  subroutine pmc_mpi_pack_real_array_2d(buffer, position, val)
784 
785  !> Memory buffer.
786  character, intent(inout) :: buffer(:)
787  !> Current buffer position.
788  integer, intent(inout) :: position
789  !> Value to pack.
790  real(kind=dp), allocatable, intent(in) :: val(:,:)
791 
792 #ifdef PMC_USE_MPI
793  integer :: prev_position, n1, n2, ierr
794  logical :: is_allocated
795 
796  prev_position = position
797  is_allocated = allocated(val)
798  call pmc_mpi_pack_logical(buffer, position, is_allocated)
799  if (is_allocated) then
800  n1 = size(val, 1)
801  n2 = size(val, 2)
802  call pmc_mpi_pack_integer(buffer, position, n1)
803  call pmc_mpi_pack_integer(buffer, position, n2)
804  call mpi_pack(val, n1*n2, mpi_double_precision, buffer, size(buffer), &
805  position, mpi_comm_world, ierr)
806  call pmc_mpi_check_ierr(ierr)
807  end if
808  call assert(567349745, &
809  position - prev_position <= pmc_mpi_pack_size_real_array_2d(val))
810 #endif
811 
812  end subroutine pmc_mpi_pack_real_array_2d
813 
814 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
815 
816  !> Unpacks the given value from the buffer, advancing position.
817  subroutine pmc_mpi_unpack_integer(buffer, position, val)
818 
819  !> Memory buffer.
820  character, intent(inout) :: buffer(:)
821  !> Current buffer position.
822  integer, intent(inout) :: position
823  !> Value to pack.
824  integer, intent(out) :: val
825 
826 #ifdef PMC_USE_MPI
827  integer :: prev_position, ierr
828 
829  prev_position = position
830  call mpi_unpack(buffer, size(buffer), position, val, 1, mpi_integer, &
831  mpi_comm_world, ierr)
832  call pmc_mpi_check_ierr(ierr)
833  call assert(890243339, &
834  position - prev_position <= pmc_mpi_pack_size_integer(val))
835 #endif
836 
837  end subroutine pmc_mpi_unpack_integer
838 
839 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
840 
841  !> Unpacks the given value from the buffer, advancing position.
842  subroutine pmc_mpi_unpack_real(buffer, position, val)
843 
844  !> Memory buffer.
845  character, intent(inout) :: buffer(:)
846  !> Current buffer position.
847  integer, intent(inout) :: position
848  !> Value to pack.
849  real(kind=dp), intent(out) :: val
850 
851 #ifdef PMC_USE_MPI
852  integer :: prev_position, ierr
853 
854  prev_position = position
855  call mpi_unpack(buffer, size(buffer), position, val, 1, &
856  mpi_double_precision, mpi_comm_world, ierr)
857  call pmc_mpi_check_ierr(ierr)
858  call assert(570771632, &
859  position - prev_position <= pmc_mpi_pack_size_real(val))
860 #endif
861 
862  end subroutine pmc_mpi_unpack_real
863 
864 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
865 
866  !> Unpacks the given value from the buffer, advancing position.
867  subroutine pmc_mpi_unpack_string(buffer, position, val)
868 
869  !> Memory buffer.
870  character, intent(inout) :: buffer(:)
871  !> Current buffer position.
872  integer, intent(inout) :: position
873  !> Value to pack.
874  character(len=*), intent(out) :: val
875 
876 #ifdef PMC_USE_MPI
877  integer :: prev_position, length, ierr
878 
879  prev_position = position
880  call pmc_mpi_unpack_integer(buffer, position, length)
881  call assert(946399479, length <= len(val))
882  val = ''
883  call mpi_unpack(buffer, size(buffer), position, val, length, &
884  mpi_character, mpi_comm_world, ierr)
885  call pmc_mpi_check_ierr(ierr)
886  call assert(503378058, &
887  position - prev_position <= pmc_mpi_pack_size_string(val))
888 #endif
889 
890  end subroutine pmc_mpi_unpack_string
891 
892 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
893 
894  !> Unpacks the given value from the buffer, advancing position.
895  subroutine pmc_mpi_unpack_logical(buffer, position, val)
896 
897  !> Memory buffer.
898  character, intent(inout) :: buffer(:)
899  !> Current buffer position.
900  integer, intent(inout) :: position
901  !> Value to pack.
902  logical, intent(out) :: val
903 
904 #ifdef PMC_USE_MPI
905  integer :: prev_position, ierr
906 
907  prev_position = position
908  call mpi_unpack(buffer, size(buffer), position, val, 1, mpi_logical, &
909  mpi_comm_world, ierr)
910  call pmc_mpi_check_ierr(ierr)
911  call assert(694750528, &
912  position - prev_position <= pmc_mpi_pack_size_logical(val))
913 #endif
914 
915  end subroutine pmc_mpi_unpack_logical
916 
917 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
918 
919  !> Unpacks the given value from the buffer, advancing position.
920  subroutine pmc_mpi_unpack_complex(buffer, position, val)
921 
922  !> Memory buffer.
923  character, intent(inout) :: buffer(:)
924  !> Current buffer position.
925  integer, intent(inout) :: position
926  !> Value to pack.
927  complex(kind=dc), intent(out) :: val
928 
929 #ifdef PMC_USE_MPI
930  integer :: prev_position, ierr
931 
932  prev_position = position
933  call mpi_unpack(buffer, size(buffer), position, val, 1, &
934  mpi_double_complex, mpi_comm_world, ierr)
935  call pmc_mpi_check_ierr(ierr)
936  call assert(969672634, &
937  position - prev_position <= pmc_mpi_pack_size_complex(val))
938 #endif
939 
940  end subroutine pmc_mpi_unpack_complex
941 
942 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
943 
944  !> Unpacks the given value from the buffer, advancing position.
945  subroutine pmc_mpi_unpack_integer_array(buffer, position, val)
946 
947  !> Memory buffer.
948  character, intent(inout) :: buffer(:)
949  !> Current buffer position.
950  integer, intent(inout) :: position
951  !> Value to pack.
952  integer, allocatable, intent(inout) :: val(:)
953 
954 #ifdef PMC_USE_MPI
955  integer :: prev_position, n, ierr
956  logical :: is_allocated
957 
958  prev_position = position
959  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
960  if (allocated(val)) deallocate(val)
961  if (is_allocated) then
962  call pmc_mpi_unpack_integer(buffer, position, n)
963  allocate(val(n))
964  call mpi_unpack(buffer, size(buffer), position, val, n, mpi_integer, &
965  mpi_comm_world, ierr)
966  call pmc_mpi_check_ierr(ierr)
967  end if
968  call assert(565840919, &
969  position - prev_position <= pmc_mpi_pack_size_integer_array(val))
970 #endif
971 
972  end subroutine pmc_mpi_unpack_integer_array
973 
974 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
975 
976  !> Unpacks the given value from the buffer, advancing position.
977  subroutine pmc_mpi_unpack_real_array(buffer, position, val)
978 
979  !> Memory buffer.
980  character, intent(inout) :: buffer(:)
981  !> Current buffer position.
982  integer, intent(inout) :: position
983  !> Value to pack.
984  real(kind=dp), allocatable, intent(inout) :: val(:)
985 
986 #ifdef PMC_USE_MPI
987  integer :: prev_position, n, ierr
988  logical :: is_allocated
989 
990  prev_position = position
991  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
992  if (allocated(val)) deallocate(val)
993  if (is_allocated) then
994  call pmc_mpi_unpack_integer(buffer, position, n)
995  allocate(val(n))
996  call mpi_unpack(buffer, size(buffer), position, val, n, &
997  mpi_double_precision, mpi_comm_world, ierr)
998  call pmc_mpi_check_ierr(ierr)
999  end if
1000  call assert(782875761, &
1001  position - prev_position <= pmc_mpi_pack_size_real_array(val))
1002 #endif
1003 
1004  end subroutine pmc_mpi_unpack_real_array
1005 
1006 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1007 
1008  !> Unpacks the given value from the buffer, advancing position.
1009  subroutine pmc_mpi_unpack_string_array(buffer, position, val)
1010 
1011  !> Memory buffer.
1012  character, intent(inout) :: buffer(:)
1013  !> Current buffer position.
1014  integer, intent(inout) :: position
1015  !> Value to pack.
1016  character(len=*), allocatable, intent(inout) :: val(:)
1017 
1018 #ifdef PMC_USE_MPI
1019  integer :: prev_position, i, n
1020  logical :: is_allocated
1021 
1022  prev_position = position
1023  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
1024  if (allocated(val)) deallocate(val)
1025  if (is_allocated) then
1026  call pmc_mpi_unpack_integer(buffer, position, n)
1027  allocate(val(n))
1028  do i = 1,n
1029  call pmc_mpi_unpack_string(buffer, position, val(i))
1030  end do
1031  end if
1032  call assert(320065648, &
1033  position - prev_position <= pmc_mpi_pack_size_string_array(val))
1034 #endif
1035 
1036  end subroutine pmc_mpi_unpack_string_array
1037 
1038 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1039 
1040  !> Unpacks the given value from the buffer, advancing position.
1041  subroutine pmc_mpi_unpack_real_array_2d(buffer, position, val)
1042 
1043  !> Memory buffer.
1044  character, intent(inout) :: buffer(:)
1045  !> Current buffer position.
1046  integer, intent(inout) :: position
1047  !> Value to pack.
1048  real(kind=dp), allocatable, intent(inout) :: val(:,:)
1049 
1050 #ifdef PMC_USE_MPI
1051  integer :: prev_position, n1, n2, ierr
1052  logical :: is_allocated
1053 
1054  prev_position = position
1055  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
1056  if (allocated(val)) deallocate(val)
1057  if (is_allocated) then
1058  call pmc_mpi_unpack_integer(buffer, position, n1)
1059  call pmc_mpi_unpack_integer(buffer, position, n2)
1060  allocate(val(n1,n2))
1061  call mpi_unpack(buffer, size(buffer), position, val, n1*n2, &
1062  mpi_double_precision, mpi_comm_world, ierr)
1063  call pmc_mpi_check_ierr(ierr)
1064  end if
1065  call assert(781681739, position - prev_position &
1067 #endif
1068 
1069  end subroutine pmc_mpi_unpack_real_array_2d
1070 
1071 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1072 
1073  !> Computes the average of val across all processes, storing the
1074  !> result in val_avg on the root process.
1075  subroutine pmc_mpi_reduce_avg_real(val, val_avg)
1076 
1077  !> Value to average.
1078  real(kind=dp), intent(in) :: val
1079  !> Result.
1080  real(kind=dp), intent(out) :: val_avg
1081 
1082 #ifdef PMC_USE_MPI
1083  integer :: ierr
1084 
1085  call mpi_reduce(val, val_avg, 1, mpi_double_precision, mpi_sum, 0, &
1086  mpi_comm_world, ierr)
1087  call pmc_mpi_check_ierr(ierr)
1088  if (pmc_mpi_rank() == 0) then
1089  val_avg = val_avg / real(pmc_mpi_size(), kind=dp)
1090  end if
1091 #else
1092  val_avg = val
1093 #endif
1094 
1095  end subroutine pmc_mpi_reduce_avg_real
1096 
1097 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1098 
1099  !> Transfer the value between the given processes.
1100  subroutine pmc_mpi_transfer_real(from_val, to_val, from_proc, to_proc)
1101 
1102  !> Value to send.
1103  real(kind=dp), intent(in) :: from_val
1104  !> Variable to send to.
1105  real(kind=dp), intent(out) :: to_val
1106  !> Process to send from.
1107  integer, intent(in) :: from_proc
1108  !> Process to send to.
1109  integer, intent(in) :: to_proc
1110 
1111 #ifdef PMC_USE_MPI
1112  integer :: rank, ierr, status(MPI_STATUS_SIZE)
1113 
1114  rank = pmc_mpi_rank()
1115  if (from_proc == to_proc) then
1116  if (rank == from_proc) then
1117  to_val = from_val
1118  end if
1119  else
1120  if (rank == from_proc) then
1121  call mpi_send(from_val, 1, mpi_double_precision, to_proc, &
1122  208020430, mpi_comm_world, ierr)
1123  call pmc_mpi_check_ierr(ierr)
1124  elseif (rank == to_proc) then
1125  call mpi_recv(to_val, 1, mpi_double_precision, from_proc, &
1126  208020430, mpi_comm_world, status, ierr)
1127  call pmc_mpi_check_ierr(ierr)
1128  end if
1129  end if
1130 #else
1131  to_val = from_val
1132 #endif
1133 
1134  end subroutine pmc_mpi_transfer_real
1135 
1136 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1137 
1138  !> Transfer the value between the given processes.
1139  subroutine pmc_mpi_transfer_integer(from_val, to_val, from_proc, to_proc)
1140 
1141  !> Value to send.
1142  integer, intent(in) :: from_val
1143  !> Variable to send to.
1144  integer, intent(out) :: to_val
1145  !> Process to send from.
1146  integer, intent(in) :: from_proc
1147  !> Process to send to.
1148  integer, intent(in) :: to_proc
1149 
1150 #ifdef PMC_USE_MPI
1151  integer :: rank, ierr, status(MPI_STATUS_SIZE)
1152 
1153  rank = pmc_mpi_rank()
1154  if (from_proc == to_proc) then
1155  if (rank == from_proc) then
1156  to_val = from_val
1157  end if
1158  else
1159  if (rank == from_proc) then
1160  call mpi_send(from_val, 1, mpi_integer, to_proc, &
1161  208020430, mpi_comm_world, ierr)
1162  call pmc_mpi_check_ierr(ierr)
1163  elseif (rank == to_proc) then
1164  call mpi_recv(to_val, 1, mpi_integer, from_proc, &
1165  208020430, mpi_comm_world, status, ierr)
1166  call pmc_mpi_check_ierr(ierr)
1167  end if
1168  end if
1169 #else
1170  to_val = from_val
1171 #endif
1172 
1173  end subroutine pmc_mpi_transfer_integer
1174 
1175 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1176 
1177  !> Computes the sum of \c val across all processes, storing the
1178  !> result in \c val_sum on the root process.
1179  subroutine pmc_mpi_reduce_sum_integer(val, val_sum)
1180 
1181  !> Value to sum.
1182  integer, intent(in) :: val
1183  !> Result.
1184  integer, intent(out) :: val_sum
1185 
1186 #ifdef PMC_USE_MPI
1187  integer :: ierr
1188 
1189  call mpi_reduce(val, val_sum, 1, mpi_integer, mpi_sum, 0, &
1190  mpi_comm_world, ierr)
1191  call pmc_mpi_check_ierr(ierr)
1192 #else
1193  val_sum = val
1194 #endif
1195 
1196  end subroutine pmc_mpi_reduce_sum_integer
1197 
1198 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1199 
1200  !> Computes the sum of \c val across all processes, storing the
1201  !> result in \c val_sum on all processes.
1202  subroutine pmc_mpi_allreduce_sum_integer(val, val_sum)
1203 
1204  !> Value to sum.
1205  integer, intent(in) :: val
1206  !> Result.
1207  integer, intent(out) :: val_sum
1208 
1209 #ifdef PMC_USE_MPI
1210  integer :: ierr
1211 
1212  call mpi_allreduce(val, val_sum, 1, mpi_integer, mpi_sum, &
1213  mpi_comm_world, ierr)
1214  call pmc_mpi_check_ierr(ierr)
1215 #else
1216  val_sum = val
1217 #endif
1218 
1219  end subroutine pmc_mpi_allreduce_sum_integer
1220 
1221 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1222 
1223  !> Computes the average of val across all processes, storing the
1224  !> result in val_avg on the root process.
1225  subroutine pmc_mpi_reduce_avg_real_array(val, val_avg)
1226 
1227  !> Value to average.
1228  real(kind=dp), intent(in) :: val(:)
1229  !> Result.
1230  real(kind=dp), intent(out) :: val_avg(:)
1231 
1232 #ifdef PMC_USE_MPI
1233  integer :: ierr
1234 
1235  call assert(915136121, size(val) == size(val_avg))
1236  call mpi_reduce(val, val_avg, size(val), mpi_double_precision, &
1237  mpi_sum, 0, mpi_comm_world, ierr)
1238  call pmc_mpi_check_ierr(ierr)
1239  if (pmc_mpi_rank() == 0) then
1240  val_avg = val_avg / real(pmc_mpi_size(), kind=dp)
1241  end if
1242 #else
1243  val_avg = val
1244 #endif
1245 
1246  end subroutine pmc_mpi_reduce_avg_real_array
1247 
1248 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1249 
1250  !> Computes the average of val across all processes, storing the
1251  !> result in val_avg on the root process.
1252  subroutine pmc_mpi_reduce_avg_real_array_2d(val, val_avg)
1253 
1254  !> Value to average.
1255  real(kind=dp), intent(in) :: val(:,:)
1256  !> Result.
1257  real(kind=dp), intent(out) :: val_avg(:,:)
1258 
1259 #ifdef PMC_USE_MPI
1260  integer :: ierr
1261 
1262  call assert(131229046, size(val,1) == size(val_avg,1))
1263  call assert(992122167, size(val,2) == size(val_avg,2))
1264  call mpi_reduce(val, val_avg, size(val), mpi_double_precision, &
1265  mpi_sum, 0, mpi_comm_world, ierr)
1266  call pmc_mpi_check_ierr(ierr)
1267  if (pmc_mpi_rank() == 0) then
1268  val_avg = val_avg / real(pmc_mpi_size(), kind=dp)
1269  end if
1270 #else
1271  val_avg = val
1272 #endif
1273 
1274  end subroutine pmc_mpi_reduce_avg_real_array_2d
1275 
1276 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1277 
1278  !> Computes the average of val across all processes, storing the
1279  !> result in val_avg on all processes.
1280  subroutine pmc_mpi_allreduce_average_real(val, val_avg)
1281 
1282  !> Value to average.
1283  real(kind=dp), intent(in) :: val
1284  !> Result.
1285  real(kind=dp), intent(out) :: val_avg
1286 
1287 #ifdef PMC_USE_MPI
1288  integer :: ierr
1289 
1290  call mpi_allreduce(val, val_avg, 1, mpi_double_precision, mpi_sum, &
1291  mpi_comm_world, ierr)
1292  call pmc_mpi_check_ierr(ierr)
1293  val_avg = val_avg / real(pmc_mpi_size(), kind=dp)
1294 #else
1295  val_avg = val
1296 #endif
1297 
1298  end subroutine pmc_mpi_allreduce_average_real
1299 
1300 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1301 
1302  !> Computes the average of val across all processes, storing the
1303  !> result in val_avg on all processes.
1304  subroutine pmc_mpi_allreduce_average_real_array(val, val_avg)
1305 
1306  !> Value to average.
1307  real(kind=dp), intent(in) :: val(:)
1308  !> Result.
1309  real(kind=dp), intent(out) :: val_avg(:)
1310 
1311 #ifdef PMC_USE_MPI
1312  integer :: ierr
1313 
1314  call assert(948533359, size(val) == size(val_avg))
1315  call mpi_allreduce(val, val_avg, size(val), mpi_double_precision, &
1316  mpi_sum, mpi_comm_world, ierr)
1317  call pmc_mpi_check_ierr(ierr)
1318  val_avg = val_avg / real(pmc_mpi_size(), kind=dp)
1319 #else
1320  val_avg = val
1321 #endif
1322 
1324 
1325 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1326 
1327  !> Computes the minimum of val across all processes, storing the
1328  !> result in val_min on all processes.
1329  subroutine pmc_mpi_allreduce_min_integer(val, val_min)
1330 
1331  !> Value to minimize.
1332  integer, intent(in) :: val
1333  !> Result.
1334  integer, intent(out) :: val_min
1335 
1336 #ifdef PMC_USE_MPI
1337  integer :: ierr
1338 
1339  call mpi_allreduce(val, val_min, 1, mpi_integer, mpi_min, &
1340  mpi_comm_world, ierr)
1341  call pmc_mpi_check_ierr(ierr)
1342 #else
1343  val_min = val
1344 #endif
1345 
1346  end subroutine pmc_mpi_allreduce_min_integer
1347 
1348 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1349 
1350  !> Computes the maximum of val across all processes, storing the
1351  !> result in val_max on all processes.
1352  subroutine pmc_mpi_allreduce_max_integer(val, val_max)
1353 
1354  !> Value to maximize.
1355  integer, intent(in) :: val
1356  !> Result.
1357  integer, intent(out) :: val_max
1358 
1359 #ifdef PMC_USE_MPI
1360  integer :: ierr
1361 
1362  call mpi_allreduce(val, val_max, 1, mpi_integer, mpi_max, &
1363  mpi_comm_world, ierr)
1364  call pmc_mpi_check_ierr(ierr)
1365 #else
1366  val_max = val
1367 #endif
1368 
1369  end subroutine pmc_mpi_allreduce_max_integer
1370 
1371 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1372 
1373  !> Computes the minimum of val across all processes, storing the
1374  !> result in val_min on all processes.
1375  subroutine pmc_mpi_allreduce_min_real(val, val_min)
1376 
1377  !> Value to minimize.
1378  real(kind=dp), intent(in) :: val
1379  !> Result.
1380  real(kind=dp), intent(out) :: val_min
1381 
1382 #ifdef PMC_USE_MPI
1383  integer :: ierr
1384 
1385  call mpi_allreduce(val, val_min, 1, mpi_double_precision, mpi_min, &
1386  mpi_comm_world, ierr)
1387  call pmc_mpi_check_ierr(ierr)
1388 #else
1389  val_min = val
1390 #endif
1391 
1392  end subroutine pmc_mpi_allreduce_min_real
1393 
1394 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1395 
1396  !> Computes the maximum of val across all processes, storing the
1397  !> result in val_max on all processes.
1398  subroutine pmc_mpi_allreduce_max_real(val, val_max)
1399 
1400  !> Value to maximize.
1401  real(kind=dp), intent(in) :: val
1402  !> Result.
1403  real(kind=dp), intent(out) :: val_max
1404 
1405 #ifdef PMC_USE_MPI
1406  integer :: ierr
1407 
1408  call mpi_allreduce(val, val_max, 1, mpi_double_precision, mpi_max, &
1409  mpi_comm_world, ierr)
1410  call pmc_mpi_check_ierr(ierr)
1411 #else
1412  val_max = val
1413 #endif
1414 
1415  end subroutine pmc_mpi_allreduce_max_real
1416 
1417 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1418 
1419  !> Returns whether all processors have the same value.
1420  logical function pmc_mpi_allequal_integer(val)
1421 
1422  !> Value to compare.
1423  integer, intent(in) :: val
1424 
1425 #ifdef PMC_USE_MPI
1426  integer :: min_val, max_val
1427 
1428  call pmc_mpi_allreduce_min_integer(val, min_val)
1429  call pmc_mpi_allreduce_max_integer(val, max_val)
1430  if (min_val == max_val) then
1431  pmc_mpi_allequal_integer = .true.
1432  else
1433  pmc_mpi_allequal_integer = .false.
1434  end if
1435 #else
1436  pmc_mpi_allequal_integer = .true.
1437 #endif
1438 
1439  end function pmc_mpi_allequal_integer
1440 
1441 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1442 
1443  !> Returns whether all processors have the same value.
1444  logical function pmc_mpi_allequal_real(val)
1445 
1446  !> Value to compare.
1447  real(kind=dp), intent(in) :: val
1448 
1449 #ifdef PMC_USE_MPI
1450  real(kind=dp) :: min_val, max_val
1451 
1452  call pmc_mpi_allreduce_min_real(val, min_val)
1453  call pmc_mpi_allreduce_max_real(val, max_val)
1454  if (min_val == max_val) then
1455  pmc_mpi_allequal_real = .true.
1456  else
1457  pmc_mpi_allequal_real = .false.
1458  end if
1459 #else
1460  pmc_mpi_allequal_real = .true.
1461 #endif
1462 
1463  end function pmc_mpi_allequal_real
1464 
1465 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1466 
1467  !> Does an all-to-all transfer of integers.
1468  subroutine pmc_mpi_alltoall_integer(send, recv)
1469 
1470  !> Values to send (must be one per process).
1471  integer, intent(in) :: send(:)
1472  !> Values to receive (must be one per process).
1473  integer, intent(out) :: recv(size(send))
1474 
1475 #ifdef PMC_USE_MPI
1476  integer :: ierr
1477 
1478  call mpi_alltoall(send, 1, mpi_integer, recv, 1, mpi_integer, &
1479  mpi_comm_world, ierr)
1480  call pmc_mpi_check_ierr(ierr)
1481 #else
1482  recv = send
1483 #endif
1484 
1485  end subroutine pmc_mpi_alltoall_integer
1486 
1487 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1488 
1489  !> Does an allgather of integer arrays (must be the same size on all
1490  !> processes).
1491  subroutine pmc_mpi_allgather_integer_array(send, recv)
1492 
1493  !> Values to send on each process.
1494  integer, intent(in) :: send(:)
1495  !> Values to receive (will be the same on all processes.
1496  integer, intent(out) :: recv(:,:)
1497 
1498 #ifdef PMC_USE_MPI
1499  integer :: n_proc, n_bin, n_data, ierr
1500  integer, allocatable :: send_buf(:), recv_buf(:)
1501 
1502  n_proc = pmc_mpi_size()
1503  n_data = size(send, 1)
1504  call assert(353005542, all(shape(recv) == (/n_data, n_proc/)))
1505 
1506  ! use a new send_buf to make sure the memory is contiguous
1507  allocate(send_buf(n_data))
1508  allocate(recv_buf(n_data * n_proc))
1509  send_buf = send
1510  call mpi_allgather(send_buf, n_data, mpi_integer, &
1511  recv_buf, n_data, mpi_integer, mpi_comm_world, ierr)
1512  call pmc_mpi_check_ierr(ierr)
1513  recv = reshape(recv_buf, (/n_data, n_proc/))
1514  deallocate(send_buf)
1515  deallocate(recv_buf)
1516 #else
1517  recv(:, 1) = send
1518 #endif
1519 
1520  end subroutine pmc_mpi_allgather_integer_array
1521 
1522 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1523 
1524  !> Does an allgather of real arrays (must be the same size on all
1525  !> processes).
1526  subroutine pmc_mpi_allgather_real_array(send, recv)
1527 
1528  !> Values to send on each process.
1529  real(kind=dp), intent(in) :: send(:)
1530  !> Values to receive (will be the same on all processes.
1531  real(kind=dp), intent(out) :: recv(:,:)
1532 
1533 #ifdef PMC_USE_MPI
1534  integer :: n_proc, n_bin, n_data, ierr
1535  real(kind=dp), allocatable :: send_buf(:), recv_buf(:)
1536 
1537  n_proc = pmc_mpi_size()
1538  n_data = size(send, 1)
1539  call assert(291000580, all(shape(recv) == (/n_data, n_proc/)))
1540 
1541  ! use a new send_buf to make sure the memory is contiguous
1542  allocate(send_buf(n_data))
1543  allocate(recv_buf(n_data * n_proc))
1544  send_buf = send
1545  call mpi_allgather(send_buf, n_data, mpi_double_precision, &
1546  recv_buf, n_data, mpi_double_precision, mpi_comm_world, ierr)
1547  call pmc_mpi_check_ierr(ierr)
1548  recv = reshape(recv_buf, (/n_data, n_proc/))
1549  deallocate(send_buf)
1550  deallocate(recv_buf)
1551 #else
1552  recv(:, 1) = send
1553 #endif
1554 
1555  end subroutine pmc_mpi_allgather_real_array
1556 
1557 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1558 
1559 end module pmc_mpi
pmc_mpi::pmc_mpi_init
subroutine pmc_mpi_init()
Initialize MPI.
Definition: mpi.F90:56
pmc_mpi::pmc_mpi_pack_string_array
subroutine pmc_mpi_pack_string_array(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:752
pmc_mpi::pmc_mpi_pack_size_complex
integer function pmc_mpi_pack_size_complex(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:427
pmc_util::logical_to_string
character(len=pmc_util_convert_string_len) function logical_to_string(val)
Convert a logical to a string format.
Definition: util.F90:798
pmc_mpi::pmc_mpi_allreduce_average_real_array
subroutine pmc_mpi_allreduce_average_real_array(val, val_avg)
Computes the average of val across all processes, storing the result in val_avg on all processes.
Definition: mpi.F90:1305
pmc_util::complex_to_string
character(len=pmc_util_convert_string_len) function complex_to_string(val)
Convert a complex to a string format.
Definition: util.F90:818
pmc_mpi::pmc_mpi_size
integer function pmc_mpi_size()
Returns the total number of processes.
Definition: mpi.F90:134
pmc_mpi
Wrapper functions for MPI.
Definition: mpi.F90:13
pmc_mpi::pmc_mpi_unpack_complex
subroutine pmc_mpi_unpack_complex(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:921
pmc_mpi::pmc_mpi_unpack_string_array
subroutine pmc_mpi_unpack_string_array(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1010
pmc_mpi::pmc_mpi_reduce_avg_real_array_2d
subroutine pmc_mpi_reduce_avg_real_array_2d(val, val_avg)
Computes the average of val across all processes, storing the result in val_avg on the root process.
Definition: mpi.F90:1253
pmc_mpi::pmc_mpi_pack_size_real
integer function pmc_mpi_pack_size_real(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:365
pmc_mpi::pmc_mpi_unpack_integer_array
subroutine pmc_mpi_unpack_integer_array(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:946
pmc_mpi::pmc_mpi_pack_integer_array
subroutine pmc_mpi_pack_integer_array(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:688
pmc_mpi::pmc_mpi_allreduce_sum_integer
subroutine pmc_mpi_allreduce_sum_integer(val, val_sum)
Computes the sum of val across all processes, storing the result in val_sum on all processes.
Definition: mpi.F90:1203
pmc_mpi::pmc_mpi_allreduce_max_integer
subroutine pmc_mpi_allreduce_max_integer(val, val_max)
Computes the maximum of val across all processes, storing the result in val_max on all processes.
Definition: mpi.F90:1353
pmc_mpi::pmc_mpi_allreduce_min_real
subroutine pmc_mpi_allreduce_min_real(val, val_min)
Computes the minimum of val across all processes, storing the result in val_min on all processes.
Definition: mpi.F90:1376
pmc_mpi::pmc_mpi_reduce_avg_real
subroutine pmc_mpi_reduce_avg_real(val, val_avg)
Computes the average of val across all processes, storing the result in val_avg on the root process.
Definition: mpi.F90:1076
pmc_mpi::pmc_mpi_allgather_real_array
subroutine pmc_mpi_allgather_real_array(send, recv)
Does an allgather of real arrays (must be the same size on all processes).
Definition: mpi.F90:1527
pmc_mpi::pmc_mpi_rank
integer function pmc_mpi_rank()
Returns the rank of the current process.
Definition: mpi.F90:117
pmc_mpi::pmc_mpi_pack_logical
subroutine pmc_mpi_pack_logical(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:638
pmc_mpi::pmc_mpi_allequal_integer
logical function pmc_mpi_allequal_integer(val)
Returns whether all processors have the same value.
Definition: mpi.F90:1421
pmc_constants::dp
integer, parameter dp
Kind of a double precision real number.
Definition: constants.F90:12
pmc_mpi::pmc_mpi_pack_string
subroutine pmc_mpi_pack_string(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:611
pmc_mpi::pmc_mpi_pack_real
subroutine pmc_mpi_pack_real(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:586
pmc_util::assert
subroutine assert(code, condition_ok)
Errors unless condition_ok is true.
Definition: util.F90:103
pmc_mpi::pmc_mpi_pack_size_real_array
integer function pmc_mpi_pack_size_real_array(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:477
pmc_mpi::pmc_mpi_unpack_string
subroutine pmc_mpi_unpack_string(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:868
pmc_mpi::pmc_mpi_pack_size_logical
integer function pmc_mpi_pack_size_logical(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:407
pmc_mpi::pmc_mpi_pack_complex
subroutine pmc_mpi_pack_complex(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:663
pmc_mpi::pmc_mpi_finalize
subroutine pmc_mpi_finalize()
Shut down MPI.
Definition: mpi.F90:89
pmc_mpi::pmc_mpi_bcast_integer
subroutine pmc_mpi_bcast_integer(val)
Broadcast the given value from process 0 to all other processes.
Definition: mpi.F90:288
pmc_mpi::pmc_mpi_pack_size_real_array_2d
integer function pmc_mpi_pack_size_real_array_2d(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:530
pmc_util::integer_to_string
character(len=pmc_util_convert_string_len) function integer_to_string(val)
Convert an integer to a string format.
Definition: util.F90:766
pmc_util::real_to_string
character(len=pmc_util_convert_string_len) function real_to_string(val)
Convert a real to a string format.
Definition: util.F90:782
pmc_util::assert_msg
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition: util.F90:77
pmc_mpi::pmc_mpi_abort
subroutine pmc_mpi_abort(status)
Abort the program.
Definition: mpi.F90:71
pmc_mpi::pmc_mpi_pack_real_array_2d
subroutine pmc_mpi_pack_real_array_2d(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:784
pmc_mpi::pmc_mpi_test
subroutine pmc_mpi_test()
Perform basic sanity checks on send/receive.
Definition: mpi.F90:151
pmc_mpi::pmc_mpi_transfer_real
subroutine pmc_mpi_transfer_real(from_val, to_val, from_proc, to_proc)
Transfer the value between the given processes.
Definition: mpi.F90:1101
pmc_mpi::pmc_mpi_alltoall_integer
subroutine pmc_mpi_alltoall_integer(send, recv)
Does an all-to-all transfer of integers.
Definition: mpi.F90:1469
pmc_mpi::pmc_mpi_bcast_packed
subroutine pmc_mpi_bcast_packed(val)
Broadcast the given value from process 0 to all other processes.
Definition: mpi.F90:326
pmc_mpi::pmc_mpi_unpack_integer
subroutine pmc_mpi_unpack_integer(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:818
pmc_mpi::pmc_mpi_unpack_logical
subroutine pmc_mpi_unpack_logical(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:896
pmc_mpi::pmc_mpi_check_ierr
subroutine pmc_mpi_check_ierr(ierr)
Dies if ierr is not ok.
Definition: mpi.F90:40
pmc_mpi::pmc_mpi_allreduce_max_real
subroutine pmc_mpi_allreduce_max_real(val, val_max)
Computes the maximum of val across all processes, storing the result in val_max on all processes.
Definition: mpi.F90:1399
pmc_mpi::pmc_mpi_pack_size_integer_array
integer function pmc_mpi_pack_size_integer_array(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:447
pmc_mpi::pmc_mpi_support
logical function pmc_mpi_support()
Whether MPI support is compiled in.
Definition: mpi.F90:27
pmc_util
Common utility subroutines.
Definition: util.F90:9
pmc_mpi::pmc_mpi_allgather_integer_array
subroutine pmc_mpi_allgather_integer_array(send, recv)
Does an allgather of integer arrays (must be the same size on all processes).
Definition: mpi.F90:1492
pmc_mpi::pmc_mpi_unpack_real_array_2d
subroutine pmc_mpi_unpack_real_array_2d(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1042
pmc_mpi::pmc_mpi_allreduce_min_integer
subroutine pmc_mpi_allreduce_min_integer(val, val_min)
Computes the minimum of val across all processes, storing the result in val_min on all processes.
Definition: mpi.F90:1330
pmc_mpi::pmc_mpi_pack_size_string_array
integer function pmc_mpi_pack_size_string_array(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:507
pmc_mpi::pmc_mpi_allequal_real
logical function pmc_mpi_allequal_real(val)
Returns whether all processors have the same value.
Definition: mpi.F90:1445
pmc_mpi::pmc_mpi_barrier
subroutine pmc_mpi_barrier()
Synchronize all processes.
Definition: mpi.F90:103
pmc_mpi::pmc_mpi_pack_size_integer
integer function pmc_mpi_pack_size_integer(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:345
pmc_mpi::pmc_mpi_pack_integer
subroutine pmc_mpi_pack_integer(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:561
pmc_mpi::pmc_mpi_allreduce_average_real
subroutine pmc_mpi_allreduce_average_real(val, val_avg)
Computes the average of val across all processes, storing the result in val_avg on all processes.
Definition: mpi.F90:1281
pmc_mpi::pmc_mpi_reduce_sum_integer
subroutine pmc_mpi_reduce_sum_integer(val, val_sum)
Computes the sum of val across all processes, storing the result in val_sum on the root process.
Definition: mpi.F90:1180
pmc_util::die
subroutine die(code)
Error immediately.
Definition: util.F90:122
pmc_mpi::pmc_mpi_pack_real_array
subroutine pmc_mpi_pack_real_array(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:720
pmc_mpi::pmc_mpi_reduce_avg_real_array
subroutine pmc_mpi_reduce_avg_real_array(val, val_avg)
Computes the average of val across all processes, storing the result in val_avg on the root process.
Definition: mpi.F90:1226
pmc_mpi::pmc_mpi_unpack_real
subroutine pmc_mpi_unpack_real(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:843
pmc_mpi::pmc_mpi_transfer_integer
subroutine pmc_mpi_transfer_integer(from_val, to_val, from_proc, to_proc)
Transfer the value between the given processes.
Definition: mpi.F90:1140
pmc_mpi::pmc_mpi_unpack_real_array
subroutine pmc_mpi_unpack_real_array(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:978
pmc_mpi::pmc_mpi_bcast_string
subroutine pmc_mpi_bcast_string(val)
Broadcast the given value from process 0 to all other processes.
Definition: mpi.F90:307
pmc_mpi::pmc_mpi_pack_size_string
integer function pmc_mpi_pack_size_string(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:385