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 8095059a4SDave May these paths we can always uniquely assign message identifers. 9095059a4SDave May 10095059a4SDave May edge 11095059a4SDave May 10 12095059a4SDave May proc ---------> proc 13095059a4SDave May 0 <-------- 1 14095059a4SDave May 11 15095059a4SDave May twin 16095059a4SDave May 17*2d4ee042Sprj- 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 19*2d4ee042Sprj- 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 36095059a4SDave May User has to unpack message themselves. I can get you the pointer for each i 37095059a4SDave May entry, but you'll have to cast it to the appropriate data type. 38095059a4SDave May 39095059a4SDave May 40095059a4SDave May 41095059a4SDave May 42095059a4SDave May Phase A: Build topology 43095059a4SDave May 44095059a4SDave May Phase B: Define message lengths 45095059a4SDave May 46095059a4SDave May Phase C: Pack data 47095059a4SDave May 48095059a4SDave May Phase D: Send data 49095059a4SDave May 502064fc68SDave May + Constructor 5177048351SPatrick Sanan DMSwarmDataExCreate() 522064fc68SDave May + Phase A 5377048351SPatrick Sanan DMSwarmDataExTopologyInitialize() 5477048351SPatrick Sanan DMSwarmDataExTopologyAddNeighbour() 5577048351SPatrick Sanan DMSwarmDataExTopologyAddNeighbour() 5677048351SPatrick Sanan DMSwarmDataExTopologyFinalize() 572064fc68SDave May + Phase B 5877048351SPatrick Sanan DMSwarmDataExZeroAllSendCount() 5977048351SPatrick Sanan DMSwarmDataExAddToSendCount() 6077048351SPatrick Sanan DMSwarmDataExAddToSendCount() 6177048351SPatrick Sanan DMSwarmDataExAddToSendCount() 622064fc68SDave May + Phase C 6377048351SPatrick Sanan DMSwarmDataExPackInitialize() 6477048351SPatrick Sanan DMSwarmDataExPackData() 6577048351SPatrick Sanan DMSwarmDataExPackData() 6677048351SPatrick Sanan DMSwarmDataExPackFinalize() 672064fc68SDave May +Phase D 6877048351SPatrick Sanan DMSwarmDataExBegin() 692064fc68SDave May ... perform any calculations ... 7077048351SPatrick Sanan DMSwarmDataExEnd() 71095059a4SDave May 722064fc68SDave May ... user calls any getters here ... 73095059a4SDave May 74095059a4SDave May 75095059a4SDave May */ 76095059a4SDave May #include <petscvec.h> 77095059a4SDave May #include <petscmat.h> 78095059a4SDave May 79279f676cSBarry Smith #include "../src/dm/impls/swarm/data_ex.h" 80095059a4SDave May 81095059a4SDave May const char *status_names[] = {"initialized", "finalized", "unknown"}; 82095059a4SDave May 83ed923d71SDave May PETSC_EXTERN PetscLogEvent DMSWARM_DataExchangerTopologySetup; 84ed923d71SDave May PETSC_EXTERN PetscLogEvent DMSWARM_DataExchangerBegin; 85ed923d71SDave May PETSC_EXTERN PetscLogEvent DMSWARM_DataExchangerEnd; 86ed923d71SDave May PETSC_EXTERN PetscLogEvent DMSWARM_DataExchangerSendCount; 87ed923d71SDave May PETSC_EXTERN PetscLogEvent DMSWARM_DataExchangerPack; 88095059a4SDave May 8977048351SPatrick Sanan PetscErrorCode DMSwarmDataExCreate(MPI_Comm comm,const PetscInt count, DMSwarmDataEx *ex) 90095059a4SDave May { 91095059a4SDave May PetscErrorCode ierr; 9277048351SPatrick Sanan DMSwarmDataEx d; 93095059a4SDave May 94521f74f9SMatthew G. Knepley PetscFunctionBegin; 9577048351SPatrick Sanan ierr = PetscMalloc(sizeof(struct _p_DMSwarmDataEx), &d);CHKERRQ(ierr); 9677048351SPatrick Sanan ierr = PetscMemzero(d, sizeof(struct _p_DMSwarmDataEx));CHKERRQ(ierr); 97521f74f9SMatthew G. Knepley ierr = MPI_Comm_dup(comm,&d->comm);CHKERRQ(ierr); 98521f74f9SMatthew G. Knepley ierr = MPI_Comm_rank(d->comm,&d->rank);CHKERRQ(ierr); 99095059a4SDave May 100095059a4SDave May d->instance = count; 101095059a4SDave May 102095059a4SDave May d->topology_status = DEOBJECT_STATE_UNKNOWN; 103095059a4SDave May d->message_lengths_status = DEOBJECT_STATE_UNKNOWN; 104095059a4SDave May d->packer_status = DEOBJECT_STATE_UNKNOWN; 105095059a4SDave May d->communication_status = DEOBJECT_STATE_UNKNOWN; 106095059a4SDave May 107095059a4SDave May d->n_neighbour_procs = -1; 108095059a4SDave May d->neighbour_procs = NULL; 109095059a4SDave May 110095059a4SDave May d->messages_to_be_sent = NULL; 111095059a4SDave May d->message_offsets = NULL; 112095059a4SDave May d->messages_to_be_recvieved = NULL; 113095059a4SDave May 114095059a4SDave May d->unit_message_size = -1; 115095059a4SDave May d->send_message = NULL; 116095059a4SDave May d->send_message_length = -1; 117095059a4SDave May d->recv_message = NULL; 118095059a4SDave May d->recv_message_length = -1; 119095059a4SDave May d->total_pack_cnt = -1; 120095059a4SDave May d->pack_cnt = NULL; 121095059a4SDave May 122095059a4SDave May d->send_tags = NULL; 123095059a4SDave May d->recv_tags = NULL; 124095059a4SDave May 125095059a4SDave May d->_stats = NULL; 126095059a4SDave May d->_requests = NULL; 127521f74f9SMatthew G. Knepley *ex = d; 128521f74f9SMatthew G. Knepley PetscFunctionReturn(0); 129095059a4SDave May } 130095059a4SDave May 131298827fbSBarry Smith /* 132298827fbSBarry Smith This code is horrible, who let it get into master. 133298827fbSBarry Smith 134298827fbSBarry Smith Should be printing to a viewer, should not be using PETSC_COMM_WORLD 135298827fbSBarry Smith 136298827fbSBarry Smith */ 13777048351SPatrick Sanan PetscErrorCode DMSwarmDataExView(DMSwarmDataEx d) 138095059a4SDave May { 139095059a4SDave May PetscMPIInt p; 140521f74f9SMatthew G. Knepley PetscErrorCode ierr; 141095059a4SDave May 142095059a4SDave May PetscFunctionBegin; 14377048351SPatrick Sanan ierr = PetscPrintf( PETSC_COMM_WORLD, "DMSwarmDataEx: instance=%D\n",d->instance);CHKERRQ(ierr); 144521f74f9SMatthew G. Knepley ierr = PetscPrintf( PETSC_COMM_WORLD, " topology status: %s \n", status_names[d->topology_status]);CHKERRQ(ierr); 145521f74f9SMatthew G. Knepley ierr = PetscPrintf( PETSC_COMM_WORLD, " message lengths status: %s \n", status_names[d->message_lengths_status] );CHKERRQ(ierr); 146521f74f9SMatthew G. Knepley ierr = PetscPrintf( PETSC_COMM_WORLD, " packer status status: %s \n", status_names[d->packer_status] );CHKERRQ(ierr); 147521f74f9SMatthew G. Knepley ierr = PetscPrintf( PETSC_COMM_WORLD, " communication status: %s \n", status_names[d->communication_status] );CHKERRQ(ierr); 148095059a4SDave May 149095059a4SDave May if (d->topology_status == DEOBJECT_FINALIZED) { 150521f74f9SMatthew G. Knepley ierr = PetscPrintf( PETSC_COMM_WORLD, " Topology:\n");CHKERRQ(ierr); 151dfe27cbaSBarry Smith ierr = PetscSynchronizedPrintf( PETSC_COMM_WORLD, " [%d] neighbours: %d \n", d->rank, d->n_neighbour_procs );CHKERRQ(ierr); 152095059a4SDave May for (p=0; p<d->n_neighbour_procs; p++) { 153dfe27cbaSBarry Smith ierr = PetscSynchronizedPrintf( PETSC_COMM_WORLD, " [%d] neighbour[%d] = %d \n", d->rank, p, d->neighbour_procs[p]);CHKERRQ(ierr); 154095059a4SDave May } 155298827fbSBarry Smith ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD,stdout);CHKERRQ(ierr); 156095059a4SDave May } 157298827fbSBarry Smith 158095059a4SDave May if (d->message_lengths_status == DEOBJECT_FINALIZED) { 159521f74f9SMatthew G. Knepley ierr = PetscPrintf( PETSC_COMM_WORLD, " Message lengths:\n");CHKERRQ(ierr); 160dfe27cbaSBarry Smith ierr = PetscSynchronizedPrintf( PETSC_COMM_WORLD, " [%d] atomic size: %ld \n", d->rank, (long int)d->unit_message_size );CHKERRQ(ierr); 161095059a4SDave May for (p=0; p<d->n_neighbour_procs; p++) { 162dfe27cbaSBarry Smith ierr = PetscSynchronizedPrintf( PETSC_COMM_WORLD, " [%d] >>>>> ( %D units :: tag = %d ) >>>>> [%d] \n", d->rank, d->messages_to_be_sent[p], d->send_tags[p], d->neighbour_procs[p] );CHKERRQ(ierr); 163095059a4SDave May } 164095059a4SDave May for (p=0; p<d->n_neighbour_procs; p++) { 165dfe27cbaSBarry Smith ierr = PetscSynchronizedPrintf( PETSC_COMM_WORLD, " [%d] <<<<< ( %D units :: tag = %d ) <<<<< [%d] \n", d->rank, d->messages_to_be_recvieved[p], d->recv_tags[p], d->neighbour_procs[p] );CHKERRQ(ierr); 166095059a4SDave May } 167298827fbSBarry Smith ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD,stdout);CHKERRQ(ierr); 168095059a4SDave May } 169521f74f9SMatthew G. Knepley if (d->packer_status == DEOBJECT_FINALIZED) {} 170521f74f9SMatthew G. Knepley if (d->communication_status == DEOBJECT_FINALIZED) {} 171095059a4SDave May PetscFunctionReturn(0); 172095059a4SDave May } 173095059a4SDave May 17477048351SPatrick Sanan PetscErrorCode DMSwarmDataExDestroy(DMSwarmDataEx d) 175095059a4SDave May { 176095059a4SDave May PetscErrorCode ierr; 177095059a4SDave May 178095059a4SDave May PetscFunctionBegin; 179095059a4SDave May ierr = MPI_Comm_free(&d->comm);CHKERRQ(ierr); 180521f74f9SMatthew G. Knepley if (d->neighbour_procs) {ierr = PetscFree(d->neighbour_procs);CHKERRQ(ierr);} 181521f74f9SMatthew G. Knepley if (d->messages_to_be_sent) {ierr = PetscFree(d->messages_to_be_sent);CHKERRQ(ierr);} 182521f74f9SMatthew G. Knepley if (d->message_offsets) {ierr = PetscFree(d->message_offsets);CHKERRQ(ierr);} 183521f74f9SMatthew G. Knepley if (d->messages_to_be_recvieved) {ierr = PetscFree(d->messages_to_be_recvieved);CHKERRQ(ierr);} 184521f74f9SMatthew G. Knepley if (d->send_message) {ierr = PetscFree(d->send_message);CHKERRQ(ierr);} 185521f74f9SMatthew G. Knepley if (d->recv_message) {ierr = PetscFree(d->recv_message);CHKERRQ(ierr);} 186521f74f9SMatthew G. Knepley if (d->pack_cnt) {ierr = PetscFree(d->pack_cnt);CHKERRQ(ierr);} 187521f74f9SMatthew G. Knepley if (d->send_tags) {ierr = PetscFree(d->send_tags);CHKERRQ(ierr);} 188521f74f9SMatthew G. Knepley if (d->recv_tags) {ierr = PetscFree(d->recv_tags);CHKERRQ(ierr);} 189521f74f9SMatthew G. Knepley if (d->_stats) {ierr = PetscFree(d->_stats);CHKERRQ(ierr);} 190521f74f9SMatthew G. Knepley if (d->_requests) {ierr = PetscFree(d->_requests);CHKERRQ(ierr);} 191521f74f9SMatthew G. Knepley ierr = PetscFree(d);CHKERRQ(ierr); 192095059a4SDave May PetscFunctionReturn(0); 193095059a4SDave May } 194095059a4SDave May 195095059a4SDave May /* === Phase A === */ 196095059a4SDave May 19777048351SPatrick Sanan PetscErrorCode DMSwarmDataExTopologyInitialize(DMSwarmDataEx d) 198095059a4SDave May { 199521f74f9SMatthew G. Knepley PetscErrorCode ierr; 200521f74f9SMatthew G. Knepley 201095059a4SDave May PetscFunctionBegin; 202095059a4SDave May d->topology_status = DEOBJECT_INITIALIZED; 203095059a4SDave May d->n_neighbour_procs = 0; 204781df12bSMatthew G. Knepley ierr = PetscFree(d->neighbour_procs);CHKERRQ(ierr); 205781df12bSMatthew G. Knepley ierr = PetscFree(d->messages_to_be_sent);CHKERRQ(ierr); 206781df12bSMatthew G. Knepley ierr = PetscFree(d->message_offsets);CHKERRQ(ierr); 207781df12bSMatthew G. Knepley ierr = PetscFree(d->messages_to_be_recvieved);CHKERRQ(ierr); 208781df12bSMatthew G. Knepley ierr = PetscFree(d->pack_cnt);CHKERRQ(ierr); 209781df12bSMatthew G. Knepley ierr = PetscFree(d->send_tags);CHKERRQ(ierr); 210781df12bSMatthew G. Knepley ierr = PetscFree(d->recv_tags);CHKERRQ(ierr); 211095059a4SDave May PetscFunctionReturn(0); 212095059a4SDave May } 213095059a4SDave May 21477048351SPatrick Sanan PetscErrorCode DMSwarmDataExTopologyAddNeighbour(DMSwarmDataEx d,const PetscMPIInt proc_id) 215095059a4SDave May { 216095059a4SDave May PetscMPIInt n,found; 217d7d19db6SBarry Smith PetscMPIInt size; 218095059a4SDave May PetscErrorCode ierr; 219095059a4SDave May 220095059a4SDave May PetscFunctionBegin; 22177048351SPatrick Sanan if (d->topology_status == DEOBJECT_FINALIZED) SETERRQ(d->comm, PETSC_ERR_ARG_WRONGSTATE, "Topology has been finalized. To modify or update call DMSwarmDataExTopologyInitialize() first"); 222*2d4ee042Sprj- else if (d->topology_status != DEOBJECT_INITIALIZED) SETERRQ(d->comm, PETSC_ERR_ARG_WRONGSTATE, "Topology must be initialised. Call DMSwarmDataExTopologyInitialize() first"); 2232064fc68SDave May 224095059a4SDave May /* error on negative entries */ 225521f74f9SMatthew G. Knepley if (proc_id < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Trying to set proc neighbour with a rank < 0"); 226095059a4SDave May /* error on ranks larger than number of procs in communicator */ 227d7d19db6SBarry Smith ierr = MPI_Comm_size(d->comm,&size);CHKERRQ(ierr); 228d7d19db6SBarry Smith if (proc_id >= size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Trying to set proc neighbour %d with a rank >= size %d",proc_id,size); 229521f74f9SMatthew G. Knepley if (d->n_neighbour_procs == 0) {ierr = PetscMalloc1(1, &d->neighbour_procs);CHKERRQ(ierr);} 230095059a4SDave May /* check for proc_id */ 231095059a4SDave May found = 0; 232095059a4SDave May for (n = 0; n < d->n_neighbour_procs; n++) { 233095059a4SDave May if (d->neighbour_procs[n] == proc_id) { 234095059a4SDave May found = 1; 235095059a4SDave May } 236095059a4SDave May } 237095059a4SDave May if (found == 0) { /* add it to list */ 2384be7464cSMatthew G. Knepley ierr = PetscRealloc(sizeof(PetscMPIInt)*(d->n_neighbour_procs+1), &d->neighbour_procs);CHKERRQ(ierr); 239095059a4SDave May d->neighbour_procs[ d->n_neighbour_procs ] = proc_id; 240095059a4SDave May d->n_neighbour_procs++; 241095059a4SDave May } 242095059a4SDave May PetscFunctionReturn(0); 243095059a4SDave May } 244095059a4SDave May 245095059a4SDave May /* 246095059a4SDave May counter: the index of the communication object 247095059a4SDave May N: the number of processors 248095059a4SDave May r0: rank of sender 249095059a4SDave May r1: rank of receiver 250095059a4SDave May 251095059a4SDave May procs = { 0, 1, 2, 3 } 252095059a4SDave May 253095059a4SDave May 0 ==> 0 e=0 254095059a4SDave May 0 ==> 1 e=1 255095059a4SDave May 0 ==> 2 e=2 256095059a4SDave May 0 ==> 3 e=3 257095059a4SDave May 258095059a4SDave May 1 ==> 0 e=4 259095059a4SDave May 1 ==> 1 e=5 260095059a4SDave May 1 ==> 2 e=6 261095059a4SDave May 1 ==> 3 e=7 262095059a4SDave May 263095059a4SDave May 2 ==> 0 e=8 264095059a4SDave May 2 ==> 1 e=9 265095059a4SDave May 2 ==> 2 e=10 266095059a4SDave May 2 ==> 3 e=11 267095059a4SDave May 268095059a4SDave May 3 ==> 0 e=12 269095059a4SDave May 3 ==> 1 e=13 270095059a4SDave May 3 ==> 2 e=14 271095059a4SDave May 3 ==> 3 e=15 272095059a4SDave May 273095059a4SDave May If we require that proc A sends to proc B, then the SEND tag index will be given by 274095059a4SDave May N * rank(A) + rank(B) + offset 275095059a4SDave May If we require that proc A will receive from proc B, then the RECV tag index will be given by 276095059a4SDave May N * rank(B) + rank(A) + offset 277095059a4SDave May 278095059a4SDave May */ 279521f74f9SMatthew G. Knepley static void _get_tags(PetscInt counter, PetscMPIInt N, PetscMPIInt r0,PetscMPIInt r1, PetscMPIInt *_st, PetscMPIInt *_rt) 280095059a4SDave May { 281095059a4SDave May PetscMPIInt st,rt; 282095059a4SDave May 283095059a4SDave May st = N*r0 + r1 + N*N*counter; 284095059a4SDave May rt = N*r1 + r0 + N*N*counter; 285095059a4SDave May *_st = st; 286095059a4SDave May *_rt = rt; 287095059a4SDave May } 288095059a4SDave May 289095059a4SDave May /* 290095059a4SDave May Makes the communication map symmetric 291095059a4SDave May */ 29277048351SPatrick Sanan PetscErrorCode _DMSwarmDataExCompleteCommunicationMap(MPI_Comm comm,PetscMPIInt n,PetscMPIInt proc_neighbours[],PetscMPIInt *n_new,PetscMPIInt **proc_neighbours_new) 293095059a4SDave May { 294dcf43ee8SDave May Mat A; 295095059a4SDave May PetscInt i,j,nc; 296095059a4SDave May PetscInt n_, *proc_neighbours_; 297e4fbd051SBarry Smith PetscInt rank_; 298e4fbd051SBarry Smith PetscMPIInt size, rank; 299095059a4SDave May PetscScalar *vals; 300095059a4SDave May const PetscInt *cols; 301095059a4SDave May const PetscScalar *red_vals; 302095059a4SDave May PetscMPIInt _n_new, *_proc_neighbours_new; 303095059a4SDave May PetscErrorCode ierr; 304095059a4SDave May 305095059a4SDave May PetscFunctionBegin; 306095059a4SDave May n_ = n; 307095059a4SDave May ierr = PetscMalloc(sizeof(PetscInt) * n_, &proc_neighbours_);CHKERRQ(ierr); 308521f74f9SMatthew G. Knepley for (i = 0; i < n_; ++i) { 309095059a4SDave May proc_neighbours_[i] = proc_neighbours[i]; 310095059a4SDave May } 311095059a4SDave May ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 312e4fbd051SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 313e4fbd051SBarry Smith rank_ = rank; 314095059a4SDave May 315095059a4SDave May ierr = MatCreate(comm,&A);CHKERRQ(ierr); 316095059a4SDave May ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,size,size);CHKERRQ(ierr); 317095059a4SDave May ierr = MatSetType(A,MATAIJ);CHKERRQ(ierr); 318dcf43ee8SDave May ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr); 319dcf43ee8SDave May ierr = MatMPIAIJSetPreallocation(A,n_,NULL,n_,NULL);CHKERRQ(ierr); 320dcf43ee8SDave May ierr = MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRQ(ierr); 321095059a4SDave May /* Build original map */ 322521f74f9SMatthew G. Knepley ierr = PetscMalloc1(n_, &vals);CHKERRQ(ierr); 323521f74f9SMatthew G. Knepley for (i = 0; i < n_; ++i) { 324095059a4SDave May vals[i] = 1.0; 325095059a4SDave May } 326e4fbd051SBarry Smith ierr = MatSetValues( A, 1,&rank_, n_,proc_neighbours_, vals, INSERT_VALUES );CHKERRQ(ierr); 327095059a4SDave May ierr = MatAssemblyBegin(A,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 328095059a4SDave May ierr = MatAssemblyEnd(A,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 329095059a4SDave May /* Now force all other connections if they are not already there */ 330095059a4SDave May /* It's more efficient to do them all at once */ 331521f74f9SMatthew G. Knepley for (i = 0; i < n_; ++i) { 332095059a4SDave May vals[i] = 2.0; 333095059a4SDave May } 334e4fbd051SBarry Smith ierr = MatSetValues( A, n_,proc_neighbours_, 1,&rank_, vals, INSERT_VALUES );CHKERRQ(ierr); 335095059a4SDave May ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 336095059a4SDave May ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3376275818cSDave May /* 338095059a4SDave May ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr); 339095059a4SDave May ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 340095059a4SDave May ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 3416275818cSDave May */ 342095059a4SDave May if ((n_new != NULL) && (proc_neighbours_new != NULL)) { 343e4fbd051SBarry Smith ierr = MatGetRow(A, rank_, &nc, &cols, &red_vals);CHKERRQ(ierr); 344095059a4SDave May _n_new = (PetscMPIInt) nc; 345521f74f9SMatthew G. Knepley ierr = PetscMalloc1(_n_new, &_proc_neighbours_new);CHKERRQ(ierr); 346521f74f9SMatthew G. Knepley for (j = 0; j < nc; ++j) { 347095059a4SDave May _proc_neighbours_new[j] = (PetscMPIInt)cols[j]; 348095059a4SDave May } 349e4fbd051SBarry Smith ierr = MatRestoreRow( A, rank_, &nc, &cols, &red_vals );CHKERRQ(ierr); 350095059a4SDave May *n_new = (PetscMPIInt)_n_new; 351095059a4SDave May *proc_neighbours_new = (PetscMPIInt*)_proc_neighbours_new; 352095059a4SDave May } 353095059a4SDave May ierr = MatDestroy(&A);CHKERRQ(ierr); 354095059a4SDave May ierr = PetscFree(vals);CHKERRQ(ierr); 355095059a4SDave May ierr = PetscFree(proc_neighbours_);CHKERRQ(ierr); 356095059a4SDave May ierr = MPI_Barrier(comm);CHKERRQ(ierr); 357095059a4SDave May PetscFunctionReturn(0); 358095059a4SDave May } 359095059a4SDave May 36077048351SPatrick Sanan PetscErrorCode DMSwarmDataExTopologyFinalize(DMSwarmDataEx d) 361095059a4SDave May { 362095059a4SDave May PetscMPIInt symm_nn; 363095059a4SDave May PetscMPIInt *symm_procs; 364095059a4SDave May PetscMPIInt r0,n,st,rt; 365d7d19db6SBarry Smith PetscMPIInt size; 366095059a4SDave May PetscErrorCode ierr; 367095059a4SDave May 368095059a4SDave May PetscFunctionBegin; 369*2d4ee042Sprj- if (d->topology_status != DEOBJECT_INITIALIZED) SETERRQ(d->comm, PETSC_ERR_ARG_WRONGSTATE, "Topology must be initialised. Call DMSwarmDataExTopologyInitialize() first"); 3702064fc68SDave May 371ed923d71SDave May ierr = PetscLogEventBegin(DMSWARM_DataExchangerTopologySetup,0,0,0,0);CHKERRQ(ierr); 372095059a4SDave May /* given infomation about all my neighbours, make map symmetric */ 37377048351SPatrick Sanan ierr = _DMSwarmDataExCompleteCommunicationMap( d->comm,d->n_neighbour_procs,d->neighbour_procs, &symm_nn, &symm_procs );CHKERRQ(ierr); 374095059a4SDave May /* update my arrays */ 375459726d8SSatish Balay ierr = PetscFree(d->neighbour_procs);CHKERRQ(ierr); 376095059a4SDave May d->n_neighbour_procs = symm_nn; 377095059a4SDave May d->neighbour_procs = symm_procs; 378095059a4SDave May /* allocates memory */ 379b9a482c4SDave May if (!d->messages_to_be_sent) {ierr = PetscMalloc1(d->n_neighbour_procs+1, &d->messages_to_be_sent);CHKERRQ(ierr);} 380b9a482c4SDave May if (!d->message_offsets) {ierr = PetscMalloc1(d->n_neighbour_procs+1, &d->message_offsets);CHKERRQ(ierr);} 381b9a482c4SDave May if (!d->messages_to_be_recvieved) {ierr = PetscMalloc1(d->n_neighbour_procs+1, &d->messages_to_be_recvieved);CHKERRQ(ierr);} 382521f74f9SMatthew G. Knepley if (!d->pack_cnt) {ierr = PetscMalloc(sizeof(PetscInt) * d->n_neighbour_procs, &d->pack_cnt);CHKERRQ(ierr);} 383521f74f9SMatthew G. Knepley if (!d->_stats) {ierr = PetscMalloc(sizeof(MPI_Status) * 2*d->n_neighbour_procs, &d->_stats);CHKERRQ(ierr);} 384521f74f9SMatthew G. Knepley if (!d->_requests) {ierr = PetscMalloc(sizeof(MPI_Request) * 2*d->n_neighbour_procs, &d->_requests);CHKERRQ(ierr);} 385521f74f9SMatthew G. Knepley if (!d->send_tags) {ierr = PetscMalloc(sizeof(int) * d->n_neighbour_procs, &d->send_tags);CHKERRQ(ierr);} 386521f74f9SMatthew G. Knepley if (!d->recv_tags) {ierr = PetscMalloc(sizeof(int) * d->n_neighbour_procs, &d->recv_tags);CHKERRQ(ierr);} 387095059a4SDave May /* compute message tags */ 388d7d19db6SBarry Smith ierr = MPI_Comm_size(d->comm,&size);CHKERRQ(ierr); 389095059a4SDave May r0 = d->rank; 390521f74f9SMatthew G. Knepley for (n = 0; n < d->n_neighbour_procs; ++n) { 391095059a4SDave May PetscMPIInt r1 = d->neighbour_procs[n]; 392095059a4SDave May 393d7d19db6SBarry Smith _get_tags( d->instance, size, r0,r1, &st, &rt ); 394095059a4SDave May d->send_tags[n] = (int)st; 395095059a4SDave May d->recv_tags[n] = (int)rt; 396095059a4SDave May } 397095059a4SDave May d->topology_status = DEOBJECT_FINALIZED; 398ed923d71SDave May ierr = PetscLogEventEnd(DMSWARM_DataExchangerTopologySetup,0,0,0,0);CHKERRQ(ierr); 399095059a4SDave May PetscFunctionReturn(0); 400095059a4SDave May } 401095059a4SDave May 402095059a4SDave May /* === Phase B === */ 40377048351SPatrick Sanan PetscErrorCode _DMSwarmDataExConvertProcIdToLocalIndex(DMSwarmDataEx de,PetscMPIInt proc_id,PetscMPIInt *local) 404095059a4SDave May { 405095059a4SDave May PetscMPIInt i,np; 406095059a4SDave May 407095059a4SDave May PetscFunctionBegin; 408095059a4SDave May np = de->n_neighbour_procs; 409095059a4SDave May *local = -1; 410521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 411095059a4SDave May if (proc_id == de->neighbour_procs[i]) { 412095059a4SDave May *local = i; 413095059a4SDave May break; 414095059a4SDave May } 415095059a4SDave May } 416095059a4SDave May PetscFunctionReturn(0); 417095059a4SDave May } 418095059a4SDave May 41977048351SPatrick Sanan PetscErrorCode DMSwarmDataExInitializeSendCount(DMSwarmDataEx de) 420095059a4SDave May { 421095059a4SDave May PetscMPIInt i; 422ed923d71SDave May PetscErrorCode ierr; 423095059a4SDave May 424095059a4SDave May PetscFunctionBegin; 425521f74f9SMatthew G. Knepley if (de->topology_status != DEOBJECT_FINALIZED) SETERRQ(de->comm, PETSC_ERR_ORDER, "Topology not finalized"); 426ed923d71SDave May ierr = PetscLogEventBegin(DMSWARM_DataExchangerSendCount,0,0,0,0);CHKERRQ(ierr); 427095059a4SDave May de->message_lengths_status = DEOBJECT_INITIALIZED; 428521f74f9SMatthew G. Knepley for (i = 0; i < de->n_neighbour_procs; ++i) { 429095059a4SDave May de->messages_to_be_sent[i] = 0; 430095059a4SDave May } 431095059a4SDave May PetscFunctionReturn(0); 432095059a4SDave May } 433095059a4SDave May 434095059a4SDave May /* 435095059a4SDave May 1) only allows counters to be set on neighbouring cpus 436095059a4SDave May */ 43777048351SPatrick Sanan PetscErrorCode DMSwarmDataExAddToSendCount(DMSwarmDataEx de,const PetscMPIInt proc_id,const PetscInt count) 438095059a4SDave May { 439095059a4SDave May PetscMPIInt local_val; 440095059a4SDave May PetscErrorCode ierr; 441095059a4SDave May 442095059a4SDave May PetscFunctionBegin; 44377048351SPatrick Sanan if (de->message_lengths_status == DEOBJECT_FINALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Message lengths have been defined. To modify these call DMSwarmDataExInitializeSendCount() first" ); 44477048351SPatrick Sanan else if (de->message_lengths_status != DEOBJECT_INITIALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Message lengths must be defined. Call DMSwarmDataExInitializeSendCount() first" ); 4452064fc68SDave May 44677048351SPatrick Sanan ierr = _DMSwarmDataExConvertProcIdToLocalIndex( de, proc_id, &local_val );CHKERRQ(ierr); 4472064fc68SDave May if (local_val == -1) SETERRQ1( PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Proc %d is not a valid neighbour rank", (int)proc_id ); 4482064fc68SDave May 449095059a4SDave May de->messages_to_be_sent[local_val] = de->messages_to_be_sent[local_val] + count; 450095059a4SDave May PetscFunctionReturn(0); 451095059a4SDave May } 452095059a4SDave May 45377048351SPatrick Sanan PetscErrorCode DMSwarmDataExFinalizeSendCount(DMSwarmDataEx de) 454095059a4SDave May { 455ed923d71SDave May PetscErrorCode ierr; 456ed923d71SDave May 457095059a4SDave May PetscFunctionBegin; 45877048351SPatrick Sanan if (de->message_lengths_status != DEOBJECT_INITIALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Message lengths must be defined. Call DMSwarmDataExInitializeSendCount() first" ); 4592064fc68SDave May 460095059a4SDave May de->message_lengths_status = DEOBJECT_FINALIZED; 461ed923d71SDave May ierr = PetscLogEventEnd(DMSWARM_DataExchangerSendCount,0,0,0,0);CHKERRQ(ierr); 462095059a4SDave May PetscFunctionReturn(0); 463095059a4SDave May } 464095059a4SDave May 465095059a4SDave May /* === Phase C === */ 466095059a4SDave May /* 467095059a4SDave May * zero out all send counts 468095059a4SDave May * free send and recv buffers 469095059a4SDave May * zeros out message length 470095059a4SDave May * zeros out all counters 471095059a4SDave May * zero out packed data counters 472095059a4SDave May */ 47377048351SPatrick Sanan PetscErrorCode _DMSwarmDataExInitializeTmpStorage(DMSwarmDataEx de) 474095059a4SDave May { 475095059a4SDave May PetscMPIInt i, np; 476521f74f9SMatthew G. Knepley PetscErrorCode ierr; 477095059a4SDave May 478095059a4SDave May PetscFunctionBegin; 4792064fc68SDave May /*if (de->n_neighbour_procs < 0) SETERRQ( PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Number of neighbour procs < 0"); 480b9a482c4SDave May */ 481b9a482c4SDave May /* 4822064fc68SDave May if (!de->neighbour_procs) SETERRQ( PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Neighbour proc list is NULL" ); 483b9a482c4SDave May */ 484095059a4SDave May np = de->n_neighbour_procs; 485521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 486095059a4SDave May /* de->messages_to_be_sent[i] = -1; */ 487095059a4SDave May de->messages_to_be_recvieved[i] = -1; 488095059a4SDave May } 489521f74f9SMatthew G. Knepley ierr = PetscFree(de->send_message);CHKERRQ(ierr); 490521f74f9SMatthew G. Knepley ierr = PetscFree(de->recv_message);CHKERRQ(ierr); 491095059a4SDave May PetscFunctionReturn(0); 492095059a4SDave May } 493095059a4SDave May 494095059a4SDave May /* 495095059a4SDave May *) Zeros out pack data counters 496095059a4SDave May *) Ensures mesaage length is set 497095059a4SDave May *) Checks send counts properly initialized 498095059a4SDave May *) allocates space for pack data 499095059a4SDave May */ 50077048351SPatrick Sanan PetscErrorCode DMSwarmDataExPackInitialize(DMSwarmDataEx de,size_t unit_message_size) 501095059a4SDave May { 502095059a4SDave May PetscMPIInt i,np; 503095059a4SDave May PetscInt total; 504095059a4SDave May PetscErrorCode ierr; 505095059a4SDave May 506095059a4SDave May PetscFunctionBegin; 507521f74f9SMatthew G. Knepley if (de->topology_status != DEOBJECT_FINALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Topology not finalized" ); 508521f74f9SMatthew G. Knepley if (de->message_lengths_status != DEOBJECT_FINALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Message lengths not finalized" ); 509ed923d71SDave May ierr = PetscLogEventBegin(DMSWARM_DataExchangerPack,0,0,0,0);CHKERRQ(ierr); 510095059a4SDave May de->packer_status = DEOBJECT_INITIALIZED; 51177048351SPatrick Sanan ierr = _DMSwarmDataExInitializeTmpStorage(de);CHKERRQ(ierr); 512095059a4SDave May np = de->n_neighbour_procs; 513095059a4SDave May de->unit_message_size = unit_message_size; 514095059a4SDave May total = 0; 515521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 516095059a4SDave May if (de->messages_to_be_sent[i] == -1) { 517095059a4SDave May PetscMPIInt proc_neighour = de->neighbour_procs[i]; 51877048351SPatrick Sanan SETERRQ1( PETSC_COMM_SELF, PETSC_ERR_ORDER, "Messages_to_be_sent[neighbour_proc=%d] is un-initialised. Call DMSwarmDataExSetSendCount() first", (int)proc_neighour ); 519095059a4SDave May } 520095059a4SDave May total = total + de->messages_to_be_sent[i]; 521095059a4SDave May } 522095059a4SDave May /* create space for the data to be sent */ 523521f74f9SMatthew G. Knepley ierr = PetscMalloc(unit_message_size * (total + 1), &de->send_message);CHKERRQ(ierr); 524095059a4SDave May /* initialize memory */ 525521f74f9SMatthew G. Knepley ierr = PetscMemzero(de->send_message, unit_message_size * (total + 1));CHKERRQ(ierr); 526095059a4SDave May /* set total items to send */ 527095059a4SDave May de->send_message_length = total; 528095059a4SDave May de->message_offsets[0] = 0; 529095059a4SDave May total = de->messages_to_be_sent[0]; 530521f74f9SMatthew G. Knepley for (i = 1; i < np; ++i) { 531095059a4SDave May de->message_offsets[i] = total; 532095059a4SDave May total = total + de->messages_to_be_sent[i]; 533095059a4SDave May } 534095059a4SDave May /* init the packer counters */ 535095059a4SDave May de->total_pack_cnt = 0; 536521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 537095059a4SDave May de->pack_cnt[i] = 0; 538095059a4SDave May } 539095059a4SDave May PetscFunctionReturn(0); 540095059a4SDave May } 541095059a4SDave May 542095059a4SDave May /* 543095059a4SDave May *) Ensures data gets been packed appropriately and no overlaps occur 544095059a4SDave May */ 54577048351SPatrick Sanan PetscErrorCode DMSwarmDataExPackData(DMSwarmDataEx de,PetscMPIInt proc_id,PetscInt n,void *data) 546095059a4SDave May { 547095059a4SDave May PetscMPIInt local; 548095059a4SDave May PetscInt insert_location; 549095059a4SDave May void *dest; 550095059a4SDave May PetscErrorCode ierr; 551095059a4SDave May 552095059a4SDave May PetscFunctionBegin; 55377048351SPatrick Sanan if (de->packer_status == DEOBJECT_FINALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Packed data have been defined. To modify these call DMSwarmDataExInitializeSendCount(), DMSwarmDataExAddToSendCount(), DMSwarmDataExPackInitialize() first" ); 55477048351SPatrick Sanan else if (de->packer_status != DEOBJECT_INITIALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Packed data must be defined. Call DMSwarmDataExInitializeSendCount(), DMSwarmDataExAddToSendCount(), DMSwarmDataExPackInitialize() first" ); 5552064fc68SDave May 55677048351SPatrick Sanan if (!de->send_message) SETERRQ( de->comm, PETSC_ERR_ORDER, "send_message is not initialized. Call DMSwarmDataExPackInitialize() first" ); 55777048351SPatrick Sanan ierr = _DMSwarmDataExConvertProcIdToLocalIndex( de, proc_id, &local );CHKERRQ(ierr); 558521f74f9SMatthew G. Knepley if (local == -1) SETERRQ1( PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "proc_id %d is not registered neighbour", (int)proc_id ); 5592064fc68SDave May if (n+de->pack_cnt[local] > de->messages_to_be_sent[local]) SETERRQ3( PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to pack too many entries to be sent to proc %d. Space requested = %D: Attempt to insert %D", 560095059a4SDave May (int)proc_id, de->messages_to_be_sent[local], n+de->pack_cnt[local] ); 5612064fc68SDave May 562095059a4SDave May /* copy memory */ 563095059a4SDave May insert_location = de->message_offsets[local] + de->pack_cnt[local]; 564095059a4SDave May dest = ((char*)de->send_message) + de->unit_message_size*insert_location; 565521f74f9SMatthew G. Knepley ierr = PetscMemcpy(dest, data, de->unit_message_size * n);CHKERRQ(ierr); 566095059a4SDave May /* increment counter */ 567095059a4SDave May de->pack_cnt[local] = de->pack_cnt[local] + n; 568095059a4SDave May PetscFunctionReturn(0); 569095059a4SDave May } 570095059a4SDave May 571095059a4SDave May /* 572095059a4SDave May *) Ensures all data has been packed 573095059a4SDave May */ 57477048351SPatrick Sanan PetscErrorCode DMSwarmDataExPackFinalize(DMSwarmDataEx de) 575095059a4SDave May { 576095059a4SDave May PetscMPIInt i,np; 577095059a4SDave May PetscInt total; 578095059a4SDave May PetscErrorCode ierr; 579095059a4SDave May 580095059a4SDave May PetscFunctionBegin; 58177048351SPatrick Sanan if (de->packer_status != DEOBJECT_INITIALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Packer has not been initialized. Must call DMSwarmDataExPackInitialize() first." ); 582095059a4SDave May np = de->n_neighbour_procs; 583521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 5842064fc68SDave May if (de->pack_cnt[i] != de->messages_to_be_sent[i]) SETERRQ3( PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not all messages for neighbour[%d] have been packed. Expected %D : Inserted %D", 585095059a4SDave May (int)de->neighbour_procs[i], de->messages_to_be_sent[i], de->pack_cnt[i] ); 586095059a4SDave May } 587095059a4SDave May /* init */ 588521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 589095059a4SDave May de->messages_to_be_recvieved[i] = -1; 590095059a4SDave May } 591095059a4SDave May /* figure out the recv counts here */ 592521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 593095059a4SDave May ierr = MPI_Isend(&de->messages_to_be_sent[i], 1, MPIU_INT, de->neighbour_procs[i], de->send_tags[i], de->comm, &de->_requests[i]);CHKERRQ(ierr); 594095059a4SDave May } 595521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 596095059a4SDave May ierr = MPI_Irecv(&de->messages_to_be_recvieved[i], 1, MPIU_INT, de->neighbour_procs[i], de->recv_tags[i], de->comm, &de->_requests[np+i]);CHKERRQ(ierr); 597095059a4SDave May } 598095059a4SDave May ierr = MPI_Waitall(2*np, de->_requests, de->_stats);CHKERRQ(ierr); 599095059a4SDave May /* create space for the data to be recvieved */ 600095059a4SDave May total = 0; 601521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 602095059a4SDave May total = total + de->messages_to_be_recvieved[i]; 603095059a4SDave May } 604521f74f9SMatthew G. Knepley ierr = PetscMalloc(de->unit_message_size * (total + 1), &de->recv_message);CHKERRQ(ierr); 605095059a4SDave May /* initialize memory */ 606521f74f9SMatthew G. Knepley ierr = PetscMemzero(de->recv_message, de->unit_message_size * (total + 1));CHKERRQ(ierr); 607*2d4ee042Sprj- /* set total items to receive */ 608095059a4SDave May de->recv_message_length = total; 609095059a4SDave May de->packer_status = DEOBJECT_FINALIZED; 610095059a4SDave May de->communication_status = DEOBJECT_INITIALIZED; 611ed923d71SDave May ierr = PetscLogEventEnd(DMSWARM_DataExchangerPack,0,0,0,0);CHKERRQ(ierr); 612095059a4SDave May PetscFunctionReturn(0); 613095059a4SDave May } 614095059a4SDave May 615095059a4SDave May /* do the actual message passing now */ 61677048351SPatrick Sanan PetscErrorCode DMSwarmDataExBegin(DMSwarmDataEx de) 617095059a4SDave May { 618095059a4SDave May PetscMPIInt i,np; 619095059a4SDave May void *dest; 620095059a4SDave May PetscInt length; 621095059a4SDave May PetscErrorCode ierr; 622095059a4SDave May 623095059a4SDave May PetscFunctionBegin; 624521f74f9SMatthew G. Knepley if (de->topology_status != DEOBJECT_FINALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Topology not finalized" ); 625521f74f9SMatthew G. Knepley if (de->message_lengths_status != DEOBJECT_FINALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Message lengths not finalized" ); 626521f74f9SMatthew G. Knepley if (de->packer_status != DEOBJECT_FINALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Packer not finalized" ); 62777048351SPatrick Sanan if (de->communication_status == DEOBJECT_FINALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Communication has already been finalized. Must call DMSwarmDataExInitialize() first." ); 62877048351SPatrick Sanan if (!de->recv_message) SETERRQ( de->comm, PETSC_ERR_ORDER, "recv_message has not been initialized. Must call DMSwarmDataExPackFinalize() first" ); 629ed923d71SDave May ierr = PetscLogEventBegin(DMSWARM_DataExchangerBegin,0,0,0,0);CHKERRQ(ierr); 630095059a4SDave May np = de->n_neighbour_procs; 631095059a4SDave May /* == NON BLOCKING == */ 632521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 633095059a4SDave May length = de->messages_to_be_sent[i] * de->unit_message_size; 634095059a4SDave May dest = ((char*)de->send_message) + de->unit_message_size * de->message_offsets[i]; 635095059a4SDave May ierr = MPI_Isend( dest, length, MPI_CHAR, de->neighbour_procs[i], de->send_tags[i], de->comm, &de->_requests[i] );CHKERRQ(ierr); 636095059a4SDave May } 637ed923d71SDave May ierr = PetscLogEventEnd(DMSWARM_DataExchangerBegin,0,0,0,0);CHKERRQ(ierr); 638095059a4SDave May PetscFunctionReturn(0); 639095059a4SDave May } 640095059a4SDave May 641095059a4SDave May /* do the actual message passing now */ 64277048351SPatrick Sanan PetscErrorCode DMSwarmDataExEnd(DMSwarmDataEx de) 643095059a4SDave May { 644095059a4SDave May PetscMPIInt i,np; 645095059a4SDave May PetscInt total; 646095059a4SDave May PetscInt *message_recv_offsets; 647095059a4SDave May void *dest; 648095059a4SDave May PetscInt length; 649095059a4SDave May PetscErrorCode ierr; 650095059a4SDave May 651095059a4SDave May PetscFunctionBegin; 65277048351SPatrick Sanan if (de->communication_status != DEOBJECT_INITIALIZED) SETERRQ( de->comm, PETSC_ERR_ORDER, "Communication has not been initialized. Must call DMSwarmDataExInitialize() first." ); 65377048351SPatrick Sanan if (!de->recv_message) SETERRQ( de->comm, PETSC_ERR_ORDER, "recv_message has not been initialized. Must call DMSwarmDataExPackFinalize() first" ); 654ed923d71SDave May ierr = PetscLogEventBegin(DMSWARM_DataExchangerEnd,0,0,0,0);CHKERRQ(ierr); 655095059a4SDave May np = de->n_neighbour_procs; 656b9a482c4SDave May ierr = PetscMalloc1(np+1, &message_recv_offsets);CHKERRQ(ierr); 657095059a4SDave May message_recv_offsets[0] = 0; 658095059a4SDave May total = de->messages_to_be_recvieved[0]; 659521f74f9SMatthew G. Knepley for (i = 1; i < np; ++i) { 660095059a4SDave May message_recv_offsets[i] = total; 661095059a4SDave May total = total + de->messages_to_be_recvieved[i]; 662095059a4SDave May } 663095059a4SDave May /* == NON BLOCKING == */ 664521f74f9SMatthew G. Knepley for (i = 0; i < np; ++i) { 665095059a4SDave May length = de->messages_to_be_recvieved[i] * de->unit_message_size; 666095059a4SDave May dest = ((char*)de->recv_message) + de->unit_message_size * message_recv_offsets[i]; 667095059a4SDave May ierr = MPI_Irecv( dest, length, MPI_CHAR, de->neighbour_procs[i], de->recv_tags[i], de->comm, &de->_requests[np+i] );CHKERRQ(ierr); 668095059a4SDave May } 669095059a4SDave May ierr = MPI_Waitall( 2*np, de->_requests, de->_stats );CHKERRQ(ierr); 670459726d8SSatish Balay ierr = PetscFree(message_recv_offsets);CHKERRQ(ierr); 671095059a4SDave May de->communication_status = DEOBJECT_FINALIZED; 672ed923d71SDave May ierr = PetscLogEventEnd(DMSWARM_DataExchangerEnd,0,0,0,0);CHKERRQ(ierr); 673095059a4SDave May PetscFunctionReturn(0); 674095059a4SDave May } 675095059a4SDave May 67677048351SPatrick Sanan PetscErrorCode DMSwarmDataExGetSendData(DMSwarmDataEx de,PetscInt *length,void **send) 677095059a4SDave May { 678095059a4SDave May PetscFunctionBegin; 679521f74f9SMatthew G. Knepley if (de->packer_status != DEOBJECT_FINALIZED) SETERRQ( de->comm, PETSC_ERR_ARG_WRONGSTATE, "Data has not finished being packed." ); 680095059a4SDave May *length = de->send_message_length; 681095059a4SDave May *send = de->send_message; 682095059a4SDave May PetscFunctionReturn(0); 683095059a4SDave May } 684095059a4SDave May 68577048351SPatrick Sanan PetscErrorCode DMSwarmDataExGetRecvData(DMSwarmDataEx de,PetscInt *length,void **recv) 686095059a4SDave May { 687095059a4SDave May PetscFunctionBegin; 688521f74f9SMatthew G. Knepley if (de->communication_status != DEOBJECT_FINALIZED) SETERRQ( de->comm, PETSC_ERR_ARG_WRONGSTATE, "Data has not finished being sent." ); 689095059a4SDave May *length = de->recv_message_length; 690095059a4SDave May *recv = de->recv_message; 691095059a4SDave May PetscFunctionReturn(0); 692095059a4SDave May } 693095059a4SDave May 69477048351SPatrick Sanan PetscErrorCode DMSwarmDataExTopologyGetNeighbours(DMSwarmDataEx de,PetscMPIInt *n,PetscMPIInt *neigh[]) 695095059a4SDave May { 696095059a4SDave May PetscFunctionBegin; 697095059a4SDave May if (n) {*n = de->n_neighbour_procs;} 698095059a4SDave May if (neigh) {*neigh = de->neighbour_procs;} 699095059a4SDave May PetscFunctionReturn(0); 700095059a4SDave May } 701095059a4SDave May 702