GADGET-4
hypercube_allgatherv.cc
Go to the documentation of this file.
1/*******************************************************************************
2 * \copyright This file is part of the GADGET4 N-body/SPH code developed
3 * \copyright by Volker Springel. Copyright (C) 2014-2020 by Volker Springel
4 * \copyright (vspringel@mpa-garching.mpg.de) and all contributing authors.
5 *******************************************************************************/
6
12#include "gadgetconfig.h"
13
14#include <math.h>
15#include <mpi.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19
20#include "../data/allvars.h"
21#include "../data/dtypes.h"
22#include "../mpi_utils/mpi_utils.h"
23
24#define TAG 100
25
26int myMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcount, int *displs,
27 MPI_Datatype recvtype, MPI_Comm comm)
28{
29#ifndef MPI_HYPERCUBE_ALLGATHERV
30 return MPI_Allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcount, displs, recvtype, comm);
31#else
32 int ntask, thistask, ptask, ngrp, size_sendtype, size_recvtype;
33 MPI_Status status;
34
35 MPI_Comm_rank(comm, &thistask);
36 MPI_Comm_size(comm, &ntask);
37
38 MPI_Type_size(sendtype, &size_sendtype);
39 MPI_Type_size(recvtype, &size_recvtype);
40
41 for(ptask = 0; ntask > (1 << ptask); ptask++)
42 ;
43
44 for(ngrp = 1; ngrp < (1 << ptask); ngrp++)
45 {
46 int recvtask = thistask ^ ngrp;
47
48 if(recvtask < ntask)
49 {
50 if(sendbuf == MPI_IN_PLACE)
51 myMPI_Sendrecv((char *)recvbuf + displs[thistask] * size_recvtype, recvcount[thistask], sendtype, recvtask, TAG,
52 (char *)recvbuf + displs[recvtask] * size_recvtype, recvcount[recvtask], recvtype, recvtask, TAG, comm,
53 &status);
54 else
55 myMPI_Sendrecv(sendbuf, sendcount, sendtype, recvtask, TAG, (char *)recvbuf + displs[recvtask] * size_recvtype,
56 recvcount[recvtask], recvtype, recvtask, TAG, comm, &status);
57 }
58 }
59
60 if(sendbuf != MPI_IN_PLACE)
61 if((char *)sendbuf != (char *)recvbuf + displs[thistask] * size_recvtype)
62 memcpy((char *)recvbuf + displs[thistask] * size_recvtype, sendbuf, sendcount * size_sendtype);
63
64 return 0;
65
66#endif
67}
int myMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcount, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
#define TAG
int myMPI_Sendrecv(void *sendbuf, size_t sendcount, MPI_Datatype sendtype, int dest, int sendtag, void *recvbuf, size_t recvcount, MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, MPI_Status *status)