12d5177cdSBarry Smith 2b45d2f2cSJed Brown #include <petsc-private/matimpl.h> 35bd3b8fbSHong Zhang 4bc5ccf88SSatish Balay #define DEFAULT_STASH_SIZE 10000 54c1ff481SSatish Balay 6*ac2b2aa0SJed Brown static PetscErrorCode MatStashScatterBegin_Ref(Mat,MatStash*,PetscInt*); 7*ac2b2aa0SJed Brown static PetscErrorCode MatStashScatterGetMesg_Ref(MatStash*,PetscMPIInt*,PetscInt**,PetscInt**,PetscScalar**,PetscInt*); 8*ac2b2aa0SJed Brown static PetscErrorCode MatStashScatterEnd_Ref(MatStash*); 99417f4adSLois Curfman McInnes /* 108798bf22SSatish Balay MatStashCreate_Private - Creates a stash,currently used for all the parallel 114c1ff481SSatish Balay matrix implementations. The stash is where elements of a matrix destined 124c1ff481SSatish Balay to be stored on other processors are kept until matrix assembly is done. 139417f4adSLois Curfman McInnes 144c1ff481SSatish Balay This is a simple minded stash. Simply adds entries to end of stash. 154c1ff481SSatish Balay 164c1ff481SSatish Balay Input Parameters: 174c1ff481SSatish Balay comm - communicator, required for scatters. 184c1ff481SSatish Balay bs - stash block size. used when stashing blocks of values 194c1ff481SSatish Balay 204c1ff481SSatish Balay Output Parameters: 214c1ff481SSatish Balay stash - the newly created stash 229417f4adSLois Curfman McInnes */ 234a2ae208SSatish Balay #undef __FUNCT__ 244a2ae208SSatish Balay #define __FUNCT__ "MatStashCreate_Private" 25c1ac3661SBarry Smith PetscErrorCode MatStashCreate_Private(MPI_Comm comm,PetscInt bs,MatStash *stash) 269417f4adSLois Curfman McInnes { 27dfbe8321SBarry Smith PetscErrorCode ierr; 28533163c2SBarry Smith PetscInt max,*opt,nopt,i; 29ace3abfcSBarry Smith PetscBool flg; 30bc5ccf88SSatish Balay 313a40ed3dSBarry Smith PetscFunctionBegin; 32bc5ccf88SSatish Balay /* Require 2 tags,get the second using PetscCommGetNewTag() */ 33752ec6e0SSatish Balay stash->comm = comm; 348865f1eaSKarl Rupp 35752ec6e0SSatish Balay ierr = PetscCommGetNewTag(stash->comm,&stash->tag1);CHKERRQ(ierr); 36a2d1c673SSatish Balay ierr = PetscCommGetNewTag(stash->comm,&stash->tag2);CHKERRQ(ierr); 37a2d1c673SSatish Balay ierr = MPI_Comm_size(stash->comm,&stash->size);CHKERRQ(ierr); 38a2d1c673SSatish Balay ierr = MPI_Comm_rank(stash->comm,&stash->rank);CHKERRQ(ierr); 39785e854fSJed Brown ierr = PetscMalloc1(2*stash->size,&stash->flg_v);CHKERRQ(ierr); 40533163c2SBarry Smith for (i=0; i<2*stash->size; i++) stash->flg_v[i] = -1; 41533163c2SBarry Smith 42bc5ccf88SSatish Balay 43434d7ff9SSatish Balay nopt = stash->size; 44785e854fSJed Brown ierr = PetscMalloc1(nopt,&opt);CHKERRQ(ierr); 450298fd71SBarry Smith ierr = PetscOptionsGetIntArray(NULL,"-matstash_initial_size",opt,&nopt,&flg);CHKERRQ(ierr); 46434d7ff9SSatish Balay if (flg) { 47434d7ff9SSatish Balay if (nopt == 1) max = opt[0]; 48434d7ff9SSatish Balay else if (nopt == stash->size) max = opt[stash->rank]; 49434d7ff9SSatish Balay else if (stash->rank < nopt) max = opt[stash->rank]; 50f4ab19daSSatish Balay else max = 0; /* Use default */ 51434d7ff9SSatish Balay stash->umax = max; 52434d7ff9SSatish Balay } else { 53434d7ff9SSatish Balay stash->umax = 0; 54434d7ff9SSatish Balay } 55606d414cSSatish Balay ierr = PetscFree(opt);CHKERRQ(ierr); 564c1ff481SSatish Balay if (bs <= 0) bs = 1; 57a2d1c673SSatish Balay 584c1ff481SSatish Balay stash->bs = bs; 599417f4adSLois Curfman McInnes stash->nmax = 0; 60434d7ff9SSatish Balay stash->oldnmax = 0; 619417f4adSLois Curfman McInnes stash->n = 0; 624c1ff481SSatish Balay stash->reallocs = -1; 6375cae7c1SHong Zhang stash->space_head = 0; 6475cae7c1SHong Zhang stash->space = 0; 659417f4adSLois Curfman McInnes 66bc5ccf88SSatish Balay stash->send_waits = 0; 67bc5ccf88SSatish Balay stash->recv_waits = 0; 68a2d1c673SSatish Balay stash->send_status = 0; 69bc5ccf88SSatish Balay stash->nsends = 0; 70bc5ccf88SSatish Balay stash->nrecvs = 0; 71bc5ccf88SSatish Balay stash->svalues = 0; 72bc5ccf88SSatish Balay stash->rvalues = 0; 73563fb871SSatish Balay stash->rindices = 0; 74a2d1c673SSatish Balay stash->nprocessed = 0; 7567318a8aSJed Brown stash->reproduce = PETSC_FALSE; 768865f1eaSKarl Rupp 770298fd71SBarry Smith ierr = PetscOptionsGetBool(NULL,"-matstash_reproduce",&stash->reproduce,NULL);CHKERRQ(ierr); 78*ac2b2aa0SJed Brown ierr = PetscOptionsGetBool(NULL,"-matstash_bts",&flg,NULL);CHKERRQ(ierr); 79*ac2b2aa0SJed Brown if (flg) { 80*ac2b2aa0SJed Brown SETERRQ(comm,PETSC_ERR_SUP,"Not implemented yet"); 81*ac2b2aa0SJed Brown } else { 82*ac2b2aa0SJed Brown stash->ScatterBegin = MatStashScatterBegin_Ref; 83*ac2b2aa0SJed Brown stash->ScatterGetMesg = MatStashScatterGetMesg_Ref; 84*ac2b2aa0SJed Brown stash->ScatterEnd = MatStashScatterEnd_Ref; 85*ac2b2aa0SJed Brown stash->ScatterDestroy = NULL; 86*ac2b2aa0SJed Brown } 873a40ed3dSBarry Smith PetscFunctionReturn(0); 889417f4adSLois Curfman McInnes } 899417f4adSLois Curfman McInnes 904c1ff481SSatish Balay /* 918798bf22SSatish Balay MatStashDestroy_Private - Destroy the stash 924c1ff481SSatish Balay */ 934a2ae208SSatish Balay #undef __FUNCT__ 944a2ae208SSatish Balay #define __FUNCT__ "MatStashDestroy_Private" 95dfbe8321SBarry Smith PetscErrorCode MatStashDestroy_Private(MatStash *stash) 969417f4adSLois Curfman McInnes { 97dfbe8321SBarry Smith PetscErrorCode ierr; 98a2d1c673SSatish Balay 99bc5ccf88SSatish Balay PetscFunctionBegin; 1006bf464f9SBarry Smith ierr = PetscMatStashSpaceDestroy(&stash->space_head);CHKERRQ(ierr); 101*ac2b2aa0SJed Brown if (stash->ScatterDestroy) {ierr = (*stash->ScatterDestroy)(stash);CHKERRQ(ierr);} 1028865f1eaSKarl Rupp 10382740460SHong Zhang stash->space = 0; 1048865f1eaSKarl Rupp 105533163c2SBarry Smith ierr = PetscFree(stash->flg_v);CHKERRQ(ierr); 106bc5ccf88SSatish Balay PetscFunctionReturn(0); 107bc5ccf88SSatish Balay } 108bc5ccf88SSatish Balay 1094c1ff481SSatish Balay /* 11067318a8aSJed Brown MatStashScatterEnd_Private - This is called as the final stage of 1114c1ff481SSatish Balay scatter. The final stages of message passing is done here, and 11267318a8aSJed Brown all the memory used for message passing is cleaned up. This 1134c1ff481SSatish Balay routine also resets the stash, and deallocates the memory used 1144c1ff481SSatish Balay for the stash. It also keeps track of the current memory usage 1154c1ff481SSatish Balay so that the same value can be used the next time through. 1164c1ff481SSatish Balay */ 1174a2ae208SSatish Balay #undef __FUNCT__ 1184a2ae208SSatish Balay #define __FUNCT__ "MatStashScatterEnd_Private" 119dfbe8321SBarry Smith PetscErrorCode MatStashScatterEnd_Private(MatStash *stash) 120bc5ccf88SSatish Balay { 1216849ba73SBarry Smith PetscErrorCode ierr; 122*ac2b2aa0SJed Brown 123*ac2b2aa0SJed Brown PetscFunctionBegin; 124*ac2b2aa0SJed Brown ierr = (*stash->ScatterEnd)(stash);CHKERRQ(ierr); 125*ac2b2aa0SJed Brown PetscFunctionReturn(0); 126*ac2b2aa0SJed Brown } 127*ac2b2aa0SJed Brown 128*ac2b2aa0SJed Brown #undef __FUNCT__ 129*ac2b2aa0SJed Brown #define __FUNCT__ "MatStashScatterEnd_Ref" 130*ac2b2aa0SJed Brown static PetscErrorCode MatStashScatterEnd_Ref(MatStash *stash) 131*ac2b2aa0SJed Brown { 132*ac2b2aa0SJed Brown PetscErrorCode ierr; 133533163c2SBarry Smith PetscInt nsends=stash->nsends,bs2,oldnmax,i; 134a2d1c673SSatish Balay MPI_Status *send_status; 135a2d1c673SSatish Balay 1363a40ed3dSBarry Smith PetscFunctionBegin; 137533163c2SBarry Smith for (i=0; i<2*stash->size; i++) stash->flg_v[i] = -1; 138a2d1c673SSatish Balay /* wait on sends */ 139a2d1c673SSatish Balay if (nsends) { 140785e854fSJed Brown ierr = PetscMalloc1(2*nsends,&send_status);CHKERRQ(ierr); 141a2d1c673SSatish Balay ierr = MPI_Waitall(2*nsends,stash->send_waits,send_status);CHKERRQ(ierr); 142606d414cSSatish Balay ierr = PetscFree(send_status);CHKERRQ(ierr); 143a2d1c673SSatish Balay } 144a2d1c673SSatish Balay 145c0c58ca7SSatish Balay /* Now update nmaxold to be app 10% more than max n used, this way the 146434d7ff9SSatish Balay wastage of space is reduced the next time this stash is used. 147434d7ff9SSatish Balay Also update the oldmax, only if it increases */ 148b9b97703SBarry Smith if (stash->n) { 14994b769a5SSatish Balay bs2 = stash->bs*stash->bs; 1508a9378f0SSatish Balay oldnmax = ((int)(stash->n * 1.1) + 5)*bs2; 151434d7ff9SSatish Balay if (oldnmax > stash->oldnmax) stash->oldnmax = oldnmax; 152b9b97703SBarry Smith } 153434d7ff9SSatish Balay 154d07ff455SSatish Balay stash->nmax = 0; 155d07ff455SSatish Balay stash->n = 0; 1564c1ff481SSatish Balay stash->reallocs = -1; 157a2d1c673SSatish Balay stash->nprocessed = 0; 1588865f1eaSKarl Rupp 1596bf464f9SBarry Smith ierr = PetscMatStashSpaceDestroy(&stash->space_head);CHKERRQ(ierr); 1608865f1eaSKarl Rupp 16182740460SHong Zhang stash->space = 0; 1628865f1eaSKarl Rupp 163606d414cSSatish Balay ierr = PetscFree(stash->send_waits);CHKERRQ(ierr); 164606d414cSSatish Balay ierr = PetscFree(stash->recv_waits);CHKERRQ(ierr); 165c05d87d6SBarry Smith ierr = PetscFree2(stash->svalues,stash->sindices);CHKERRQ(ierr); 166c05d87d6SBarry Smith ierr = PetscFree(stash->rvalues[0]);CHKERRQ(ierr); 167606d414cSSatish Balay ierr = PetscFree(stash->rvalues);CHKERRQ(ierr); 168c05d87d6SBarry Smith ierr = PetscFree(stash->rindices[0]);CHKERRQ(ierr); 169563fb871SSatish Balay ierr = PetscFree(stash->rindices);CHKERRQ(ierr); 1703a40ed3dSBarry Smith PetscFunctionReturn(0); 1719417f4adSLois Curfman McInnes } 1729417f4adSLois Curfman McInnes 1734c1ff481SSatish Balay /* 1748798bf22SSatish Balay MatStashGetInfo_Private - Gets the relavant statistics of the stash 1754c1ff481SSatish Balay 1764c1ff481SSatish Balay Input Parameters: 1774c1ff481SSatish Balay stash - the stash 17894b769a5SSatish Balay nstash - the size of the stash. Indicates the number of values stored. 1794c1ff481SSatish Balay reallocs - the number of additional mallocs incurred. 1804c1ff481SSatish Balay 1814c1ff481SSatish Balay */ 1824a2ae208SSatish Balay #undef __FUNCT__ 1834a2ae208SSatish Balay #define __FUNCT__ "MatStashGetInfo_Private" 184c1ac3661SBarry Smith PetscErrorCode MatStashGetInfo_Private(MatStash *stash,PetscInt *nstash,PetscInt *reallocs) 18597530c3fSBarry Smith { 186c1ac3661SBarry Smith PetscInt bs2 = stash->bs*stash->bs; 18794b769a5SSatish Balay 1883a40ed3dSBarry Smith PetscFunctionBegin; 1891ecfd215SBarry Smith if (nstash) *nstash = stash->n*bs2; 1901ecfd215SBarry Smith if (reallocs) { 191434d7ff9SSatish Balay if (stash->reallocs < 0) *reallocs = 0; 192434d7ff9SSatish Balay else *reallocs = stash->reallocs; 1931ecfd215SBarry Smith } 194bc5ccf88SSatish Balay PetscFunctionReturn(0); 195bc5ccf88SSatish Balay } 1964c1ff481SSatish Balay 1974c1ff481SSatish Balay /* 1988798bf22SSatish Balay MatStashSetInitialSize_Private - Sets the initial size of the stash 1994c1ff481SSatish Balay 2004c1ff481SSatish Balay Input Parameters: 2014c1ff481SSatish Balay stash - the stash 2024c1ff481SSatish Balay max - the value that is used as the max size of the stash. 2034c1ff481SSatish Balay this value is used while allocating memory. 2044c1ff481SSatish Balay */ 2054a2ae208SSatish Balay #undef __FUNCT__ 2064a2ae208SSatish Balay #define __FUNCT__ "MatStashSetInitialSize_Private" 207c1ac3661SBarry Smith PetscErrorCode MatStashSetInitialSize_Private(MatStash *stash,PetscInt max) 208bc5ccf88SSatish Balay { 209bc5ccf88SSatish Balay PetscFunctionBegin; 210434d7ff9SSatish Balay stash->umax = max; 2113a40ed3dSBarry Smith PetscFunctionReturn(0); 21297530c3fSBarry Smith } 21397530c3fSBarry Smith 2148798bf22SSatish Balay /* MatStashExpand_Private - Expand the stash. This function is called 2154c1ff481SSatish Balay when the space in the stash is not sufficient to add the new values 2164c1ff481SSatish Balay being inserted into the stash. 2174c1ff481SSatish Balay 2184c1ff481SSatish Balay Input Parameters: 2194c1ff481SSatish Balay stash - the stash 2204c1ff481SSatish Balay incr - the minimum increase requested 2214c1ff481SSatish Balay 2224c1ff481SSatish Balay Notes: 2234c1ff481SSatish Balay This routine doubles the currently used memory. 2244c1ff481SSatish Balay */ 2254a2ae208SSatish Balay #undef __FUNCT__ 2264a2ae208SSatish Balay #define __FUNCT__ "MatStashExpand_Private" 227c1ac3661SBarry Smith static PetscErrorCode MatStashExpand_Private(MatStash *stash,PetscInt incr) 2289417f4adSLois Curfman McInnes { 2296849ba73SBarry Smith PetscErrorCode ierr; 2305bd3b8fbSHong Zhang PetscInt newnmax,bs2= stash->bs*stash->bs; 2319417f4adSLois Curfman McInnes 2323a40ed3dSBarry Smith PetscFunctionBegin; 2339417f4adSLois Curfman McInnes /* allocate a larger stash */ 234c481ceb5SSatish Balay if (!stash->oldnmax && !stash->nmax) { /* new stash */ 235434d7ff9SSatish Balay if (stash->umax) newnmax = stash->umax/bs2; 236434d7ff9SSatish Balay else newnmax = DEFAULT_STASH_SIZE/bs2; 237c481ceb5SSatish Balay } else if (!stash->nmax) { /* resuing stash */ 238434d7ff9SSatish Balay if (stash->umax > stash->oldnmax) newnmax = stash->umax/bs2; 239434d7ff9SSatish Balay else newnmax = stash->oldnmax/bs2; 240434d7ff9SSatish Balay } else newnmax = stash->nmax*2; 2414c1ff481SSatish Balay if (newnmax < (stash->nmax + incr)) newnmax += 2*incr; 242d07ff455SSatish Balay 24375cae7c1SHong Zhang /* Get a MatStashSpace and attach it to stash */ 24475cae7c1SHong Zhang ierr = PetscMatStashSpaceGet(bs2,newnmax,&stash->space);CHKERRQ(ierr); 245b087b6d6SSatish Balay if (!stash->space_head) { /* new stash or resuing stash->oldnmax */ 246b087b6d6SSatish Balay stash->space_head = stash->space; 24775cae7c1SHong Zhang } 248b087b6d6SSatish Balay 249bc5ccf88SSatish Balay stash->reallocs++; 25075cae7c1SHong Zhang stash->nmax = newnmax; 251bc5ccf88SSatish Balay PetscFunctionReturn(0); 252bc5ccf88SSatish Balay } 253bc5ccf88SSatish Balay /* 2548798bf22SSatish Balay MatStashValuesRow_Private - inserts values into the stash. This function 2554c1ff481SSatish Balay expects the values to be roworiented. Multiple columns belong to the same row 2564c1ff481SSatish Balay can be inserted with a single call to this function. 2574c1ff481SSatish Balay 2584c1ff481SSatish Balay Input Parameters: 2594c1ff481SSatish Balay stash - the stash 2604c1ff481SSatish Balay row - the global row correspoiding to the values 2614c1ff481SSatish Balay n - the number of elements inserted. All elements belong to the above row. 2624c1ff481SSatish Balay idxn - the global column indices corresponding to each of the values. 2634c1ff481SSatish Balay values - the values inserted 264bc5ccf88SSatish Balay */ 2654a2ae208SSatish Balay #undef __FUNCT__ 2664a2ae208SSatish Balay #define __FUNCT__ "MatStashValuesRow_Private" 267ace3abfcSBarry Smith PetscErrorCode MatStashValuesRow_Private(MatStash *stash,PetscInt row,PetscInt n,const PetscInt idxn[],const PetscScalar values[],PetscBool ignorezeroentries) 268bc5ccf88SSatish Balay { 269dfbe8321SBarry Smith PetscErrorCode ierr; 270b400d20cSBarry Smith PetscInt i,k,cnt = 0; 27175cae7c1SHong Zhang PetscMatStashSpace space=stash->space; 272bc5ccf88SSatish Balay 273bc5ccf88SSatish Balay PetscFunctionBegin; 2744c1ff481SSatish Balay /* Check and see if we have sufficient memory */ 27575cae7c1SHong Zhang if (!space || space->local_remaining < n) { 2768798bf22SSatish Balay ierr = MatStashExpand_Private(stash,n);CHKERRQ(ierr); 2779417f4adSLois Curfman McInnes } 27875cae7c1SHong Zhang space = stash->space; 27975cae7c1SHong Zhang k = space->local_used; 2804c1ff481SSatish Balay for (i=0; i<n; i++) { 28188c3974fSBarry Smith if (ignorezeroentries && (values[i] == 0.0)) continue; 28275cae7c1SHong Zhang space->idx[k] = row; 28375cae7c1SHong Zhang space->idy[k] = idxn[i]; 28475cae7c1SHong Zhang space->val[k] = values[i]; 28575cae7c1SHong Zhang k++; 286b400d20cSBarry Smith cnt++; 2879417f4adSLois Curfman McInnes } 288b400d20cSBarry Smith stash->n += cnt; 289b400d20cSBarry Smith space->local_used += cnt; 290b400d20cSBarry Smith space->local_remaining -= cnt; 291a2d1c673SSatish Balay PetscFunctionReturn(0); 292a2d1c673SSatish Balay } 29375cae7c1SHong Zhang 2944c1ff481SSatish Balay /* 2958798bf22SSatish Balay MatStashValuesCol_Private - inserts values into the stash. This function 2964c1ff481SSatish Balay expects the values to be columnoriented. Multiple columns belong to the same row 2974c1ff481SSatish Balay can be inserted with a single call to this function. 298a2d1c673SSatish Balay 2994c1ff481SSatish Balay Input Parameters: 3004c1ff481SSatish Balay stash - the stash 3014c1ff481SSatish Balay row - the global row correspoiding to the values 3024c1ff481SSatish Balay n - the number of elements inserted. All elements belong to the above row. 3034c1ff481SSatish Balay idxn - the global column indices corresponding to each of the values. 3044c1ff481SSatish Balay values - the values inserted 3054c1ff481SSatish Balay stepval - the consecutive values are sepated by a distance of stepval. 3064c1ff481SSatish Balay this happens because the input is columnoriented. 3074c1ff481SSatish Balay */ 3084a2ae208SSatish Balay #undef __FUNCT__ 3094a2ae208SSatish Balay #define __FUNCT__ "MatStashValuesCol_Private" 310ace3abfcSBarry Smith PetscErrorCode MatStashValuesCol_Private(MatStash *stash,PetscInt row,PetscInt n,const PetscInt idxn[],const PetscScalar values[],PetscInt stepval,PetscBool ignorezeroentries) 311a2d1c673SSatish Balay { 312dfbe8321SBarry Smith PetscErrorCode ierr; 31350e9ab7cSBarry Smith PetscInt i,k,cnt = 0; 31475cae7c1SHong Zhang PetscMatStashSpace space=stash->space; 315a2d1c673SSatish Balay 3164c1ff481SSatish Balay PetscFunctionBegin; 3174c1ff481SSatish Balay /* Check and see if we have sufficient memory */ 31875cae7c1SHong Zhang if (!space || space->local_remaining < n) { 3198798bf22SSatish Balay ierr = MatStashExpand_Private(stash,n);CHKERRQ(ierr); 3204c1ff481SSatish Balay } 32175cae7c1SHong Zhang space = stash->space; 32275cae7c1SHong Zhang k = space->local_used; 3234c1ff481SSatish Balay for (i=0; i<n; i++) { 32488c3974fSBarry Smith if (ignorezeroentries && (values[i*stepval] == 0.0)) continue; 32575cae7c1SHong Zhang space->idx[k] = row; 32675cae7c1SHong Zhang space->idy[k] = idxn[i]; 32775cae7c1SHong Zhang space->val[k] = values[i*stepval]; 32875cae7c1SHong Zhang k++; 329b400d20cSBarry Smith cnt++; 3304c1ff481SSatish Balay } 331b400d20cSBarry Smith stash->n += cnt; 332b400d20cSBarry Smith space->local_used += cnt; 333b400d20cSBarry Smith space->local_remaining -= cnt; 3344c1ff481SSatish Balay PetscFunctionReturn(0); 3354c1ff481SSatish Balay } 3364c1ff481SSatish Balay 3374c1ff481SSatish Balay /* 3388798bf22SSatish Balay MatStashValuesRowBlocked_Private - inserts blocks of values into the stash. 3394c1ff481SSatish Balay This function expects the values to be roworiented. Multiple columns belong 3404c1ff481SSatish Balay to the same block-row can be inserted with a single call to this function. 3414c1ff481SSatish Balay This function extracts the sub-block of values based on the dimensions of 3424c1ff481SSatish Balay the original input block, and the row,col values corresponding to the blocks. 3434c1ff481SSatish Balay 3444c1ff481SSatish Balay Input Parameters: 3454c1ff481SSatish Balay stash - the stash 3464c1ff481SSatish Balay row - the global block-row correspoiding to the values 3474c1ff481SSatish Balay n - the number of elements inserted. All elements belong to the above row. 3484c1ff481SSatish Balay idxn - the global block-column indices corresponding to each of the blocks of 3494c1ff481SSatish Balay values. Each block is of size bs*bs. 3504c1ff481SSatish Balay values - the values inserted 3514c1ff481SSatish Balay rmax - the number of block-rows in the original block. 3524c1ff481SSatish Balay cmax - the number of block-columsn on the original block. 3534c1ff481SSatish Balay idx - the index of the current block-row in the original block. 3544c1ff481SSatish Balay */ 3554a2ae208SSatish Balay #undef __FUNCT__ 3564a2ae208SSatish Balay #define __FUNCT__ "MatStashValuesRowBlocked_Private" 35754f21887SBarry Smith PetscErrorCode MatStashValuesRowBlocked_Private(MatStash *stash,PetscInt row,PetscInt n,const PetscInt idxn[],const PetscScalar values[],PetscInt rmax,PetscInt cmax,PetscInt idx) 3584c1ff481SSatish Balay { 359dfbe8321SBarry Smith PetscErrorCode ierr; 36075cae7c1SHong Zhang PetscInt i,j,k,bs2,bs=stash->bs,l; 36154f21887SBarry Smith const PetscScalar *vals; 36254f21887SBarry Smith PetscScalar *array; 36375cae7c1SHong Zhang PetscMatStashSpace space=stash->space; 364a2d1c673SSatish Balay 365a2d1c673SSatish Balay PetscFunctionBegin; 36675cae7c1SHong Zhang if (!space || space->local_remaining < n) { 3678798bf22SSatish Balay ierr = MatStashExpand_Private(stash,n);CHKERRQ(ierr); 368a2d1c673SSatish Balay } 36975cae7c1SHong Zhang space = stash->space; 37075cae7c1SHong Zhang l = space->local_used; 37175cae7c1SHong Zhang bs2 = bs*bs; 3724c1ff481SSatish Balay for (i=0; i<n; i++) { 37375cae7c1SHong Zhang space->idx[l] = row; 37475cae7c1SHong Zhang space->idy[l] = idxn[i]; 37575cae7c1SHong Zhang /* Now copy over the block of values. Store the values column oriented. 37675cae7c1SHong Zhang This enables inserting multiple blocks belonging to a row with a single 37775cae7c1SHong Zhang funtion call */ 37875cae7c1SHong Zhang array = space->val + bs2*l; 37975cae7c1SHong Zhang vals = values + idx*bs2*n + bs*i; 38075cae7c1SHong Zhang for (j=0; j<bs; j++) { 38175cae7c1SHong Zhang for (k=0; k<bs; k++) array[k*bs] = vals[k]; 38275cae7c1SHong Zhang array++; 38375cae7c1SHong Zhang vals += cmax*bs; 38475cae7c1SHong Zhang } 38575cae7c1SHong Zhang l++; 386a2d1c673SSatish Balay } 3875bd3b8fbSHong Zhang stash->n += n; 38875cae7c1SHong Zhang space->local_used += n; 38975cae7c1SHong Zhang space->local_remaining -= n; 3904c1ff481SSatish Balay PetscFunctionReturn(0); 3914c1ff481SSatish Balay } 3924c1ff481SSatish Balay 3934c1ff481SSatish Balay /* 3948798bf22SSatish Balay MatStashValuesColBlocked_Private - inserts blocks of values into the stash. 3954c1ff481SSatish Balay This function expects the values to be roworiented. Multiple columns belong 3964c1ff481SSatish Balay to the same block-row can be inserted with a single call to this function. 3974c1ff481SSatish Balay This function extracts the sub-block of values based on the dimensions of 3984c1ff481SSatish Balay the original input block, and the row,col values corresponding to the blocks. 3994c1ff481SSatish Balay 4004c1ff481SSatish Balay Input Parameters: 4014c1ff481SSatish Balay stash - the stash 4024c1ff481SSatish Balay row - the global block-row correspoiding to the values 4034c1ff481SSatish Balay n - the number of elements inserted. All elements belong to the above row. 4044c1ff481SSatish Balay idxn - the global block-column indices corresponding to each of the blocks of 4054c1ff481SSatish Balay values. Each block is of size bs*bs. 4064c1ff481SSatish Balay values - the values inserted 4074c1ff481SSatish Balay rmax - the number of block-rows in the original block. 4084c1ff481SSatish Balay cmax - the number of block-columsn on the original block. 4094c1ff481SSatish Balay idx - the index of the current block-row in the original block. 4104c1ff481SSatish Balay */ 4114a2ae208SSatish Balay #undef __FUNCT__ 4124a2ae208SSatish Balay #define __FUNCT__ "MatStashValuesColBlocked_Private" 41354f21887SBarry Smith PetscErrorCode MatStashValuesColBlocked_Private(MatStash *stash,PetscInt row,PetscInt n,const PetscInt idxn[],const PetscScalar values[],PetscInt rmax,PetscInt cmax,PetscInt idx) 4144c1ff481SSatish Balay { 415dfbe8321SBarry Smith PetscErrorCode ierr; 41675cae7c1SHong Zhang PetscInt i,j,k,bs2,bs=stash->bs,l; 41754f21887SBarry Smith const PetscScalar *vals; 41854f21887SBarry Smith PetscScalar *array; 41975cae7c1SHong Zhang PetscMatStashSpace space=stash->space; 4204c1ff481SSatish Balay 4214c1ff481SSatish Balay PetscFunctionBegin; 42275cae7c1SHong Zhang if (!space || space->local_remaining < n) { 4238798bf22SSatish Balay ierr = MatStashExpand_Private(stash,n);CHKERRQ(ierr); 4244c1ff481SSatish Balay } 42575cae7c1SHong Zhang space = stash->space; 42675cae7c1SHong Zhang l = space->local_used; 42775cae7c1SHong Zhang bs2 = bs*bs; 4284c1ff481SSatish Balay for (i=0; i<n; i++) { 42975cae7c1SHong Zhang space->idx[l] = row; 43075cae7c1SHong Zhang space->idy[l] = idxn[i]; 43175cae7c1SHong Zhang /* Now copy over the block of values. Store the values column oriented. 43275cae7c1SHong Zhang This enables inserting multiple blocks belonging to a row with a single 43375cae7c1SHong Zhang funtion call */ 43475cae7c1SHong Zhang array = space->val + bs2*l; 43575cae7c1SHong Zhang vals = values + idx*bs2*n + bs*i; 43675cae7c1SHong Zhang for (j=0; j<bs; j++) { 4378865f1eaSKarl Rupp for (k=0; k<bs; k++) array[k] = vals[k]; 43875cae7c1SHong Zhang array += bs; 43975cae7c1SHong Zhang vals += rmax*bs; 44075cae7c1SHong Zhang } 4415bd3b8fbSHong Zhang l++; 442a2d1c673SSatish Balay } 4435bd3b8fbSHong Zhang stash->n += n; 44475cae7c1SHong Zhang space->local_used += n; 44575cae7c1SHong Zhang space->local_remaining -= n; 4463a40ed3dSBarry Smith PetscFunctionReturn(0); 4479417f4adSLois Curfman McInnes } 4484c1ff481SSatish Balay /* 4498798bf22SSatish Balay MatStashScatterBegin_Private - Initiates the transfer of values to the 4504c1ff481SSatish Balay correct owners. This function goes through the stash, and check the 4514c1ff481SSatish Balay owners of each stashed value, and sends the values off to the owner 4524c1ff481SSatish Balay processors. 453bc5ccf88SSatish Balay 4544c1ff481SSatish Balay Input Parameters: 4554c1ff481SSatish Balay stash - the stash 4564c1ff481SSatish Balay owners - an array of size 'no-of-procs' which gives the ownership range 4574c1ff481SSatish Balay for each node. 4584c1ff481SSatish Balay 4594c1ff481SSatish Balay Notes: The 'owners' array in the cased of the blocked-stash has the 4604c1ff481SSatish Balay ranges specified blocked global indices, and for the regular stash in 4614c1ff481SSatish Balay the proper global indices. 4624c1ff481SSatish Balay */ 4634a2ae208SSatish Balay #undef __FUNCT__ 4644a2ae208SSatish Balay #define __FUNCT__ "MatStashScatterBegin_Private" 4651e2582c4SBarry Smith PetscErrorCode MatStashScatterBegin_Private(Mat mat,MatStash *stash,PetscInt *owners) 466bc5ccf88SSatish Balay { 467*ac2b2aa0SJed Brown PetscErrorCode ierr; 468*ac2b2aa0SJed Brown 469*ac2b2aa0SJed Brown PetscFunctionBegin; 470*ac2b2aa0SJed Brown ierr = (*stash->ScatterBegin)(mat,stash,owners);CHKERRQ(ierr); 471*ac2b2aa0SJed Brown PetscFunctionReturn(0); 472*ac2b2aa0SJed Brown } 473*ac2b2aa0SJed Brown 474*ac2b2aa0SJed Brown #undef __FUNCT__ 475*ac2b2aa0SJed Brown #define __FUNCT__ "MatStashScatterBegin_Ref" 476*ac2b2aa0SJed Brown static PetscErrorCode MatStashScatterBegin_Ref(Mat mat,MatStash *stash,PetscInt *owners) 477*ac2b2aa0SJed Brown { 478c1ac3661SBarry Smith PetscInt *owner,*startv,*starti,tag1=stash->tag1,tag2=stash->tag2,bs2; 479fe09c992SBarry Smith PetscInt size=stash->size,nsends; 4806849ba73SBarry Smith PetscErrorCode ierr; 48175cae7c1SHong Zhang PetscInt count,*sindices,**rindices,i,j,idx,lastidx,l; 48254f21887SBarry Smith PetscScalar **rvalues,*svalues; 483bc5ccf88SSatish Balay MPI_Comm comm = stash->comm; 484563fb871SSatish Balay MPI_Request *send_waits,*recv_waits,*recv_waits1,*recv_waits2; 48576ec1555SBarry Smith PetscMPIInt *sizes,*nlengths,nreceives; 4865bd3b8fbSHong Zhang PetscInt *sp_idx,*sp_idy; 48754f21887SBarry Smith PetscScalar *sp_val; 4885bd3b8fbSHong Zhang PetscMatStashSpace space,space_next; 489bc5ccf88SSatish Balay 490bc5ccf88SSatish Balay PetscFunctionBegin; 4914c1ff481SSatish Balay bs2 = stash->bs*stash->bs; 49275cae7c1SHong Zhang 493bc5ccf88SSatish Balay /* first count number of contributors to each processor */ 494037dbc42SBarry Smith ierr = PetscCalloc1(size,&sizes);CHKERRQ(ierr); 4951795a4d1SJed Brown ierr = PetscCalloc1(size,&nlengths);CHKERRQ(ierr); 496037dbc42SBarry Smith ierr = PetscMalloc1(stash->n+1,&owner);CHKERRQ(ierr); 497a2d1c673SSatish Balay 49875cae7c1SHong Zhang i = j = 0; 4997357eb19SBarry Smith lastidx = -1; 5005bd3b8fbSHong Zhang space = stash->space_head; 5010298fd71SBarry Smith while (space != NULL) { 50275cae7c1SHong Zhang space_next = space->next; 5035bd3b8fbSHong Zhang sp_idx = space->idx; 50475cae7c1SHong Zhang for (l=0; l<space->local_used; l++) { 5057357eb19SBarry Smith /* if indices are NOT locally sorted, need to start search at the beginning */ 5065bd3b8fbSHong Zhang if (lastidx > (idx = sp_idx[l])) j = 0; 5077357eb19SBarry Smith lastidx = idx; 5087357eb19SBarry Smith for (; j<size; j++) { 5094c1ff481SSatish Balay if (idx >= owners[j] && idx < owners[j+1]) { 510563fb871SSatish Balay nlengths[j]++; owner[i] = j; break; 511bc5ccf88SSatish Balay } 512bc5ccf88SSatish Balay } 51375cae7c1SHong Zhang i++; 51475cae7c1SHong Zhang } 51575cae7c1SHong Zhang space = space_next; 516bc5ccf88SSatish Balay } 517563fb871SSatish Balay /* Now check what procs get messages - and compute nsends. */ 518563fb871SSatish Balay for (i=0, nsends=0; i<size; i++) { 5198865f1eaSKarl Rupp if (nlengths[i]) { 52076ec1555SBarry Smith sizes[i] = 1; nsends++; 5218865f1eaSKarl Rupp } 522563fb871SSatish Balay } 523bc5ccf88SSatish Balay 52454f21887SBarry Smith {PetscMPIInt *onodes,*olengths; 525563fb871SSatish Balay /* Determine the number of messages to expect, their lengths, from from-ids */ 52676ec1555SBarry Smith ierr = PetscGatherNumberOfMessages(comm,sizes,nlengths,&nreceives);CHKERRQ(ierr); 527563fb871SSatish Balay ierr = PetscGatherMessageLengths(comm,nsends,nreceives,nlengths,&onodes,&olengths);CHKERRQ(ierr); 528563fb871SSatish Balay /* since clubbing row,col - lengths are multiplied by 2 */ 529563fb871SSatish Balay for (i=0; i<nreceives; i++) olengths[i] *=2; 530563fb871SSatish Balay ierr = PetscPostIrecvInt(comm,tag1,nreceives,onodes,olengths,&rindices,&recv_waits1);CHKERRQ(ierr); 531563fb871SSatish Balay /* values are size 'bs2' lengths (and remove earlier factor 2 */ 532563fb871SSatish Balay for (i=0; i<nreceives; i++) olengths[i] = olengths[i]*bs2/2; 533563fb871SSatish Balay ierr = PetscPostIrecvScalar(comm,tag2,nreceives,onodes,olengths,&rvalues,&recv_waits2);CHKERRQ(ierr); 534563fb871SSatish Balay ierr = PetscFree(onodes);CHKERRQ(ierr); 5358865f1eaSKarl Rupp ierr = PetscFree(olengths);CHKERRQ(ierr);} 536bc5ccf88SSatish Balay 537bc5ccf88SSatish Balay /* do sends: 538bc5ccf88SSatish Balay 1) starts[i] gives the starting index in svalues for stuff going to 539bc5ccf88SSatish Balay the ith processor 540bc5ccf88SSatish Balay */ 541dcca6d9dSJed Brown ierr = PetscMalloc2(bs2*stash->n,&svalues,2*(stash->n+1),&sindices);CHKERRQ(ierr); 542785e854fSJed Brown ierr = PetscMalloc1(2*nsends,&send_waits);CHKERRQ(ierr); 543dcca6d9dSJed Brown ierr = PetscMalloc2(size,&startv,size,&starti);CHKERRQ(ierr); 544a2d1c673SSatish Balay /* use 2 sends the first with all_a, the next with all_i and all_j */ 545bc5ccf88SSatish Balay startv[0] = 0; starti[0] = 0; 546bc5ccf88SSatish Balay for (i=1; i<size; i++) { 547563fb871SSatish Balay startv[i] = startv[i-1] + nlengths[i-1]; 548533163c2SBarry Smith starti[i] = starti[i-1] + 2*nlengths[i-1]; 549bc5ccf88SSatish Balay } 55075cae7c1SHong Zhang 55175cae7c1SHong Zhang i = 0; 5525bd3b8fbSHong Zhang space = stash->space_head; 5530298fd71SBarry Smith while (space != NULL) { 55475cae7c1SHong Zhang space_next = space->next; 5555bd3b8fbSHong Zhang sp_idx = space->idx; 5565bd3b8fbSHong Zhang sp_idy = space->idy; 5575bd3b8fbSHong Zhang sp_val = space->val; 55875cae7c1SHong Zhang for (l=0; l<space->local_used; l++) { 559bc5ccf88SSatish Balay j = owner[i]; 560a2d1c673SSatish Balay if (bs2 == 1) { 5615bd3b8fbSHong Zhang svalues[startv[j]] = sp_val[l]; 562a2d1c673SSatish Balay } else { 563c1ac3661SBarry Smith PetscInt k; 56454f21887SBarry Smith PetscScalar *buf1,*buf2; 5654c1ff481SSatish Balay buf1 = svalues+bs2*startv[j]; 566b087b6d6SSatish Balay buf2 = space->val + bs2*l; 5678865f1eaSKarl Rupp for (k=0; k<bs2; k++) buf1[k] = buf2[k]; 568a2d1c673SSatish Balay } 5695bd3b8fbSHong Zhang sindices[starti[j]] = sp_idx[l]; 5705bd3b8fbSHong Zhang sindices[starti[j]+nlengths[j]] = sp_idy[l]; 571bc5ccf88SSatish Balay startv[j]++; 572bc5ccf88SSatish Balay starti[j]++; 57375cae7c1SHong Zhang i++; 57475cae7c1SHong Zhang } 57575cae7c1SHong Zhang space = space_next; 576bc5ccf88SSatish Balay } 577bc5ccf88SSatish Balay startv[0] = 0; 5788865f1eaSKarl Rupp for (i=1; i<size; i++) startv[i] = startv[i-1] + nlengths[i-1]; 579e5d0e772SSatish Balay 580bc5ccf88SSatish Balay for (i=0,count=0; i<size; i++) { 58176ec1555SBarry Smith if (sizes[i]) { 582563fb871SSatish Balay ierr = MPI_Isend(sindices+2*startv[i],2*nlengths[i],MPIU_INT,i,tag1,comm,send_waits+count++);CHKERRQ(ierr); 583a77337e4SBarry Smith ierr = MPI_Isend(svalues+bs2*startv[i],bs2*nlengths[i],MPIU_SCALAR,i,tag2,comm,send_waits+count++);CHKERRQ(ierr); 584bc5ccf88SSatish Balay } 585b85c94c3SSatish Balay } 5866cf91177SBarry Smith #if defined(PETSC_USE_INFO) 58793157e10SBarry Smith ierr = PetscInfo1(NULL,"No of messages: %d \n",nsends);CHKERRQ(ierr); 588e5d0e772SSatish Balay for (i=0; i<size; i++) { 58976ec1555SBarry Smith if (sizes[i]) { 59030c47e72SSatish Balay ierr = PetscInfo2(NULL,"Mesg_to: %d: size: %d bytes\n",i,nlengths[i]*(bs2*sizeof(PetscScalar)+2*sizeof(PetscInt)));CHKERRQ(ierr); 591e5d0e772SSatish Balay } 592e5d0e772SSatish Balay } 593e5d0e772SSatish Balay #endif 594c05d87d6SBarry Smith ierr = PetscFree(nlengths);CHKERRQ(ierr); 595606d414cSSatish Balay ierr = PetscFree(owner);CHKERRQ(ierr); 596c05d87d6SBarry Smith ierr = PetscFree2(startv,starti);CHKERRQ(ierr); 59776ec1555SBarry Smith ierr = PetscFree(sizes);CHKERRQ(ierr); 598a2d1c673SSatish Balay 599563fb871SSatish Balay /* recv_waits need to be contiguous for MatStashScatterGetMesg_Private() */ 600785e854fSJed Brown ierr = PetscMalloc1(2*nreceives,&recv_waits);CHKERRQ(ierr); 601563fb871SSatish Balay 602563fb871SSatish Balay for (i=0; i<nreceives; i++) { 603563fb871SSatish Balay recv_waits[2*i] = recv_waits1[i]; 604563fb871SSatish Balay recv_waits[2*i+1] = recv_waits2[i]; 605563fb871SSatish Balay } 606563fb871SSatish Balay stash->recv_waits = recv_waits; 6078865f1eaSKarl Rupp 608563fb871SSatish Balay ierr = PetscFree(recv_waits1);CHKERRQ(ierr); 609563fb871SSatish Balay ierr = PetscFree(recv_waits2);CHKERRQ(ierr); 610563fb871SSatish Balay 611c05d87d6SBarry Smith stash->svalues = svalues; 612c05d87d6SBarry Smith stash->sindices = sindices; 613c05d87d6SBarry Smith stash->rvalues = rvalues; 614c05d87d6SBarry Smith stash->rindices = rindices; 615c05d87d6SBarry Smith stash->send_waits = send_waits; 616c05d87d6SBarry Smith stash->nsends = nsends; 617c05d87d6SBarry Smith stash->nrecvs = nreceives; 61867318a8aSJed Brown stash->reproduce_count = 0; 619bc5ccf88SSatish Balay PetscFunctionReturn(0); 620bc5ccf88SSatish Balay } 621bc5ccf88SSatish Balay 622a2d1c673SSatish Balay /* 6238798bf22SSatish Balay MatStashScatterGetMesg_Private - This function waits on the receives posted 6248798bf22SSatish Balay in the function MatStashScatterBegin_Private() and returns one message at 6254c1ff481SSatish Balay a time to the calling function. If no messages are left, it indicates this 6264c1ff481SSatish Balay by setting flg = 0, else it sets flg = 1. 6274c1ff481SSatish Balay 6284c1ff481SSatish Balay Input Parameters: 6294c1ff481SSatish Balay stash - the stash 6304c1ff481SSatish Balay 6314c1ff481SSatish Balay Output Parameters: 6324c1ff481SSatish Balay nvals - the number of entries in the current message. 6334c1ff481SSatish Balay rows - an array of row indices (or blocked indices) corresponding to the values 6344c1ff481SSatish Balay cols - an array of columnindices (or blocked indices) corresponding to the values 6354c1ff481SSatish Balay vals - the values 6364c1ff481SSatish Balay flg - 0 indicates no more message left, and the current call has no values associated. 6374c1ff481SSatish Balay 1 indicates that the current call successfully received a message, and the 6384c1ff481SSatish Balay other output parameters nvals,rows,cols,vals are set appropriately. 639a2d1c673SSatish Balay */ 6404a2ae208SSatish Balay #undef __FUNCT__ 6414a2ae208SSatish Balay #define __FUNCT__ "MatStashScatterGetMesg_Private" 64254f21887SBarry Smith PetscErrorCode MatStashScatterGetMesg_Private(MatStash *stash,PetscMPIInt *nvals,PetscInt **rows,PetscInt **cols,PetscScalar **vals,PetscInt *flg) 643bc5ccf88SSatish Balay { 6446849ba73SBarry Smith PetscErrorCode ierr; 645*ac2b2aa0SJed Brown 646*ac2b2aa0SJed Brown PetscFunctionBegin; 647*ac2b2aa0SJed Brown ierr = (*stash->ScatterGetMesg)(stash,nvals,rows,cols,vals,flg);CHKERRQ(ierr); 648*ac2b2aa0SJed Brown PetscFunctionReturn(0); 649*ac2b2aa0SJed Brown } 650*ac2b2aa0SJed Brown 651*ac2b2aa0SJed Brown #undef __FUNCT__ 652*ac2b2aa0SJed Brown #define __FUNCT__ "MatStashScatterGetMesg_Ref" 653*ac2b2aa0SJed Brown static PetscErrorCode MatStashScatterGetMesg_Ref(MatStash *stash,PetscMPIInt *nvals,PetscInt **rows,PetscInt **cols,PetscScalar **vals,PetscInt *flg) 654*ac2b2aa0SJed Brown { 655*ac2b2aa0SJed Brown PetscErrorCode ierr; 656533163c2SBarry Smith PetscMPIInt i,*flg_v = stash->flg_v,i1,i2; 657fe09c992SBarry Smith PetscInt bs2; 658a2d1c673SSatish Balay MPI_Status recv_status; 659ace3abfcSBarry Smith PetscBool match_found = PETSC_FALSE; 660bc5ccf88SSatish Balay 661bc5ccf88SSatish Balay PetscFunctionBegin; 662a2d1c673SSatish Balay *flg = 0; /* When a message is discovered this is reset to 1 */ 663a2d1c673SSatish Balay /* Return if no more messages to process */ 6648865f1eaSKarl Rupp if (stash->nprocessed == stash->nrecvs) PetscFunctionReturn(0); 665a2d1c673SSatish Balay 6664c1ff481SSatish Balay bs2 = stash->bs*stash->bs; 66767318a8aSJed Brown /* If a matching pair of receives are found, process them, and return the data to 668a2d1c673SSatish Balay the calling function. Until then keep receiving messages */ 669a2d1c673SSatish Balay while (!match_found) { 67067318a8aSJed Brown if (stash->reproduce) { 67167318a8aSJed Brown i = stash->reproduce_count++; 67267318a8aSJed Brown ierr = MPI_Wait(stash->recv_waits+i,&recv_status);CHKERRQ(ierr); 67367318a8aSJed Brown } else { 674a2d1c673SSatish Balay ierr = MPI_Waitany(2*stash->nrecvs,stash->recv_waits,&i,&recv_status);CHKERRQ(ierr); 67567318a8aSJed Brown } 676e32f2f54SBarry Smith if (recv_status.MPI_SOURCE < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Negative MPI source!"); 677533163c2SBarry Smith 67867318a8aSJed Brown /* Now pack the received message into a structure which is usable by others */ 679a2d1c673SSatish Balay if (i % 2) { 680a77337e4SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_SCALAR,nvals);CHKERRQ(ierr); 6818865f1eaSKarl Rupp 682c1dc657dSBarry Smith flg_v[2*recv_status.MPI_SOURCE] = i/2; 6838865f1eaSKarl Rupp 684a2d1c673SSatish Balay *nvals = *nvals/bs2; 685563fb871SSatish Balay } else { 686563fb871SSatish Balay ierr = MPI_Get_count(&recv_status,MPIU_INT,nvals);CHKERRQ(ierr); 6878865f1eaSKarl Rupp 688563fb871SSatish Balay flg_v[2*recv_status.MPI_SOURCE+1] = i/2; 6898865f1eaSKarl Rupp 690563fb871SSatish Balay *nvals = *nvals/2; /* This message has both row indices and col indices */ 691bc5ccf88SSatish Balay } 692a2d1c673SSatish Balay 693cb2b73ccSBarry Smith /* Check if we have both messages from this proc */ 694c1dc657dSBarry Smith i1 = flg_v[2*recv_status.MPI_SOURCE]; 695c1dc657dSBarry Smith i2 = flg_v[2*recv_status.MPI_SOURCE+1]; 696a2d1c673SSatish Balay if (i1 != -1 && i2 != -1) { 697563fb871SSatish Balay *rows = stash->rindices[i2]; 698a2d1c673SSatish Balay *cols = *rows + *nvals; 699563fb871SSatish Balay *vals = stash->rvalues[i1]; 700a2d1c673SSatish Balay *flg = 1; 701a2d1c673SSatish Balay stash->nprocessed++; 70235d8aa7fSBarry Smith match_found = PETSC_TRUE; 703bc5ccf88SSatish Balay } 704bc5ccf88SSatish Balay } 705bc5ccf88SSatish Balay PetscFunctionReturn(0); 706bc5ccf88SSatish Balay } 707