Branch data Line data Source code
1 : : !{\src2tex{textfont=tt}}
2 : : !!****f* ABINIT/xmpi_send
3 : : !! NAME
4 : : !! xmpi_send
5 : : !!
6 : : !! FUNCTION
7 : : !! This module contains functions that calls MPI routine MPI_SEND,
8 : : !! to send data from one processor to another,
9 : : !! if we compile the code using the MPI CPP flags.
10 : : !! xmpi_send is the generic function.
11 : : !!
12 : : !! COPYRIGHT
13 : : !! Copyright (C) 2001-2026 ABINIT group
14 : : !! This file is distributed under the terms of the
15 : : !! GNU General Public License, see ~ABINIT/COPYING
16 : : !! or http://www.gnu.org/copyleft/gpl.txt .
17 : : !!
18 : : !! SOURCE
19 : : !!***
20 : :
21 : : !!****f* ABINIT/xmpi_send_char
22 : : !! NAME
23 : : !! xmpi_send_char
24 : : !!
25 : : !! FUNCTION
26 : : !! Sends data from one proc to another.
27 : : !! Target: character.
28 : : !!
29 : : !! INPUTS
30 : : !! dest :: rank of destination process
31 : : !! tag :: integer message tag
32 : : !! comm :: MPI communicator
33 : : !!
34 : : !! OUTPUT
35 : : !! ier= exit status, a non-zero value meaning there is an error
36 : : !!
37 : : !! SIDE EFFECTS
38 : : !! xval= buffer array
39 : : !!
40 : : !! SOURCE
41 : :
42 : 88 : subroutine xmpi_send_char(xval,dest,tag,comm,ier)
43 : :
44 : : !Arguments-------------------------
45 : : character(len=*),intent(inout),target :: xval
46 : : integer ,intent(in) :: dest,tag,comm
47 : : integer ,intent(out) :: ier
48 : :
49 : : !Local variables-------------------
50 : : #if defined HAVE_MPI
51 : : integer :: my_tag
52 : 88 : character,pointer :: arr_xval(:)
53 : : type(c_ptr) :: cptr
54 : : #endif
55 : :
56 : : ! *************************************************************************
57 : :
58 : 88 : ier=0
59 : : #if defined HAVE_MPI
60 : 88 : if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
61 : 88 : my_tag = MOD(tag,xmpi_tag_ub)
62 [ + + ]: 176 : cptr=c_loc(xval) ; call c_f_pointer(cptr,arr_xval,[len(xval)])
63 [ - + ]: 88 : call MPI_SEND(arr_xval,len(xval),MPI_CHARACTER,dest,my_tag,comm,ier)
64 : : end if
65 : : #endif
66 : :
67 [ + - ]: 88 : end subroutine xmpi_send_char
68 : : !!***
69 : :
70 : : !!****f* ABINIT/xmpi_send_intv
71 : : !! NAME
72 : : !! xmpi_send_intv
73 : : !!
74 : : !! FUNCTION
75 : : !! Sends data from one processor to another.
76 : : !! Target: single integer.
77 : : !!
78 : : !! INPUTS
79 : : !! dest :: rank of destination process
80 : : !! tag :: integer message tag
81 : : !! comm :: MPI communicator
82 : : !!
83 : : !! OUTPUT
84 : : !! ier= exit status, a non-zero value meaning there is an error
85 : : !!
86 : : !! SIDE EFFECTS
87 : : !! xval= buffer array
88 : : !!
89 : : !! SOURCE
90 : :
91 : 11104 : subroutine xmpi_send_intv(xval,dest,tag,comm,ier)
92 : :
93 : : !Arguments-------------------------
94 : : integer,intent(inout) :: xval
95 : : integer,intent(in) :: dest,tag,comm
96 : : integer,intent(out) :: ier
97 : :
98 : : !Local variables-------------------
99 : : #if defined HAVE_MPI
100 : : integer :: my_tag
101 : : #endif
102 : :
103 : : ! *************************************************************************
104 : :
105 : 11104 : ier=0
106 : : #if defined HAVE_MPI
107 [ + - ]: 11104 : if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
108 : 11104 : my_tag = MOD(tag,xmpi_tag_ub)
109 [ + + ]: 22208 : call MPI_SEND([xval],1,MPI_INTEGER,dest,my_tag,comm,ier)
110 : : end if
111 : : #endif
112 : :
113 : 11104 : end subroutine xmpi_send_intv
114 : :
115 : : !!***
116 : :
117 : : !!****f* ABINIT/xmpi_send_int1d
118 : : !! NAME
119 : : !! xmpi_send_int1d
120 : : !!
121 : : !! FUNCTION
122 : : !! Sends data from one processor to another.
123 : : !! Target: integer one-dimensional arrays.
124 : : !!
125 : : !! INPUTS
126 : : !! dest :: rank of destination process
127 : : !! tag :: integer message tag
128 : : !! comm :: MPI communicator
129 : : !!
130 : : !! OUTPUT
131 : : !! ier= exit status, a non-zero value meaning there is an error
132 : : !!
133 : : !! SIDE EFFECTS
134 : : !! xval= buffer array
135 : : !!
136 : : !! SOURCE
137 : :
138 [ - + ]: 18360 : subroutine xmpi_send_int1d(xval,dest,tag,comm,ier)
139 : :
140 : : !Arguments-------------------------
141 : : integer, DEV_CONTARRD intent(inout) :: xval(:)
142 : : integer,intent(in) :: dest,tag,comm
143 : : integer,intent(out) :: ier
144 : :
145 : : !Local variables-------------------
146 : : #if defined HAVE_MPI
147 : : integer :: my_tag, n1
148 : : #endif
149 : :
150 : : ! *************************************************************************
151 : :
152 : 18360 : ier=0
153 : : #if defined HAVE_MPI
154 [ + - ]: 18360 : if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
155 : 18360 : n1=size(xval,dim=1)
156 : 18360 : my_tag = MOD(tag,xmpi_tag_ub)
157 [ - + ]: 18360 : call MPI_SEND(xval,n1,MPI_INTEGER,dest,my_tag,comm,ier)
158 : : end if
159 : : #endif
160 : :
161 : 18360 : end subroutine xmpi_send_int1d
162 : : !!***
163 : :
164 : : !!****f* ABINIT/xmpi_send_int2d
165 : : !! NAME
166 : : !! xmpi_send_int2d
167 : : !!
168 : : !! FUNCTION
169 : : !! Sends data from one proc to another.
170 : : !! Target: integer two-dimensional arrays.
171 : : !!
172 : : !! INPUTS
173 : : !! dest :: rank of destination process
174 : : !! tag :: integer message tag
175 : : !! comm :: MPI communicator
176 : : !!
177 : : !! OUTPUT
178 : : !! ier= exit status, a non-zero value meaning there is an error
179 : : !!
180 : : !! SIDE EFFECTS
181 : : !! xval= buffer array
182 : : !!
183 : : !! SOURCE
184 : :
185 [ - + ]: 3672 : subroutine xmpi_send_int2d(xval,dest,tag,comm,ier)
186 : :
187 : : !Arguments-------------------------
188 : : integer,intent(inout) :: xval(:,:)
189 : : integer ,intent(in) :: dest,tag,comm
190 : : integer ,intent(out) :: ier
191 : :
192 : : !Local variables-------------------
193 : : #if defined HAVE_MPI
194 : : integer :: my_dt,my_op,n1,n2,my_tag
195 : : integer(kind=int64) :: ntot
196 : : #endif
197 : :
198 : : ! *************************************************************************
199 : :
200 : 3672 : ier=0
201 : : #if defined HAVE_MPI
202 [ + - ]: 3672 : if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
203 : 3672 : n1=size(xval,dim=1)
204 : 3672 : n2=size(xval,dim=2)
205 : 3672 : my_tag = MOD(tag,xmpi_tag_ub)
206 : :
207 : : !This product of dimensions can be greater than a 32bit integer
208 : : !We use a INT64 to store it. If it is too large, we switch to an
209 : : !alternate routine because MPI<4 doesnt handle 64 bit counts.
210 : 3672 : ntot=int(n1,kind=int64)*n2
211 : :
212 [ + - ]: 3672 : if (ntot<=xmpi_maxint32_64) then
213 [ - + ]: 3672 : call MPI_SEND(xval,n1*n2,MPI_INTEGER,dest,my_tag,comm,ier)
214 : : else
215 : 0 : call xmpi_largetype_create(ntot,MPI_INTEGER,my_dt,my_op,MPI_OP_NULL)
216 [ # # ]: 0 : call MPI_SEND(xval,1,my_dt,dest,my_tag,comm,ier)
217 : 0 : call xmpi_largetype_free(my_dt,my_op)
218 : : end if
219 : :
220 : : end if
221 : : #endif
222 : :
223 : 3672 : end subroutine xmpi_send_int2d
224 : : !!***
225 : :
226 : : !!****f* ABINIT/xmpi_send_int3d
227 : : !! NAME
228 : : !! xmpi_send_int3d
229 : : !!
230 : : !! FUNCTION
231 : : !! Sends data from one proc to another.
232 : : !! Target: integer three-dimensional arrays.
233 : : !!
234 : : !! INPUTS
235 : : !! dest :: rank of destination process
236 : : !! tag :: integer message tag
237 : : !! comm :: MPI communicator
238 : : !!
239 : : !! OUTPUT
240 : : !! ier= exit status, a non-zero value meaning there is an error
241 : : !!
242 : : !! SIDE EFFECTS
243 : : !! xval= buffer array
244 : : !!
245 : : !! SOURCE
246 : :
247 [ - + ]: 3672 : subroutine xmpi_send_int3d(xval,dest,tag,comm,ier)
248 : :
249 : : !Arguments-------------------------
250 : : integer,intent(inout) :: xval(:,:,:)
251 : : integer ,intent(in) :: dest,tag,comm
252 : : integer ,intent(out) :: ier
253 : :
254 : : !Local variables-------------------
255 : : #if defined HAVE_MPI
256 : : integer :: my_dt,my_op,n1,n2,n3,my_tag
257 : : integer(kind=int64) :: ntot
258 : : #endif
259 : :
260 : : ! *************************************************************************
261 : :
262 : 3672 : ier=0
263 : : #if defined HAVE_MPI
264 [ + - ]: 3672 : if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
265 : 3672 : n1=size(xval,dim=1)
266 : 3672 : n2=size(xval,dim=2)
267 : 3672 : n3=size(xval,dim=3)
268 : 3672 : my_tag = MOD(tag,xmpi_tag_ub)
269 : :
270 : : !This product of dimensions can be greater than a 32bit integer
271 : : !We use a INT64 to store it. If it is too large, we switch to an
272 : : !alternate routine because MPI<4 doesnt handle 64 bit counts.
273 : 3672 : ntot=int(n1,kind=int64)*n2*n3
274 : :
275 [ + - ]: 3672 : if (ntot<=xmpi_maxint32_64) then
276 [ - + ]: 3672 : call MPI_SEND(xval,n1*n2*n3,MPI_INTEGER,dest,my_tag,comm,ier)
277 : : else
278 : 0 : call xmpi_largetype_create(ntot,MPI_INTEGER,my_dt,my_op,MPI_OP_NULL)
279 [ # # ]: 0 : call MPI_SEND(xval,1,my_dt,dest,my_tag,comm,ier)
280 : 0 : call xmpi_largetype_free(my_dt,my_op)
281 : : end if
282 : :
283 : : end if
284 : : #endif
285 : :
286 : 3672 : end subroutine xmpi_send_int3d
287 : : !!***
288 : :
289 : : !!****f* ABINIT/xmpi_send_dp
290 : : !! NAME
291 : : !! xmpi_send_dp
292 : : !!
293 : : !! FUNCTION
294 : : !! Sends data from one proc to another.
295 : : !! Target: double precision value.
296 : : !!
297 : : !! INPUTS
298 : : !! dest :: rank of destination process
299 : : !! tag :: integer message tag
300 : : !! comm :: MPI communicator
301 : : !!
302 : : !! OUTPUT
303 : : !! ier= exit status, a non-zero value meaning there is an error
304 : : !!
305 : : !! SIDE EFFECTS
306 : : !! xval= buffer array
307 : : !!
308 : : !! SOURCE
309 : :
310 : 3760 : subroutine xmpi_send_dp(xval,dest,tag,comm,ier)
311 : :
312 : : !Arguments-------------------------
313 : : real(dp), DEV_CONTARRD intent(inout) :: xval
314 : : integer ,intent(in) :: dest,tag,comm
315 : : integer ,intent(out) :: ier
316 : :
317 : : !Local variables-------------------
318 : : #if defined HAVE_MPI
319 : : integer :: my_tag
320 : : #endif
321 : :
322 : : ! *************************************************************************
323 : :
324 : 3760 : ier=0
325 : : #if defined HAVE_MPI
326 [ + - ]: 3760 : if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
327 : 3760 : my_tag = MOD(tag,xmpi_tag_ub)
328 [ + + ]: 7520 : call MPI_SEND([xval],1,MPI_DOUBLE_PRECISION,dest,my_tag,comm,ier)
329 : : end if
330 : : #endif
331 : :
332 : 3760 : end subroutine xmpi_send_dp
333 : : !!***
334 : :
335 : : !!****f* ABINIT/xmpi_send_dp1d
336 : : !! NAME
337 : : !! xmpi_send_dp1d
338 : : !!
339 : : !! FUNCTION
340 : : !! Sends data from one proc to another.
341 : : !! Target: double precision one-dimensional arrays.
342 : : !!
343 : : !! INPUTS
344 : : !! dest :: rank of destination process
345 : : !! tag :: integer message tag
346 : : !! comm :: MPI communicator
347 : : !!
348 : : !! OUTPUT
349 : : !! ier= exit status, a non-zero value meaning there is an error
350 : : !!
351 : : !! SIDE EFFECTS
352 : : !! xval= buffer array
353 : : !!
354 : : !! SOURCE
355 : :
356 [ # # ]: 0 : subroutine xmpi_send_dp1d(xval,dest,tag,comm,ier)
357 : :
358 : : !Arguments-------------------------
359 : : real(dp), DEV_CONTARRD intent(inout) :: xval(:)
360 : : integer ,intent(in) :: dest,tag,comm
361 : : integer ,intent(out) :: ier
362 : :
363 : : !Local variables-------------------
364 : : #if defined HAVE_MPI
365 : : integer :: n1,my_tag
366 : : #endif
367 : :
368 : : ! *************************************************************************
369 : :
370 : 0 : ier=0
371 : : #if defined HAVE_MPI
372 [ # # ]: 0 : if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
373 : 0 : n1=size(xval,dim=1)
374 : 0 : my_tag = MOD(tag,xmpi_tag_ub)
375 [ # # ]: 0 : call MPI_SEND(xval,n1,MPI_DOUBLE_PRECISION,dest,my_tag,comm,ier)
376 : : end if
377 : : #endif
378 : :
379 : 0 : end subroutine xmpi_send_dp1d
380 : : !!***
381 : :
382 : : !!****f* ABINIT/xmpi_send_dp2d
383 : : !! NAME
384 : : !! xmpi_send_dp2d
385 : : !!
386 : : !! FUNCTION
387 : : !! Sends data from one proc to another.
388 : : !! Target: double precision two-dimensional arrays.
389 : : !!
390 : : !! INPUTS
391 : : !! dest :: rank of destination process
392 : : !! tag :: integer message tag
393 : : !! comm :: MPI communicator
394 : : !!
395 : : !! OUTPUT
396 : : !! ier= exit status, a non-zero value meaning there is an error
397 : : !!
398 : : !! SIDE EFFECTS
399 : : !! xval= buffer array
400 : : !!
401 : : !! SOURCE
402 : :
403 [ - + ]: 138163 : subroutine xmpi_send_dp2d(xval,dest,tag,comm,ier)
404 : :
405 : : !Arguments-------------------------
406 : : real(dp), DEV_CONTARRD intent(inout) :: xval(:,:)
407 : : integer ,intent(in) :: dest,tag,comm
408 : : integer ,intent(out) :: ier
409 : :
410 : : !Local variables-------------------
411 : : #if defined HAVE_MPI
412 : : integer :: my_dt,my_op,n1,n2,my_tag
413 : : integer(kind=int64) :: ntot
414 : : #endif
415 : :
416 : : ! *************************************************************************
417 : :
418 : 138163 : ier=0
419 : : #if defined HAVE_MPI
420 [ + - ]: 138163 : if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
421 : 138163 : n1=size(xval,dim=1)
422 : 138163 : n2=size(xval,dim=2)
423 : 138163 : my_tag = MOD(tag,xmpi_tag_ub)
424 : :
425 : : !This product of dimensions can be greater than a 32bit integer
426 : : !We use a INT64 to store it. If it is too large, we switch to an
427 : : !alternate routine because MPI<4 doesnt handle 64 bit counts.
428 : 138163 : ntot=int(n1,kind=int64)*n2
429 : :
430 [ + - ]: 138163 : if (ntot<=xmpi_maxint32_64) then
431 [ - + ]: 138163 : call MPI_SEND(xval,n1*n2,MPI_DOUBLE_PRECISION,dest,my_tag,comm,ier)
432 : : else
433 : 0 : call xmpi_largetype_create(ntot,MPI_DOUBLE_PRECISION,my_dt,my_op,MPI_OP_NULL)
434 [ # # ]: 0 : call MPI_SEND(xval,1,my_dt,dest,my_tag,comm,ier)
435 : 0 : call xmpi_largetype_free(my_dt,my_op)
436 : : end if
437 : :
438 : : end if
439 : : #endif
440 : :
441 : 138163 : end subroutine xmpi_send_dp2d
442 : : !!***
443 : :
444 : : !!****f* ABINIT/xmpi_send_dp3d
445 : : !! NAME
446 : : !! xmpi_send_dp3d
447 : : !!
448 : : !! FUNCTION
449 : : !! Sends data from one proc to another.
450 : : !! Target: double precision three-dimensional arrays.
451 : : !!
452 : : !! INPUTS
453 : : !! dest :: rank of destination process
454 : : !! tag :: integer message tag
455 : : !! comm :: MPI communicator
456 : : !!
457 : : !! OUTPUT
458 : : !! ier= exit status, a non-zero value meaning there is an error
459 : : !!
460 : : !! SIDE EFFECTS
461 : : !! xval= buffer array
462 : : !!
463 : : !! SOURCE
464 : :
465 [ - + ]: 35520 : subroutine xmpi_send_dp3d(xval,dest,tag,comm,ier)
466 : :
467 : : !Arguments-------------------------
468 : : real(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:)
469 : : integer ,intent(in) :: dest,tag,comm
470 : : integer ,intent(out) :: ier
471 : :
472 : : !Local variables-------------------
473 : : #if defined HAVE_MPI
474 : : integer :: my_dt,my_op,n1,n2,n3,my_tag
475 : : integer(kind=int64) :: ntot
476 : : #endif
477 : :
478 : : ! *************************************************************************
479 : :
480 : 35520 : ier=0
481 : : #if defined HAVE_MPI
482 [ + - ]: 35520 : if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
483 : 35520 : n1=size(xval,dim=1)
484 : 35520 : n2=size(xval,dim=2)
485 : 35520 : n3=size(xval,dim=3)
486 : 35520 : my_tag = MOD(tag,xmpi_tag_ub)
487 : :
488 : : !This product of dimensions can be greater than a 32bit integer
489 : : !We use a INT64 to store it. If it is too large, we switch to an
490 : : !alternate routine because MPI<4 doesnt handle 64 bit counts.
491 : 35520 : ntot=int(n1,kind=int64)*n2*n3
492 : :
493 [ + - ]: 35520 : if (ntot<=xmpi_maxint32_64) then
494 [ - + ]: 35520 : call MPI_SEND(xval,n1*n2*n3,MPI_DOUBLE_PRECISION,dest,my_tag,comm,ier)
495 : : else
496 : 0 : call xmpi_largetype_create(ntot,MPI_DOUBLE_PRECISION,my_dt,my_op,MPI_OP_NULL)
497 [ # # ]: 0 : call MPI_SEND(xval,1,my_dt,dest,my_tag,comm,ier)
498 : 0 : call xmpi_largetype_free(my_dt,my_op)
499 : : end if
500 : :
501 : : end if
502 : : #endif
503 : :
504 : 35520 : end subroutine xmpi_send_dp3d
505 : : !!***
506 : : !
507 : :
508 : : !!****f* ABINIT/xmpi_send_dp4d
509 : : !! NAME
510 : : !! xmpi_send_dp4d
511 : : !!
512 : : !! FUNCTION
513 : : !! Sends data from one proc to another.
514 : : !! Target: double precision four-dimensional arrays.
515 : : !!
516 : : !! INPUTS
517 : : !! dest :: rank of destination process
518 : : !! tag :: integer message tag
519 : : !! comm :: MPI communicator
520 : : !!
521 : : !! OUTPUT
522 : : !! ier= exit status, a non-zero value meaning there is an error
523 : : !!
524 : : !! SIDE EFFECTS
525 : : !! xval= buffer array
526 : : !!
527 : : !! SOURCE
528 : :
529 [ # # ]: 0 : subroutine xmpi_send_dp4d(xval,dest,tag,comm,ier)
530 : :
531 : : !Arguments-------------------------
532 : : real(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:)
533 : : integer ,intent(in) :: dest,tag,comm
534 : : integer ,intent(out) :: ier
535 : :
536 : : !Local variables-------------------
537 : : #if defined HAVE_MPI
538 : : integer :: my_dt,my_op,n1,n2,n3,n4,my_tag
539 : : integer(kind=int64) :: ntot
540 : : #endif
541 : :
542 : : ! *************************************************************************
543 : :
544 : 0 : ier=0
545 : : #if defined HAVE_MPI
546 [ # # ]: 0 : if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
547 : 0 : n1=size(xval,dim=1)
548 : 0 : n2=size(xval,dim=2)
549 : 0 : n3=size(xval,dim=3)
550 : 0 : n4=size(xval,dim=4)
551 : 0 : my_tag = MOD(tag,xmpi_tag_ub)
552 : :
553 : : !This product of dimensions can be greater than a 32bit integer
554 : : !We use a INT64 to store it. If it is too large, we switch to an
555 : : !alternate routine because MPI<4 doesnt handle 64 bit counts.
556 : 0 : ntot=int(n1,kind=int64)*n2*n3*n4
557 : :
558 [ # # ]: 0 : if (ntot<=xmpi_maxint32_64) then
559 [ # # ]: 0 : call MPI_SEND(xval,n1*n2*n3*n4,MPI_DOUBLE_PRECISION,dest,my_tag,comm,ier)
560 : : else
561 : 0 : call xmpi_largetype_create(ntot,MPI_DOUBLE_PRECISION,my_dt,my_op,MPI_OP_NULL)
562 [ # # ]: 0 : call MPI_SEND(xval,1,my_dt,dest,my_tag,comm,ier)
563 : 0 : call xmpi_largetype_free(my_dt,my_op)
564 : : end if
565 : :
566 : : end if
567 : : #endif
568 : :
569 : 0 : end subroutine xmpi_send_dp4d
570 : : !!***
571 : : !
|