1095059a4SDave May /* 2095059a4SDave May Build a few basic tools to help with partitioned domains. 3095059a4SDave May 4095059a4SDave May 1) 5095059a4SDave May On each processor, have a DomainExchangerTopology. 6095059a4SDave May This is a doubly-connected edge list which enumerates the 7095059a4SDave May communication paths between connected processors. By numbering 8da81f932SPierre Jolivet these paths we can always uniquely assign message identifiers. 9095059a4SDave May 10095059a4SDave May edge 11095059a4SDave May 10 12095059a4SDave May proc ---------> proc 13095059a4SDave May 0 <-------- 1 14095059a4SDave May 11 15095059a4SDave May twin 16095059a4SDave May 172d4ee042Sprj- Eg: Proc 0 send to proc 1 with message id is 10. To receive the correct 18095059a4SDave May message, proc 1 looks for the edge connected to proc 0, and then the 192d4ee042Sprj- message id comes from the twin of that edge 20095059a4SDave May 21095059a4SDave May 2) 22095059a4SDave May A DomainExchangerArrayPacker. 23095059a4SDave May A little function which given a piece of data, will memcpy the data into 24095059a4SDave May an array (which will be sent to procs) into the correct place. 25095059a4SDave May 26095059a4SDave May On Proc 1 we sent data to procs 0,2,3. The data is on different lengths. 27095059a4SDave May All data gets jammed into single array. Need to "jam" data into correct locations 28095059a4SDave May The Packer knows how much is to going to each processor and keeps track of the inserts 29095059a4SDave May so as to avoid ever packing TOO much into one slot, and inevatbly corrupting some memory 30095059a4SDave May 31095059a4SDave May data to 0 data to 2 data to 3 32095059a4SDave May 33095059a4SDave May |--------|-----------------|--| 34095059a4SDave May 35095059a4SDave May User has to unpack message themselves. I can get you the pointer for each i 36095059a4SDave May entry, but you'll have to cast it to the appropriate data type. 37095059a4SDave May 38095059a4SDave May Phase A: Build topology 39095059a4SDave May 40095059a4SDave May Phase B: Define message lengths 41095059a4SDave May 42095059a4SDave May Phase C: Pack data 43095059a4SDave May 44095059a4SDave May Phase D: Send data 45095059a4SDave May 462064fc68SDave May + Constructor 4777048351SPatrick Sanan DMSwarmDataExCreate() 482064fc68SDave May + Phase A 4977048351SPatrick Sanan DMSwarmDataExTopologyInitialize() 5077048351SPatrick Sanan DMSwarmDataExTopologyAddNeighbour() 5177048351SPatrick Sanan DMSwarmDataExTopologyAddNeighbour() 5277048351SPatrick Sanan DMSwarmDataExTopologyFinalize() 532064fc68SDave May + Phase B 5477048351SPatrick Sanan DMSwarmDataExZeroAllSendCount() 5577048351SPatrick Sanan DMSwarmDataExAddToSendCount() 5677048351SPatrick Sanan DMSwarmDataExAddToSendCount() 5777048351SPatrick Sanan DMSwarmDataExAddToSendCount() 582064fc68SDave May + Phase C 5977048351SPatrick Sanan DMSwarmDataExPackInitialize() 6077048351SPatrick Sanan DMSwarmDataExPackData() 6177048351SPatrick Sanan DMSwarmDataExPackData() 6277048351SPatrick Sanan DMSwarmDataExPackFinalize() 632064fc68SDave May +Phase D 6477048351SPatrick Sanan DMSwarmDataExBegin() 652064fc68SDave May ... perform any calculations ... 6677048351SPatrick Sanan DMSwarmDataExEnd() 67095059a4SDave May 682064fc68SDave May ... user calls any getters here ... 69095059a4SDave May 70095059a4SDave May */ 71095059a4SDave May #include <petscvec.h> 72095059a4SDave May #include <petscmat.h> 736497c311SBarry Smith #include <petsc/private/petscimpl.h> 74095059a4SDave May 75279f676cSBarry Smith #include "../src/dm/impls/swarm/data_ex.h" 76095059a4SDave May 77095059a4SDave May const char *status_names[] = {"initialized", "finalized", "unknown"}; 78095059a4SDave May 79ed923d71SDave May PETSC_EXTERN PetscLogEvent DMSWARM_DataExchangerTopologySetup; 80ed923d71SDave May PETSC_EXTERN PetscLogEvent DMSWARM_DataExchangerBegin; 81ed923d71SDave May PETSC_EXTERN PetscLogEvent DMSWARM_DataExchangerEnd; 82ed923d71SDave May PETSC_EXTERN PetscLogEvent DMSWARM_DataExchangerSendCount; 83ed923d71SDave May PETSC_EXTERN PetscLogEvent DMSWARM_DataExchangerPack; 84095059a4SDave May 85d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExCreate(MPI_Comm comm, const PetscInt count, DMSwarmDataEx *ex) 86d71ae5a4SJacob Faibussowitsch { 8777048351SPatrick Sanan DMSwarmDataEx d; 88095059a4SDave May 89521f74f9SMatthew G. Knepley PetscFunctionBegin; 909566063dSJacob Faibussowitsch PetscCall(PetscNew(&d)); 919566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_dup(comm, &d->comm)); 929566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(d->comm, &d->rank)); 93095059a4SDave May 94095059a4SDave May d->instance = count; 95095059a4SDave May 96095059a4SDave May d->topology_status = DEOBJECT_STATE_UNKNOWN; 97095059a4SDave May d->message_lengths_status = DEOBJECT_STATE_UNKNOWN; 98095059a4SDave May d->packer_status = DEOBJECT_STATE_UNKNOWN; 99095059a4SDave May d->communication_status = DEOBJECT_STATE_UNKNOWN; 100095059a4SDave May 101095059a4SDave May d->n_neighbour_procs = -1; 102095059a4SDave May d->neighbour_procs = NULL; 103095059a4SDave May 104095059a4SDave May d->messages_to_be_sent = NULL; 105095059a4SDave May d->message_offsets = NULL; 106095059a4SDave May d->messages_to_be_recvieved = NULL; 107095059a4SDave May 10878c64234SJose E. Roman d->unit_message_size = (size_t)-1; 109095059a4SDave May d->send_message = NULL; 110095059a4SDave May d->send_message_length = -1; 111095059a4SDave May d->recv_message = NULL; 112095059a4SDave May d->recv_message_length = -1; 113095059a4SDave May d->total_pack_cnt = -1; 114095059a4SDave May d->pack_cnt = NULL; 115095059a4SDave May 116095059a4SDave May d->send_tags = NULL; 117095059a4SDave May d->recv_tags = NULL; 118095059a4SDave May 119095059a4SDave May d->_stats = NULL; 120095059a4SDave May d->_requests = NULL; 121521f74f9SMatthew G. Knepley *ex = d; 1223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 123095059a4SDave May } 124095059a4SDave May 125298827fbSBarry Smith /* 1269dddd249SSatish Balay This code is horrible, who let it get into main. 127298827fbSBarry Smith 128298827fbSBarry Smith Should be printing to a viewer, should not be using PETSC_COMM_WORLD 129298827fbSBarry Smith 130298827fbSBarry Smith */ 131d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExView(DMSwarmDataEx d) 132d71ae5a4SJacob Faibussowitsch { 133095059a4SDave May PetscMPIInt p; 134095059a4SDave May 135095059a4SDave May PetscFunctionBegin; 13663a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "DMSwarmDataEx: instance=%" PetscInt_FMT "\n", d->instance)); 1379566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " topology status: %s \n", status_names[d->topology_status])); 1389566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " message lengths status: %s \n", status_names[d->message_lengths_status])); 1399566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " packer status status: %s \n", status_names[d->packer_status])); 1409566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " communication status: %s \n", status_names[d->communication_status])); 141095059a4SDave May 142095059a4SDave May if (d->topology_status == DEOBJECT_FINALIZED) { 1439566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Topology:\n")); 1449566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, " [%d] neighbours: %d \n", d->rank, d->n_neighbour_procs)); 14548a46eb9SPierre Jolivet for (p = 0; p < d->n_neighbour_procs; p++) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, " [%d] neighbour[%d] = %d \n", d->rank, p, d->neighbour_procs[p])); 1469566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, stdout)); 147095059a4SDave May } 148298827fbSBarry Smith 149095059a4SDave May if (d->message_lengths_status == DEOBJECT_FINALIZED) { 1509566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Message lengths:\n")); 1519566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, " [%d] atomic size: %ld \n", d->rank, (long int)d->unit_message_size)); 1523a7d0413SPierre Jolivet for (p = 0; p < d->n_neighbour_procs; p++) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, " [%d] >>>>> ( %" PetscInt_FMT " units :: tag = %d) >>>>> [%d] \n", d->rank, d->messages_to_be_sent[p], d->send_tags[p], d->neighbour_procs[p])); 153095059a4SDave May for (p = 0; p < d->n_neighbour_procs; p++) { 15463a3b9bcSJacob Faibussowitsch PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, " [%d] <<<<< ( %" PetscInt_FMT " units :: tag = %d) <<<<< [%d] \n", d->rank, d->messages_to_be_recvieved[p], d->recv_tags[p], d->neighbour_procs[p])); 155095059a4SDave May } 1569566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, stdout)); 157095059a4SDave May } 158521f74f9SMatthew G. Knepley if (d->packer_status == DEOBJECT_FINALIZED) { } 159521f74f9SMatthew G. Knepley if (d->communication_status == DEOBJECT_FINALIZED) { } 1603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 161095059a4SDave May } 162095059a4SDave May 163d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExDestroy(DMSwarmDataEx d) 164d71ae5a4SJacob Faibussowitsch { 165095059a4SDave May PetscFunctionBegin; 1669566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&d->comm)); 1679566063dSJacob Faibussowitsch if (d->neighbour_procs) PetscCall(PetscFree(d->neighbour_procs)); 1689566063dSJacob Faibussowitsch if (d->messages_to_be_sent) PetscCall(PetscFree(d->messages_to_be_sent)); 1699566063dSJacob Faibussowitsch if (d->message_offsets) PetscCall(PetscFree(d->message_offsets)); 1709566063dSJacob Faibussowitsch if (d->messages_to_be_recvieved) PetscCall(PetscFree(d->messages_to_be_recvieved)); 1719566063dSJacob Faibussowitsch if (d->send_message) PetscCall(PetscFree(d->send_message)); 1729566063dSJacob Faibussowitsch if (d->recv_message) PetscCall(PetscFree(d->recv_message)); 1739566063dSJacob Faibussowitsch if (d->pack_cnt) PetscCall(PetscFree(d->pack_cnt)); 1749566063dSJacob Faibussowitsch if (d->send_tags) PetscCall(PetscFree(d->send_tags)); 1759566063dSJacob Faibussowitsch if (d->recv_tags) PetscCall(PetscFree(d->recv_tags)); 1769566063dSJacob Faibussowitsch if (d->_stats) PetscCall(PetscFree(d->_stats)); 1779566063dSJacob Faibussowitsch if (d->_requests) PetscCall(PetscFree(d->_requests)); 1789566063dSJacob Faibussowitsch PetscCall(PetscFree(d)); 1793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 180095059a4SDave May } 181095059a4SDave May 182095059a4SDave May /* === Phase A === */ 183095059a4SDave May 184d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExTopologyInitialize(DMSwarmDataEx d) 185d71ae5a4SJacob Faibussowitsch { 186095059a4SDave May PetscFunctionBegin; 187095059a4SDave May d->topology_status = DEOBJECT_INITIALIZED; 188095059a4SDave May d->n_neighbour_procs = 0; 1899566063dSJacob Faibussowitsch PetscCall(PetscFree(d->neighbour_procs)); 1909566063dSJacob Faibussowitsch PetscCall(PetscFree(d->messages_to_be_sent)); 1919566063dSJacob Faibussowitsch PetscCall(PetscFree(d->message_offsets)); 1929566063dSJacob Faibussowitsch PetscCall(PetscFree(d->messages_to_be_recvieved)); 1939566063dSJacob Faibussowitsch PetscCall(PetscFree(d->pack_cnt)); 1949566063dSJacob Faibussowitsch PetscCall(PetscFree(d->send_tags)); 1959566063dSJacob Faibussowitsch PetscCall(PetscFree(d->recv_tags)); 1963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 197095059a4SDave May } 198095059a4SDave May 199d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExTopologyAddNeighbour(DMSwarmDataEx d, const PetscMPIInt proc_id) 200d71ae5a4SJacob Faibussowitsch { 201095059a4SDave May PetscMPIInt n, found; 202d7d19db6SBarry Smith PetscMPIInt size; 203095059a4SDave May 204095059a4SDave May PetscFunctionBegin; 20508401ef6SPierre Jolivet PetscCheck(d->topology_status != DEOBJECT_FINALIZED, d->comm, PETSC_ERR_ARG_WRONGSTATE, "Topology has been finalized. To modify or update call DMSwarmDataExTopologyInitialize() first"); 206f7d195e4SLawrence Mitchell PetscCheck(d->topology_status == DEOBJECT_INITIALIZED, d->comm, PETSC_ERR_ARG_WRONGSTATE, "Topology must be initialised. Call DMSwarmDataExTopologyInitialize() first"); 2072064fc68SDave May 208095059a4SDave May /* error on negative entries */ 20908401ef6SPierre Jolivet PetscCheck(proc_id >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Trying to set proc neighbour with a rank < 0"); 210095059a4SDave May /* error on ranks larger than number of procs in communicator */ 2119566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(d->comm, &size)); 21208401ef6SPierre Jolivet PetscCheck(proc_id < size, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Trying to set proc neighbour %d with a rank >= size %d", proc_id, size); 2139566063dSJacob Faibussowitsch if (d->n_neighbour_procs == 0) PetscCall(PetscMalloc1(1, &d->neighbour_procs)); 214095059a4SDave May /* check for proc_id */ 215095059a4SDave May found = 0; 216095059a4SDave May for (n = 0; n < d->n_neighbour_procs; n++) { 217ad540459SPierre Jolivet if (d->neighbour_procs[n] == proc_id) found = 1; 218095059a4SDave May } 219095059a4SDave May if (found == 0) { /* add it to list */ 2209566063dSJacob Faibussowitsch PetscCall(PetscRealloc(sizeof(PetscMPIInt) * (d->n_neighbour_procs + 1), &d->neighbour_procs)); 221095059a4SDave May d->neighbour_procs[d->n_neighbour_procs] = proc_id; 222095059a4SDave May d->n_neighbour_procs++; 223095059a4SDave May } 2243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 225095059a4SDave May } 226095059a4SDave May 227095059a4SDave May /* 228095059a4SDave May counter: the index of the communication object 229095059a4SDave May N: the number of processors 230095059a4SDave May r0: rank of sender 231095059a4SDave May r1: rank of receiver 232095059a4SDave May 233095059a4SDave May procs = { 0, 1, 2, 3 } 234095059a4SDave May 235095059a4SDave May 0 ==> 0 e=0 236095059a4SDave May 0 ==> 1 e=1 237095059a4SDave May 0 ==> 2 e=2 238095059a4SDave May 0 ==> 3 e=3 239095059a4SDave May 240095059a4SDave May 1 ==> 0 e=4 241095059a4SDave May 1 ==> 1 e=5 242095059a4SDave May 1 ==> 2 e=6 243095059a4SDave May 1 ==> 3 e=7 244095059a4SDave May 245095059a4SDave May 2 ==> 0 e=8 246095059a4SDave May 2 ==> 1 e=9 247095059a4SDave May 2 ==> 2 e=10 248095059a4SDave May 2 ==> 3 e=11 249095059a4SDave May 250095059a4SDave May 3 ==> 0 e=12 251095059a4SDave May 3 ==> 1 e=13 252095059a4SDave May 3 ==> 2 e=14 253095059a4SDave May 3 ==> 3 e=15 254095059a4SDave May 255095059a4SDave May If we require that proc A sends to proc B, then the SEND tag index will be given by 256095059a4SDave May N * rank(A) + rank(B) + offset 257095059a4SDave May If we require that proc A will receive from proc B, then the RECV tag index will be given by 258095059a4SDave May N * rank(B) + rank(A) + offset 259095059a4SDave May 260095059a4SDave May */ 26152c42f6eSMatthew G. Knepley static void _get_tags(PetscInt counter, PetscMPIInt N, PetscMPIInt r0, PetscMPIInt r1, PetscMPIInt maxtag, PetscMPIInt *_st, PetscMPIInt *_rt) 262d71ae5a4SJacob Faibussowitsch { 263095059a4SDave May PetscMPIInt st, rt; 264095059a4SDave May 26552c42f6eSMatthew G. Knepley st = (N * r0 + r1 + N * N * counter) % maxtag; 26652c42f6eSMatthew G. Knepley rt = (N * r1 + r0 + N * N * counter) % maxtag; 267095059a4SDave May *_st = st; 268095059a4SDave May *_rt = rt; 269095059a4SDave May } 270095059a4SDave May 271095059a4SDave May /* 272095059a4SDave May Makes the communication map symmetric 273095059a4SDave May */ 27466976f2fSJacob Faibussowitsch static PetscErrorCode DMSwarmDataExCompleteCommunicationMap_Private(MPI_Comm comm, PetscMPIInt n, const PetscMPIInt proc_neighbours[], PetscMPIInt *n_new, PetscMPIInt **proc_neighbours_new) 275d71ae5a4SJacob Faibussowitsch { 276dcf43ee8SDave May Mat A; 277095059a4SDave May PetscInt i, j, nc; 278095059a4SDave May PetscInt n_, *proc_neighbours_; 279e4fbd051SBarry Smith PetscInt rank_; 280e4fbd051SBarry Smith PetscMPIInt size, rank; 281095059a4SDave May PetscScalar *vals; 282095059a4SDave May const PetscInt *cols; 283095059a4SDave May const PetscScalar *red_vals; 284095059a4SDave May PetscMPIInt _n_new, *_proc_neighbours_new; 285095059a4SDave May 286095059a4SDave May PetscFunctionBegin; 287095059a4SDave May n_ = n; 28866976f2fSJacob Faibussowitsch PetscCall(PetscMalloc1(n_, &proc_neighbours_)); 289ad540459SPierre Jolivet for (i = 0; i < n_; ++i) proc_neighbours_[i] = proc_neighbours[i]; 2909566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 2919566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 292e4fbd051SBarry Smith rank_ = rank; 293095059a4SDave May 2949566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, &A)); 2959566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, size, size)); 2969566063dSJacob Faibussowitsch PetscCall(MatSetType(A, MATAIJ)); 2979566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A, 1, NULL)); 2989566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A, n_, NULL, n_, NULL)); 2999566063dSJacob Faibussowitsch PetscCall(MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 300095059a4SDave May /* Build original map */ 3019566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n_, &vals)); 302ad540459SPierre Jolivet for (i = 0; i < n_; ++i) vals[i] = 1.0; 3039566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &rank_, n_, proc_neighbours_, vals, INSERT_VALUES)); 3049566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FLUSH_ASSEMBLY)); 3059566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FLUSH_ASSEMBLY)); 306095059a4SDave May /* Now force all other connections if they are not already there */ 307095059a4SDave May /* It's more efficient to do them all at once */ 308ad540459SPierre Jolivet for (i = 0; i < n_; ++i) vals[i] = 2.0; 3099566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, n_, proc_neighbours_, 1, &rank_, vals, INSERT_VALUES)); 3109566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 3119566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 3126275818cSDave May /* 3139566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_INFO)); 3149566063dSJacob Faibussowitsch PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD)); 3159566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD)); 3166275818cSDave May */ 317095059a4SDave May if ((n_new != NULL) && (proc_neighbours_new != NULL)) { 3189566063dSJacob Faibussowitsch PetscCall(MatGetRow(A, rank_, &nc, &cols, &red_vals)); 319835f2295SStefano Zampini PetscCall(PetscMPIIntCast(nc, &_n_new)); 3209566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(_n_new, &_proc_neighbours_new)); 321835f2295SStefano Zampini for (j = 0; j < nc; ++j) PetscCall(PetscMPIIntCast(cols[j], &_proc_neighbours_new[j])); 3229566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(A, rank_, &nc, &cols, &red_vals)); 323835f2295SStefano Zampini *n_new = _n_new; 324835f2295SStefano Zampini *proc_neighbours_new = _proc_neighbours_new; 325095059a4SDave May } 3269566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 3279566063dSJacob Faibussowitsch PetscCall(PetscFree(vals)); 3289566063dSJacob Faibussowitsch PetscCall(PetscFree(proc_neighbours_)); 3299566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(comm)); 3303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 331095059a4SDave May } 332095059a4SDave May 333d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExTopologyFinalize(DMSwarmDataEx d) 334d71ae5a4SJacob Faibussowitsch { 335*b8b5be36SMartin Diehl PetscMPIInt symm_nn = 0, *symm_procs = NULL, r0, n, st, rt, size, *maxtag, iflg; 336095059a4SDave May 337095059a4SDave May PetscFunctionBegin; 33808401ef6SPierre Jolivet PetscCheck(d->topology_status == DEOBJECT_INITIALIZED, d->comm, PETSC_ERR_ARG_WRONGSTATE, "Topology must be initialised. Call DMSwarmDataExTopologyInitialize() first"); 3392064fc68SDave May 3409566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_DataExchangerTopologySetup, 0, 0, 0, 0)); 341a5b23f4aSJose E. Roman /* given information about all my neighbours, make map symmetric */ 34266976f2fSJacob Faibussowitsch PetscCall(DMSwarmDataExCompleteCommunicationMap_Private(d->comm, d->n_neighbour_procs, d->neighbour_procs, &symm_nn, &symm_procs)); 343095059a4SDave May /* update my arrays */ 3449566063dSJacob Faibussowitsch PetscCall(PetscFree(d->neighbour_procs)); 345095059a4SDave May d->n_neighbour_procs = symm_nn; 346095059a4SDave May d->neighbour_procs = symm_procs; 347095059a4SDave May /* allocates memory */ 3489566063dSJacob Faibussowitsch if (!d->messages_to_be_sent) PetscCall(PetscMalloc1(d->n_neighbour_procs + 1, &d->messages_to_be_sent)); 3499566063dSJacob Faibussowitsch if (!d->message_offsets) PetscCall(PetscMalloc1(d->n_neighbour_procs + 1, &d->message_offsets)); 3509566063dSJacob Faibussowitsch if (!d->messages_to_be_recvieved) PetscCall(PetscMalloc1(d->n_neighbour_procs + 1, &d->messages_to_be_recvieved)); 3519566063dSJacob Faibussowitsch if (!d->pack_cnt) PetscCall(PetscMalloc(sizeof(PetscInt) * d->n_neighbour_procs, &d->pack_cnt)); 3529566063dSJacob Faibussowitsch if (!d->_stats) PetscCall(PetscMalloc(sizeof(MPI_Status) * 2 * d->n_neighbour_procs, &d->_stats)); 3539566063dSJacob Faibussowitsch if (!d->_requests) PetscCall(PetscMalloc(sizeof(MPI_Request) * 2 * d->n_neighbour_procs, &d->_requests)); 3549566063dSJacob Faibussowitsch if (!d->send_tags) PetscCall(PetscMalloc(sizeof(int) * d->n_neighbour_procs, &d->send_tags)); 3559566063dSJacob Faibussowitsch if (!d->recv_tags) PetscCall(PetscMalloc(sizeof(int) * d->n_neighbour_procs, &d->recv_tags)); 356095059a4SDave May /* compute message tags */ 3579566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(d->comm, &size)); 358*b8b5be36SMartin Diehl PetscCallMPI(MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &maxtag, &iflg)); 359*b8b5be36SMartin Diehl PetscCheck(iflg, d->comm, PETSC_ERR_LIB, "MPI error: MPI_Comm_get_attr() is not returning a MPI_TAG_UB"); 360095059a4SDave May r0 = d->rank; 361521f74f9SMatthew G. Knepley for (n = 0; n < d->n_neighbour_procs; ++n) { 362095059a4SDave May PetscMPIInt r1 = d->neighbour_procs[n]; 363095059a4SDave May 36452c42f6eSMatthew G. Knepley _get_tags(d->instance, size, r0, r1, *maxtag, &st, &rt); 365835f2295SStefano Zampini d->send_tags[n] = st; 366835f2295SStefano Zampini d->recv_tags[n] = rt; 367095059a4SDave May } 368095059a4SDave May d->topology_status = DEOBJECT_FINALIZED; 3699566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_DataExchangerTopologySetup, 0, 0, 0, 0)); 3703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 371095059a4SDave May } 372095059a4SDave May 373095059a4SDave May /* === Phase B === */ 37466976f2fSJacob Faibussowitsch static PetscErrorCode _DMSwarmDataExConvertProcIdToLocalIndex(DMSwarmDataEx de, PetscMPIInt proc_id, PetscMPIInt *local) 375d71ae5a4SJacob Faibussowitsch { 376095059a4SDave May PetscMPIInt i, np; 377095059a4SDave May 378095059a4SDave May PetscFunctionBegin; 379095059a4SDave May np = de->n_neighbour_procs; 380095059a4SDave May *local = -1; 381521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 382095059a4SDave May if (proc_id == de->neighbour_procs[i]) { 383095059a4SDave May *local = i; 384095059a4SDave May break; 385095059a4SDave May } 386095059a4SDave May } 3873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 388095059a4SDave May } 389095059a4SDave May 390d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExInitializeSendCount(DMSwarmDataEx de) 391d71ae5a4SJacob Faibussowitsch { 392095059a4SDave May PetscMPIInt i; 393095059a4SDave May 394095059a4SDave May PetscFunctionBegin; 39508401ef6SPierre Jolivet PetscCheck(de->topology_status == DEOBJECT_FINALIZED, de->comm, PETSC_ERR_ORDER, "Topology not finalized"); 3969566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_DataExchangerSendCount, 0, 0, 0, 0)); 397095059a4SDave May de->message_lengths_status = DEOBJECT_INITIALIZED; 398ad540459SPierre Jolivet for (i = 0; i < de->n_neighbour_procs; ++i) de->messages_to_be_sent[i] = 0; 3993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 400095059a4SDave May } 401095059a4SDave May 402095059a4SDave May /* 403095059a4SDave May 1) only allows counters to be set on neighbouring cpus 404095059a4SDave May */ 405d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExAddToSendCount(DMSwarmDataEx de, const PetscMPIInt proc_id, const PetscInt count) 406d71ae5a4SJacob Faibussowitsch { 407095059a4SDave May PetscMPIInt local_val; 408095059a4SDave May 409095059a4SDave May PetscFunctionBegin; 41008401ef6SPierre Jolivet PetscCheck(de->message_lengths_status != DEOBJECT_FINALIZED, de->comm, PETSC_ERR_ORDER, "Message lengths have been defined. To modify these call DMSwarmDataExInitializeSendCount() first"); 411f7d195e4SLawrence Mitchell PetscCheck(de->message_lengths_status == DEOBJECT_INITIALIZED, de->comm, PETSC_ERR_ORDER, "Message lengths must be defined. Call DMSwarmDataExInitializeSendCount() first"); 4122064fc68SDave May 4139566063dSJacob Faibussowitsch PetscCall(_DMSwarmDataExConvertProcIdToLocalIndex(de, proc_id, &local_val)); 41408401ef6SPierre Jolivet PetscCheck(local_val != -1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Proc %d is not a valid neighbour rank", (int)proc_id); 4152064fc68SDave May 416095059a4SDave May de->messages_to_be_sent[local_val] = de->messages_to_be_sent[local_val] + count; 4173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 418095059a4SDave May } 419095059a4SDave May 420d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExFinalizeSendCount(DMSwarmDataEx de) 421d71ae5a4SJacob Faibussowitsch { 422095059a4SDave May PetscFunctionBegin; 42308401ef6SPierre Jolivet PetscCheck(de->message_lengths_status == DEOBJECT_INITIALIZED, de->comm, PETSC_ERR_ORDER, "Message lengths must be defined. Call DMSwarmDataExInitializeSendCount() first"); 4242064fc68SDave May 425095059a4SDave May de->message_lengths_status = DEOBJECT_FINALIZED; 4269566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_DataExchangerSendCount, 0, 0, 0, 0)); 4273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 428095059a4SDave May } 429095059a4SDave May 430095059a4SDave May /* === Phase C === */ 431095059a4SDave May /* 4325627991aSBarry Smith zero out all send counts 4335627991aSBarry Smith free send and recv buffers 4345627991aSBarry Smith zeros out message length 4355627991aSBarry Smith zeros out all counters 4365627991aSBarry Smith zero out packed data counters 437095059a4SDave May */ 43866976f2fSJacob Faibussowitsch static PetscErrorCode _DMSwarmDataExInitializeTmpStorage(DMSwarmDataEx de) 439d71ae5a4SJacob Faibussowitsch { 440095059a4SDave May PetscMPIInt i, np; 441095059a4SDave May 442095059a4SDave May PetscFunctionBegin; 443095059a4SDave May np = de->n_neighbour_procs; 444521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 445095059a4SDave May /* de->messages_to_be_sent[i] = -1; */ 446095059a4SDave May de->messages_to_be_recvieved[i] = -1; 447095059a4SDave May } 4489566063dSJacob Faibussowitsch PetscCall(PetscFree(de->send_message)); 4499566063dSJacob Faibussowitsch PetscCall(PetscFree(de->recv_message)); 4503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 451095059a4SDave May } 452095059a4SDave May 453095059a4SDave May /* 4545627991aSBarry Smith Zeros out pack data counters 4555627991aSBarry Smith Ensures mesaage length is set 4565627991aSBarry Smith Checks send counts properly initialized 4575627991aSBarry Smith allocates space for pack data 458095059a4SDave May */ 459d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExPackInitialize(DMSwarmDataEx de, size_t unit_message_size) 460d71ae5a4SJacob Faibussowitsch { 461095059a4SDave May PetscMPIInt i, np; 462095059a4SDave May PetscInt total; 463095059a4SDave May 464095059a4SDave May PetscFunctionBegin; 46508401ef6SPierre Jolivet PetscCheck(de->topology_status == DEOBJECT_FINALIZED, de->comm, PETSC_ERR_ORDER, "Topology not finalized"); 46608401ef6SPierre Jolivet PetscCheck(de->message_lengths_status == DEOBJECT_FINALIZED, de->comm, PETSC_ERR_ORDER, "Message lengths not finalized"); 4679566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_DataExchangerPack, 0, 0, 0, 0)); 468095059a4SDave May de->packer_status = DEOBJECT_INITIALIZED; 4699566063dSJacob Faibussowitsch PetscCall(_DMSwarmDataExInitializeTmpStorage(de)); 470095059a4SDave May np = de->n_neighbour_procs; 471095059a4SDave May de->unit_message_size = unit_message_size; 472095059a4SDave May total = 0; 473521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 474095059a4SDave May if (de->messages_to_be_sent[i] == -1) { 475095059a4SDave May PetscMPIInt proc_neighour = de->neighbour_procs[i]; 476835f2295SStefano Zampini SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ORDER, "Messages_to_be_sent[neighbour_proc=%d] is un-initialised. Call DMSwarmDataExSetSendCount() first", proc_neighour); 477095059a4SDave May } 478095059a4SDave May total = total + de->messages_to_be_sent[i]; 479095059a4SDave May } 480095059a4SDave May /* create space for the data to be sent */ 4819566063dSJacob Faibussowitsch PetscCall(PetscMalloc(unit_message_size * (total + 1), &de->send_message)); 482095059a4SDave May /* initialize memory */ 4839566063dSJacob Faibussowitsch PetscCall(PetscMemzero(de->send_message, unit_message_size * (total + 1))); 484095059a4SDave May /* set total items to send */ 485095059a4SDave May de->send_message_length = total; 486095059a4SDave May de->message_offsets[0] = 0; 487095059a4SDave May total = de->messages_to_be_sent[0]; 488521f74f9SMatthew G. Knepley for (i = 1; i < np; ++i) { 489095059a4SDave May de->message_offsets[i] = total; 490095059a4SDave May total = total + de->messages_to_be_sent[i]; 491095059a4SDave May } 492095059a4SDave May /* init the packer counters */ 493095059a4SDave May de->total_pack_cnt = 0; 494ad540459SPierre Jolivet for (i = 0; i < np; ++i) de->pack_cnt[i] = 0; 4953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 496095059a4SDave May } 497095059a4SDave May 498095059a4SDave May /* 4995627991aSBarry Smith Ensures data gets been packed appropriately and no overlaps occur 500095059a4SDave May */ 501d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExPackData(DMSwarmDataEx de, PetscMPIInt proc_id, PetscInt n, void *data) 502d71ae5a4SJacob Faibussowitsch { 503095059a4SDave May PetscMPIInt local; 504095059a4SDave May PetscInt insert_location; 505095059a4SDave May void *dest; 506095059a4SDave May 507095059a4SDave May PetscFunctionBegin; 50808401ef6SPierre Jolivet PetscCheck(de->packer_status != DEOBJECT_FINALIZED, de->comm, PETSC_ERR_ORDER, "Packed data have been defined. To modify these call DMSwarmDataExInitializeSendCount(), DMSwarmDataExAddToSendCount(), DMSwarmDataExPackInitialize() first"); 509f7d195e4SLawrence Mitchell PetscCheck(de->packer_status == DEOBJECT_INITIALIZED, de->comm, PETSC_ERR_ORDER, "Packed data must be defined. Call DMSwarmDataExInitializeSendCount(), DMSwarmDataExAddToSendCount(), DMSwarmDataExPackInitialize() first"); 5102064fc68SDave May 51128b400f6SJacob Faibussowitsch PetscCheck(de->send_message, de->comm, PETSC_ERR_ORDER, "send_message is not initialized. Call DMSwarmDataExPackInitialize() first"); 5129566063dSJacob Faibussowitsch PetscCall(_DMSwarmDataExConvertProcIdToLocalIndex(de, proc_id, &local)); 513835f2295SStefano Zampini PetscCheck(local != -1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "proc_id %d is not registered neighbour", proc_id); 514835f2295SStefano Zampini PetscCheck(n + de->pack_cnt[local] <= de->messages_to_be_sent[local], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to pack too many entries to be sent to proc %d. Space requested = %" PetscInt_FMT ": Attempt to insert %" PetscInt_FMT, proc_id, de->messages_to_be_sent[local], n + de->pack_cnt[local]); 5152064fc68SDave May 516095059a4SDave May /* copy memory */ 517095059a4SDave May insert_location = de->message_offsets[local] + de->pack_cnt[local]; 518095059a4SDave May dest = ((char *)de->send_message) + de->unit_message_size * insert_location; 5199566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(dest, data, de->unit_message_size * n)); 520095059a4SDave May /* increment counter */ 521095059a4SDave May de->pack_cnt[local] = de->pack_cnt[local] + n; 5223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 523095059a4SDave May } 524095059a4SDave May 525095059a4SDave May /* 526095059a4SDave May *) Ensures all data has been packed 527095059a4SDave May */ 528d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExPackFinalize(DMSwarmDataEx de) 529d71ae5a4SJacob Faibussowitsch { 530095059a4SDave May PetscMPIInt i, np; 531095059a4SDave May PetscInt total; 532095059a4SDave May 533095059a4SDave May PetscFunctionBegin; 53408401ef6SPierre Jolivet PetscCheck(de->packer_status == DEOBJECT_INITIALIZED, de->comm, PETSC_ERR_ORDER, "Packer has not been initialized. Must call DMSwarmDataExPackInitialize() first."); 535095059a4SDave May np = de->n_neighbour_procs; 536521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 537835f2295SStefano Zampini PetscCheck(de->pack_cnt[i] == de->messages_to_be_sent[i], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not all messages for neighbour[%d] have been packed. Expected %" PetscInt_FMT " : Inserted %" PetscInt_FMT, de->neighbour_procs[i], de->messages_to_be_sent[i], de->pack_cnt[i]); 538095059a4SDave May } 539095059a4SDave May /* init */ 540ad540459SPierre Jolivet for (i = 0; i < np; ++i) de->messages_to_be_recvieved[i] = -1; 541095059a4SDave May /* figure out the recv counts here */ 5426497c311SBarry Smith for (i = 0; i < np; ++i) PetscCallMPI(MPIU_Isend(&de->messages_to_be_sent[i], 1, MPIU_INT, de->neighbour_procs[i], de->send_tags[i], de->comm, &de->_requests[i])); 5436497c311SBarry Smith for (i = 0; i < np; ++i) PetscCallMPI(MPIU_Irecv(&de->messages_to_be_recvieved[i], 1, MPIU_INT, de->neighbour_procs[i], de->recv_tags[i], de->comm, &de->_requests[np + i])); 5449566063dSJacob Faibussowitsch PetscCallMPI(MPI_Waitall(2 * np, de->_requests, de->_stats)); 545095059a4SDave May /* create space for the data to be recvieved */ 546095059a4SDave May total = 0; 547ad540459SPierre Jolivet for (i = 0; i < np; ++i) total = total + de->messages_to_be_recvieved[i]; 5489566063dSJacob Faibussowitsch PetscCall(PetscMalloc(de->unit_message_size * (total + 1), &de->recv_message)); 549095059a4SDave May /* initialize memory */ 5509566063dSJacob Faibussowitsch PetscCall(PetscMemzero(de->recv_message, de->unit_message_size * (total + 1))); 5512d4ee042Sprj- /* set total items to receive */ 552095059a4SDave May de->recv_message_length = total; 553095059a4SDave May de->packer_status = DEOBJECT_FINALIZED; 554095059a4SDave May de->communication_status = DEOBJECT_INITIALIZED; 5559566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_DataExchangerPack, 0, 0, 0, 0)); 5563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 557095059a4SDave May } 558095059a4SDave May 5595627991aSBarry Smith /* do the actual message passing */ 560d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExBegin(DMSwarmDataEx de) 561d71ae5a4SJacob Faibussowitsch { 562e91c04dfSPierre Jolivet PetscMPIInt i, np; 563095059a4SDave May void *dest; 564095059a4SDave May 565095059a4SDave May PetscFunctionBegin; 56608401ef6SPierre Jolivet PetscCheck(de->topology_status == DEOBJECT_FINALIZED, de->comm, PETSC_ERR_ORDER, "Topology not finalized"); 56708401ef6SPierre Jolivet PetscCheck(de->message_lengths_status == DEOBJECT_FINALIZED, de->comm, PETSC_ERR_ORDER, "Message lengths not finalized"); 56808401ef6SPierre Jolivet PetscCheck(de->packer_status == DEOBJECT_FINALIZED, de->comm, PETSC_ERR_ORDER, "Packer not finalized"); 56908401ef6SPierre Jolivet PetscCheck(de->communication_status != DEOBJECT_FINALIZED, de->comm, PETSC_ERR_ORDER, "Communication has already been finalized. Must call DMSwarmDataExInitialize() first."); 57028b400f6SJacob Faibussowitsch PetscCheck(de->recv_message, de->comm, PETSC_ERR_ORDER, "recv_message has not been initialized. Must call DMSwarmDataExPackFinalize() first"); 5719566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_DataExchangerBegin, 0, 0, 0, 0)); 572095059a4SDave May np = de->n_neighbour_procs; 573095059a4SDave May /* == NON BLOCKING == */ 574521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 575095059a4SDave May dest = ((char *)de->send_message) + de->unit_message_size * de->message_offsets[i]; 576e91c04dfSPierre Jolivet PetscCallMPI(MPIU_Isend(dest, de->messages_to_be_sent[i] * de->unit_message_size, MPI_CHAR, de->neighbour_procs[i], de->send_tags[i], de->comm, &de->_requests[i])); 577095059a4SDave May } 5789566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_DataExchangerBegin, 0, 0, 0, 0)); 5793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 580095059a4SDave May } 581095059a4SDave May 582095059a4SDave May /* do the actual message passing now */ 583d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExEnd(DMSwarmDataEx de) 584d71ae5a4SJacob Faibussowitsch { 585e91c04dfSPierre Jolivet PetscMPIInt i, np; 586095059a4SDave May PetscInt total; 587095059a4SDave May PetscInt *message_recv_offsets; 588095059a4SDave May void *dest; 589095059a4SDave May 590095059a4SDave May PetscFunctionBegin; 59108401ef6SPierre Jolivet PetscCheck(de->communication_status == DEOBJECT_INITIALIZED, de->comm, PETSC_ERR_ORDER, "Communication has not been initialized. Must call DMSwarmDataExInitialize() first."); 59228b400f6SJacob Faibussowitsch PetscCheck(de->recv_message, de->comm, PETSC_ERR_ORDER, "recv_message has not been initialized. Must call DMSwarmDataExPackFinalize() first"); 5939566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_DataExchangerEnd, 0, 0, 0, 0)); 594095059a4SDave May np = de->n_neighbour_procs; 5959566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np + 1, &message_recv_offsets)); 596095059a4SDave May message_recv_offsets[0] = 0; 597095059a4SDave May total = de->messages_to_be_recvieved[0]; 598521f74f9SMatthew G. Knepley for (i = 1; i < np; ++i) { 599095059a4SDave May message_recv_offsets[i] = total; 600095059a4SDave May total = total + de->messages_to_be_recvieved[i]; 601095059a4SDave May } 602095059a4SDave May /* == NON BLOCKING == */ 603521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 604095059a4SDave May dest = ((char *)de->recv_message) + de->unit_message_size * message_recv_offsets[i]; 605e91c04dfSPierre Jolivet PetscCallMPI(MPIU_Irecv(dest, de->messages_to_be_recvieved[i] * de->unit_message_size, MPI_CHAR, de->neighbour_procs[i], de->recv_tags[i], de->comm, &de->_requests[np + i])); 606095059a4SDave May } 6079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Waitall(2 * np, de->_requests, de->_stats)); 6089566063dSJacob Faibussowitsch PetscCall(PetscFree(message_recv_offsets)); 609095059a4SDave May de->communication_status = DEOBJECT_FINALIZED; 6109566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_DataExchangerEnd, 0, 0, 0, 0)); 6113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 612095059a4SDave May } 613095059a4SDave May 614d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExGetSendData(DMSwarmDataEx de, PetscInt *length, void **send) 615d71ae5a4SJacob Faibussowitsch { 616095059a4SDave May PetscFunctionBegin; 61708401ef6SPierre Jolivet PetscCheck(de->packer_status == DEOBJECT_FINALIZED, de->comm, PETSC_ERR_ARG_WRONGSTATE, "Data has not finished being packed."); 618095059a4SDave May *length = de->send_message_length; 619095059a4SDave May *send = de->send_message; 6203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 621095059a4SDave May } 622095059a4SDave May 623d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExGetRecvData(DMSwarmDataEx de, PetscInt *length, void **recv) 624d71ae5a4SJacob Faibussowitsch { 625095059a4SDave May PetscFunctionBegin; 62608401ef6SPierre Jolivet PetscCheck(de->communication_status == DEOBJECT_FINALIZED, de->comm, PETSC_ERR_ARG_WRONGSTATE, "Data has not finished being sent."); 627095059a4SDave May *length = de->recv_message_length; 628095059a4SDave May *recv = de->recv_message; 6293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 630095059a4SDave May } 631095059a4SDave May 632d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmDataExTopologyGetNeighbours(DMSwarmDataEx de, PetscMPIInt *n, PetscMPIInt *neigh[]) 633d71ae5a4SJacob Faibussowitsch { 634095059a4SDave May PetscFunctionBegin; 635ad540459SPierre Jolivet if (n) *n = de->n_neighbour_procs; 636ad540459SPierre Jolivet if (neigh) *neigh = de->neighbour_procs; 6373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 638095059a4SDave May } 639