CAMP 1.0.0
Chemistry Across Multiple Phases
mpi.F90
Go to the documentation of this file.
1! Copyright (C) 2007-2021 Barcelona Supercomputing Center and University of
2! Illinois at Urbana-Champaign
3! SPDX-License-Identifier: MIT
4
5!> \file
6!> The camp_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).
14
15 use camp_util
16
17#ifdef CAMP_USE_MPI
18 use mpi
19#endif
20
21 implicit none
22
23contains
24
25!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
26
27 !> Whether MPI support is compiled in.
28 logical function camp_mpi_support()
29
30#ifdef CAMP_USE_MPI
31 camp_mpi_support = .true.
32#else
33 camp_mpi_support = .false.
34#endif
35
36 end function camp_mpi_support
37
38!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
39
40 !> Dies if \c ierr is not ok.
41 subroutine camp_mpi_check_ierr(ierr)
42
43 !> MPI status code.
44 integer, intent(in) :: ierr
45
46#ifdef CAMP_USE_MPI
47 if (ierr /= mpi_success) then
48 call camp_mpi_abort(1)
49 end if
50#endif
51
52 end subroutine camp_mpi_check_ierr
53
54!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
55
56 !> Initialize MPI.
57 subroutine camp_mpi_init()
58
59#ifdef CAMP_USE_MPI
60 integer :: ierr
61
62 call mpi_init(ierr)
63 call camp_mpi_check_ierr(ierr)
64 call camp_mpi_test()
65#endif
66
67 end subroutine camp_mpi_init
68
69!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
70
71 !> Abort the program.
72 subroutine camp_mpi_abort(status)
73
74 !> Status flag to abort with.
75 integer, intent(in) :: status
76
77#ifdef CAMP_USE_MPI
78 integer :: ierr
79
80 call mpi_abort(mpi_comm_world, status, ierr)
81#else
82 call die(status)
83#endif
84
85 end subroutine camp_mpi_abort
86
87!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
88
89 !> Shut down MPI.
90 subroutine camp_mpi_finalize()
91
92#ifdef CAMP_USE_MPI
93 integer :: ierr
94
95 call mpi_finalize(ierr)
96 call camp_mpi_check_ierr(ierr)
97#endif
98
99 end subroutine camp_mpi_finalize
100
101!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
102
103 !> Synchronize all processes.
104 subroutine camp_mpi_barrier( comm )
105
106 !> MPI communicator
107 integer, intent(in), optional :: comm
108
109#ifdef CAMP_USE_MPI
110 integer :: ierr, l_comm
111
112 if (present(comm)) then
113 l_comm = comm
114 else
115 l_comm = mpi_comm_world
116 endif
117
118 call mpi_barrier(l_comm, ierr)
119 call camp_mpi_check_ierr(ierr)
120#endif
121
122 end subroutine camp_mpi_barrier
123
124!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
125
126 !> Returns the rank of the current process.
127 integer function camp_mpi_rank( comm )
128
129 !> MPI communicator
130 integer, intent(in), optional :: comm
131
132#ifdef CAMP_USE_MPI
133 integer :: rank, ierr, l_comm
134
135 if (present(comm)) then
136 l_comm = comm
137 else
138 l_comm = mpi_comm_world
139 endif
140
141 call mpi_comm_rank(l_comm, rank, ierr)
142 call camp_mpi_check_ierr(ierr)
143 camp_mpi_rank = rank
144#else
145 camp_mpi_rank = 0
146#endif
147
148 end function camp_mpi_rank
149
150!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
151
152 !> Returns the total number of processes.
153 integer function camp_mpi_size( comm )
154
155 !> MPI communicator
156 integer, intent(in), optional :: comm
157
158#ifdef CAMP_USE_MPI
159 integer :: size, ierr, l_comm
160
161 if (present(comm)) then
162 l_comm = comm
163 else
164 l_comm = mpi_comm_world
165 endif
166
167 call mpi_comm_size(l_comm, size, ierr)
168 call camp_mpi_check_ierr(ierr)
169 camp_mpi_size = size
170#else
171 camp_mpi_size = 1
172#endif
173
174 end function camp_mpi_size
175
176!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
177
178 !> Perform basic sanity checks on send/receive.
179 subroutine camp_mpi_test()
180
181#ifdef CAMP_USE_MPI
182 real(kind=dp), parameter :: test_real = 2.718281828459d0
183 complex(kind=dc), parameter :: test_complex &
184 = (0.707106781187d0, 1.4142135624d0)
185 logical, parameter :: test_logical = .true.
186 character(len=100), parameter :: test_string &
187 = "a truth universally acknowledged"
188 integer, parameter :: test_integer = 314159
189
190 character, allocatable :: buffer(:)
191 integer :: buffer_size, max_buffer_size, position
192 real(kind=dp) :: send_real, recv_real
193 complex(kind=dc) :: send_complex, recv_complex
194 logical :: send_logical, recv_logical
195 character(len=100) :: send_string, recv_string
196 integer :: send_integer, recv_integer
197 real(kind=dp), allocatable :: send_real_array(:)
198 real(kind=dp), allocatable :: recv_real_array(:)
199
200 if (camp_mpi_rank() == 0) then
201 send_real = test_real
202 send_complex = test_complex
203 send_logical = test_logical
204 send_string = test_string
205 send_integer = test_integer
206 allocate(send_real_array(2))
207 send_real_array(1) = real(test_complex)
208 send_real_array(2) = aimag(test_complex)
209
210 max_buffer_size = 0
211 max_buffer_size = max_buffer_size &
212 + camp_mpi_pack_size_integer(send_integer)
213 max_buffer_size = max_buffer_size &
214 + camp_mpi_pack_size_real(send_real)
215 max_buffer_size = max_buffer_size &
216 + camp_mpi_pack_size_complex(send_complex)
217 max_buffer_size = max_buffer_size &
218 + camp_mpi_pack_size_logical(send_logical)
219 max_buffer_size = max_buffer_size &
220 + camp_mpi_pack_size_string(send_string)
221 max_buffer_size = max_buffer_size &
222 + camp_mpi_pack_size_real_array(send_real_array)
223
224 allocate(buffer(max_buffer_size))
225
226 position = 0
227 call camp_mpi_pack_real(buffer, position, send_real)
228 call camp_mpi_pack_complex(buffer, position, send_complex)
229 call camp_mpi_pack_logical(buffer, position, send_logical)
230 call camp_mpi_pack_string(buffer, position, send_string)
231 call camp_mpi_pack_integer(buffer, position, send_integer)
232 call camp_mpi_pack_real_array(buffer, position, send_real_array)
233 call assert_msg(350740830, position <= max_buffer_size, &
234 "MPI test failure: pack position " &
235 // trim(integer_to_string(position)) &
236 // " greater than max_buffer_size " &
237 // trim(integer_to_string(max_buffer_size)))
238 buffer_size = position ! might be less than we allocated
239 end if
240
241 call camp_mpi_bcast_integer(buffer_size)
242
243 if (camp_mpi_rank() /= 0) then
244 allocate(buffer(buffer_size))
245 end if
246
247 call camp_mpi_bcast_packed(buffer)
248
249 if (camp_mpi_rank() /= 0) then
250 position = 0
251 call camp_mpi_unpack_real(buffer, position, recv_real)
252 call camp_mpi_unpack_complex(buffer, position, recv_complex)
253 call camp_mpi_unpack_logical(buffer, position, recv_logical)
254 call camp_mpi_unpack_string(buffer, position, recv_string)
255 call camp_mpi_unpack_integer(buffer, position, recv_integer)
256 call camp_mpi_unpack_real_array(buffer, position, recv_real_array)
257 call assert_msg(787677020, position == buffer_size, &
258 "MPI test failure: unpack position " &
259 // trim(integer_to_string(position)) &
260 // " not equal to buffer_size " &
261 // trim(integer_to_string(buffer_size)))
262 end if
263
264 deallocate(buffer)
265
266 if (camp_mpi_rank() /= 0) then
267 call assert_msg(567548916, recv_real == test_real, &
268 "MPI test failure: real recv " &
269 // trim(to_string(recv_real)) &
270 // " not equal to " &
271 // trim(to_string(test_real)))
272 call assert_msg(653908509, recv_complex == test_complex, &
273 "MPI test failure: complex recv " &
274 // trim(complex_to_string(recv_complex)) &
275 // " not equal to " &
276 // trim(complex_to_string(test_complex)))
277 call assert_msg(307746296, recv_logical .eqv. test_logical, &
278 "MPI test failure: logical recv " &
279 // trim(logical_to_string(recv_logical)) &
280 // " not equal to " &
281 // trim(logical_to_string(test_logical)))
282 call assert_msg(155693492, recv_string == test_string, &
283 "MPI test failure: string recv '" &
284 // trim(recv_string) &
285 // "' not equal to '" &
286 // trim(test_string) // "'")
287 call assert_msg(875699427, recv_integer == test_integer, &
288 "MPI test failure: integer recv " &
289 // trim(integer_to_string(recv_integer)) &
290 // " not equal to " &
291 // trim(integer_to_string(test_integer)))
292 call assert_msg(326982363, size(recv_real_array) == 2, &
293 "MPI test failure: real array recv size " &
294 // trim(integer_to_string(size(recv_real_array))) &
295 // " not equal to 2")
296 call assert_msg(744394323, &
297 recv_real_array(1) == real(test_complex), &
298 "MPI test failure: real array recv index 1 " &
299 // trim(to_string(recv_real_array(1))) &
300 // " not equal to " &
301 // trim(to_string(real(test_complex))))
302 call assert_msg(858902527, &
303 recv_real_array(2) == aimag(test_complex), &
304 "MPI test failure: real array recv index 2 " &
305 // trim(to_string(recv_real_array(2))) &
306 // " not equal to " &
307 // trim(to_string(aimag(test_complex))))
308 end if
309#endif
310
311 end subroutine camp_mpi_test
312
313!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
314
315 !> Broadcast the given value from process 0 to all other processes.
316 subroutine camp_mpi_bcast_integer(val, comm)
317
318 !> Value to broadcast.
319 integer, intent(inout) :: val
320 !> MPI communicator
321 integer, intent(in), optional :: comm
322
323#ifdef CAMP_USE_MPI
324 integer :: root, ierr, l_comm
325
326 if (present(comm)) then
327 l_comm = comm
328 else
329 l_comm = mpi_comm_world
330 endif
331
332 root = 0 ! source of data to broadcast
333 call mpi_bcast(val, 1, mpi_integer, root, &
334 l_comm, ierr)
335 call camp_mpi_check_ierr(ierr)
336#endif
337
338 end subroutine camp_mpi_bcast_integer
339
340!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
341
342 !> Broadcast the given value from process 0 to all other processes.
343 subroutine camp_mpi_bcast_string(val, comm)
344
345 !> Value to broadcast.
346 character(len=*), intent(inout) :: val
347 !> MPI communicator
348 integer, intent(in), optional :: comm
349
350#ifdef CAMP_USE_MPI
351 integer :: root, ierr, l_comm
352
353 if (present(comm)) then
354 l_comm = comm
355 else
356 l_comm = mpi_comm_world
357 endif
358
359 root = 0 ! source of data to broadcast
360 call mpi_bcast(val, len(val), mpi_character, root, &
361 l_comm, ierr)
362 call camp_mpi_check_ierr(ierr)
363#endif
364
365 end subroutine camp_mpi_bcast_string
366
367!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
368
369 !> Broadcast the given value from process 0 to all other processes.
370 subroutine camp_mpi_bcast_packed(val, comm)
371
372 !> Value to broadcast.
373 character, intent(inout) :: val(:)
374 !> MPI communicator
375 integer, intent(in), optional :: comm
376
377#ifdef CAMP_USE_MPI
378 integer :: root, ierr, l_comm
379
380 if (present(comm)) then
381 l_comm = comm
382 else
383 l_comm = mpi_comm_world
384 endif
385
386 root = 0 ! source of data to broadcast
387 call mpi_bcast(val, size(val), mpi_character, root, &
388 l_comm, ierr)
389 call camp_mpi_check_ierr(ierr)
390#endif
391
392 end subroutine camp_mpi_bcast_packed
393
394!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
395
396 !> Determines the number of bytes required to pack the given value.
397 integer function camp_mpi_pack_size_integer(val, comm)
398
399 !> Value to pack.
400 integer, intent(in) :: val
401 !> MPI communicator
402 integer, intent(in), optional :: comm
403
404 integer :: ierr, l_comm
405
406#ifdef CAMP_USE_MPI
407 if (present(comm)) then
408 l_comm = comm
409 else
410 l_comm = mpi_comm_world
411 endif
412
413 call mpi_pack_size(1, mpi_integer, l_comm, &
415 call camp_mpi_check_ierr(ierr)
416#else
418#endif
419
420 end function camp_mpi_pack_size_integer
421
422!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
423
424 !> Determines the number of bytes required to pack the given value.
425 integer function camp_mpi_pack_size_real(val, comm)
426
427 !> Value to pack.
428 real(kind=dp), intent(in) :: val
429 !> MPI communicator
430 integer, intent(in), optional :: comm
431
432 integer :: ierr, l_comm
433
434#ifdef CAMP_USE_MPI
435 if (present(comm)) then
436 l_comm = comm
437 else
438 l_comm = mpi_comm_world
439 endif
440
441 call mpi_pack_size(1, mpi_double_precision, l_comm, &
443 call camp_mpi_check_ierr(ierr)
444#else
446#endif
447
448 end function camp_mpi_pack_size_real
449
450!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
451
452 !> Determines the number of bytes required to pack the given value.
453 integer function camp_mpi_pack_size_string(val, comm)
454
455 !> Value to pack.
456 character(len=*), intent(in) :: val
457 !> MPI communicator
458 integer, intent(in), optional :: comm
459
460 integer :: ierr, l_comm
461
462#ifdef CAMP_USE_MPI
463 if (present(comm)) then
464 l_comm = comm
465 else
466 l_comm = mpi_comm_world
467 endif
468
469 call mpi_pack_size(len_trim(val), mpi_character, l_comm, &
471 call camp_mpi_check_ierr(ierr)
473 + camp_mpi_pack_size_integer(len_trim(val))
474#else
476#endif
477
478 end function camp_mpi_pack_size_string
479
480!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
481
482 !> Determines the number of bytes required to pack the given value.
483 integer function camp_mpi_pack_size_logical(val, comm)
484
485 !> Value to pack.
486 logical, intent(in) :: val
487 !> MPI communicator
488 integer, intent(in), optional :: comm
489
490 integer :: ierr, l_comm
491
492#ifdef CAMP_USE_MPI
493 if (present(comm)) then
494 l_comm = comm
495 else
496 l_comm = mpi_comm_world
497 endif
498
499 call mpi_pack_size(1, mpi_logical, l_comm, &
501 call camp_mpi_check_ierr(ierr)
502#else
504#endif
505
506 end function camp_mpi_pack_size_logical
507
508!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
509
510 !> Determines the number of bytes required to pack the given value.
511 integer function camp_mpi_pack_size_complex(val, comm)
512
513 !> Value to pack.
514 complex(kind=dc), intent(in) :: val
515 !> MPI communicator
516 integer, intent(in), optional :: comm
517
518 integer :: ierr, l_comm
519
520#ifdef CAMP_USE_MPI
521 if (present(comm)) then
522 l_comm = comm
523 else
524 l_comm = mpi_comm_world
525 endif
526
527 call mpi_pack_size(1, mpi_double_complex, l_comm, &
529 call camp_mpi_check_ierr(ierr)
530#else
532#endif
533
534 end function camp_mpi_pack_size_complex
535
536!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
537
538 !> Determines the number of bytes required to pack the given value.
539 integer function camp_mpi_pack_size_integer_array(val, comm)
540
541 !> Value to pack.
542 integer, allocatable, intent(in) :: val(:)
543 !> MPI communicator
544 integer, intent(in), optional :: comm
545
546 integer :: total_size, ierr, l_comm
547
548#ifdef CAMP_USE_MPI
549 logical :: is_allocated
550
551 if (present(comm)) then
552 l_comm = comm
553 else
554 l_comm = mpi_comm_world
555 endif
556
557 total_size = 0
558 is_allocated = allocated(val)
559 if (is_allocated) then
560 call mpi_pack_size(size(val), mpi_integer, l_comm, &
561 total_size, ierr)
562 call camp_mpi_check_ierr(ierr)
563 total_size = total_size + camp_mpi_pack_size_integer(size(val), l_comm)
564 end if
565 total_size = total_size + camp_mpi_pack_size_logical(is_allocated, l_comm)
566#else
567 total_size = 0
568#endif
569
571
573
574!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
575
576 !> Determines the number of bytes required to pack the given value.
577 integer function camp_mpi_pack_size_real_array(val, comm)
578
579 !> Value to pack.
580 real(kind=dp), allocatable, intent(in) :: val(:)
581 !> MPI communicator
582 integer, intent(in), optional :: comm
583
584 integer :: total_size, ierr, l_comm
585
586#ifdef CAMP_USE_MPI
587 logical :: is_allocated
588
589 if (present(comm)) then
590 l_comm = comm
591 else
592 l_comm = mpi_comm_world
593 endif
594
595 total_size = 0
596 is_allocated = allocated(val)
597 if (is_allocated) then
598 call mpi_pack_size(size(val), mpi_double_precision, l_comm, &
599 total_size, ierr)
600 call camp_mpi_check_ierr(ierr)
601 total_size = total_size + camp_mpi_pack_size_integer(size(val), l_comm)
602 end if
603 total_size = total_size + camp_mpi_pack_size_logical(is_allocated, l_comm)
604#else
605 total_size = 0
606#endif
607
609
611
612!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
613
614 !> Determines the number of bytes required to pack the given value.
615 integer function camp_mpi_pack_size_string_array(val, comm)
616
617 !> Value to pack.
618 character(len=*), allocatable, intent(in) :: val(:)
619 !> MPI communicator
620 integer, intent(in), optional :: comm
621
622 integer :: i, total_size, l_comm
623#ifdef CAMP_USE_MPI
624 logical :: is_allocated
625
626 if (present(comm)) then
627 l_comm = comm
628 else
629 l_comm = mpi_comm_world
630 endif
631
632 is_allocated = allocated(val)
633 if (is_allocated) then
634 total_size = camp_mpi_pack_size_integer(size(val), l_comm)
635 do i = 1,size(val)
636 total_size = total_size + camp_mpi_pack_size_string(val(i), l_comm)
637 end do
638 end if
639 total_size = total_size + camp_mpi_pack_size_logical(is_allocated, l_comm)
641#else
642 total_size = 0
643#endif
644
646
647!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
648
649 !> Determines the number of bytes required to pack the given value.
650 integer function camp_mpi_pack_size_real_array_2d(val, comm)
651
652 !> Value to pack.
653 real(kind=dp), allocatable, intent(in) :: val(:,:)
654 !> MPI communicator
655 integer, intent(in), optional :: comm
656
657 integer :: total_size, ierr, l_comm
658
659#ifdef CAMP_USE_MPI
660 logical :: is_allocated
661
662 if (present(comm)) then
663 l_comm = comm
664 else
665 l_comm = mpi_comm_world
666 endif
667
668 total_size = 0
669 is_allocated = allocated(val)
670 if (is_allocated) then
671 call mpi_pack_size(size(val), mpi_double_precision, l_comm, &
672 total_size, ierr)
673 call camp_mpi_check_ierr(ierr)
674 total_size = total_size &
675 + camp_mpi_pack_size_integer(size(val,1), l_comm) &
676 + camp_mpi_pack_size_integer(size(val,2), l_comm)
677 end if
678 total_size = total_size + camp_mpi_pack_size_logical(is_allocated, l_comm)
679#else
680 total_size = 0
681#endif
682
684
686
687!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
688
689 !> Packs the given value into the buffer, advancing position.
690 subroutine camp_mpi_pack_integer(buffer, position, val, comm)
691
692 !> Memory buffer.
693 character, intent(inout) :: buffer(:)
694 !> Current buffer position.
695 integer, intent(inout) :: position
696 !> Value to pack.
697 integer, intent(in) :: val
698 !> MPI communicator
699 integer, intent(in), optional :: comm
700
701#ifdef CAMP_USE_MPI
702 integer :: prev_position, ierr, l_comm
703
704 if (present(comm)) then
705 l_comm = comm
706 else
707 l_comm = mpi_comm_world
708 endif
709
710 prev_position = position
711 call mpi_pack(val, 1, mpi_integer, buffer, size(buffer), &
712 position, l_comm, ierr)
713 call camp_mpi_check_ierr(ierr)
714 call assert(913495993, &
715 position - prev_position <= camp_mpi_pack_size_integer(val, l_comm))
716#endif
717
718 end subroutine camp_mpi_pack_integer
719
720!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
721
722 !> Packs the given value into the buffer, advancing position.
723 subroutine camp_mpi_pack_real(buffer, position, val, comm)
724
725 !> Memory buffer.
726 character, intent(inout) :: buffer(:)
727 !> Current buffer position.
728 integer, intent(inout) :: position
729 !> Value to pack.
730 real(kind=dp), intent(in) :: val
731 !> MPI communicator
732 integer, intent(in), optional :: comm
733
734#ifdef CAMP_USE_MPI
735 integer :: prev_position, ierr, l_comm
736
737 if (present(comm)) then
738 l_comm = comm
739 else
740 l_comm = mpi_comm_world
741 endif
742
743 prev_position = position
744 call mpi_pack(val, 1, mpi_double_precision, buffer, size(buffer), &
745 position, l_comm, ierr)
746 call camp_mpi_check_ierr(ierr)
747 call assert(395354132, &
748 position - prev_position <= camp_mpi_pack_size_real(val, l_comm))
749#endif
750
751 end subroutine camp_mpi_pack_real
752
753!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
754
755 !> Packs the given value into the buffer, advancing position.
756 subroutine camp_mpi_pack_string(buffer, position, val, comm)
757
758 !> Memory buffer.
759 character, intent(inout) :: buffer(:)
760 !> Current buffer position.
761 integer, intent(inout) :: position
762 !> Value to pack.
763 character(len=*), intent(in) :: val
764 !> MPI communicator
765 integer, intent(in), optional :: comm
766
767#ifdef CAMP_USE_MPI
768 integer :: prev_position, length, ierr, l_comm
769
770 if (present(comm)) then
771 l_comm = comm
772 else
773 l_comm = mpi_comm_world
774 endif
775
776 prev_position = position
777 length = len_trim(val)
778 call camp_mpi_pack_integer(buffer, position, length, l_comm)
779 call mpi_pack(val, length, mpi_character, buffer, size(buffer), &
780 position, l_comm, ierr)
781 call camp_mpi_check_ierr(ierr)
782 call assert(607212018, &
783 position - prev_position <= camp_mpi_pack_size_string(val, l_comm))
784#endif
785
786 end subroutine camp_mpi_pack_string
787
788!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
789
790 !> Packs the given value into the buffer, advancing position.
791 subroutine camp_mpi_pack_logical(buffer, position, val, comm)
792
793 !> Memory buffer.
794 character, intent(inout) :: buffer(:)
795 !> Current buffer position.
796 integer, intent(inout) :: position
797 !> Value to pack.
798 logical, intent(in) :: val
799 !> MPI communicator
800 integer, intent(in), optional :: comm
801
802#ifdef CAMP_USE_MPI
803 integer :: prev_position, ierr, l_comm
804
805 if (present(comm)) then
806 l_comm = comm
807 else
808 l_comm = mpi_comm_world
809 endif
810
811 prev_position = position
812 call mpi_pack(val, 1, mpi_logical, buffer, size(buffer), &
813 position, l_comm, ierr)
814 call camp_mpi_check_ierr(ierr)
815 call assert(104535200, &
816 position - prev_position <= camp_mpi_pack_size_logical(val, l_comm))
817#endif
818
819 end subroutine camp_mpi_pack_logical
820
821!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
822
823 !> Packs the given value into the buffer, advancing position.
824 subroutine camp_mpi_pack_complex(buffer, position, val, comm)
825
826 !> Memory buffer.
827 character, intent(inout) :: buffer(:)
828 !> Current buffer position.
829 integer, intent(inout) :: position
830 !> Value to pack.
831 complex(kind=dc), intent(in) :: val
832 !> MPI communicator
833 integer, intent(in), optional :: comm
834
835#ifdef CAMP_USE_MPI
836 integer :: prev_position, ierr, l_comm
837
838 if (present(comm)) then
839 l_comm = comm
840 else
841 l_comm = mpi_comm_world
842 endif
843
844 prev_position = position
845 call mpi_pack(val, 1, mpi_double_complex, buffer, size(buffer), &
846 position, l_comm, ierr)
847 call camp_mpi_check_ierr(ierr)
848 call assert(640416372, &
849 position - prev_position <= camp_mpi_pack_size_complex(val, l_comm))
850#endif
851
852 end subroutine camp_mpi_pack_complex
853
854!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
855
856 !> Packs the given value into the buffer, advancing position.
857 subroutine camp_mpi_pack_integer_array(buffer, position, val, comm)
858
859 !> Memory buffer.
860 character, intent(inout) :: buffer(:)
861 !> Current buffer position.
862 integer, intent(inout) :: position
863 !> Value to pack.
864 integer, allocatable, intent(in) :: val(:)
865 !> MPI communicator
866 integer, intent(in), optional :: comm
867
868#ifdef CAMP_USE_MPI
869 integer :: prev_position, n, ierr, l_comm
870 logical :: is_allocated
871
872 if (present(comm)) then
873 l_comm = comm
874 else
875 l_comm = mpi_comm_world
876 endif
877
878 prev_position = position
879 is_allocated = allocated(val)
880 call camp_mpi_pack_logical(buffer, position, is_allocated, l_comm)
881 if (is_allocated) then
882 n = size(val)
883 call camp_mpi_pack_integer(buffer, position, n, l_comm)
884 call mpi_pack(val, n, mpi_integer, buffer, size(buffer), &
885 position, l_comm, ierr)
886 call camp_mpi_check_ierr(ierr)
887 end if
888 call assert(698601296, &
889 position - prev_position <= &
891#endif
892
893 end subroutine camp_mpi_pack_integer_array
894
895!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
896
897 !> Packs the given value into the buffer, advancing position.
898 subroutine camp_mpi_pack_real_array(buffer, position, val, comm)
899
900 !> Memory buffer.
901 character, intent(inout) :: buffer(:)
902 !> Current buffer position.
903 integer, intent(inout) :: position
904 !> Value to pack.
905 real(kind=dp), allocatable, intent(in) :: val(:)
906 !> MPI communicator
907 integer, intent(in), optional :: comm
908
909#ifdef CAMP_USE_MPI
910 integer :: prev_position, n, ierr, l_comm
911 logical :: is_allocated
912
913 if (present(comm)) then
914 l_comm = comm
915 else
916 l_comm = mpi_comm_world
917 endif
918
919 prev_position = position
920 is_allocated = allocated(val)
921 call camp_mpi_pack_logical(buffer, position, is_allocated, l_comm)
922 if (is_allocated) then
923 n = size(val)
924 call camp_mpi_pack_integer(buffer, position, n, l_comm)
925 call mpi_pack(val, n, mpi_double_precision, buffer, size(buffer), &
926 position, l_comm, ierr)
927 call camp_mpi_check_ierr(ierr)
928 end if
929 call assert(825718791, &
930 position - prev_position <= camp_mpi_pack_size_real_array(val,l_comm))
931#endif
932
933 end subroutine camp_mpi_pack_real_array
934
935!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
936
937 !> Packs the given value into the buffer, advancing position.
938 subroutine camp_mpi_pack_string_array(buffer, position, val, comm)
939
940 !> Memory buffer.
941 character, intent(inout) :: buffer(:)
942 !> Current buffer position.
943 integer, intent(inout) :: position
944 !> Value to pack.
945 character(len=*), allocatable, intent(in) :: val(:)
946 !> MPI communicator
947 integer, intent(in), optional :: comm
948
949#ifdef CAMP_USE_MPI
950 integer :: prev_position, i, n, l_comm
951 logical :: is_allocated
952
953 if (present(comm)) then
954 l_comm = comm
955 else
956 l_comm = mpi_comm_world
957 endif
958
959 prev_position = position
960 is_allocated = allocated(val)
961 call camp_mpi_pack_logical(buffer, position, is_allocated, l_comm)
962 if (is_allocated) then
963 n = size(val)
964 call camp_mpi_pack_integer(buffer, position, n, l_comm)
965 do i = 1,n
966 call camp_mpi_pack_string(buffer, position, val(i), l_comm)
967 end do
968 end if
969 call assert(630900704, &
970 position - prev_position <= &
972#endif
973
974 end subroutine camp_mpi_pack_string_array
975
976!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
977
978 !> Packs the given value into the buffer, advancing position.
979 subroutine camp_mpi_pack_real_array_2d(buffer, position, val, comm)
980
981 !> Memory buffer.
982 character, intent(inout) :: buffer(:)
983 !> Current buffer position.
984 integer, intent(inout) :: position
985 !> Value to pack.
986 real(kind=dp), allocatable, intent(in) :: val(:,:)
987 !> MPI communicator
988 integer, intent(in), optional :: comm
989
990#ifdef CAMP_USE_MPI
991 integer :: prev_position, n1, n2, ierr, l_comm
992 logical :: is_allocated
993
994 if (present(comm)) then
995 l_comm = comm
996 else
997 l_comm = mpi_comm_world
998 endif
999
1000 prev_position = position
1001 is_allocated = allocated(val)
1002 call camp_mpi_pack_logical(buffer, position, is_allocated, l_comm)
1003 if (is_allocated) then
1004 n1 = size(val, 1)
1005 n2 = size(val, 2)
1006 call camp_mpi_pack_integer(buffer, position, n1, l_comm)
1007 call camp_mpi_pack_integer(buffer, position, n2, l_comm)
1008 call mpi_pack(val, n1*n2, mpi_double_precision, buffer, size(buffer), &
1009 position, l_comm, ierr)
1010 call camp_mpi_check_ierr(ierr)
1011 end if
1012 call assert(567349745, &
1013 position - prev_position <= &
1015#endif
1016
1017 end subroutine camp_mpi_pack_real_array_2d
1018
1019!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1020
1021 !> Unpacks the given value from the buffer, advancing position.
1022 subroutine camp_mpi_unpack_integer(buffer, position, val, comm)
1023
1024 !> Memory buffer.
1025 character, intent(inout) :: buffer(:)
1026 !> Current buffer position.
1027 integer, intent(inout) :: position
1028 !> Value to pack.
1029 integer, intent(out) :: val
1030 !> MPI communicator
1031 integer, intent(in), optional :: comm
1032
1033#ifdef CAMP_USE_MPI
1034 integer :: prev_position, ierr, l_comm
1035
1036 if (present(comm)) then
1037 l_comm = comm
1038 else
1039 l_comm = mpi_comm_world
1040 endif
1041
1042 prev_position = position
1043 call mpi_unpack(buffer, size(buffer), position, val, 1, mpi_integer, &
1044 l_comm, ierr)
1045 call camp_mpi_check_ierr(ierr)
1046 call assert(890243339, &
1047 position - prev_position <= camp_mpi_pack_size_integer(val, l_comm))
1048#else
1049 val = 0
1050#endif
1051
1052 end subroutine camp_mpi_unpack_integer
1053
1054!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1055
1056 !> Unpacks the given value from the buffer, advancing position.
1057 subroutine camp_mpi_unpack_real(buffer, position, val, comm)
1058
1059 !> Memory buffer.
1060 character, intent(inout) :: buffer(:)
1061 !> Current buffer position.
1062 integer, intent(inout) :: position
1063 !> Value to pack.
1064 real(kind=dp), intent(out) :: val
1065 !> MPI communicator
1066 integer, intent(in), optional :: comm
1067
1068#ifdef CAMP_USE_MPI
1069 integer :: prev_position, ierr, l_comm
1070
1071 if (present(comm)) then
1072 l_comm = comm
1073 else
1074 l_comm = mpi_comm_world
1075 endif
1076
1077 prev_position = position
1078 call mpi_unpack(buffer, size(buffer), position, val, 1, &
1079 mpi_double_precision, l_comm, ierr)
1080 call camp_mpi_check_ierr(ierr)
1081 call assert(570771632, &
1082 position - prev_position <= camp_mpi_pack_size_real(val, l_comm))
1083#else
1084 val = real(0.0, kind=dp)
1085#endif
1086
1087 end subroutine camp_mpi_unpack_real
1088
1089!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1090
1091 !> Unpacks the given value from the buffer, advancing position.
1092 subroutine camp_mpi_unpack_string(buffer, position, val, comm)
1093
1094 !> Memory buffer.
1095 character, intent(inout) :: buffer(:)
1096 !> Current buffer position.
1097 integer, intent(inout) :: position
1098 !> Value to pack.
1099 character(len=*), intent(out) :: val
1100 !> MPI communicator
1101 integer, intent(in), optional :: comm
1102
1103#ifdef CAMP_USE_MPI
1104 integer :: prev_position, length, ierr, l_comm
1105
1106 if (present(comm)) then
1107 l_comm = comm
1108 else
1109 l_comm = mpi_comm_world
1110 endif
1111
1112 prev_position = position
1113 call camp_mpi_unpack_integer(buffer, position, length, l_comm)
1114 call assert(946399479, length <= len(val))
1115 val = ''
1116 call mpi_unpack(buffer, size(buffer), position, val, length, &
1117 mpi_character, l_comm, ierr)
1118 call camp_mpi_check_ierr(ierr)
1119 call assert(503378058, &
1120 position - prev_position <= camp_mpi_pack_size_string(val, l_comm))
1121#else
1122 val = ''
1123#endif
1124
1125 end subroutine camp_mpi_unpack_string
1126
1127!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1128
1129 !> Unpacks the given value from the buffer, advancing position.
1130 subroutine camp_mpi_unpack_logical(buffer, position, val, comm)
1131
1132 !> Memory buffer.
1133 character, intent(inout) :: buffer(:)
1134 !> Current buffer position.
1135 integer, intent(inout) :: position
1136 !> Value to pack.
1137 logical, intent(out) :: val
1138 !> MPI communicator
1139 integer, intent(in), optional :: comm
1140
1141#ifdef CAMP_USE_MPI
1142 integer :: prev_position, ierr, l_comm
1143
1144 if (present(comm)) then
1145 l_comm = comm
1146 else
1147 l_comm = mpi_comm_world
1148 endif
1149
1150 prev_position = position
1151 call mpi_unpack(buffer, size(buffer), position, val, 1, mpi_logical, &
1152 l_comm, ierr)
1153 call camp_mpi_check_ierr(ierr)
1154 call assert(694750528, &
1155 position - prev_position <= camp_mpi_pack_size_logical(val, l_comm))
1156#else
1157 val = .false.
1158#endif
1159
1160 end subroutine camp_mpi_unpack_logical
1161
1162!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1163
1164 !> Unpacks the given value from the buffer, advancing position.
1165 subroutine camp_mpi_unpack_complex(buffer, position, val, comm)
1166
1167 !> Memory buffer.
1168 character, intent(inout) :: buffer(:)
1169 !> Current buffer position.
1170 integer, intent(inout) :: position
1171 !> Value to pack.
1172 complex(kind=dc), intent(out) :: val
1173 !> MPI communicator
1174 integer, intent(in), optional :: comm
1175
1176#ifdef CAMP_USE_MPI
1177 integer :: prev_position, ierr, l_comm
1178
1179 if (present(comm)) then
1180 l_comm = comm
1181 else
1182 l_comm = mpi_comm_world
1183 endif
1184
1185 prev_position = position
1186 call mpi_unpack(buffer, size(buffer), position, val, 1, &
1187 mpi_double_complex, l_comm, ierr)
1188 call camp_mpi_check_ierr(ierr)
1189 call assert(969672634, &
1190 position - prev_position <= camp_mpi_pack_size_complex(val, l_comm))
1191#else
1192 val = cmplx(0)
1193#endif
1194
1195 end subroutine camp_mpi_unpack_complex
1196
1197!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1198
1199 !> Unpacks the given value from the buffer, advancing position.
1200 subroutine camp_mpi_unpack_integer_array(buffer, position, val, comm)
1201
1202 !> Memory buffer.
1203 character, intent(inout) :: buffer(:)
1204 !> Current buffer position.
1205 integer, intent(inout) :: position
1206 !> Value to pack.
1207 integer, allocatable, intent(inout) :: val(:)
1208 !> MPI communicator
1209 integer, intent(in), optional :: comm
1210
1211#ifdef CAMP_USE_MPI
1212 integer :: prev_position, n, ierr, l_comm
1213 logical :: is_allocated
1214
1215 if (present(comm)) then
1216 l_comm = comm
1217 else
1218 l_comm = mpi_comm_world
1219 endif
1220
1221 prev_position = position
1222 call camp_mpi_unpack_logical(buffer, position, is_allocated, l_comm)
1223 if (allocated(val)) deallocate(val)
1224 if (is_allocated) then
1225 call camp_mpi_unpack_integer(buffer, position, n, l_comm)
1226 allocate(val(n))
1227 call mpi_unpack(buffer, size(buffer), position, val, n, mpi_integer, &
1228 l_comm, ierr)
1229 call camp_mpi_check_ierr(ierr)
1230 end if
1231 call assert(565840919, &
1232 position - prev_position <= &
1234#endif
1235
1236 end subroutine camp_mpi_unpack_integer_array
1237
1238!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1239
1240 !> Unpacks the given value from the buffer, advancing position.
1241 subroutine camp_mpi_unpack_real_array(buffer, position, val, comm)
1242
1243 !> Memory buffer.
1244 character, intent(inout) :: buffer(:)
1245 !> Current buffer position.
1246 integer, intent(inout) :: position
1247 !> Value to pack.
1248 real(kind=dp), allocatable, intent(inout) :: val(:)
1249 !> MPI communicator
1250 integer, intent(in), optional :: comm
1251
1252#ifdef CAMP_USE_MPI
1253 integer :: prev_position, n, ierr, l_comm
1254 logical :: is_allocated
1255
1256 if (present(comm)) then
1257 l_comm = comm
1258 else
1259 l_comm = mpi_comm_world
1260 endif
1261
1262 prev_position = position
1263 call camp_mpi_unpack_logical(buffer, position, is_allocated, l_comm)
1264 if (allocated(val)) deallocate(val)
1265 if (is_allocated) then
1266 call camp_mpi_unpack_integer(buffer, position, n, l_comm)
1267 allocate(val(n))
1268 call mpi_unpack(buffer, size(buffer), position, val, n, &
1269 mpi_double_precision, l_comm, ierr)
1270 call camp_mpi_check_ierr(ierr)
1271 end if
1272 call assert(782875761, &
1273 position - prev_position <= &
1274 camp_mpi_pack_size_real_array(val, l_comm))
1275#endif
1276
1277 end subroutine camp_mpi_unpack_real_array
1278
1279!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1280
1281 !> Unpacks the given value from the buffer, advancing position.
1282 subroutine camp_mpi_unpack_string_array(buffer, position, val, comm)
1283
1284 !> Memory buffer.
1285 character, intent(inout) :: buffer(:)
1286 !> Current buffer position.
1287 integer, intent(inout) :: position
1288 !> Value to pack.
1289 character(len=*), allocatable, intent(inout) :: val(:)
1290 !> MPI communicator
1291 integer, intent(in), optional :: comm
1292
1293#ifdef CAMP_USE_MPI
1294 integer :: prev_position, i, n, l_comm
1295 logical :: is_allocated
1296
1297 if (present(comm)) then
1298 l_comm = comm
1299 else
1300 l_comm = mpi_comm_world
1301 endif
1302
1303 prev_position = position
1304 call camp_mpi_unpack_logical(buffer, position, is_allocated, l_comm)
1305 if (allocated(val)) deallocate(val)
1306 if (is_allocated) then
1307 call camp_mpi_unpack_integer(buffer, position, n, l_comm)
1308 allocate(val(n))
1309 do i = 1,n
1310 call camp_mpi_unpack_string(buffer, position, val(i), l_comm)
1311 end do
1312 end if
1313 call assert(320065648, &
1314 position - prev_position <= &
1316#endif
1317
1318 end subroutine camp_mpi_unpack_string_array
1319
1320!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1321
1322 !> Unpacks the given value from the buffer, advancing position.
1323 subroutine camp_mpi_unpack_real_array_2d(buffer, position, val, comm)
1324
1325 !> Memory buffer.
1326 character, intent(inout) :: buffer(:)
1327 !> Current buffer position.
1328 integer, intent(inout) :: position
1329 !> Value to pack.
1330 real(kind=dp), allocatable, intent(inout) :: val(:,:)
1331 !> MPI communicator
1332 integer, intent(in), optional :: comm
1333
1334#ifdef CAMP_USE_MPI
1335 integer :: prev_position, n1, n2, ierr, l_comm
1336 logical :: is_allocated
1337
1338 if (present(comm)) then
1339 l_comm = comm
1340 else
1341 l_comm = mpi_comm_world
1342 endif
1343
1344 prev_position = position
1345 call camp_mpi_unpack_logical(buffer, position, is_allocated, l_comm)
1346 if (allocated(val)) deallocate(val)
1347 if (is_allocated) then
1348 call camp_mpi_unpack_integer(buffer, position, n1, l_comm)
1349 call camp_mpi_unpack_integer(buffer, position, n2, l_comm)
1350 allocate(val(n1,n2))
1351 call mpi_unpack(buffer, size(buffer), position, val, n1*n2, &
1352 mpi_double_precision, l_comm, ierr)
1353 call camp_mpi_check_ierr(ierr)
1354 end if
1355 call assert(781681739, position - prev_position &
1356 <= camp_mpi_pack_size_real_array_2d(val, l_comm))
1357#endif
1358
1359 end subroutine camp_mpi_unpack_real_array_2d
1360
1361!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1362
1363 !> Computes the average of val across all processes, storing the
1364 !> result in val_avg on the root process.
1365 subroutine camp_mpi_reduce_avg_real(val, val_avg)
1366
1367 !> Value to average.
1368 real(kind=dp), intent(in) :: val
1369 !> Result.
1370 real(kind=dp), intent(out) :: val_avg
1371
1372#ifdef CAMP_USE_MPI
1373 integer :: ierr
1374
1375 call mpi_reduce(val, val_avg, 1, mpi_double_precision, mpi_sum, 0, &
1376 mpi_comm_world, ierr)
1377 call camp_mpi_check_ierr(ierr)
1378 if (camp_mpi_rank() == 0) then
1379 val_avg = val_avg / real(camp_mpi_size(), kind=dp)
1380 end if
1381#else
1382 val_avg = val
1383#endif
1384
1385 end subroutine camp_mpi_reduce_avg_real
1386
1387!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1388
1389 !> Transfer the value between the given processes.
1390 subroutine camp_mpi_transfer_real(from_val, to_val, from_proc, to_proc)
1391
1392 !> Value to send.
1393 real(kind=dp), intent(in) :: from_val
1394 !> Variable to send to.
1395 real(kind=dp), intent(out) :: to_val
1396 !> Process to send from.
1397 integer, intent(in) :: from_proc
1398 !> Process to send to.
1399 integer, intent(in) :: to_proc
1400
1401#ifdef CAMP_USE_MPI
1402 integer :: rank, ierr, status(MPI_STATUS_SIZE)
1403
1404 rank = camp_mpi_rank()
1405 if (from_proc == to_proc) then
1406 if (rank == from_proc) then
1407 to_val = from_val
1408 end if
1409 else
1410 if (rank == from_proc) then
1411 call mpi_send(from_val, 1, mpi_double_precision, to_proc, &
1412 208020430, mpi_comm_world, ierr)
1413 call camp_mpi_check_ierr(ierr)
1414 elseif (rank == to_proc) then
1415 call mpi_recv(to_val, 1, mpi_double_precision, from_proc, &
1416 208020430, mpi_comm_world, status, ierr)
1417 call camp_mpi_check_ierr(ierr)
1418 end if
1419 end if
1420#else
1421 to_val = from_val
1422#endif
1423
1424 end subroutine camp_mpi_transfer_real
1425
1426!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1427
1428 !> Transfer the value between the given processes.
1429 subroutine camp_mpi_transfer_integer(from_val, to_val, from_proc, to_proc)
1430
1431 !> Value to send.
1432 integer, intent(in) :: from_val
1433 !> Variable to send to.
1434 integer, intent(out) :: to_val
1435 !> Process to send from.
1436 integer, intent(in) :: from_proc
1437 !> Process to send to.
1438 integer, intent(in) :: to_proc
1439
1440#ifdef CAMP_USE_MPI
1441 integer :: rank, ierr, status(MPI_STATUS_SIZE)
1442
1443 rank = camp_mpi_rank()
1444 if (from_proc == to_proc) then
1445 if (rank == from_proc) then
1446 to_val = from_val
1447 end if
1448 else
1449 if (rank == from_proc) then
1450 call mpi_send(from_val, 1, mpi_integer, to_proc, &
1451 208020430, mpi_comm_world, ierr)
1452 call camp_mpi_check_ierr(ierr)
1453 elseif (rank == to_proc) then
1454 call mpi_recv(to_val, 1, mpi_integer, from_proc, &
1455 208020430, mpi_comm_world, status, ierr)
1456 call camp_mpi_check_ierr(ierr)
1457 end if
1458 end if
1459#else
1460 to_val = from_val
1461#endif
1462
1463 end subroutine camp_mpi_transfer_integer
1464
1465!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1466
1467 !> Computes the sum of \c val across all processes, storing the
1468 !> result in \c val_sum on the root process.
1469 subroutine camp_mpi_reduce_sum_integer(val, val_sum)
1470
1471 !> Value to sum.
1472 integer, intent(in) :: val
1473 !> Result.
1474 integer, intent(out) :: val_sum
1475
1476#ifdef CAMP_USE_MPI
1477 integer :: ierr
1478
1479 call mpi_reduce(val, val_sum, 1, mpi_integer, mpi_sum, 0, &
1480 mpi_comm_world, ierr)
1481 call camp_mpi_check_ierr(ierr)
1482#else
1483 val_sum = val
1484#endif
1485
1486 end subroutine camp_mpi_reduce_sum_integer
1487
1488!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1489
1490 !> Computes the sum of \c val across all processes, storing the
1491 !> result in \c val_sum on all processes.
1492 subroutine camp_mpi_allreduce_sum_integer(val, val_sum)
1493
1494 !> Value to sum.
1495 integer, intent(in) :: val
1496 !> Result.
1497 integer, intent(out) :: val_sum
1498
1499#ifdef CAMP_USE_MPI
1500 integer :: ierr
1501
1502 call mpi_allreduce(val, val_sum, 1, mpi_integer, mpi_sum, &
1503 mpi_comm_world, ierr)
1504 call camp_mpi_check_ierr(ierr)
1505#else
1506 val_sum = val
1507#endif
1508
1509 end subroutine camp_mpi_allreduce_sum_integer
1510
1511!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1512
1513 !> Computes the average of val across all processes, storing the
1514 !> result in val_avg on the root process.
1515 subroutine camp_mpi_reduce_avg_real_array(val, val_avg)
1516
1517 !> Value to average.
1518 real(kind=dp), intent(in) :: val(:)
1519 !> Result.
1520 real(kind=dp), intent(out) :: val_avg(:)
1521
1522#ifdef CAMP_USE_MPI
1523 integer :: ierr
1524
1525 call assert(915136121, size(val) == size(val_avg))
1526 call mpi_reduce(val, val_avg, size(val), mpi_double_precision, &
1527 mpi_sum, 0, mpi_comm_world, ierr)
1528 call camp_mpi_check_ierr(ierr)
1529 if (camp_mpi_rank() == 0) then
1530 val_avg = val_avg / real(camp_mpi_size(), kind=dp)
1531 end if
1532#else
1533 val_avg = val
1534#endif
1535
1536 end subroutine camp_mpi_reduce_avg_real_array
1537
1538!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1539
1540 !> Computes the average of val across all processes, storing the
1541 !> result in val_avg on the root process.
1542 subroutine camp_mpi_reduce_avg_real_array_2d(val, val_avg)
1543
1544 !> Value to average.
1545 real(kind=dp), intent(in) :: val(:,:)
1546 !> Result.
1547 real(kind=dp), intent(out) :: val_avg(:,:)
1548
1549#ifdef CAMP_USE_MPI
1550 integer :: ierr
1551
1552 call assert(131229046, size(val,1) == size(val_avg,1))
1553 call assert(992122167, size(val,2) == size(val_avg,2))
1554 call mpi_reduce(val, val_avg, size(val), mpi_double_precision, &
1555 mpi_sum, 0, mpi_comm_world, ierr)
1556 call camp_mpi_check_ierr(ierr)
1557 if (camp_mpi_rank() == 0) then
1558 val_avg = val_avg / real(camp_mpi_size(), kind=dp)
1559 end if
1560#else
1561 val_avg = val
1562#endif
1563
1565
1566!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1567
1568 !> Computes the average of val across all processes, storing the
1569 !> result in val_avg on all processes.
1570 subroutine camp_mpi_allreduce_average_real(val, val_avg)
1571
1572 !> Value to average.
1573 real(kind=dp), intent(in) :: val
1574 !> Result.
1575 real(kind=dp), intent(out) :: val_avg
1576
1577#ifdef CAMP_USE_MPI
1578 integer :: ierr
1579
1580 call mpi_allreduce(val, val_avg, 1, mpi_double_precision, mpi_sum, &
1581 mpi_comm_world, ierr)
1582 call camp_mpi_check_ierr(ierr)
1583 val_avg = val_avg / real(camp_mpi_size(), kind=dp)
1584#else
1585 val_avg = val
1586#endif
1587
1588 end subroutine camp_mpi_allreduce_average_real
1589
1590!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1591
1592 !> Computes the average of val across all processes, storing the
1593 !> result in val_avg on all processes.
1595
1596 !> Value to average.
1597 real(kind=dp), intent(in) :: val(:)
1598 !> Result.
1599 real(kind=dp), intent(out) :: val_avg(:)
1600
1601#ifdef CAMP_USE_MPI
1602 integer :: ierr
1603
1604 call assert(948533359, size(val) == size(val_avg))
1605 call mpi_allreduce(val, val_avg, size(val), mpi_double_precision, &
1606 mpi_sum, mpi_comm_world, ierr)
1607 call camp_mpi_check_ierr(ierr)
1608 val_avg = val_avg / real(camp_mpi_size(), kind=dp)
1609#else
1610 val_avg = val
1611#endif
1612
1614
1615!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1616
1617 !> Computes the minimum of val across all processes, storing the
1618 !> result in val_min on all processes.
1619 subroutine camp_mpi_allreduce_min_integer(val, val_min)
1620
1621 !> Value to minimize.
1622 integer, intent(in) :: val
1623 !> Result.
1624 integer, intent(out) :: val_min
1625
1626#ifdef CAMP_USE_MPI
1627 integer :: ierr
1628
1629 call mpi_allreduce(val, val_min, 1, mpi_integer, mpi_min, &
1630 mpi_comm_world, ierr)
1631 call camp_mpi_check_ierr(ierr)
1632#else
1633 val_min = val
1634#endif
1635
1636 end subroutine camp_mpi_allreduce_min_integer
1637
1638!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1639
1640 !> Computes the maximum of val across all processes, storing the
1641 !> result in val_max on all processes.
1642 subroutine camp_mpi_allreduce_max_integer(val, val_max)
1643
1644 !> Value to maximize.
1645 integer, intent(in) :: val
1646 !> Result.
1647 integer, intent(out) :: val_max
1648
1649#ifdef CAMP_USE_MPI
1650 integer :: ierr
1651
1652 call mpi_allreduce(val, val_max, 1, mpi_integer, mpi_max, &
1653 mpi_comm_world, ierr)
1654 call camp_mpi_check_ierr(ierr)
1655#else
1656 val_max = val
1657#endif
1658
1659 end subroutine camp_mpi_allreduce_max_integer
1660
1661!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1662
1663 !> Computes the minimum of val across all processes, storing the
1664 !> result in val_min on all processes.
1665 subroutine camp_mpi_allreduce_min_real(val, val_min)
1666
1667 !> Value to minimize.
1668 real(kind=dp), intent(in) :: val
1669 !> Result.
1670 real(kind=dp), intent(out) :: val_min
1671
1672#ifdef CAMP_USE_MPI
1673 integer :: ierr
1674
1675 call mpi_allreduce(val, val_min, 1, mpi_double_precision, mpi_min, &
1676 mpi_comm_world, ierr)
1677 call camp_mpi_check_ierr(ierr)
1678#else
1679 val_min = val
1680#endif
1681
1682 end subroutine camp_mpi_allreduce_min_real
1683
1684!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1685
1686 !> Computes the maximum of val across all processes, storing the
1687 !> result in val_max on all processes.
1688 subroutine camp_mpi_allreduce_max_real(val, val_max)
1689
1690 !> Value to maximize.
1691 real(kind=dp), intent(in) :: val
1692 !> Result.
1693 real(kind=dp), intent(out) :: val_max
1694
1695#ifdef CAMP_USE_MPI
1696 integer :: ierr
1697
1698 call mpi_allreduce(val, val_max, 1, mpi_double_precision, mpi_max, &
1699 mpi_comm_world, ierr)
1700 call camp_mpi_check_ierr(ierr)
1701#else
1702 val_max = val
1703#endif
1704
1705 end subroutine camp_mpi_allreduce_max_real
1706
1707!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1708
1709 !> Returns whether all processors have the same value.
1710 logical function camp_mpi_allequal_integer(val)
1711
1712 !> Value to compare.
1713 integer, intent(in) :: val
1714
1715#ifdef CAMP_USE_MPI
1716 integer :: min_val, max_val
1717
1718 call camp_mpi_allreduce_min_integer(val, min_val)
1719 call camp_mpi_allreduce_max_integer(val, max_val)
1720 if (min_val == max_val) then
1722 else
1724 end if
1725#else
1727#endif
1728
1729 end function camp_mpi_allequal_integer
1730
1731!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1732
1733 !> Returns whether all processors have the same value.
1734 logical function camp_mpi_allequal_real(val)
1735
1736 !> Value to compare.
1737 real(kind=dp), intent(in) :: val
1738
1739#ifdef CAMP_USE_MPI
1740 real(kind=dp) :: min_val, max_val
1741
1742 call camp_mpi_allreduce_min_real(val, min_val)
1743 call camp_mpi_allreduce_max_real(val, max_val)
1744 if (min_val == max_val) then
1745 camp_mpi_allequal_real = .true.
1746 else
1747 camp_mpi_allequal_real = .false.
1748 end if
1749#else
1750 camp_mpi_allequal_real = .true.
1751#endif
1752
1753 end function camp_mpi_allequal_real
1754
1755!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1756
1757 !> Does an all-to-all transfer of integers.
1758 subroutine camp_mpi_alltoall_integer(send, recv)
1759
1760 !> Values to send (must be one per process).
1761 integer, intent(in) :: send(:)
1762 !> Values to receive (must be one per process).
1763 integer, intent(out) :: recv(size(send))
1764
1765#ifdef CAMP_USE_MPI
1766 integer :: ierr
1767
1768 call mpi_alltoall(send, 1, mpi_integer, recv, 1, mpi_integer, &
1769 mpi_comm_world, ierr)
1770 call camp_mpi_check_ierr(ierr)
1771#else
1772 recv = send
1773#endif
1774
1775 end subroutine camp_mpi_alltoall_integer
1776
1777!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1778
1779 !> Does an allgather of integer arrays (must be the same size on all
1780 !> processes).
1782
1783 !> Values to send on each process.
1784 integer, intent(in) :: send(:)
1785 !> Values to receive (will be the same on all processes.
1786 integer, intent(out) :: recv(:,:)
1787
1788#ifdef CAMP_USE_MPI
1789 integer :: n_proc, n_bin, n_data, ierr
1790 integer, allocatable :: send_buf(:), recv_buf(:)
1791
1792 n_proc = camp_mpi_size()
1793 n_data = size(send, 1)
1794 call assert(353005542, all(shape(recv) == (/n_data, n_proc/)))
1795
1796 ! use a new send_buf to make sure the memory is contiguous
1797 allocate(send_buf(n_data))
1798 allocate(recv_buf(n_data * n_proc))
1799 send_buf = send
1800 call mpi_allgather(send_buf, n_data, mpi_integer, &
1801 recv_buf, n_data, mpi_integer, mpi_comm_world, ierr)
1802 call camp_mpi_check_ierr(ierr)
1803 recv = reshape(recv_buf, (/n_data, n_proc/))
1804 deallocate(send_buf)
1805 deallocate(recv_buf)
1806#else
1807 recv(:, 1) = send
1808#endif
1809
1811
1812!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1813
1814 !> Does an allgather of real arrays (must be the same size on all
1815 !> processes).
1816 subroutine camp_mpi_allgather_real_array(send, recv)
1817
1818 !> Values to send on each process.
1819 real(kind=dp), intent(in) :: send(:)
1820 !> Values to receive (will be the same on all processes.
1821 real(kind=dp), intent(out) :: recv(:,:)
1822
1823#ifdef CAMP_USE_MPI
1824 integer :: n_proc, n_bin, n_data, ierr
1825 real(kind=dp), allocatable :: send_buf(:), recv_buf(:)
1826
1827 n_proc = camp_mpi_size()
1828 n_data = size(send, 1)
1829 call assert(291000580, all(shape(recv) == (/n_data, n_proc/)))
1830
1831 ! use a new send_buf to make sure the memory is contiguous
1832 allocate(send_buf(n_data))
1833 allocate(recv_buf(n_data * n_proc))
1834 send_buf = send
1835 call mpi_allgather(send_buf, n_data, mpi_double_precision, &
1836 recv_buf, n_data, mpi_double_precision, mpi_comm_world, ierr)
1837 call camp_mpi_check_ierr(ierr)
1838 recv = reshape(recv_buf, (/n_data, n_proc/))
1839 deallocate(send_buf)
1840 deallocate(recv_buf)
1841#else
1842 recv(:, 1) = send
1843#endif
1844
1845 end subroutine camp_mpi_allgather_real_array
1846
1847!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1848
1849end module camp_mpi
Interface for to_string functions.
Definition util.F90:32
Wrapper functions for MPI.
Definition mpi.F90:13
subroutine camp_mpi_init()
Initialize MPI.
Definition mpi.F90:58
subroutine camp_mpi_pack_integer_array(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:858
integer function camp_mpi_rank(comm)
Returns the rank of the current process.
Definition mpi.F90:128
subroutine camp_mpi_pack_real(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:724
subroutine camp_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:1620
subroutine camp_mpi_pack_real_array(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:899
subroutine camp_mpi_unpack_complex(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1166
logical function camp_mpi_support()
Whether MPI support is compiled in.
Definition mpi.F90:29
subroutine camp_mpi_bcast_packed(val, comm)
Broadcast the given value from process 0 to all other processes.
Definition mpi.F90:371
subroutine camp_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:1543
subroutine camp_mpi_unpack_real_array_2d(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1324
subroutine camp_mpi_pack_real_array_2d(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:980
subroutine camp_mpi_pack_string_array(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:939
subroutine camp_mpi_test()
Perform basic sanity checks on send/receive.
Definition mpi.F90:180
subroutine camp_mpi_unpack_integer_array(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1201
subroutine camp_mpi_pack_logical(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:792
subroutine camp_mpi_pack_complex(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:825
subroutine camp_mpi_unpack_integer(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1023
subroutine camp_mpi_allgather_integer_array(send, recv)
Does an allgather of integer arrays (must be the same size on all processes).
Definition mpi.F90:1782
subroutine camp_mpi_bcast_string(val, comm)
Broadcast the given value from process 0 to all other processes.
Definition mpi.F90:344
subroutine camp_mpi_unpack_logical(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1131
logical function camp_mpi_allequal_integer(val)
Returns whether all processors have the same value.
Definition mpi.F90:1711
subroutine camp_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:1470
subroutine camp_mpi_finalize()
Shut down MPI.
Definition mpi.F90:91
subroutine camp_mpi_bcast_integer(val, comm)
Broadcast the given value from process 0 to all other processes.
Definition mpi.F90:317
subroutine camp_mpi_abort(status)
Abort the program.
Definition mpi.F90:73
integer function camp_mpi_pack_size_real_array(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:578
subroutine camp_mpi_transfer_integer(from_val, to_val, from_proc, to_proc)
Transfer the value between the given processes.
Definition mpi.F90:1430
subroutine camp_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:1516
integer function camp_mpi_pack_size_integer_array(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:540
integer function camp_mpi_pack_size_logical(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:484
subroutine camp_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:1689
subroutine camp_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:1366
subroutine camp_mpi_unpack_string_array(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1283
integer function camp_mpi_pack_size_complex(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:512
subroutine camp_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:1595
subroutine camp_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:1643
subroutine camp_mpi_barrier(comm)
Synchronize all processes.
Definition mpi.F90:105
subroutine camp_mpi_pack_integer(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:691
integer function camp_mpi_pack_size_string_array(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:616
integer function camp_mpi_pack_size_integer(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:398
integer function camp_mpi_size(comm)
Returns the total number of processes.
Definition mpi.F90:154
subroutine camp_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:1571
subroutine camp_mpi_unpack_string(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1093
subroutine camp_mpi_alltoall_integer(send, recv)
Does an all-to-all transfer of integers.
Definition mpi.F90:1759
subroutine camp_mpi_unpack_real(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1058
subroutine camp_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:1666
subroutine camp_mpi_check_ierr(ierr)
Dies if ierr is not ok.
Definition mpi.F90:42
subroutine camp_mpi_transfer_real(from_val, to_val, from_proc, to_proc)
Transfer the value between the given processes.
Definition mpi.F90:1391
integer function camp_mpi_pack_size_real(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:426
subroutine camp_mpi_allgather_real_array(send, recv)
Does an allgather of real arrays (must be the same size on all processes).
Definition mpi.F90:1817
logical function camp_mpi_allequal_real(val)
Returns whether all processors have the same value.
Definition mpi.F90:1735
subroutine camp_mpi_unpack_real_array(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1242
subroutine camp_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:1493
integer function camp_mpi_pack_size_real_array_2d(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:651
integer function camp_mpi_pack_size_string(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:454
subroutine camp_mpi_pack_string(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:757
Common utility subroutines.
Definition util.F90:9
subroutine assert(code, condition_ok)
Errors unless condition_ok is true.
Definition util.F90:165
character(len=camp_util_convert_string_len) function logical_to_string(val)
Convert a logical to a string format.
Definition util.F90:887
subroutine die(code)
Error immediately.
Definition util.F90:184
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition util.F90:130
character(len=camp_util_convert_string_len) function complex_to_string(val)
Convert a complex to a string format.
Definition util.F90:907
character(len=camp_util_convert_string_len) function integer_to_string(val)
Convert an integer to a string format.
Definition util.F90:839