PartMC  2.8.0
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_integer64(val)
365 
366  !> Value to pack.
367  integer(kind=8), intent(in) :: val
368 
369  integer :: ierr
370 
371 #ifdef PMC_USE_MPI
372  call mpi_pack_size(1, mpi_integer8, mpi_comm_world, &
374  call pmc_mpi_check_ierr(ierr)
375 #else
377 #endif
378 
379  end function pmc_mpi_pack_size_integer64
380 
381 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
382 
383  !> Determines the number of bytes required to pack the given value.
384  integer function pmc_mpi_pack_size_real(val)
385 
386  !> Value to pack.
387  real(kind=dp), intent(in) :: val
388 
389  integer :: ierr
390 
391 #ifdef PMC_USE_MPI
392  call mpi_pack_size(1, mpi_double_precision, mpi_comm_world, &
394  call pmc_mpi_check_ierr(ierr)
395 #else
397 #endif
398 
399  end function pmc_mpi_pack_size_real
400 
401 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
402 
403  !> Determines the number of bytes required to pack the given value.
404  integer function pmc_mpi_pack_size_string(val)
405 
406  !> Value to pack.
407  character(len=*), intent(in) :: val
408 
409  integer :: ierr
410 
411 #ifdef PMC_USE_MPI
412  call mpi_pack_size(len_trim(val), mpi_character, mpi_comm_world, &
414  call pmc_mpi_check_ierr(ierr)
416  + pmc_mpi_pack_size_integer(len_trim(val))
417 #else
419 #endif
420 
421  end function pmc_mpi_pack_size_string
422 
423 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
424 
425  !> Determines the number of bytes required to pack the given value.
426  integer function pmc_mpi_pack_size_logical(val)
427 
428  !> Value to pack.
429  logical, intent(in) :: val
430 
431  integer :: ierr
432 
433 #ifdef PMC_USE_MPI
434  call mpi_pack_size(1, mpi_logical, mpi_comm_world, &
436  call pmc_mpi_check_ierr(ierr)
437 #else
439 #endif
440 
441  end function pmc_mpi_pack_size_logical
442 
443 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
444 
445  !> Determines the number of bytes required to pack the given value.
446  integer function pmc_mpi_pack_size_complex(val)
447 
448  !> Value to pack.
449  complex(kind=dc), intent(in) :: val
450 
451  integer :: ierr
452 
453 #ifdef PMC_USE_MPI
454  call mpi_pack_size(1, mpi_double_complex, mpi_comm_world, &
456  call pmc_mpi_check_ierr(ierr)
457 #else
459 #endif
460 
461  end function pmc_mpi_pack_size_complex
462 
463 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
464 
465  !> Determines the number of bytes required to pack the given value.
466  integer function pmc_mpi_pack_size_complex_array(val)
467 
468  !> Value to pack.
469  complex(kind=dc), allocatable, intent(in) :: val(:)
470 
471  integer :: ierr, total_size
472 
473 #ifdef PMC_USE_MPI
474  logical :: is_allocated
475 
476  total_size = 0
477  is_allocated = allocated(val)
478  if (is_allocated) then
479  call mpi_pack_size(size(val), mpi_double_complex, mpi_comm_world, &
480  total_size, ierr)
481  call pmc_mpi_check_ierr(ierr)
482  total_size = total_size + pmc_mpi_pack_size_integer(size(val))
483  end if
484  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
485 #else
486  total_size = 0
487 #endif
488 
490 
492 
493 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
494 
495  !> Determines the number of bytes required to pack the given value.
496  integer function pmc_mpi_pack_size_integer_array(val)
497 
498  !> Value to pack.
499  integer, allocatable, intent(in) :: val(:)
500 
501  integer :: total_size, ierr
502 
503 #ifdef PMC_USE_MPI
504  logical :: is_allocated
505 
506  total_size = 0
507  is_allocated = allocated(val)
508  if (is_allocated) then
509  call mpi_pack_size(size(val), mpi_integer, mpi_comm_world, &
510  total_size, ierr)
511  call pmc_mpi_check_ierr(ierr)
512  total_size = total_size + pmc_mpi_pack_size_integer(size(val))
513  end if
514  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
515 #else
516  total_size = 0
517 #endif
518 
520 
522 
523 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
524 
525  !> Determines the number of bytes required to pack the given value.
526  integer function pmc_mpi_pack_size_real_array(val)
527 
528  !> Value to pack.
529  real(kind=dp), allocatable, intent(in) :: val(:)
530 
531  integer :: total_size, ierr
532 
533 #ifdef PMC_USE_MPI
534  logical :: is_allocated
535 
536  total_size = 0
537  is_allocated = allocated(val)
538  if (is_allocated) then
539  call mpi_pack_size(size(val), mpi_double_precision, mpi_comm_world, &
540  total_size, ierr)
541  call pmc_mpi_check_ierr(ierr)
542  total_size = total_size + pmc_mpi_pack_size_integer(size(val))
543  end if
544  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
545 #else
546  total_size = 0
547 #endif
548 
549  pmc_mpi_pack_size_real_array = total_size
550 
551  end function pmc_mpi_pack_size_real_array
552 
553 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
554 
555  !> Determines the number of bytes required to pack the given value.
556  integer function pmc_mpi_pack_size_string_array(val)
557 
558  !> Value to pack.
559  character(len=*), allocatable, intent(in) :: val(:)
560 
561  integer :: i, total_size
562  logical :: is_allocated
563 
564  total_size = 0
565  is_allocated = allocated(val)
566  if (is_allocated) then
567  total_size = pmc_mpi_pack_size_integer(size(val))
568  do i = 1,size(val)
569  total_size = total_size + pmc_mpi_pack_size_string(val(i))
570  end do
571  end if
572  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
573  pmc_mpi_pack_size_string_array = total_size
574 
575  end function pmc_mpi_pack_size_string_array
576 
577 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
578 
579  !> Determines the number of bytes required to pack the given value.
580  integer function pmc_mpi_pack_size_real_array_2d(val)
581 
582  !> Value to pack.
583  real(kind=dp), allocatable, intent(in) :: val(:,:)
584 
585  integer :: total_size, ierr
586 
587 #ifdef PMC_USE_MPI
588  logical :: is_allocated
589 
590  total_size = 0
591  is_allocated = allocated(val)
592  if (is_allocated) then
593  call mpi_pack_size(size(val), mpi_double_precision, mpi_comm_world, &
594  total_size, ierr)
595  call pmc_mpi_check_ierr(ierr)
596  total_size = total_size + pmc_mpi_pack_size_integer(size(val,1)) &
597  + pmc_mpi_pack_size_integer(size(val,2))
598  end if
599  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
600 #else
601  total_size = 0
602 #endif
603 
605 
607 
608 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
609 
610  !> Determines the number of bytes required to pack the given value.
611  integer function pmc_mpi_pack_size_real_array_3d(val)
612 
613  !> Value to pack.
614  real(kind=dp), allocatable, intent(in) :: val(:,:,:)
615 
616  integer :: ierr, total_size
617 
618 #ifdef PMC_USE_MPI
619  logical :: is_allocated
620 
621  total_size = 0
622  is_allocated = allocated(val)
623  if (is_allocated) then
624  call mpi_pack_size(size(val), mpi_double_precision, mpi_comm_world, &
625  total_size, ierr)
626  call pmc_mpi_check_ierr(ierr)
627  total_size = total_size + pmc_mpi_pack_size_integer(size(val,1)) &
628  + pmc_mpi_pack_size_integer(size(val,2)) &
629  + pmc_mpi_pack_size_integer(size(val,3))
630  end if
631  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
632 #else
633  total_size = 0
634 #endif
635 
637 
639 
640 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
641 
642  !> Determines the number of bytes required to pack the given value.
643  integer function pmc_mpi_pack_size_real_array_4d(val)
644 
645  !> Value to pack.
646  real(kind=dp), allocatable, intent(in) :: val(:,:,:,:)
647 
648  integer :: ierr, total_size
649 
650 #ifdef PMC_USE_MPI
651  logical :: is_allocated
652 
653  total_size = 0
654  is_allocated = allocated(val)
655  if (is_allocated) then
656  call mpi_pack_size(size(val), mpi_double_precision, mpi_comm_world, &
657  total_size, ierr)
658  call pmc_mpi_check_ierr(ierr)
659  total_size = total_size + pmc_mpi_pack_size_integer(size(val,1)) &
660  + pmc_mpi_pack_size_integer(size(val,2)) &
661  + pmc_mpi_pack_size_integer(size(val,3)) &
662  + pmc_mpi_pack_size_integer(size(val,4))
663  end if
664  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
665 #else
666  total_size = 0
667 #endif
668 
670 
672 
673 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
674 
675  !> Determines the number of bytes required to pack the given value.
676  integer function pmc_mpi_pack_size_real_array_5d(val)
677 
678  !> Value to pack.
679  real(kind=dp), allocatable, intent(in) :: val(:,:,:,:,:)
680 
681  integer :: ierr, total_size
682 
683 #ifdef PMC_USE_MPI
684  logical :: is_allocated
685 
686  total_size = 0
687  is_allocated = allocated(val)
688  if (is_allocated) then
689  call mpi_pack_size(size(val), mpi_double_precision, mpi_comm_world, &
690  total_size, ierr)
691  call pmc_mpi_check_ierr(ierr)
692  total_size = total_size + pmc_mpi_pack_size_integer(size(val,1)) &
693  + pmc_mpi_pack_size_integer(size(val,2)) &
694  + pmc_mpi_pack_size_integer(size(val,3)) &
695  + pmc_mpi_pack_size_integer(size(val,4)) &
696  + pmc_mpi_pack_size_integer(size(val,5))
697  end if
698  total_size = total_size + pmc_mpi_pack_size_logical(is_allocated)
699 #else
700  total_size = 0
701 #endif
702 
704 
706 
707 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
708 
709  !> Packs the given value into the buffer, advancing position.
710  subroutine pmc_mpi_pack_integer(buffer, position, val)
711 
712  !> Memory buffer.
713  character, intent(inout) :: buffer(:)
714  !> Current buffer position.
715  integer, intent(inout) :: position
716  !> Value to pack.
717  integer, intent(in) :: val
718 
719 #ifdef PMC_USE_MPI
720  integer :: prev_position, ierr
721 
722  prev_position = position
723  call mpi_pack(val, 1, mpi_integer, buffer, size(buffer), &
724  position, mpi_comm_world, ierr)
725  call pmc_mpi_check_ierr(ierr)
726  call assert(913495993, &
727  position - prev_position <= pmc_mpi_pack_size_integer(val))
728 #endif
729 
730  end subroutine pmc_mpi_pack_integer
731 
732 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
733 
734  !> Packs the given value into the buffer, advancing position.
735  subroutine pmc_mpi_pack_integer64(buffer, position, val)
736 
737  !> Memory buffer.
738  character, intent(inout) :: buffer(:)
739  !> Current buffer position.
740  integer, intent(inout) :: position
741  !> Value to pack.
742  integer(kind=8), intent(in) :: val
743 
744 #ifdef PMC_USE_MPI
745  integer :: prev_position, ierr
746 
747  prev_position = position
748  call mpi_pack(val, 1, mpi_integer8, buffer, size(buffer), &
749  position, mpi_comm_world, ierr)
750  call pmc_mpi_check_ierr(ierr)
751  call assert(929176455, &
752  position - prev_position <= pmc_mpi_pack_size_integer64(val))
753 #endif
754 
755  end subroutine pmc_mpi_pack_integer64
756 
757 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
758 
759  !> Packs the given value into the buffer, advancing position.
760  subroutine pmc_mpi_pack_real(buffer, position, val)
761 
762  !> Memory buffer.
763  character, intent(inout) :: buffer(:)
764  !> Current buffer position.
765  integer, intent(inout) :: position
766  !> Value to pack.
767  real(kind=dp), intent(in) :: val
768 
769 #ifdef PMC_USE_MPI
770  integer :: prev_position, ierr
771 
772  prev_position = position
773  call mpi_pack(val, 1, mpi_double_precision, buffer, size(buffer), &
774  position, mpi_comm_world, ierr)
775  call pmc_mpi_check_ierr(ierr)
776  call assert(395354132, &
777  position - prev_position <= pmc_mpi_pack_size_real(val))
778 #endif
779 
780  end subroutine pmc_mpi_pack_real
781 
782 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
783 
784  !> Packs the given value into the buffer, advancing position.
785  subroutine pmc_mpi_pack_string(buffer, position, val)
786 
787  !> Memory buffer.
788  character, intent(inout) :: buffer(:)
789  !> Current buffer position.
790  integer, intent(inout) :: position
791  !> Value to pack.
792  character(len=*), intent(in) :: val
793 
794 #ifdef PMC_USE_MPI
795  integer :: prev_position, length, ierr
796 
797  prev_position = position
798  length = len_trim(val)
799  call pmc_mpi_pack_integer(buffer, position, length)
800  call mpi_pack(val, length, mpi_character, buffer, size(buffer), &
801  position, mpi_comm_world, ierr)
802  call pmc_mpi_check_ierr(ierr)
803  call assert(607212018, &
804  position - prev_position <= pmc_mpi_pack_size_string(val))
805 #endif
806 
807  end subroutine pmc_mpi_pack_string
808 
809 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
810 
811  !> Packs the given value into the buffer, advancing position.
812  subroutine pmc_mpi_pack_logical(buffer, position, val)
813 
814  !> Memory buffer.
815  character, intent(inout) :: buffer(:)
816  !> Current buffer position.
817  integer, intent(inout) :: position
818  !> Value to pack.
819  logical, intent(in) :: val
820 
821 #ifdef PMC_USE_MPI
822  integer :: prev_position, ierr
823 
824  prev_position = position
825  call mpi_pack(val, 1, mpi_logical, buffer, size(buffer), &
826  position, mpi_comm_world, ierr)
827  call pmc_mpi_check_ierr(ierr)
828  call assert(104535200, &
829  position - prev_position <= pmc_mpi_pack_size_logical(val))
830 #endif
831 
832  end subroutine pmc_mpi_pack_logical
833 
834 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
835 
836  !> Packs the given value into the buffer, advancing position.
837  subroutine pmc_mpi_pack_complex(buffer, position, val)
838 
839  !> Memory buffer.
840  character, intent(inout) :: buffer(:)
841  !> Current buffer position.
842  integer, intent(inout) :: position
843  !> Value to pack.
844  complex(kind=dc), intent(in) :: val
845 
846 #ifdef PMC_USE_MPI
847  integer :: prev_position, ierr
848 
849  prev_position = position
850  call mpi_pack(val, 1, mpi_double_complex, buffer, size(buffer), &
851  position, mpi_comm_world, ierr)
852  call pmc_mpi_check_ierr(ierr)
853  call assert(640416372, &
854  position - prev_position <= pmc_mpi_pack_size_complex(val))
855 #endif
856 
857  end subroutine pmc_mpi_pack_complex
858 
859 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
860 
861  !> Packs the given value into the buffer, advancing position.
862  subroutine pmc_mpi_pack_complex_array(buffer, position, val)
863 
864  !> Memory buffer.
865  character, intent(inout) :: buffer(:)
866  !> Current buffer position.
867  integer, intent(inout) :: position
868  !> Value to pack.
869  complex(kind=dc), allocatable, intent(in) :: val(:)
870 
871 #ifdef PMC_USE_MPI
872  integer :: prev_position, ierr, n
873  logical :: is_allocated
874 
875  prev_position = position
876  is_allocated = allocated(val)
877  call pmc_mpi_pack_logical(buffer, position, is_allocated)
878  if (is_allocated) then
879  n = size(val)
880  call pmc_mpi_pack_integer(buffer, position, n)
881  call mpi_pack(val, n, mpi_double_complex, buffer, size(buffer), &
882  position, mpi_comm_world, ierr)
883  call pmc_mpi_check_ierr(ierr)
884  end if
885  call assert(755467878, &
886  position - prev_position <= pmc_mpi_pack_size_complex_array(val))
887 #endif
888 
889  end subroutine pmc_mpi_pack_complex_array
890 
891 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
892 
893  !> Packs the given value into the buffer, advancing position.
894  subroutine pmc_mpi_pack_integer_array(buffer, position, val)
895 
896  !> Memory buffer.
897  character, intent(inout) :: buffer(:)
898  !> Current buffer position.
899  integer, intent(inout) :: position
900  !> Value to pack.
901  integer, allocatable, intent(in) :: val(:)
902 
903 #ifdef PMC_USE_MPI
904  integer :: prev_position, n, ierr
905  logical :: is_allocated
906 
907  prev_position = position
908  is_allocated = allocated(val)
909  call pmc_mpi_pack_logical(buffer, position, is_allocated)
910  if (is_allocated) then
911  n = size(val)
912  call pmc_mpi_pack_integer(buffer, position, n)
913  call mpi_pack(val, n, mpi_integer, buffer, size(buffer), &
914  position, mpi_comm_world, ierr)
915  call pmc_mpi_check_ierr(ierr)
916  end if
917  call assert(698601296, &
918  position - prev_position <= pmc_mpi_pack_size_integer_array(val))
919 #endif
920 
921  end subroutine pmc_mpi_pack_integer_array
922 
923 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
924 
925  !> Packs the given value into the buffer, advancing position.
926  subroutine pmc_mpi_pack_real_array(buffer, position, val)
927 
928  !> Memory buffer.
929  character, intent(inout) :: buffer(:)
930  !> Current buffer position.
931  integer, intent(inout) :: position
932  !> Value to pack.
933  real(kind=dp), allocatable, intent(in) :: val(:)
934 
935 #ifdef PMC_USE_MPI
936  integer :: prev_position, n, ierr
937  logical :: is_allocated
938 
939  prev_position = position
940  is_allocated = allocated(val)
941  call pmc_mpi_pack_logical(buffer, position, is_allocated)
942  if (is_allocated) then
943  n = size(val)
944  call pmc_mpi_pack_integer(buffer, position, n)
945  call mpi_pack(val, n, mpi_double_precision, buffer, size(buffer), &
946  position, mpi_comm_world, ierr)
947  call pmc_mpi_check_ierr(ierr)
948  end if
949  call assert(825718791, &
950  position - prev_position <= pmc_mpi_pack_size_real_array(val))
951 #endif
952 
953  end subroutine pmc_mpi_pack_real_array
954 
955 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
956 
957  !> Packs the given value into the buffer, advancing position.
958  subroutine pmc_mpi_pack_string_array(buffer, position, val)
959 
960  !> Memory buffer.
961  character, intent(inout) :: buffer(:)
962  !> Current buffer position.
963  integer, intent(inout) :: position
964  !> Value to pack.
965  character(len=*), allocatable, intent(in) :: val(:)
966 
967 #ifdef PMC_USE_MPI
968  integer :: prev_position, i, n
969  logical :: is_allocated
970 
971  prev_position = position
972  is_allocated = allocated(val)
973  call pmc_mpi_pack_logical(buffer, position, is_allocated)
974  if (is_allocated) then
975  n = size(val)
976  call pmc_mpi_pack_integer(buffer, position, n)
977  do i = 1,n
978  call pmc_mpi_pack_string(buffer, position, val(i))
979  end do
980  end if
981  call assert(630900704, &
982  position - prev_position <= pmc_mpi_pack_size_string_array(val))
983 #endif
984 
985  end subroutine pmc_mpi_pack_string_array
986 
987 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
988 
989  !> Packs the given value into the buffer, advancing position.
990  subroutine pmc_mpi_pack_real_array_2d(buffer, position, val)
991 
992  !> Memory buffer.
993  character, intent(inout) :: buffer(:)
994  !> Current buffer position.
995  integer, intent(inout) :: position
996  !> Value to pack.
997  real(kind=dp), allocatable, intent(in) :: val(:,:)
998 
999 #ifdef PMC_USE_MPI
1000  integer :: prev_position, n1, n2, ierr
1001  logical :: is_allocated
1002 
1003  prev_position = position
1004  is_allocated = allocated(val)
1005  call pmc_mpi_pack_logical(buffer, position, is_allocated)
1006  if (is_allocated) then
1007  n1 = size(val, 1)
1008  n2 = size(val, 2)
1009  call pmc_mpi_pack_integer(buffer, position, n1)
1010  call pmc_mpi_pack_integer(buffer, position, n2)
1011  call mpi_pack(val, n1*n2, mpi_double_precision, buffer, size(buffer), &
1012  position, mpi_comm_world, ierr)
1013  call pmc_mpi_check_ierr(ierr)
1014  end if
1015  call assert(567349745, &
1016  position - prev_position <= pmc_mpi_pack_size_real_array_2d(val))
1017 #endif
1018 
1019  end subroutine pmc_mpi_pack_real_array_2d
1020 
1021 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1022 
1023  !> Packs the given value into the buffer, advancing position.
1024  subroutine pmc_mpi_pack_real_array_3d(buffer, position, val)
1025 
1026  !> Memory buffer.
1027  character, intent(inout) :: buffer(:)
1028  !> Current buffer position.
1029  integer, intent(inout) :: position
1030  !> Value to pack.
1031  real(kind=dp), allocatable, intent(in) :: val(:,:,:)
1032 
1033 #ifdef PMC_USE_MPI
1034  integer :: prev_position, n1, n2, n3, ierr
1035  logical :: is_allocated
1036 
1037  prev_position = position
1038  is_allocated = allocated(val)
1039  call pmc_mpi_pack_logical(buffer, position, is_allocated)
1040  if (is_allocated) then
1041  n1 = size(val, 1)
1042  n2 = size(val, 2)
1043  n3 = size(val, 3)
1044  call pmc_mpi_pack_integer(buffer, position, n1)
1045  call pmc_mpi_pack_integer(buffer, position, n2)
1046  call pmc_mpi_pack_integer(buffer, position, n3)
1047  call mpi_pack(val, n1*n2*n3, mpi_double_precision, buffer, &
1048  size(buffer), position, mpi_comm_world, ierr)
1049  call pmc_mpi_check_ierr(ierr)
1050  end if
1051  call assert(115193783, &
1052  position - prev_position <= pmc_mpi_pack_size_real_array_3d(val))
1053 #endif
1054 
1055  end subroutine pmc_mpi_pack_real_array_3d
1056 
1057 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1058 
1059  !> Packs the given value into the buffer, advancing position.
1060  subroutine pmc_mpi_pack_real_array_4d(buffer, position, val)
1061 
1062  !> Memory buffer.
1063  character, intent(inout) :: buffer(:)
1064  !> Current buffer position.
1065  integer, intent(inout) :: position
1066  !> Value to pack.
1067  real(kind=dp), allocatable, intent(in) :: val(:,:,:,:)
1068 
1069 #ifdef PMC_USE_MPI
1070  integer :: prev_position, n1, n2, n3, n4, ierr
1071  logical :: is_allocated
1072 
1073  prev_position = position
1074  is_allocated = allocated(val)
1075  call pmc_mpi_pack_logical(buffer, position, is_allocated)
1076  if (is_allocated) then
1077  n1 = size(val, 1)
1078  n2 = size(val, 2)
1079  n3 = size(val, 3)
1080  n4 = size(val, 4)
1081  call pmc_mpi_pack_integer(buffer, position, n1)
1082  call pmc_mpi_pack_integer(buffer, position, n2)
1083  call pmc_mpi_pack_integer(buffer, position, n3)
1084  call pmc_mpi_pack_integer(buffer, position, n4)
1085  call mpi_pack(val, n1*n2*n3*n4, mpi_double_precision, buffer, &
1086  size(buffer), position, mpi_comm_world, ierr)
1087  call pmc_mpi_check_ierr(ierr)
1088  end if
1089  call assert(532144807, &
1090  position - prev_position <= pmc_mpi_pack_size_real_array_4d(val))
1091 #endif
1092 
1093  end subroutine pmc_mpi_pack_real_array_4d
1094 
1095 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1096 
1097  !> Packs the given value into the buffer, advancing position.
1098  subroutine pmc_mpi_pack_real_array_5d(buffer, position, val)
1099 
1100  !> Memory buffer.
1101  character, intent(inout) :: buffer(:)
1102  !> Current buffer position.
1103  integer, intent(inout) :: position
1104  !> Value to pack.
1105  real(kind=dp), allocatable, intent(in) :: val(:,:,:,:,:)
1106 
1107 #ifdef PMC_USE_MPI
1108  integer :: prev_position, n1, n2, n3, n4, n5, ierr
1109  logical :: is_allocated
1110 
1111  prev_position = position
1112  is_allocated = allocated(val)
1113  call pmc_mpi_pack_logical(buffer, position, is_allocated)
1114  if (is_allocated) then
1115  n1 = size(val, 1)
1116  n2 = size(val, 2)
1117  n3 = size(val, 3)
1118  n4 = size(val, 4)
1119  n5 = size(val, 5)
1120  call pmc_mpi_pack_integer(buffer, position, n1)
1121  call pmc_mpi_pack_integer(buffer, position, n2)
1122  call pmc_mpi_pack_integer(buffer, position, n3)
1123  call pmc_mpi_pack_integer(buffer, position, n4)
1124  call pmc_mpi_pack_integer(buffer, position, n5)
1125  call mpi_pack(val, n1*n2*n3*n4*n5, mpi_double_precision, buffer, &
1126  size(buffer), position, mpi_comm_world, ierr)
1127  call pmc_mpi_check_ierr(ierr)
1128  end if
1129  call assert(863374914, &
1130  position - prev_position <= pmc_mpi_pack_size_real_array_5d(val))
1131 #endif
1132 
1133  end subroutine pmc_mpi_pack_real_array_5d
1134 
1135 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1136 
1137  !> Unpacks the given value from the buffer, advancing position.
1138  subroutine pmc_mpi_unpack_integer(buffer, position, val)
1139 
1140  !> Memory buffer.
1141  character, intent(inout) :: buffer(:)
1142  !> Current buffer position.
1143  integer, intent(inout) :: position
1144  !> Value to pack.
1145  integer, intent(out) :: val
1146 
1147 #ifdef PMC_USE_MPI
1148  integer :: prev_position, ierr
1149 
1150  prev_position = position
1151  call mpi_unpack(buffer, size(buffer), position, val, 1, mpi_integer, &
1152  mpi_comm_world, ierr)
1153  call pmc_mpi_check_ierr(ierr)
1154  call assert(890243339, &
1155  position - prev_position <= pmc_mpi_pack_size_integer(val))
1156 #endif
1157 
1158  end subroutine pmc_mpi_unpack_integer
1159 
1160 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1161 
1162  !> Unpacks the given value from the buffer, advancing position.
1163  subroutine pmc_mpi_unpack_integer64(buffer, position, val)
1164 
1165  !> Memory buffer.
1166  character, intent(inout) :: buffer(:)
1167  !> Current buffer position.
1168  integer, intent(inout) :: position
1169  !> Value to pack.
1170  integer(kind=8), intent(out) :: val
1171 
1172 #ifdef PMC_USE_MPI
1173  integer :: prev_position, ierr
1174 
1175  prev_position = position
1176  call mpi_unpack(buffer, size(buffer), position, val, 1, mpi_integer8, &
1177  mpi_comm_world, ierr)
1178  call pmc_mpi_check_ierr(ierr)
1179  call assert(752979474, &
1180  position - prev_position <= pmc_mpi_pack_size_integer64(val))
1181 #endif
1182 
1183  end subroutine pmc_mpi_unpack_integer64
1184 
1185 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1186 
1187  !> Unpacks the given value from the buffer, advancing position.
1188  subroutine pmc_mpi_unpack_real(buffer, position, val)
1189 
1190  !> Memory buffer.
1191  character, intent(inout) :: buffer(:)
1192  !> Current buffer position.
1193  integer, intent(inout) :: position
1194  !> Value to pack.
1195  real(kind=dp), intent(out) :: val
1196 
1197 #ifdef PMC_USE_MPI
1198  integer :: prev_position, ierr
1199 
1200  prev_position = position
1201  call mpi_unpack(buffer, size(buffer), position, val, 1, &
1202  mpi_double_precision, mpi_comm_world, ierr)
1203  call pmc_mpi_check_ierr(ierr)
1204  call assert(570771632, &
1205  position - prev_position <= pmc_mpi_pack_size_real(val))
1206 #endif
1207 
1208  end subroutine pmc_mpi_unpack_real
1209 
1210 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1211 
1212  !> Unpacks the given value from the buffer, advancing position.
1213  subroutine pmc_mpi_unpack_string(buffer, position, val)
1214 
1215  !> Memory buffer.
1216  character, intent(inout) :: buffer(:)
1217  !> Current buffer position.
1218  integer, intent(inout) :: position
1219  !> Value to pack.
1220  character(len=*), intent(out) :: val
1221 
1222 #ifdef PMC_USE_MPI
1223  integer :: prev_position, length, ierr
1224 
1225  prev_position = position
1226  call pmc_mpi_unpack_integer(buffer, position, length)
1227  call assert(946399479, length <= len(val))
1228  val = ''
1229  call mpi_unpack(buffer, size(buffer), position, val, length, &
1230  mpi_character, mpi_comm_world, ierr)
1231  call pmc_mpi_check_ierr(ierr)
1232  call assert(503378058, &
1233  position - prev_position <= pmc_mpi_pack_size_string(val))
1234 #endif
1235 
1236  end subroutine pmc_mpi_unpack_string
1237 
1238 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1239 
1240  !> Unpacks the given value from the buffer, advancing position.
1241  subroutine pmc_mpi_unpack_logical(buffer, position, val)
1242 
1243  !> Memory buffer.
1244  character, intent(inout) :: buffer(:)
1245  !> Current buffer position.
1246  integer, intent(inout) :: position
1247  !> Value to pack.
1248  logical, intent(out) :: val
1249 
1250 #ifdef PMC_USE_MPI
1251  integer :: prev_position, ierr
1252 
1253  prev_position = position
1254  call mpi_unpack(buffer, size(buffer), position, val, 1, mpi_logical, &
1255  mpi_comm_world, ierr)
1256  call pmc_mpi_check_ierr(ierr)
1257  call assert(694750528, &
1258  position - prev_position <= pmc_mpi_pack_size_logical(val))
1259 #endif
1260 
1261  end subroutine pmc_mpi_unpack_logical
1262 
1263 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1264 
1265  !> Unpacks the given value from the buffer, advancing position.
1266  subroutine pmc_mpi_unpack_complex(buffer, position, val)
1267 
1268  !> Memory buffer.
1269  character, intent(inout) :: buffer(:)
1270  !> Current buffer position.
1271  integer, intent(inout) :: position
1272  !> Value to pack.
1273  complex(kind=dc), intent(out) :: val
1274 
1275 #ifdef PMC_USE_MPI
1276  integer :: prev_position, ierr
1277 
1278  prev_position = position
1279  call mpi_unpack(buffer, size(buffer), position, val, 1, &
1280  mpi_double_complex, mpi_comm_world, ierr)
1281  call pmc_mpi_check_ierr(ierr)
1282  call assert(969672634, &
1283  position - prev_position <= pmc_mpi_pack_size_complex(val))
1284 #endif
1285 
1286  end subroutine pmc_mpi_unpack_complex
1287 
1288 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1289 
1290  !> Unpacks the given value from the buffer, advancing position.
1291  subroutine pmc_mpi_unpack_complex_array(buffer, position, val)
1292 
1293  !> Memory buffer.
1294  character, intent(inout) :: buffer(:)
1295  !> Current buffer position.
1296  integer, intent(inout) :: position
1297  !> Value to pack.
1298  complex(kind=dc), allocatable, intent(out) :: val(:)
1299 
1300 #ifdef PMC_USE_MPI
1301  integer :: prev_position, ierr, n
1302  logical :: is_allocated
1303 
1304  prev_position = position
1305  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
1306  if (allocated(val)) deallocate(val)
1307  if (is_allocated) then
1308  call pmc_mpi_unpack_integer(buffer, position, n)
1309  allocate(val(n))
1310  call mpi_unpack(buffer, size(buffer), position, val, n, &
1311  mpi_double_complex, mpi_comm_world, ierr)
1312  call pmc_mpi_check_ierr(ierr)
1313  end if
1314  call assert(969672631, &
1315  position - prev_position <= pmc_mpi_pack_size_complex_array(val))
1316 #endif
1317 
1318  end subroutine pmc_mpi_unpack_complex_array
1319 
1320 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1321 
1322  !> Unpacks the given value from the buffer, advancing position.
1323  subroutine pmc_mpi_unpack_integer_array(buffer, position, val)
1324 
1325  !> Memory buffer.
1326  character, intent(inout) :: buffer(:)
1327  !> Current buffer position.
1328  integer, intent(inout) :: position
1329  !> Value to pack.
1330  integer, allocatable, intent(inout) :: val(:)
1331 
1332 #ifdef PMC_USE_MPI
1333  integer :: prev_position, n, ierr
1334  logical :: is_allocated
1335 
1336  prev_position = position
1337  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
1338  if (allocated(val)) deallocate(val)
1339  if (is_allocated) then
1340  call pmc_mpi_unpack_integer(buffer, position, n)
1341  allocate(val(n))
1342  call mpi_unpack(buffer, size(buffer), position, val, n, mpi_integer, &
1343  mpi_comm_world, ierr)
1344  call pmc_mpi_check_ierr(ierr)
1345  end if
1346  call assert(565840919, &
1347  position - prev_position <= pmc_mpi_pack_size_integer_array(val))
1348 #endif
1349 
1350  end subroutine pmc_mpi_unpack_integer_array
1351 
1352 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1353 
1354  !> Unpacks the given value from the buffer, advancing position.
1355  subroutine pmc_mpi_unpack_real_array(buffer, position, val)
1356 
1357  !> Memory buffer.
1358  character, intent(inout) :: buffer(:)
1359  !> Current buffer position.
1360  integer, intent(inout) :: position
1361  !> Value to pack.
1362  real(kind=dp), allocatable, intent(inout) :: val(:)
1363 
1364 #ifdef PMC_USE_MPI
1365  integer :: prev_position, n, ierr
1366  logical :: is_allocated
1367 
1368  prev_position = position
1369  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
1370  if (allocated(val)) deallocate(val)
1371  if (is_allocated) then
1372  call pmc_mpi_unpack_integer(buffer, position, n)
1373  allocate(val(n))
1374  call mpi_unpack(buffer, size(buffer), position, val, n, &
1375  mpi_double_precision, mpi_comm_world, ierr)
1376  call pmc_mpi_check_ierr(ierr)
1377  end if
1378  call assert(782875761, &
1379  position - prev_position <= pmc_mpi_pack_size_real_array(val))
1380 #endif
1381 
1382  end subroutine pmc_mpi_unpack_real_array
1383 
1384 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1385 
1386  !> Unpacks the given value from the buffer, advancing position.
1387  subroutine pmc_mpi_unpack_string_array(buffer, position, val)
1388 
1389  !> Memory buffer.
1390  character, intent(inout) :: buffer(:)
1391  !> Current buffer position.
1392  integer, intent(inout) :: position
1393  !> Value to pack.
1394  character(len=*), allocatable, intent(inout) :: val(:)
1395 
1396 #ifdef PMC_USE_MPI
1397  integer :: prev_position, i, n
1398  logical :: is_allocated
1399 
1400  prev_position = position
1401  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
1402  if (allocated(val)) deallocate(val)
1403  if (is_allocated) then
1404  call pmc_mpi_unpack_integer(buffer, position, n)
1405  allocate(val(n))
1406  do i = 1,n
1407  call pmc_mpi_unpack_string(buffer, position, val(i))
1408  end do
1409  end if
1410  call assert(320065648, &
1411  position - prev_position <= pmc_mpi_pack_size_string_array(val))
1412 #endif
1413 
1414  end subroutine pmc_mpi_unpack_string_array
1415 
1416 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1417 
1418  !> Unpacks the given value from the buffer, advancing position.
1419  subroutine pmc_mpi_unpack_real_array_2d(buffer, position, val)
1420 
1421  !> Memory buffer.
1422  character, intent(inout) :: buffer(:)
1423  !> Current buffer position.
1424  integer, intent(inout) :: position
1425  !> Value to pack.
1426  real(kind=dp), allocatable, intent(inout) :: val(:,:)
1427 
1428 #ifdef PMC_USE_MPI
1429  integer :: prev_position, n1, n2, ierr
1430  logical :: is_allocated
1431 
1432  prev_position = position
1433  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
1434  if (allocated(val)) deallocate(val)
1435  if (is_allocated) then
1436  call pmc_mpi_unpack_integer(buffer, position, n1)
1437  call pmc_mpi_unpack_integer(buffer, position, n2)
1438  allocate(val(n1,n2))
1439  call mpi_unpack(buffer, size(buffer), position, val, n1*n2, &
1440  mpi_double_precision, mpi_comm_world, ierr)
1441  call pmc_mpi_check_ierr(ierr)
1442  end if
1443  call assert(781681739, position - prev_position &
1445 #endif
1446 
1447  end subroutine pmc_mpi_unpack_real_array_2d
1448 
1449 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1450 
1451  !> Unpacks the given value from the buffer, advancing position.
1452  subroutine pmc_mpi_unpack_real_array_3d(buffer, position, val)
1453 
1454  !> Memory buffer.
1455  character, intent(inout) :: buffer(:)
1456  !> Current buffer position.
1457  integer, intent(inout) :: position
1458  !> Value to pack.
1459  real(kind=dp), allocatable, intent(inout) :: val(:,:,:)
1460 
1461 #ifdef PMC_USE_MPI
1462  integer :: prev_position, n1, n2, n3, ierr
1463  logical :: is_allocated
1464 
1465  prev_position = position
1466  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
1467  if (allocated(val)) deallocate(val)
1468  if (is_allocated) then
1469  call pmc_mpi_unpack_integer(buffer, position, n1)
1470  call pmc_mpi_unpack_integer(buffer, position, n2)
1471  call pmc_mpi_unpack_integer(buffer, position, n3)
1472  allocate(val(n1,n2,n3))
1473  call mpi_unpack(buffer, size(buffer), position, val, n1*n2*n3, &
1474  mpi_double_precision, mpi_comm_world, ierr)
1475  call pmc_mpi_check_ierr(ierr)
1476  end if
1477  call assert(116666533, position - prev_position &
1479 #endif
1480 
1481  end subroutine pmc_mpi_unpack_real_array_3d
1482 
1483 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1484 
1485  !> Unpacks the given value from the buffer, advancing position.
1486  subroutine pmc_mpi_unpack_real_array_4d(buffer, position, val)
1487 
1488  !> Memory buffer.
1489  character, intent(inout) :: buffer(:)
1490  !> Current buffer position.
1491  integer, intent(inout) :: position
1492  !> Value to pack.
1493  real(kind=dp), allocatable, intent(inout) :: val(:,:,:,:)
1494 
1495 #ifdef PMC_USE_MPI
1496  integer :: prev_position, n1, n2, n3, n4, ierr
1497  logical :: is_allocated
1498 
1499  prev_position = position
1500  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
1501  if (allocated(val)) deallocate(val)
1502  if (is_allocated) then
1503  call pmc_mpi_unpack_integer(buffer, position, n1)
1504  call pmc_mpi_unpack_integer(buffer, position, n2)
1505  call pmc_mpi_unpack_integer(buffer, position, n3)
1506  call pmc_mpi_unpack_integer(buffer, position, n4)
1507  allocate(val(n1,n2,n3,n4))
1508  call mpi_unpack(buffer, size(buffer), position, val, n1*n2*n3*n4, &
1509  mpi_double_precision, mpi_comm_world, ierr)
1510  call pmc_mpi_check_ierr(ierr)
1511  end if
1512  call assert(392994260, position - prev_position &
1514 #endif
1515 
1516  end subroutine pmc_mpi_unpack_real_array_4d
1517 
1518 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1519 
1520  !> Unpacks the given value from the buffer, advancing position.
1521  subroutine pmc_mpi_unpack_real_array_5d(buffer, position, val)
1522 
1523  !> Memory buffer.
1524  character, intent(inout) :: buffer(:)
1525  !> Current buffer position.
1526  integer, intent(inout) :: position
1527  !> Value to pack.
1528  real(kind=dp), allocatable, intent(inout) :: val(:,:,:,:,:)
1529 
1530 #ifdef PMC_USE_MPI
1531  integer :: prev_position, n1, n2, n3, n4, n5, ierr
1532  logical :: is_allocated
1533 
1534  prev_position = position
1535  call pmc_mpi_unpack_logical(buffer, position, is_allocated)
1536  if (allocated(val)) deallocate(val)
1537  if (is_allocated) then
1538  call pmc_mpi_unpack_integer(buffer, position, n1)
1539  call pmc_mpi_unpack_integer(buffer, position, n2)
1540  call pmc_mpi_unpack_integer(buffer, position, n3)
1541  call pmc_mpi_unpack_integer(buffer, position, n4)
1542  call pmc_mpi_unpack_integer(buffer, position, n5)
1543  allocate(val(n1,n2,n3,n4,n5))
1544  call mpi_unpack(buffer, size(buffer), position, val, n1*n2*n3*n4*n5, &
1545  mpi_double_precision, mpi_comm_world, ierr)
1546  call pmc_mpi_check_ierr(ierr)
1547  end if
1548  call assert(046688204, position - prev_position &
1550 #endif
1551 
1552  end subroutine pmc_mpi_unpack_real_array_5d
1553 
1554 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1555 
1556  !> Computes the average of val across all processes, storing the
1557  !> result in val_avg on the root process.
1558  subroutine pmc_mpi_reduce_avg_real(val, val_avg)
1559 
1560  !> Value to average.
1561  real(kind=dp), intent(in) :: val
1562  !> Result.
1563  real(kind=dp), intent(out) :: val_avg
1564 
1565 #ifdef PMC_USE_MPI
1566  integer :: ierr
1567 
1568  call mpi_reduce(val, val_avg, 1, mpi_double_precision, mpi_sum, 0, &
1569  mpi_comm_world, ierr)
1570  call pmc_mpi_check_ierr(ierr)
1571  if (pmc_mpi_rank() == 0) then
1572  val_avg = val_avg / real(pmc_mpi_size(), kind=dp)
1573  end if
1574 #else
1575  val_avg = val
1576 #endif
1577 
1578  end subroutine pmc_mpi_reduce_avg_real
1579 
1580 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1581 
1582  !> Transfer the value between the given processes.
1583  subroutine pmc_mpi_transfer_real(from_val, to_val, from_proc, to_proc)
1584 
1585  !> Value to send.
1586  real(kind=dp), intent(in) :: from_val
1587  !> Variable to send to.
1588  real(kind=dp), intent(out) :: to_val
1589  !> Process to send from.
1590  integer, intent(in) :: from_proc
1591  !> Process to send to.
1592  integer, intent(in) :: to_proc
1593 
1594 #ifdef PMC_USE_MPI
1595  integer :: rank, ierr, status(MPI_STATUS_SIZE)
1596 
1597  rank = pmc_mpi_rank()
1598  if (from_proc == to_proc) then
1599  if (rank == from_proc) then
1600  to_val = from_val
1601  end if
1602  else
1603  if (rank == from_proc) then
1604  call mpi_send(from_val, 1, mpi_double_precision, to_proc, &
1605  208020430, mpi_comm_world, ierr)
1606  call pmc_mpi_check_ierr(ierr)
1607  elseif (rank == to_proc) then
1608  call mpi_recv(to_val, 1, mpi_double_precision, from_proc, &
1609  208020430, mpi_comm_world, status, ierr)
1610  call pmc_mpi_check_ierr(ierr)
1611  end if
1612  end if
1613 #else
1614  to_val = from_val
1615 #endif
1616 
1617  end subroutine pmc_mpi_transfer_real
1618 
1619 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1620 
1621  !> Transfer the value between the given processes.
1622  subroutine pmc_mpi_transfer_integer(from_val, to_val, from_proc, to_proc)
1623 
1624  !> Value to send.
1625  integer, intent(in) :: from_val
1626  !> Variable to send to.
1627  integer, intent(out) :: to_val
1628  !> Process to send from.
1629  integer, intent(in) :: from_proc
1630  !> Process to send to.
1631  integer, intent(in) :: to_proc
1632 
1633 #ifdef PMC_USE_MPI
1634  integer :: rank, ierr, status(MPI_STATUS_SIZE)
1635 
1636  rank = pmc_mpi_rank()
1637  if (from_proc == to_proc) then
1638  if (rank == from_proc) then
1639  to_val = from_val
1640  end if
1641  else
1642  if (rank == from_proc) then
1643  call mpi_send(from_val, 1, mpi_integer, to_proc, &
1644  208020430, mpi_comm_world, ierr)
1645  call pmc_mpi_check_ierr(ierr)
1646  elseif (rank == to_proc) then
1647  call mpi_recv(to_val, 1, mpi_integer, from_proc, &
1648  208020430, mpi_comm_world, status, ierr)
1649  call pmc_mpi_check_ierr(ierr)
1650  end if
1651  end if
1652 #else
1653  to_val = from_val
1654 #endif
1655 
1656  end subroutine pmc_mpi_transfer_integer
1657 
1658 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1659 
1660  !> Computes the sum of \c val across all processes, storing the
1661  !> result in \c val_sum on the root process.
1662  subroutine pmc_mpi_reduce_sum_integer(val, val_sum)
1663 
1664  !> Value to sum.
1665  integer, intent(in) :: val
1666  !> Result.
1667  integer, intent(out) :: val_sum
1668 
1669 #ifdef PMC_USE_MPI
1670  integer :: ierr
1671 
1672  call mpi_reduce(val, val_sum, 1, mpi_integer, mpi_sum, 0, &
1673  mpi_comm_world, ierr)
1674  call pmc_mpi_check_ierr(ierr)
1675 #else
1676  val_sum = val
1677 #endif
1678 
1679  end subroutine pmc_mpi_reduce_sum_integer
1680 
1681 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1682 
1683  !> Computes the sum of \c val across all processes, storing the
1684  !> result in \c val_sum on all processes.
1685  subroutine pmc_mpi_allreduce_sum_integer(val, val_sum)
1686 
1687  !> Value to sum.
1688  integer, intent(in) :: val
1689  !> Result.
1690  integer, intent(out) :: val_sum
1691 
1692 #ifdef PMC_USE_MPI
1693  integer :: ierr
1694 
1695  call mpi_allreduce(val, val_sum, 1, mpi_integer, mpi_sum, &
1696  mpi_comm_world, ierr)
1697  call pmc_mpi_check_ierr(ierr)
1698 #else
1699  val_sum = val
1700 #endif
1701 
1702  end subroutine pmc_mpi_allreduce_sum_integer
1703 
1704 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1705 
1706  !> Computes the average of val across all processes, storing the
1707  !> result in val_avg on the root process.
1708  subroutine pmc_mpi_reduce_avg_real_array(val, val_avg)
1709 
1710  !> Value to average.
1711  real(kind=dp), intent(in) :: val(:)
1712  !> Result.
1713  real(kind=dp), intent(out) :: val_avg(:)
1714 
1715 #ifdef PMC_USE_MPI
1716  integer :: ierr
1717 
1718  call assert(915136121, size(val) == size(val_avg))
1719  call mpi_reduce(val, val_avg, size(val), mpi_double_precision, &
1720  mpi_sum, 0, mpi_comm_world, ierr)
1721  call pmc_mpi_check_ierr(ierr)
1722  if (pmc_mpi_rank() == 0) then
1723  val_avg = val_avg / real(pmc_mpi_size(), kind=dp)
1724  end if
1725 #else
1726  val_avg = val
1727 #endif
1728 
1729  end subroutine pmc_mpi_reduce_avg_real_array
1730 
1731 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1732 
1733  !> Computes the average of val across all processes, storing the
1734  !> result in val_avg on the root process.
1735  subroutine pmc_mpi_reduce_avg_real_array_2d(val, val_avg)
1736 
1737  !> Value to average.
1738  real(kind=dp), intent(in) :: val(:,:)
1739  !> Result.
1740  real(kind=dp), intent(out) :: val_avg(:,:)
1741 
1742 #ifdef PMC_USE_MPI
1743  integer :: ierr
1744 
1745  call assert(131229046, size(val,1) == size(val_avg,1))
1746  call assert(992122167, size(val,2) == size(val_avg,2))
1747  call mpi_reduce(val, val_avg, size(val), mpi_double_precision, &
1748  mpi_sum, 0, mpi_comm_world, ierr)
1749  call pmc_mpi_check_ierr(ierr)
1750  if (pmc_mpi_rank() == 0) then
1751  val_avg = val_avg / real(pmc_mpi_size(), kind=dp)
1752  end if
1753 #else
1754  val_avg = val
1755 #endif
1756 
1757  end subroutine pmc_mpi_reduce_avg_real_array_2d
1758 
1759 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1760 
1761  !> Computes the average of val across all processes, storing the
1762  !> result in val_avg on all processes.
1763  subroutine pmc_mpi_allreduce_average_real(val, val_avg)
1764 
1765  !> Value to average.
1766  real(kind=dp), intent(in) :: val
1767  !> Result.
1768  real(kind=dp), intent(out) :: val_avg
1769 
1770 #ifdef PMC_USE_MPI
1771  integer :: ierr
1772 
1773  call mpi_allreduce(val, val_avg, 1, mpi_double_precision, mpi_sum, &
1774  mpi_comm_world, ierr)
1775  call pmc_mpi_check_ierr(ierr)
1776  val_avg = val_avg / real(pmc_mpi_size(), kind=dp)
1777 #else
1778  val_avg = val
1779 #endif
1780 
1781  end subroutine pmc_mpi_allreduce_average_real
1782 
1783 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1784 
1785  !> Computes the average of val across all processes, storing the
1786  !> result in val_avg on all processes.
1787  subroutine pmc_mpi_allreduce_average_real_array(val, val_avg)
1788 
1789  !> Value to average.
1790  real(kind=dp), intent(in) :: val(:)
1791  !> Result.
1792  real(kind=dp), intent(out) :: val_avg(:)
1793 
1794 #ifdef PMC_USE_MPI
1795  integer :: ierr
1796 
1797  call assert(948533359, size(val) == size(val_avg))
1798  call mpi_allreduce(val, val_avg, size(val), mpi_double_precision, &
1799  mpi_sum, mpi_comm_world, ierr)
1800  call pmc_mpi_check_ierr(ierr)
1801  val_avg = val_avg / real(pmc_mpi_size(), kind=dp)
1802 #else
1803  val_avg = val
1804 #endif
1805 
1807 
1808 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1809 
1810  !> Computes the minimum of val across all processes, storing the
1811  !> result in val_min on all processes.
1812  subroutine pmc_mpi_allreduce_min_integer(val, val_min)
1813 
1814  !> Value to minimize.
1815  integer, intent(in) :: val
1816  !> Result.
1817  integer, intent(out) :: val_min
1818 
1819 #ifdef PMC_USE_MPI
1820  integer :: ierr
1821 
1822  call mpi_allreduce(val, val_min, 1, mpi_integer, mpi_min, &
1823  mpi_comm_world, ierr)
1824  call pmc_mpi_check_ierr(ierr)
1825 #else
1826  val_min = val
1827 #endif
1828 
1829  end subroutine pmc_mpi_allreduce_min_integer
1830 
1831 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1832 
1833  !> Computes the maximum of val across all processes, storing the
1834  !> result in val_max on all processes.
1835  subroutine pmc_mpi_allreduce_max_integer(val, val_max)
1836 
1837  !> Value to maximize.
1838  integer, intent(in) :: val
1839  !> Result.
1840  integer, intent(out) :: val_max
1841 
1842 #ifdef PMC_USE_MPI
1843  integer :: ierr
1844 
1845  call mpi_allreduce(val, val_max, 1, mpi_integer, mpi_max, &
1846  mpi_comm_world, ierr)
1847  call pmc_mpi_check_ierr(ierr)
1848 #else
1849  val_max = val
1850 #endif
1851 
1852  end subroutine pmc_mpi_allreduce_max_integer
1853 
1854 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1855 
1856  !> Computes the minimum of val across all processes, storing the
1857  !> result in val_min on all processes.
1858  subroutine pmc_mpi_allreduce_min_real(val, val_min)
1859 
1860  !> Value to minimize.
1861  real(kind=dp), intent(in) :: val
1862  !> Result.
1863  real(kind=dp), intent(out) :: val_min
1864 
1865 #ifdef PMC_USE_MPI
1866  integer :: ierr
1867 
1868  call mpi_allreduce(val, val_min, 1, mpi_double_precision, mpi_min, &
1869  mpi_comm_world, ierr)
1870  call pmc_mpi_check_ierr(ierr)
1871 #else
1872  val_min = val
1873 #endif
1874 
1875  end subroutine pmc_mpi_allreduce_min_real
1876 
1877 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1878 
1879  !> Computes the maximum of val across all processes, storing the
1880  !> result in val_max on all processes.
1881  subroutine pmc_mpi_allreduce_max_real(val, val_max)
1882 
1883  !> Value to maximize.
1884  real(kind=dp), intent(in) :: val
1885  !> Result.
1886  real(kind=dp), intent(out) :: val_max
1887 
1888 #ifdef PMC_USE_MPI
1889  integer :: ierr
1890 
1891  call mpi_allreduce(val, val_max, 1, mpi_double_precision, mpi_max, &
1892  mpi_comm_world, ierr)
1893  call pmc_mpi_check_ierr(ierr)
1894 #else
1895  val_max = val
1896 #endif
1897 
1898  end subroutine pmc_mpi_allreduce_max_real
1899 
1900 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1901 
1902  !> Returns whether all processors have the same value.
1903  logical function pmc_mpi_allequal_integer(val)
1904 
1905  !> Value to compare.
1906  integer, intent(in) :: val
1907 
1908 #ifdef PMC_USE_MPI
1909  integer :: min_val, max_val
1910 
1911  call pmc_mpi_allreduce_min_integer(val, min_val)
1912  call pmc_mpi_allreduce_max_integer(val, max_val)
1913  if (min_val == max_val) then
1914  pmc_mpi_allequal_integer = .true.
1915  else
1916  pmc_mpi_allequal_integer = .false.
1917  end if
1918 #else
1919  pmc_mpi_allequal_integer = .true.
1920 #endif
1921 
1922  end function pmc_mpi_allequal_integer
1923 
1924 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1925 
1926  !> Returns whether all processors have the same value.
1927  logical function pmc_mpi_allequal_real(val)
1928 
1929  !> Value to compare.
1930  real(kind=dp), intent(in) :: val
1931 
1932 #ifdef PMC_USE_MPI
1933  real(kind=dp) :: min_val, max_val
1934 
1935  call pmc_mpi_allreduce_min_real(val, min_val)
1936  call pmc_mpi_allreduce_max_real(val, max_val)
1937  if (min_val == max_val) then
1938  pmc_mpi_allequal_real = .true.
1939  else
1940  pmc_mpi_allequal_real = .false.
1941  end if
1942 #else
1943  pmc_mpi_allequal_real = .true.
1944 #endif
1945 
1946  end function pmc_mpi_allequal_real
1947 
1948 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1949 
1950  !> Does an all-to-all transfer of integers.
1951  subroutine pmc_mpi_alltoall_integer(send, recv)
1952 
1953  !> Values to send (must be one per process).
1954  integer, intent(in) :: send(:)
1955  !> Values to receive (must be one per process).
1956  integer, intent(out) :: recv(size(send))
1957 
1958 #ifdef PMC_USE_MPI
1959  integer :: ierr
1960 
1961  call mpi_alltoall(send, 1, mpi_integer, recv, 1, mpi_integer, &
1962  mpi_comm_world, ierr)
1963  call pmc_mpi_check_ierr(ierr)
1964 #else
1965  recv = send
1966 #endif
1967 
1968  end subroutine pmc_mpi_alltoall_integer
1969 
1970 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1971 
1972  !> Does an allgather of integer arrays (must be the same size on all
1973  !> processes).
1974  subroutine pmc_mpi_allgather_integer_array(send, recv)
1975 
1976  !> Values to send on each process.
1977  integer, intent(in) :: send(:)
1978  !> Values to receive (will be the same on all processes.
1979  integer, intent(out) :: recv(:,:)
1980 
1981 #ifdef PMC_USE_MPI
1982  integer :: n_proc, n_bin, n_data, ierr
1983  integer, allocatable :: send_buf(:), recv_buf(:)
1984 
1985  n_proc = pmc_mpi_size()
1986  n_data = size(send, 1)
1987  call assert(353005542, all(shape(recv) == (/n_data, n_proc/)))
1988 
1989  ! use a new send_buf to make sure the memory is contiguous
1990  allocate(send_buf(n_data))
1991  allocate(recv_buf(n_data * n_proc))
1992  send_buf = send
1993  call mpi_allgather(send_buf, n_data, mpi_integer, &
1994  recv_buf, n_data, mpi_integer, mpi_comm_world, ierr)
1995  call pmc_mpi_check_ierr(ierr)
1996  recv = reshape(recv_buf, (/n_data, n_proc/))
1997  deallocate(send_buf)
1998  deallocate(recv_buf)
1999 #else
2000  recv(:, 1) = send
2001 #endif
2002 
2003  end subroutine pmc_mpi_allgather_integer_array
2004 
2005 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2006 
2007  !> Does an allgather of real arrays (must be the same size on all
2008  !> processes).
2009  subroutine pmc_mpi_allgather_real_array(send, recv)
2010 
2011  !> Values to send on each process.
2012  real(kind=dp), intent(in) :: send(:)
2013  !> Values to receive (will be the same on all processes.
2014  real(kind=dp), intent(out) :: recv(:,:)
2015 
2016 #ifdef PMC_USE_MPI
2017  integer :: n_proc, n_bin, n_data, ierr
2018  real(kind=dp), allocatable :: send_buf(:), recv_buf(:)
2019 
2020  n_proc = pmc_mpi_size()
2021  n_data = size(send, 1)
2022  call assert(291000580, all(shape(recv) == (/n_data, n_proc/)))
2023 
2024  ! use a new send_buf to make sure the memory is contiguous
2025  allocate(send_buf(n_data))
2026  allocate(recv_buf(n_data * n_proc))
2027  send_buf = send
2028  call mpi_allgather(send_buf, n_data, mpi_double_precision, &
2029  recv_buf, n_data, mpi_double_precision, mpi_comm_world, ierr)
2030  call pmc_mpi_check_ierr(ierr)
2031  recv = reshape(recv_buf, (/n_data, n_proc/))
2032  deallocate(send_buf)
2033  deallocate(recv_buf)
2034 #else
2035  recv(:, 1) = send
2036 #endif
2037 
2038  end subroutine pmc_mpi_allgather_real_array
2039 
2040 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2041 
2042 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:959
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:447
pmc_mpi::pmc_mpi_unpack_real_array_5d
subroutine pmc_mpi_unpack_real_array_5d(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1522
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:815
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:1788
pmc_mpi::pmc_mpi_unpack_real_array_3d
subroutine pmc_mpi_unpack_real_array_3d(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1453
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:835
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:1267
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:1388
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:1736
pmc_mpi::pmc_mpi_unpack_real_array_4d
subroutine pmc_mpi_unpack_real_array_4d(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1487
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:385
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:1324
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:895
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:1686
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:1836
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:1859
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:1559
pmc_mpi::pmc_mpi_unpack_integer64
subroutine pmc_mpi_unpack_integer64(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1164
pmc_mpi::pmc_mpi_pack_integer64
subroutine pmc_mpi_pack_integer64(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:736
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:2010
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:813
pmc_mpi::pmc_mpi_allequal_integer
logical function pmc_mpi_allequal_integer(val)
Returns whether all processors have the same value.
Definition: mpi.F90:1904
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:786
pmc_mpi::pmc_mpi_pack_size_real_array_3d
integer function pmc_mpi_pack_size_real_array_3d(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:612
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:761
pmc_util::assert
subroutine assert(code, condition_ok)
Errors unless condition_ok is true.
Definition: util.F90:104
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:527
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:1214
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:427
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:838
pmc_mpi::pmc_mpi_pack_complex_array
subroutine pmc_mpi_pack_complex_array(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:863
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:581
pmc_mpi::pmc_mpi_unpack_complex_array
subroutine pmc_mpi_unpack_complex_array(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1292
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:767
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:799
pmc_util::assert_msg
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition: util.F90:78
pmc_mpi::pmc_mpi_pack_size_real_array_4d
integer function pmc_mpi_pack_size_real_array_4d(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:644
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:991
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:1584
pmc_mpi::pmc_mpi_alltoall_integer
subroutine pmc_mpi_alltoall_integer(send, recv)
Does an all-to-all transfer of integers.
Definition: mpi.F90:1952
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:1139
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:1242
pmc_mpi::pmc_mpi_pack_real_array_4d
subroutine pmc_mpi_pack_real_array_4d(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:1061
pmc_mpi::pmc_mpi_pack_real_array_3d
subroutine pmc_mpi_pack_real_array_3d(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:1025
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:1882
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:497
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:1975
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:1420
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:1813
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:557
pmc_mpi::pmc_mpi_allequal_real
logical function pmc_mpi_allequal_real(val)
Returns whether all processors have the same value.
Definition: mpi.F90:1928
pmc_mpi::pmc_mpi_barrier
subroutine pmc_mpi_barrier()
Synchronize all processes.
Definition: mpi.F90:103
pmc_mpi::pmc_mpi_pack_size_integer64
integer function pmc_mpi_pack_size_integer64(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:365
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:711
pmc_mpi::pmc_mpi_pack_size_complex_array
integer function pmc_mpi_pack_size_complex_array(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:467
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:1764
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:1663
pmc_util::die
subroutine die(code)
Error immediately.
Definition: util.F90:123
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:927
pmc_mpi::pmc_mpi_pack_real_array_5d
subroutine pmc_mpi_pack_real_array_5d(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:1099
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:1709
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:1189
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:1623
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:1356
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_real_array_5d
integer function pmc_mpi_pack_size_real_array_5d(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:677
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:405