12362add9SBarry Smith 2af0996ceSBarry Smith #include <petsc/private/isimpl.h> /*I "petscis.h" I*/ 30c312b8eSJed Brown #include <petscsf.h> 4665c2dedSJed Brown #include <petscviewer.h> 52362add9SBarry Smith 67087cfbeSBarry Smith PetscClassId IS_LTOGM_CLASSID; 7268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping,PetscInt*,PetscInt**,PetscInt**,PetscInt***); 88e58c17dSMatthew Knepley 9186d4ecdSBarry Smith #undef __FUNCT__ 104a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize" 11565245c5SBarry Smith /*@ 12107e9a97SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping 133b9aefa3SBarry Smith 143b9aefa3SBarry Smith Not Collective 153b9aefa3SBarry Smith 163b9aefa3SBarry Smith Input Parameter: 173b9aefa3SBarry Smith . ltog - local to global mapping 183b9aefa3SBarry Smith 193b9aefa3SBarry Smith Output Parameter: 20107e9a97SBarry Smith . n - the number of entries in the local mapping, ISLocalToGlobalMappingGetIndices() returns an array of this length 213b9aefa3SBarry Smith 223b9aefa3SBarry Smith Level: advanced 233b9aefa3SBarry Smith 24273d9f13SBarry Smith Concepts: mapping^local to global 253b9aefa3SBarry Smith 263b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 273b9aefa3SBarry Smith @*/ 287087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n) 293b9aefa3SBarry Smith { 303b9aefa3SBarry Smith PetscFunctionBegin; 310700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 324482741eSBarry Smith PetscValidIntPointer(n,2); 33107e9a97SBarry Smith *n = mapping->bs*mapping->n; 343b9aefa3SBarry Smith PetscFunctionReturn(0); 353b9aefa3SBarry Smith } 363b9aefa3SBarry Smith 374a2ae208SSatish Balay #undef __FUNCT__ 384a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 395a5d4f66SBarry Smith /*@C 405a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 415a5d4f66SBarry Smith 42b9cd556bSLois Curfman McInnes Not Collective 43b9cd556bSLois Curfman McInnes 445a5d4f66SBarry Smith Input Parameters: 453b9aefa3SBarry Smith + ltog - local to global mapping 463b9aefa3SBarry Smith - viewer - viewer 475a5d4f66SBarry Smith 48a997ad1aSLois Curfman McInnes Level: advanced 49a997ad1aSLois Curfman McInnes 50273d9f13SBarry Smith Concepts: mapping^local to global 515a5d4f66SBarry Smith 525a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 535a5d4f66SBarry Smith @*/ 547087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 555a5d4f66SBarry Smith { 5632dcc486SBarry Smith PetscInt i; 5732dcc486SBarry Smith PetscMPIInt rank; 58ace3abfcSBarry Smith PetscBool iascii; 596849ba73SBarry Smith PetscErrorCode ierr; 605a5d4f66SBarry Smith 615a5d4f66SBarry Smith PetscFunctionBegin; 620700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 633050cee2SBarry Smith if (!viewer) { 64ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mapping),&viewer);CHKERRQ(ierr); 653050cee2SBarry Smith } 660700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 675a5d4f66SBarry Smith 68ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mapping),&rank);CHKERRQ(ierr); 69251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 7032077d6dSBarry Smith if (iascii) { 7198c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mapping,viewer);CHKERRQ(ierr); 721575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 735a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 747904a332SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %D %D\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 756831982aSBarry Smith } 76b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 771575c14dSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 781575c14dSBarry Smith } 795a5d4f66SBarry Smith PetscFunctionReturn(0); 805a5d4f66SBarry Smith } 815a5d4f66SBarry Smith 824a2ae208SSatish Balay #undef __FUNCT__ 834a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 841f428162SBarry Smith /*@ 852bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 862bdab257SBarry Smith ordering and a global parallel ordering. 872bdab257SBarry Smith 880f5bd95cSBarry Smith Not collective 89b9cd556bSLois Curfman McInnes 90a997ad1aSLois Curfman McInnes Input Parameter: 918c03b21aSDmitry Karpeev . is - index set containing the global numbers for each local number 922bdab257SBarry Smith 93a997ad1aSLois Curfman McInnes Output Parameter: 942bdab257SBarry Smith . mapping - new mapping data structure 952bdab257SBarry Smith 96f0413b6fSBarry Smith Notes: the block size of the IS determines the block size of the mapping 97a997ad1aSLois Curfman McInnes Level: advanced 98a997ad1aSLois Curfman McInnes 99273d9f13SBarry Smith Concepts: mapping^local to global 1002bdab257SBarry Smith 1012bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 1022bdab257SBarry Smith @*/ 1037087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 1042bdab257SBarry Smith { 1056849ba73SBarry Smith PetscErrorCode ierr; 1063bbf0e92SBarry Smith PetscInt n,bs; 1075d0c19d7SBarry Smith const PetscInt *indices; 1082bdab257SBarry Smith MPI_Comm comm; 1093bbf0e92SBarry Smith PetscBool isblock; 1103a40ed3dSBarry Smith 1113a40ed3dSBarry Smith PetscFunctionBegin; 1120700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,1); 1134482741eSBarry Smith PetscValidPointer(mapping,2); 1142bdab257SBarry Smith 1152bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1163b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1173bbf0e92SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)is,ISBLOCK,&isblock);CHKERRQ(ierr); 1186006e8d2SBarry Smith if (!isblock) { 119f0413b6fSBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 120f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,n,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 1212bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1226006e8d2SBarry Smith } else { 1236006e8d2SBarry Smith ierr = ISGetBlockSize(is,&bs);CHKERRQ(ierr); 124f0413b6fSBarry Smith ierr = ISBlockGetIndices(is,&indices);CHKERRQ(ierr); 12528bc9809SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,bs,n/bs,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 126f0413b6fSBarry Smith ierr = ISBlockRestoreIndices(is,&indices);CHKERRQ(ierr); 1276006e8d2SBarry Smith } 1283a40ed3dSBarry Smith PetscFunctionReturn(0); 1292bdab257SBarry Smith } 1305a5d4f66SBarry Smith 131a4d96a55SJed Brown #undef __FUNCT__ 132a4d96a55SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingCreateSF" 133a4d96a55SJed Brown /*@C 134a4d96a55SJed Brown ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n) 135a4d96a55SJed Brown ordering and a global parallel ordering. 136a4d96a55SJed Brown 137a4d96a55SJed Brown Collective 138a4d96a55SJed Brown 139a4d96a55SJed Brown Input Parameter: 140a4d96a55SJed Brown + sf - star forest mapping contiguous local indices to (rank, offset) 141a4d96a55SJed Brown - start - first global index on this process 142a4d96a55SJed Brown 143a4d96a55SJed Brown Output Parameter: 144a4d96a55SJed Brown . mapping - new mapping data structure 145a4d96a55SJed Brown 146a4d96a55SJed Brown Level: advanced 147a4d96a55SJed Brown 148a4d96a55SJed Brown Concepts: mapping^local to global 149a4d96a55SJed Brown 150a4d96a55SJed Brown .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 151a4d96a55SJed Brown @*/ 152a4d96a55SJed Brown PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf,PetscInt start,ISLocalToGlobalMapping *mapping) 153a4d96a55SJed Brown { 154a4d96a55SJed Brown PetscErrorCode ierr; 155a4d96a55SJed Brown PetscInt i,maxlocal,nroots,nleaves,*globals,*ltog; 156a4d96a55SJed Brown const PetscInt *ilocal; 157a4d96a55SJed Brown MPI_Comm comm; 158a4d96a55SJed Brown 159a4d96a55SJed Brown PetscFunctionBegin; 160a4d96a55SJed Brown PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 161a4d96a55SJed Brown PetscValidPointer(mapping,3); 162a4d96a55SJed Brown 163a4d96a55SJed Brown ierr = PetscObjectGetComm((PetscObject)sf,&comm);CHKERRQ(ierr); 1640298fd71SBarry Smith ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,NULL);CHKERRQ(ierr); 165f6e5521dSKarl Rupp if (ilocal) { 166f6e5521dSKarl Rupp for (i=0,maxlocal=0; i<nleaves; i++) maxlocal = PetscMax(maxlocal,ilocal[i]+1); 167f6e5521dSKarl Rupp } 168a4d96a55SJed Brown else maxlocal = nleaves; 169785e854fSJed Brown ierr = PetscMalloc1(nroots,&globals);CHKERRQ(ierr); 170785e854fSJed Brown ierr = PetscMalloc1(maxlocal,<og);CHKERRQ(ierr); 171a4d96a55SJed Brown for (i=0; i<nroots; i++) globals[i] = start + i; 172a4d96a55SJed Brown for (i=0; i<maxlocal; i++) ltog[i] = -1; 173a4d96a55SJed Brown ierr = PetscSFBcastBegin(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 174a4d96a55SJed Brown ierr = PetscSFBcastEnd(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 175f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,maxlocal,ltog,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 176a4d96a55SJed Brown ierr = PetscFree(globals);CHKERRQ(ierr); 177a4d96a55SJed Brown PetscFunctionReturn(0); 178a4d96a55SJed Brown } 179b46b645bSBarry Smith 1804a2ae208SSatish Balay #undef __FUNCT__ 181*63fa5c83Sstefano_zampini #define __FUNCT__ "ISLocalToGlobalMappingSetBlockSize" 182*63fa5c83Sstefano_zampini /*@ 183*63fa5c83Sstefano_zampini ISLocalToGlobalMappingSetBlockSize - Sets the blocksize of the mapping 184*63fa5c83Sstefano_zampini 185*63fa5c83Sstefano_zampini Not collective 186*63fa5c83Sstefano_zampini 187*63fa5c83Sstefano_zampini Input Parameters: 188*63fa5c83Sstefano_zampini . mapping - mapping data structure 189*63fa5c83Sstefano_zampini . bs - the blocksize 190*63fa5c83Sstefano_zampini 191*63fa5c83Sstefano_zampini Level: advanced 192*63fa5c83Sstefano_zampini 193*63fa5c83Sstefano_zampini Concepts: mapping^local to global 194*63fa5c83Sstefano_zampini 195*63fa5c83Sstefano_zampini .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 196*63fa5c83Sstefano_zampini @*/ 197*63fa5c83Sstefano_zampini PetscErrorCode ISLocalToGlobalMappingSetBlockSize(ISLocalToGlobalMapping mapping,PetscInt bs) 198*63fa5c83Sstefano_zampini { 199*63fa5c83Sstefano_zampini PetscInt *nid,*oid; 200*63fa5c83Sstefano_zampini PetscInt i,on,obs,nn,cum; 201*63fa5c83Sstefano_zampini PetscErrorCode ierr; 202*63fa5c83Sstefano_zampini 203*63fa5c83Sstefano_zampini PetscFunctionBegin; 204*63fa5c83Sstefano_zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 205*63fa5c83Sstefano_zampini if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid block size %D",bs); 206*63fa5c83Sstefano_zampini if (bs == mapping->bs) PetscFunctionReturn(0); 207*63fa5c83Sstefano_zampini on = mapping->n; 208*63fa5c83Sstefano_zampini obs = mapping->bs; 209*63fa5c83Sstefano_zampini oid = mapping->indices; 210*63fa5c83Sstefano_zampini nn = (on*obs)/bs; 211*63fa5c83Sstefano_zampini if ((on*obs)%bs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block size %D is inconsistent with block size %D and number of block indices %D",bs,obs,on); 212*63fa5c83Sstefano_zampini ierr = PetscMalloc1(nn,&nid);CHKERRQ(ierr); 213*63fa5c83Sstefano_zampini for (i=0,cum=0;i<on;i++) { 214*63fa5c83Sstefano_zampini if (!((oid[i]*obs)%bs)) { 215*63fa5c83Sstefano_zampini if (cum==nn) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices",bs,obs); 216*63fa5c83Sstefano_zampini nid[cum++] = (oid[i]*obs)/bs; 217*63fa5c83Sstefano_zampini } 218*63fa5c83Sstefano_zampini } 219*63fa5c83Sstefano_zampini if (cum != nn) { 220*63fa5c83Sstefano_zampini ierr = PetscFree(nid);CHKERRQ(ierr); 221*63fa5c83Sstefano_zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Incompatible block sizes %D and %D (new block indices found %D != %D)",bs,obs,cum,nn); 222*63fa5c83Sstefano_zampini } 223*63fa5c83Sstefano_zampini mapping->n = nn; 224*63fa5c83Sstefano_zampini mapping->bs = bs; 225*63fa5c83Sstefano_zampini ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 226*63fa5c83Sstefano_zampini mapping->indices = nid; 227*63fa5c83Sstefano_zampini PetscFunctionReturn(0); 228*63fa5c83Sstefano_zampini } 229*63fa5c83Sstefano_zampini 230*63fa5c83Sstefano_zampini #undef __FUNCT__ 23145b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockSize" 23245b6f7e9SBarry Smith /*@ 23345b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping 23445b6f7e9SBarry Smith ordering and a global parallel ordering. 23545b6f7e9SBarry Smith 23645b6f7e9SBarry Smith Not Collective 23745b6f7e9SBarry Smith 23845b6f7e9SBarry Smith Input Parameters: 23945b6f7e9SBarry Smith . mapping - mapping data structure 24045b6f7e9SBarry Smith 24145b6f7e9SBarry Smith Output Parameter: 24245b6f7e9SBarry Smith . bs - the blocksize 24345b6f7e9SBarry Smith 24445b6f7e9SBarry Smith Level: advanced 24545b6f7e9SBarry Smith 24645b6f7e9SBarry Smith Concepts: mapping^local to global 24745b6f7e9SBarry Smith 24845b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 24945b6f7e9SBarry Smith @*/ 25045b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping,PetscInt *bs) 25145b6f7e9SBarry Smith { 25245b6f7e9SBarry Smith PetscFunctionBegin; 253cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 25445b6f7e9SBarry Smith *bs = mapping->bs; 25545b6f7e9SBarry Smith PetscFunctionReturn(0); 25645b6f7e9SBarry Smith } 25745b6f7e9SBarry Smith 25845b6f7e9SBarry Smith #undef __FUNCT__ 2594a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 260ba5bb76aSSatish Balay /*@ 26190f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 26290f02eecSBarry Smith ordering and a global parallel ordering. 2632362add9SBarry Smith 26489d82c54SBarry Smith Not Collective, but communicator may have more than one process 265b9cd556bSLois Curfman McInnes 2662362add9SBarry Smith Input Parameters: 26789d82c54SBarry Smith + comm - MPI communicator 268f0413b6fSBarry Smith . bs - the block size 26928bc9809SBarry Smith . n - the number of local elements divided by the block size, or equivalently the number of block indices 27028bc9809SBarry Smith . indices - the global index for each local element, these do not need to be in increasing order (sorted), these values should not be scaled (i.e. multiplied) by the blocksize bs 271d5ad8652SBarry Smith - mode - see PetscCopyMode 2722362add9SBarry Smith 273a997ad1aSLois Curfman McInnes Output Parameter: 27490f02eecSBarry Smith . mapping - new mapping data structure 2752362add9SBarry Smith 276f0413b6fSBarry Smith Notes: There is one integer value in indices per block and it represents the actual indices bs*idx + j, where j=0,..,bs-1 277a997ad1aSLois Curfman McInnes Level: advanced 278a997ad1aSLois Curfman McInnes 279273d9f13SBarry Smith Concepts: mapping^local to global 2802362add9SBarry Smith 281d5ad8652SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 2822362add9SBarry Smith @*/ 28360c7cefcSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 2842362add9SBarry Smith { 2856849ba73SBarry Smith PetscErrorCode ierr; 28632dcc486SBarry Smith PetscInt *in; 287b46b645bSBarry Smith 288b46b645bSBarry Smith PetscFunctionBegin; 28973911063SBarry Smith if (n) PetscValidIntPointer(indices,3); 2904482741eSBarry Smith PetscValidPointer(mapping,4); 291b46b645bSBarry Smith 2920298fd71SBarry Smith *mapping = NULL; 293607a6623SBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 2942362add9SBarry Smith 29573107ff1SLisandro Dalcin ierr = PetscHeaderCreate(*mapping,IS_LTOGM_CLASSID,"ISLocalToGlobalMapping","Local to global mapping","IS", 29660c7cefcSBarry Smith comm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 297d4bb536fSBarry Smith (*mapping)->n = n; 298f0413b6fSBarry Smith (*mapping)->bs = bs; 299268a049cSStefano Zampini (*mapping)->info_cached = PETSC_FALSE; 300268a049cSStefano Zampini (*mapping)->info_free = PETSC_FALSE; 301268a049cSStefano Zampini (*mapping)->info_procs = NULL; 302268a049cSStefano Zampini (*mapping)->info_numprocs = NULL; 303268a049cSStefano Zampini (*mapping)->info_indices = NULL; 304d4bb536fSBarry Smith /* 305d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 306d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 307d4bb536fSBarry Smith */ 308d4bb536fSBarry Smith (*mapping)->globals = 0; 309d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 310785e854fSJed Brown ierr = PetscMalloc1(n,&in);CHKERRQ(ierr); 311d5ad8652SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 312d5ad8652SBarry Smith (*mapping)->indices = in; 3136389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 3146389a1a1SBarry Smith } else if (mode == PETSC_OWN_POINTER) { 3156389a1a1SBarry Smith (*mapping)->indices = (PetscInt*)indices; 3166389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 3176389a1a1SBarry Smith } 31860c7cefcSBarry Smith else SETERRQ(comm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 319d96308ebSBarry Smith ierr = PetscStrallocpy("basic",&((PetscObject)*mapping)->type_name);CHKERRQ(ierr); 3203a40ed3dSBarry Smith PetscFunctionReturn(0); 3212362add9SBarry Smith } 3222362add9SBarry Smith 3234a2ae208SSatish Balay #undef __FUNCT__ 3244a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 32590f02eecSBarry Smith /*@ 32690f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 32790f02eecSBarry Smith ordering and a global parallel ordering. 32890f02eecSBarry Smith 3290f5bd95cSBarry Smith Note Collective 330b9cd556bSLois Curfman McInnes 33190f02eecSBarry Smith Input Parameters: 33290f02eecSBarry Smith . mapping - mapping data structure 33390f02eecSBarry Smith 334a997ad1aSLois Curfman McInnes Level: advanced 335a997ad1aSLois Curfman McInnes 3363acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 33790f02eecSBarry Smith @*/ 3386bf464f9SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 33990f02eecSBarry Smith { 340dfbe8321SBarry Smith PetscErrorCode ierr; 3415fd66863SKarl Rupp 3423a40ed3dSBarry Smith PetscFunctionBegin; 3436bf464f9SBarry Smith if (!*mapping) PetscFunctionReturn(0); 3446bf464f9SBarry Smith PetscValidHeaderSpecific((*mapping),IS_LTOGM_CLASSID,1); 345997056adSBarry Smith if (--((PetscObject)(*mapping))->refct > 0) {*mapping = 0;PetscFunctionReturn(0);} 3466bf464f9SBarry Smith ierr = PetscFree((*mapping)->indices);CHKERRQ(ierr); 3476bf464f9SBarry Smith ierr = PetscFree((*mapping)->globals);CHKERRQ(ierr); 348268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_procs);CHKERRQ(ierr); 349268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_numprocs);CHKERRQ(ierr); 350268a049cSStefano Zampini if ((*mapping)->info_indices) { 351268a049cSStefano Zampini PetscInt i; 352268a049cSStefano Zampini 353268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[0]);CHKERRQ(ierr); 354268a049cSStefano Zampini for (i=1; i<(*mapping)->info_nproc; i++) { 355268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[i]);CHKERRQ(ierr); 356268a049cSStefano Zampini } 357268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_indices);CHKERRQ(ierr); 358268a049cSStefano Zampini } 359d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 360992144d0SBarry Smith *mapping = 0; 3613a40ed3dSBarry Smith PetscFunctionReturn(0); 36290f02eecSBarry Smith } 36390f02eecSBarry Smith 3644a2ae208SSatish Balay #undef __FUNCT__ 3654a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 36690f02eecSBarry Smith /*@ 3673acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 3683acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 3693acfe500SLois Curfman McInnes context. 37090f02eecSBarry Smith 371b9cd556bSLois Curfman McInnes Not collective 372b9cd556bSLois Curfman McInnes 37390f02eecSBarry Smith Input Parameters: 374b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 375b9cd556bSLois Curfman McInnes - is - index set in local numbering 37690f02eecSBarry Smith 37790f02eecSBarry Smith Output Parameters: 37890f02eecSBarry Smith . newis - index set in global numbering 37990f02eecSBarry Smith 380a997ad1aSLois Curfman McInnes Level: advanced 381a997ad1aSLois Curfman McInnes 382273d9f13SBarry Smith Concepts: mapping^local to global 3833acfe500SLois Curfman McInnes 38490f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 385d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 38690f02eecSBarry Smith @*/ 3877087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 38890f02eecSBarry Smith { 3896849ba73SBarry Smith PetscErrorCode ierr; 390e24637baSBarry Smith PetscInt n,*idxout; 3915d0c19d7SBarry Smith const PetscInt *idxin; 3923a40ed3dSBarry Smith 3933a40ed3dSBarry Smith PetscFunctionBegin; 3940700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 3950700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 3964482741eSBarry Smith PetscValidPointer(newis,3); 39790f02eecSBarry Smith 3983b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 39990f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 400785e854fSJed Brown ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 401e24637baSBarry Smith ierr = ISLocalToGlobalMappingApply(mapping,n,idxin,idxout);CHKERRQ(ierr); 4023b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 403543f3098SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 4043a40ed3dSBarry Smith PetscFunctionReturn(0); 40590f02eecSBarry Smith } 40690f02eecSBarry Smith 407afcb2eb5SJed Brown #undef __FUNCT__ 408afcb2eb5SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingApply" 409b89cb25eSSatish Balay /*@ 4103acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 4113acfe500SLois Curfman McInnes and converts them to the global numbering. 41290f02eecSBarry Smith 413b9cd556bSLois Curfman McInnes Not collective 414b9cd556bSLois Curfman McInnes 415bb25748dSBarry Smith Input Parameters: 416b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 417bb25748dSBarry Smith . N - number of integers 418b9cd556bSLois Curfman McInnes - in - input indices in local numbering 419bb25748dSBarry Smith 420bb25748dSBarry Smith Output Parameter: 421bb25748dSBarry Smith . out - indices in global numbering 422bb25748dSBarry Smith 423b9cd556bSLois Curfman McInnes Notes: 424b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 425d4bb536fSBarry Smith 426a997ad1aSLois Curfman McInnes Level: advanced 427a997ad1aSLois Curfman McInnes 42845b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApplyBlock(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 4290752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 430d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 431bb25748dSBarry Smith 432273d9f13SBarry Smith Concepts: mapping^local to global 433afcb2eb5SJed Brown @*/ 434afcb2eb5SJed Brown PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 435afcb2eb5SJed Brown { 436cbc1caf0SMatthew G. Knepley PetscInt i,bs,Nmax; 43745b6f7e9SBarry Smith 43845b6f7e9SBarry Smith PetscFunctionBegin; 439cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 440cbc1caf0SMatthew G. Knepley bs = mapping->bs; 441cbc1caf0SMatthew G. Knepley Nmax = bs*mapping->n; 44245b6f7e9SBarry Smith if (bs == 1) { 443cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 44445b6f7e9SBarry Smith for (i=0; i<N; i++) { 44545b6f7e9SBarry Smith if (in[i] < 0) { 44645b6f7e9SBarry Smith out[i] = in[i]; 44745b6f7e9SBarry Smith continue; 44845b6f7e9SBarry Smith } 449e24637baSBarry Smith if (in[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local index %D too large %D (max) at %D",in[i],Nmax-1,i); 45045b6f7e9SBarry Smith out[i] = idx[in[i]]; 45145b6f7e9SBarry Smith } 45245b6f7e9SBarry Smith } else { 453cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 45445b6f7e9SBarry Smith for (i=0; i<N; i++) { 45545b6f7e9SBarry Smith if (in[i] < 0) { 45645b6f7e9SBarry Smith out[i] = in[i]; 45745b6f7e9SBarry Smith continue; 45845b6f7e9SBarry Smith } 459e24637baSBarry Smith if (in[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local index %D too large %D (max) at %D",in[i],Nmax-1,i); 46045b6f7e9SBarry Smith out[i] = idx[in[i]/bs]*bs + (in[i] % bs); 46145b6f7e9SBarry Smith } 46245b6f7e9SBarry Smith } 46345b6f7e9SBarry Smith PetscFunctionReturn(0); 46445b6f7e9SBarry Smith } 46545b6f7e9SBarry Smith 46645b6f7e9SBarry Smith #undef __FUNCT__ 46745b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingApplyBlock" 46845b6f7e9SBarry Smith /*@ 4696006e8d2SBarry Smith ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering 47045b6f7e9SBarry Smith 47145b6f7e9SBarry Smith Not collective 47245b6f7e9SBarry Smith 47345b6f7e9SBarry Smith Input Parameters: 47445b6f7e9SBarry Smith + mapping - the local to global mapping context 47545b6f7e9SBarry Smith . N - number of integers 4766006e8d2SBarry Smith - in - input indices in local block numbering 47745b6f7e9SBarry Smith 47845b6f7e9SBarry Smith Output Parameter: 4796006e8d2SBarry Smith . out - indices in global block numbering 48045b6f7e9SBarry Smith 48145b6f7e9SBarry Smith Notes: 48245b6f7e9SBarry Smith The in and out array parameters may be identical. 48345b6f7e9SBarry Smith 4846006e8d2SBarry Smith Example: 4856006e8d2SBarry Smith If the index values are {0,1,6,7} set with a call to ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,2,2,{0,3}) then the mapping applied to 0 4866006e8d2SBarry Smith (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3. 4876006e8d2SBarry Smith 48845b6f7e9SBarry Smith Level: advanced 48945b6f7e9SBarry Smith 49045b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 49145b6f7e9SBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 49245b6f7e9SBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 49345b6f7e9SBarry Smith 49445b6f7e9SBarry Smith Concepts: mapping^local to global 49545b6f7e9SBarry Smith @*/ 49645b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 49745b6f7e9SBarry Smith { 498cbc1caf0SMatthew G. Knepley 499cbc1caf0SMatthew G. Knepley PetscFunctionBegin; 500cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 501cbc1caf0SMatthew G. Knepley { 502afcb2eb5SJed Brown PetscInt i,Nmax = mapping->n; 503afcb2eb5SJed Brown const PetscInt *idx = mapping->indices; 504d4bb536fSBarry Smith 505afcb2eb5SJed Brown for (i=0; i<N; i++) { 506afcb2eb5SJed Brown if (in[i] < 0) { 507afcb2eb5SJed Brown out[i] = in[i]; 508afcb2eb5SJed Brown continue; 509afcb2eb5SJed Brown } 510e24637baSBarry Smith if (in[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local block index %D too large %D (max) at %D",in[i],Nmax-1,i); 511afcb2eb5SJed Brown out[i] = idx[in[i]]; 512afcb2eb5SJed Brown } 513cbc1caf0SMatthew G. Knepley } 514afcb2eb5SJed Brown PetscFunctionReturn(0); 515afcb2eb5SJed Brown } 516d4bb536fSBarry Smith 517d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 518d4bb536fSBarry Smith 5194a2ae208SSatish Balay #undef __FUNCT__ 5204a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 521d4bb536fSBarry Smith /* 522d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 523d4bb536fSBarry Smith */ 5246849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 525d4bb536fSBarry Smith { 5266849ba73SBarry Smith PetscErrorCode ierr; 52732dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 528d4bb536fSBarry Smith 5293a40ed3dSBarry Smith PetscFunctionBegin; 530d4bb536fSBarry Smith end = 0; 531ec268f7cSJed Brown start = PETSC_MAX_INT; 532d4bb536fSBarry Smith 533d4bb536fSBarry Smith for (i=0; i<n; i++) { 534d4bb536fSBarry Smith if (idx[i] < 0) continue; 535d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 536d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 537d4bb536fSBarry Smith } 538d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 539d4bb536fSBarry Smith mapping->globalstart = start; 540d4bb536fSBarry Smith mapping->globalend = end; 541d4bb536fSBarry Smith 542854ce69bSBarry Smith ierr = PetscMalloc1(end-start+2,&globals);CHKERRQ(ierr); 543b0a32e0cSBarry Smith mapping->globals = globals; 544f6e5521dSKarl Rupp for (i=0; i<end-start+1; i++) globals[i] = -1; 545d4bb536fSBarry Smith for (i=0; i<n; i++) { 546d4bb536fSBarry Smith if (idx[i] < 0) continue; 547d4bb536fSBarry Smith globals[idx[i] - start] = i; 548d4bb536fSBarry Smith } 549d4bb536fSBarry Smith 5503bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 5513a40ed3dSBarry Smith PetscFunctionReturn(0); 552d4bb536fSBarry Smith } 553d4bb536fSBarry Smith 5544a2ae208SSatish Balay #undef __FUNCT__ 5554a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 556d4bb536fSBarry Smith /*@ 557a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 558a997ad1aSLois Curfman McInnes specified with a global numbering. 559d4bb536fSBarry Smith 560b9cd556bSLois Curfman McInnes Not collective 561b9cd556bSLois Curfman McInnes 562d4bb536fSBarry Smith Input Parameters: 563b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 564d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 565d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 566d4bb536fSBarry Smith . n - number of global indices to map 567b9cd556bSLois Curfman McInnes - idx - global indices to map 568d4bb536fSBarry Smith 569d4bb536fSBarry Smith Output Parameters: 570b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 571b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 572e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 5730298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 574e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 575e182c471SBarry Smith a second time to set the values. 576d4bb536fSBarry Smith 577b9cd556bSLois Curfman McInnes Notes: 5780298fd71SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 579d4bb536fSBarry Smith 5800f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 5810f5bd95cSBarry Smith array to compute these. 5820f5bd95cSBarry Smith 583a997ad1aSLois Curfman McInnes Level: advanced 584a997ad1aSLois Curfman McInnes 58532fd6b96SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 58632fd6b96SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 58732fd6b96SBarry Smith 588273d9f13SBarry Smith Concepts: mapping^global to local 589d4bb536fSBarry Smith 5909d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApplyBlock(), ISLocalToGlobalMappingCreate(), 591d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 592d4bb536fSBarry Smith @*/ 5937087cfbeSBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 59432dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 595d4bb536fSBarry Smith { 5969d90f715SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end,bs; 5979d90f715SBarry Smith PetscErrorCode ierr; 5989d90f715SBarry Smith 5999d90f715SBarry Smith PetscFunctionBegin; 6009d90f715SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 6019d90f715SBarry Smith if (!mapping->globals) { 6029d90f715SBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 6039d90f715SBarry Smith } 6049d90f715SBarry Smith globals = mapping->globals; 6059d90f715SBarry Smith start = mapping->globalstart; 6069d90f715SBarry Smith end = mapping->globalend; 6079d90f715SBarry Smith bs = mapping->bs; 6089d90f715SBarry Smith 6099d90f715SBarry Smith if (type == IS_GTOLM_MASK) { 6109d90f715SBarry Smith if (idxout) { 6119d90f715SBarry Smith for (i=0; i<n; i++) { 6129d90f715SBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 6139d90f715SBarry Smith else if (idx[i] < bs*start) idxout[i] = -1; 614663bb84eSBarry Smith else if (idx[i] > bs*(end+1)-1) idxout[i] = -1; 6159d90f715SBarry Smith else idxout[i] = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6169d90f715SBarry Smith } 6179d90f715SBarry Smith } 6189d90f715SBarry Smith if (nout) *nout = n; 6199d90f715SBarry Smith } else { 6209d90f715SBarry Smith if (idxout) { 6219d90f715SBarry Smith for (i=0; i<n; i++) { 6229d90f715SBarry Smith if (idx[i] < 0) continue; 6239d90f715SBarry Smith if (idx[i] < bs*start) continue; 624663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 6259d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6269d90f715SBarry Smith if (tmp < 0) continue; 6279d90f715SBarry Smith idxout[nf++] = tmp; 6289d90f715SBarry Smith } 6299d90f715SBarry Smith } else { 6309d90f715SBarry Smith for (i=0; i<n; i++) { 6319d90f715SBarry Smith if (idx[i] < 0) continue; 6329d90f715SBarry Smith if (idx[i] < bs*start) continue; 633663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 6349d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6359d90f715SBarry Smith if (tmp < 0) continue; 6369d90f715SBarry Smith nf++; 6379d90f715SBarry Smith } 6389d90f715SBarry Smith } 6399d90f715SBarry Smith if (nout) *nout = nf; 6409d90f715SBarry Smith } 6419d90f715SBarry Smith PetscFunctionReturn(0); 6429d90f715SBarry Smith } 6439d90f715SBarry Smith 6449d90f715SBarry Smith #undef __FUNCT__ 645d4fe737eSStefano Zampini #define __FUNCT__ "ISGlobalToLocalMappingApplyIS" 646d4fe737eSStefano Zampini /*@ 647d4fe737eSStefano Zampini ISGlobalToLocalMappingApplyIS - Creates from an IS in the global numbering 648d4fe737eSStefano Zampini a new index set using the local numbering defined in an ISLocalToGlobalMapping 649d4fe737eSStefano Zampini context. 650d4fe737eSStefano Zampini 651d4fe737eSStefano Zampini Not collective 652d4fe737eSStefano Zampini 653d4fe737eSStefano Zampini Input Parameters: 654d4fe737eSStefano Zampini + mapping - mapping between local and global numbering 655d4fe737eSStefano Zampini - is - index set in global numbering 656d4fe737eSStefano Zampini 657d4fe737eSStefano Zampini Output Parameters: 658d4fe737eSStefano Zampini . newis - index set in local numbering 659d4fe737eSStefano Zampini 660d4fe737eSStefano Zampini Level: advanced 661d4fe737eSStefano Zampini 662d4fe737eSStefano Zampini Concepts: mapping^local to global 663d4fe737eSStefano Zampini 664d4fe737eSStefano Zampini .seealso: ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 665d4fe737eSStefano Zampini ISLocalToGlobalMappingDestroy() 666d4fe737eSStefano Zampini @*/ 667d4fe737eSStefano Zampini PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, IS is,IS *newis) 668d4fe737eSStefano Zampini { 669d4fe737eSStefano Zampini PetscErrorCode ierr; 670d4fe737eSStefano Zampini PetscInt n,nout,*idxout; 671d4fe737eSStefano Zampini const PetscInt *idxin; 672d4fe737eSStefano Zampini 673d4fe737eSStefano Zampini PetscFunctionBegin; 674d4fe737eSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 675d4fe737eSStefano Zampini PetscValidHeaderSpecific(is,IS_CLASSID,3); 676d4fe737eSStefano Zampini PetscValidPointer(newis,4); 677d4fe737eSStefano Zampini 678d4fe737eSStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 679d4fe737eSStefano Zampini ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 680d4fe737eSStefano Zampini if (type == IS_GTOLM_MASK) { 681d4fe737eSStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 682d4fe737eSStefano Zampini } else { 683d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,NULL);CHKERRQ(ierr); 684d4fe737eSStefano Zampini ierr = PetscMalloc1(nout,&idxout);CHKERRQ(ierr); 685d4fe737eSStefano Zampini } 686d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,idxout);CHKERRQ(ierr); 687d4fe737eSStefano Zampini ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 688d4fe737eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),nout,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 689d4fe737eSStefano Zampini PetscFunctionReturn(0); 690d4fe737eSStefano Zampini } 691d4fe737eSStefano Zampini 692d4fe737eSStefano Zampini #undef __FUNCT__ 6939d90f715SBarry Smith #define __FUNCT__ "ISGlobalToLocalMappingApplyBlock" 6949d90f715SBarry Smith /*@ 6959d90f715SBarry Smith ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers 6969d90f715SBarry Smith specified with a block global numbering. 6979d90f715SBarry Smith 6989d90f715SBarry Smith Not collective 6999d90f715SBarry Smith 7009d90f715SBarry Smith Input Parameters: 7019d90f715SBarry Smith + mapping - mapping between local and global numbering 7029d90f715SBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 7039d90f715SBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 7049d90f715SBarry Smith . n - number of global indices to map 7059d90f715SBarry Smith - idx - global indices to map 7069d90f715SBarry Smith 7079d90f715SBarry Smith Output Parameters: 7089d90f715SBarry Smith + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 7099d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough 7109d90f715SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApplyBlock() with 7119d90f715SBarry Smith idxout == NULL to determine the required length (returned in nout) 7129d90f715SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApplyBlock() 7139d90f715SBarry Smith a second time to set the values. 7149d90f715SBarry Smith 7159d90f715SBarry Smith Notes: 7169d90f715SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 7179d90f715SBarry Smith 7189d90f715SBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 7199d90f715SBarry Smith array to compute these. 7209d90f715SBarry Smith 7219d90f715SBarry Smith Level: advanced 7229d90f715SBarry Smith 7239d90f715SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 7249d90f715SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 7259d90f715SBarry Smith 7269d90f715SBarry Smith Concepts: mapping^global to local 7279d90f715SBarry Smith 7289d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 7299d90f715SBarry Smith ISLocalToGlobalMappingDestroy() 7309d90f715SBarry Smith @*/ 7319d90f715SBarry Smith PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 7329d90f715SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 7339d90f715SBarry Smith { 73432dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 7356849ba73SBarry Smith PetscErrorCode ierr; 736d4bb536fSBarry Smith 7373a40ed3dSBarry Smith PetscFunctionBegin; 7380700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 739d4bb536fSBarry Smith if (!mapping->globals) { 740d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 741d4bb536fSBarry Smith } 742d4bb536fSBarry Smith globals = mapping->globals; 743d4bb536fSBarry Smith start = mapping->globalstart; 744d4bb536fSBarry Smith end = mapping->globalend; 745d4bb536fSBarry Smith 746d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 747d4bb536fSBarry Smith if (idxout) { 748d4bb536fSBarry Smith for (i=0; i<n; i++) { 749d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 750d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 751d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 752d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 753d4bb536fSBarry Smith } 754d4bb536fSBarry Smith } 755d4bb536fSBarry Smith if (nout) *nout = n; 756d4bb536fSBarry Smith } else { 757d4bb536fSBarry Smith if (idxout) { 758d4bb536fSBarry Smith for (i=0; i<n; i++) { 759d4bb536fSBarry Smith if (idx[i] < 0) continue; 760d4bb536fSBarry Smith if (idx[i] < start) continue; 761d4bb536fSBarry Smith if (idx[i] > end) continue; 762d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 763d4bb536fSBarry Smith if (tmp < 0) continue; 764d4bb536fSBarry Smith idxout[nf++] = tmp; 765d4bb536fSBarry Smith } 766d4bb536fSBarry Smith } else { 767d4bb536fSBarry Smith for (i=0; i<n; i++) { 768d4bb536fSBarry Smith if (idx[i] < 0) continue; 769d4bb536fSBarry Smith if (idx[i] < start) continue; 770d4bb536fSBarry Smith if (idx[i] > end) continue; 771d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 772d4bb536fSBarry Smith if (tmp < 0) continue; 773d4bb536fSBarry Smith nf++; 774d4bb536fSBarry Smith } 775d4bb536fSBarry Smith } 776d4bb536fSBarry Smith if (nout) *nout = nf; 777d4bb536fSBarry Smith } 7783a40ed3dSBarry Smith PetscFunctionReturn(0); 779d4bb536fSBarry Smith } 78090f02eecSBarry Smith 7814a2ae208SSatish Balay #undef __FUNCT__ 7826a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo" 78389d82c54SBarry Smith /*@C 7846a818285SBarry Smith ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information for each processor and 78589d82c54SBarry Smith each index shared by more than one processor 78689d82c54SBarry Smith 78789d82c54SBarry Smith Collective on ISLocalToGlobalMapping 78889d82c54SBarry Smith 78989d82c54SBarry Smith Input Parameters: 79089d82c54SBarry Smith . mapping - the mapping from local to global indexing 79189d82c54SBarry Smith 79289d82c54SBarry Smith Output Parameter: 79389d82c54SBarry Smith + nproc - number of processors that are connected to this one 79489d82c54SBarry Smith . proc - neighboring processors 79507b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 7963463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 79789d82c54SBarry Smith 79889d82c54SBarry Smith Level: advanced 79989d82c54SBarry Smith 800273d9f13SBarry Smith Concepts: mapping^local to global 80189d82c54SBarry Smith 8022cfcea29SBarry Smith Fortran Usage: 8032cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 8042cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 8052cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 8062cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 8072cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 8082cfcea29SBarry Smith 8092cfcea29SBarry Smith 81007b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 81107b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 81289d82c54SBarry Smith @*/ 8136a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 81489d82c54SBarry Smith { 8156849ba73SBarry Smith PetscErrorCode ierr; 816268a049cSStefano Zampini 817268a049cSStefano Zampini PetscFunctionBegin; 818268a049cSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 819268a049cSStefano Zampini if (mapping->info_cached) { 820268a049cSStefano Zampini *nproc = mapping->info_nproc; 821268a049cSStefano Zampini *procs = mapping->info_procs; 822268a049cSStefano Zampini *numprocs = mapping->info_numprocs; 823268a049cSStefano Zampini *indices = mapping->info_indices; 824268a049cSStefano Zampini } else { 825268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo_Private(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 826268a049cSStefano Zampini } 827268a049cSStefano Zampini PetscFunctionReturn(0); 828268a049cSStefano Zampini } 829268a049cSStefano Zampini 830268a049cSStefano Zampini #undef __FUNCT__ 831268a049cSStefano Zampini #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo_Private" 832268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 833268a049cSStefano Zampini { 834268a049cSStefano Zampini PetscErrorCode ierr; 83597f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 83632dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 83732dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 83897f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 83932dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 84032dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 84189d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 84230dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 843ce94432eSBarry Smith MPI_Comm comm; 844ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 84589d82c54SBarry Smith 84689d82c54SBarry Smith PetscFunctionBegin; 847ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)mapping,&comm);CHKERRQ(ierr); 84824cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 84924cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 85024cf384cSBarry Smith if (size == 1) { 85124cf384cSBarry Smith *nproc = 0; 8520298fd71SBarry Smith *procs = NULL; 85395dccacaSBarry Smith ierr = PetscNew(numprocs);CHKERRQ(ierr); 8541e2105dcSBarry Smith (*numprocs)[0] = 0; 85595dccacaSBarry Smith ierr = PetscNew(indices);CHKERRQ(ierr); 8560298fd71SBarry Smith (*indices)[0] = NULL; 857268a049cSStefano Zampini /* save info for reuse */ 858268a049cSStefano Zampini mapping->info_nproc = *nproc; 859268a049cSStefano Zampini mapping->info_procs = *procs; 860268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 861268a049cSStefano Zampini mapping->info_indices = *indices; 862268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 86324cf384cSBarry Smith PetscFunctionReturn(0); 86424cf384cSBarry Smith } 86524cf384cSBarry Smith 866c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)mapping)->options,NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,NULL);CHKERRQ(ierr); 86707b52d57SBarry Smith 8683677ff5aSBarry Smith /* 8696a818285SBarry Smith Notes on ISLocalToGlobalMappingGetBlockInfo 8703677ff5aSBarry Smith 8713677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 8723677ff5aSBarry Smith numbering, just for this routine. 8733677ff5aSBarry Smith 8743677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 8753677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 8763677ff5aSBarry Smith 8773677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 8783677ff5aSBarry Smith 8793677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 8803677ff5aSBarry Smith local subdomain 8813677ff5aSBarry Smith */ 88224cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 88324cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 88424cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 88589d82c54SBarry Smith 88689d82c54SBarry Smith for (i=0; i<n; i++) { 88789d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 88889d82c54SBarry Smith } 889b2566f29SBarry Smith ierr = MPIU_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 89078058e43SBarry Smith Ng++; 89189d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 89289d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 893bc8ff85bSBarry Smith scale = Ng/size + 1; 894a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 895caba0dd0SBarry Smith rstart = scale*rank; 89689d82c54SBarry Smith 89789d82c54SBarry Smith /* determine ownership ranges of global indices */ 898785e854fSJed Brown ierr = PetscMalloc1(2*size,&nprocs);CHKERRQ(ierr); 89932dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 90089d82c54SBarry Smith 90189d82c54SBarry Smith /* determine owners of each local node */ 902785e854fSJed Brown ierr = PetscMalloc1(n,&owner);CHKERRQ(ierr); 90389d82c54SBarry Smith for (i=0; i<n; i++) { 9043677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 90527c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 9063677ff5aSBarry Smith owner[i] = proc; 90727c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 90889d82c54SBarry Smith } 90927c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 9107904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %D\n",nsends);CHKERRQ(ierr); 91189d82c54SBarry Smith 91289d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 91327c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 9147904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %D\n",nrecvs);CHKERRQ(ierr); 91589d82c54SBarry Smith 91689d82c54SBarry Smith /* post receives for owned rows */ 917785e854fSJed Brown ierr = PetscMalloc1((2*nrecvs+1)*(nmax+1),&recvs);CHKERRQ(ierr); 918854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&recv_waits);CHKERRQ(ierr); 91989d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 92032dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 92189d82c54SBarry Smith } 92289d82c54SBarry Smith 92389d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 924854ce69bSBarry Smith ierr = PetscMalloc1(2*n+1,&sends);CHKERRQ(ierr); 925854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&starts);CHKERRQ(ierr); 92689d82c54SBarry Smith starts[0] = 0; 927f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 92889d82c54SBarry Smith for (i=0; i<n; i++) { 92989d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 93030dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 93189d82c54SBarry Smith } 93289d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 93389d82c54SBarry Smith starts[0] = 0; 934f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 93589d82c54SBarry Smith 93689d82c54SBarry Smith /* send the messages */ 937854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&send_waits);CHKERRQ(ierr); 938854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&dest);CHKERRQ(ierr); 93989d82c54SBarry Smith cnt = 0; 94089d82c54SBarry Smith for (i=0; i<size; i++) { 94127c402fcSBarry Smith if (nprocs[2*i]) { 94232dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 94330dcb7c9SBarry Smith dest[cnt] = i; 94489d82c54SBarry Smith cnt++; 94589d82c54SBarry Smith } 94689d82c54SBarry Smith } 94789d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 94889d82c54SBarry Smith 94989d82c54SBarry Smith /* wait on receives */ 950854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&source);CHKERRQ(ierr); 951854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&len);CHKERRQ(ierr); 95289d82c54SBarry Smith cnt = nrecvs; 953854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&nownedsenders);CHKERRQ(ierr); 95432dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 95589d82c54SBarry Smith while (cnt) { 95689d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 95789d82c54SBarry Smith /* unpack receives into our local space */ 95832dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 95989d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 96030dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 961caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 96230dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 96389d82c54SBarry Smith cnt--; 96489d82c54SBarry Smith } 96589d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 96689d82c54SBarry Smith 96730dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 968bc8ff85bSBarry Smith nowned = 0; 969bc8ff85bSBarry Smith nownedm = 0; 970bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 971bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 972bc8ff85bSBarry Smith } 973bc8ff85bSBarry Smith 974bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 975854ce69bSBarry Smith ierr = PetscMalloc1(nownedm+1,&ownedsenders);CHKERRQ(ierr); 976854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&starts);CHKERRQ(ierr); 977bc8ff85bSBarry Smith starts[0] = 0; 978bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 979bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 980bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 981bc8ff85bSBarry Smith } 982bc8ff85bSBarry Smith 98330dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 984bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 985bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 98630dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 987f6e5521dSKarl Rupp if (nownedsenders[node] > 1) ownedsenders[starts[node]++] = source[i]; 988bc8ff85bSBarry Smith } 989bc8ff85bSBarry Smith } 990bc8ff85bSBarry Smith 99107b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 99230dcb7c9SBarry Smith starts[0] = 0; 99330dcb7c9SBarry Smith for (i=1; i<ng; i++) { 99430dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 99530dcb7c9SBarry Smith else starts[i] = starts[i-1]; 99630dcb7c9SBarry Smith } 99730dcb7c9SBarry Smith for (i=0; i<ng; i++) { 99830dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 9997904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %D local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 100030dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 10017904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 100230dcb7c9SBarry Smith } 100330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 100430dcb7c9SBarry Smith } 100530dcb7c9SBarry Smith } 10060ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 100707b52d57SBarry Smith } /* ----------------------------------- */ 100830dcb7c9SBarry Smith 10093677ff5aSBarry Smith /* wait on original sends */ 10103a96401aSBarry Smith if (nsends) { 1011785e854fSJed Brown ierr = PetscMalloc1(nsends,&send_status);CHKERRQ(ierr); 10123a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 10133a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 10143a96401aSBarry Smith } 101589d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 10163a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 10173677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 10183677ff5aSBarry Smith 10193677ff5aSBarry Smith /* pack messages to send back to local owners */ 102030dcb7c9SBarry Smith starts[0] = 0; 102130dcb7c9SBarry Smith for (i=1; i<ng; i++) { 102230dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 102330dcb7c9SBarry Smith else starts[i] = starts[i-1]; 102430dcb7c9SBarry Smith } 102530dcb7c9SBarry Smith nsends2 = nrecvs; 1026854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&nprocs);CHKERRQ(ierr); /* length of each message */ 102730dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 102830dcb7c9SBarry Smith nprocs[i] = 1; 102930dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 103030dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 1031f6e5521dSKarl Rupp if (nownedsenders[node] > 1) nprocs[i] += 2 + nownedsenders[node]; 103230dcb7c9SBarry Smith } 103330dcb7c9SBarry Smith } 1034f6e5521dSKarl Rupp nt = 0; 1035f6e5521dSKarl Rupp for (i=0; i<nsends2; i++) nt += nprocs[i]; 1036f6e5521dSKarl Rupp 1037854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&sends2);CHKERRQ(ierr); 1038854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&starts2);CHKERRQ(ierr); 1039f6e5521dSKarl Rupp 1040f6e5521dSKarl Rupp starts2[0] = 0; 1041f6e5521dSKarl Rupp for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 104230dcb7c9SBarry Smith /* 104330dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 104430dcb7c9SBarry Smith (0) the number of nodes being sent back 104530dcb7c9SBarry Smith (1) the local node number, 104630dcb7c9SBarry Smith (2) the number of processors sharing it, 104730dcb7c9SBarry Smith (3) the processors sharing it 104830dcb7c9SBarry Smith */ 104930dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 105030dcb7c9SBarry Smith cnt = 1; 105130dcb7c9SBarry Smith sends2[starts2[i]] = 0; 105230dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 105330dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 105430dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 105530dcb7c9SBarry Smith sends2[starts2[i]]++; 105630dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 105730dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 105832dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 105930dcb7c9SBarry Smith cnt += nownedsenders[node]; 106030dcb7c9SBarry Smith } 106130dcb7c9SBarry Smith } 106230dcb7c9SBarry Smith } 106330dcb7c9SBarry Smith 106430dcb7c9SBarry Smith /* receive the message lengths */ 106530dcb7c9SBarry Smith nrecvs2 = nsends; 1066854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&lens2);CHKERRQ(ierr); 1067854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&starts3);CHKERRQ(ierr); 1068854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 106930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 1070d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 107130dcb7c9SBarry Smith } 1072d44834fbSBarry Smith 10738a8e0b3aSBarry Smith /* send the message lengths */ 10748a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 10758a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 10768a8e0b3aSBarry Smith } 10778a8e0b3aSBarry Smith 1078d44834fbSBarry Smith /* wait on receives of lens */ 10790c468ba9SBarry Smith if (nrecvs2) { 1080785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 1081d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 1082d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 10830c468ba9SBarry Smith } 1084a2ea699eSBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 1085d44834fbSBarry Smith 108630dcb7c9SBarry Smith starts3[0] = 0; 1087d44834fbSBarry Smith nt = 0; 108830dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 108930dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 1090d44834fbSBarry Smith nt += lens2[i]; 109130dcb7c9SBarry Smith } 109276466f69SStefano Zampini if (nrecvs2) nt += lens2[nrecvs2-1]; 1093d44834fbSBarry Smith 1094854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&recvs2);CHKERRQ(ierr); 1095854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 109652b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 109732dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 109830dcb7c9SBarry Smith } 109930dcb7c9SBarry Smith 110030dcb7c9SBarry Smith /* send the messages */ 1101854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&send_waits);CHKERRQ(ierr); 110230dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 110332dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 110430dcb7c9SBarry Smith } 110530dcb7c9SBarry Smith 110630dcb7c9SBarry Smith /* wait on receives */ 11070c468ba9SBarry Smith if (nrecvs2) { 1108785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 110930dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 111030dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 11110c468ba9SBarry Smith } 111230dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 111330dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 111430dcb7c9SBarry Smith 111507b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 111630dcb7c9SBarry Smith cnt = 0; 111730dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 111830dcb7c9SBarry Smith nt = recvs2[cnt++]; 111930dcb7c9SBarry Smith for (j=0; j<nt; j++) { 11207904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %D number of subdomains %D: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 112130dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 11227904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",recvs2[cnt+2+k]);CHKERRQ(ierr); 112330dcb7c9SBarry Smith } 112430dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 112530dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 112630dcb7c9SBarry Smith } 112730dcb7c9SBarry Smith } 11280ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 112907b52d57SBarry Smith } /* ----------------------------------- */ 113030dcb7c9SBarry Smith 113130dcb7c9SBarry Smith /* count number subdomains for each local node */ 1132785e854fSJed Brown ierr = PetscMalloc1(size,&nprocs);CHKERRQ(ierr); 113332dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 113430dcb7c9SBarry Smith cnt = 0; 113530dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 113630dcb7c9SBarry Smith nt = recvs2[cnt++]; 113730dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1138f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) nprocs[recvs2[cnt+2+k]]++; 113930dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 114030dcb7c9SBarry Smith } 114130dcb7c9SBarry Smith } 114230dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 114330dcb7c9SBarry Smith *nproc = nt; 1144854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,procs);CHKERRQ(ierr); 1145854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,numprocs);CHKERRQ(ierr); 1146854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,indices);CHKERRQ(ierr); 11470298fd71SBarry Smith for (i=0;i<nt+1;i++) (*indices)[i]=NULL; 1148785e854fSJed Brown ierr = PetscMalloc1(size,&bprocs);CHKERRQ(ierr); 114930dcb7c9SBarry Smith cnt = 0; 115030dcb7c9SBarry Smith for (i=0; i<size; i++) { 115130dcb7c9SBarry Smith if (nprocs[i] > 0) { 115230dcb7c9SBarry Smith bprocs[i] = cnt; 115330dcb7c9SBarry Smith (*procs)[cnt] = i; 115430dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 1155785e854fSJed Brown ierr = PetscMalloc1(nprocs[i],&(*indices)[cnt]);CHKERRQ(ierr); 115630dcb7c9SBarry Smith cnt++; 115730dcb7c9SBarry Smith } 115830dcb7c9SBarry Smith } 115930dcb7c9SBarry Smith 116030dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 116132dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 116230dcb7c9SBarry Smith cnt = 0; 116330dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 116430dcb7c9SBarry Smith nt = recvs2[cnt++]; 116530dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1166f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 116730dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 116830dcb7c9SBarry Smith } 116930dcb7c9SBarry Smith } 117030dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 117107b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 117230dcb7c9SBarry Smith 117307b52d57SBarry Smith /* sort the node indexing by their global numbers */ 117407b52d57SBarry Smith nt = *nproc; 117507b52d57SBarry Smith for (i=0; i<nt; i++) { 1176854ce69bSBarry Smith ierr = PetscMalloc1((*numprocs)[i],&tmp);CHKERRQ(ierr); 1177f6e5521dSKarl Rupp for (j=0; j<(*numprocs)[i]; j++) tmp[j] = lindices[(*indices)[i][j]]; 117807b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 117907b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 118007b52d57SBarry Smith } 118107b52d57SBarry Smith 118207b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 118330dcb7c9SBarry Smith nt = *nproc; 118430dcb7c9SBarry Smith for (i=0; i<nt; i++) { 11857904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %D number of indices %D: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 118630dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 11877904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",(*indices)[i][j]);CHKERRQ(ierr); 118830dcb7c9SBarry Smith } 118930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 119030dcb7c9SBarry Smith } 11910ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 119207b52d57SBarry Smith } /* ----------------------------------- */ 119330dcb7c9SBarry Smith 119430dcb7c9SBarry Smith /* wait on sends */ 119530dcb7c9SBarry Smith if (nsends2) { 1196785e854fSJed Brown ierr = PetscMalloc1(nsends2,&send_status);CHKERRQ(ierr); 119730dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 119830dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 119930dcb7c9SBarry Smith } 120030dcb7c9SBarry Smith 120130dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 120230dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 120330dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 12043677ff5aSBarry Smith 1205bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 1206bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 1207bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 120830dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 120930dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 121089d82c54SBarry Smith 121189d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 121297f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 121389d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 12143a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 121530dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 121624cf384cSBarry Smith 121724cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 121824cf384cSBarry Smith first_procs = (*procs)[0]; 121924cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 122024cf384cSBarry Smith first_indices = (*indices)[0]; 122124cf384cSBarry Smith for (i=0; i<*nproc; i++) { 122224cf384cSBarry Smith if ((*procs)[i] == rank) { 122324cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 122424cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 122524cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 122624cf384cSBarry Smith (*procs)[i] = first_procs; 122724cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 122824cf384cSBarry Smith (*indices)[i] = first_indices; 122924cf384cSBarry Smith break; 123024cf384cSBarry Smith } 123124cf384cSBarry Smith } 1232268a049cSStefano Zampini 1233268a049cSStefano Zampini /* save info for reuse */ 1234268a049cSStefano Zampini mapping->info_nproc = *nproc; 1235268a049cSStefano Zampini mapping->info_procs = *procs; 1236268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 1237268a049cSStefano Zampini mapping->info_indices = *indices; 1238268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 123989d82c54SBarry Smith PetscFunctionReturn(0); 124089d82c54SBarry Smith } 124189d82c54SBarry Smith 12424a2ae208SSatish Balay #undef __FUNCT__ 12436a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockInfo" 12446a818285SBarry Smith /*@C 12456a818285SBarry Smith ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by ISLocalToGlobalMappingGetBlockInfo() 12466a818285SBarry Smith 12476a818285SBarry Smith Collective on ISLocalToGlobalMapping 12486a818285SBarry Smith 12496a818285SBarry Smith Input Parameters: 12506a818285SBarry Smith . mapping - the mapping from local to global indexing 12516a818285SBarry Smith 12526a818285SBarry Smith Output Parameter: 12536a818285SBarry Smith + nproc - number of processors that are connected to this one 12546a818285SBarry Smith . proc - neighboring processors 12556a818285SBarry Smith . numproc - number of indices for each processor 12566a818285SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 12576a818285SBarry Smith 12586a818285SBarry Smith Level: advanced 12596a818285SBarry Smith 12606a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 12616a818285SBarry Smith ISLocalToGlobalMappingGetInfo() 12626a818285SBarry Smith @*/ 12636a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 12646a818285SBarry Smith { 12656a818285SBarry Smith PetscErrorCode ierr; 12666a818285SBarry Smith 12676a818285SBarry Smith PetscFunctionBegin; 1268cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1269268a049cSStefano Zampini if (mapping->info_free) { 12706a818285SBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 12716a818285SBarry Smith if (*indices) { 1272268a049cSStefano Zampini PetscInt i; 1273268a049cSStefano Zampini 12746a818285SBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 12756a818285SBarry Smith for (i=1; i<*nproc; i++) { 12766a818285SBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 12776a818285SBarry Smith } 12786a818285SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 12796a818285SBarry Smith } 1280268a049cSStefano Zampini } 1281268a049cSStefano Zampini *nproc = 0; 1282268a049cSStefano Zampini *procs = NULL; 1283268a049cSStefano Zampini *numprocs = NULL; 1284268a049cSStefano Zampini *indices = NULL; 12856a818285SBarry Smith PetscFunctionReturn(0); 12866a818285SBarry Smith } 12876a818285SBarry Smith 12886a818285SBarry Smith #undef __FUNCT__ 12896a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 12906a818285SBarry Smith /*@C 12916a818285SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 12926a818285SBarry Smith each index shared by more than one processor 12936a818285SBarry Smith 12946a818285SBarry Smith Collective on ISLocalToGlobalMapping 12956a818285SBarry Smith 12966a818285SBarry Smith Input Parameters: 12976a818285SBarry Smith . mapping - the mapping from local to global indexing 12986a818285SBarry Smith 12996a818285SBarry Smith Output Parameter: 13006a818285SBarry Smith + nproc - number of processors that are connected to this one 13016a818285SBarry Smith . proc - neighboring processors 13026a818285SBarry Smith . numproc - number of indices for each subdomain (processor) 13036a818285SBarry Smith - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 13046a818285SBarry Smith 13056a818285SBarry Smith Level: advanced 13066a818285SBarry Smith 13076a818285SBarry Smith Concepts: mapping^local to global 13086a818285SBarry Smith 13096a818285SBarry Smith Fortran Usage: 13106a818285SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 13116a818285SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 13126a818285SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 13136a818285SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 13146a818285SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 13156a818285SBarry Smith 13166a818285SBarry Smith 13176a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 13186a818285SBarry Smith ISLocalToGlobalMappingRestoreInfo() 13196a818285SBarry Smith @*/ 13206a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 13216a818285SBarry Smith { 13226a818285SBarry Smith PetscErrorCode ierr; 1323268a049cSStefano Zampini PetscInt **bindices = NULL,*bnumprocs = NULL,bs = mapping->bs,i,j,k; 13246a818285SBarry Smith 13256a818285SBarry Smith PetscFunctionBegin; 13266a818285SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1327268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo(mapping,nproc,procs,&bnumprocs,&bindices);CHKERRQ(ierr); 1328268a049cSStefano Zampini if (bs > 1) { /* we need to expand the cached info */ 1329732f65e3SBarry Smith ierr = PetscCalloc1(*nproc,&*indices);CHKERRQ(ierr); 1330268a049cSStefano Zampini ierr = PetscCalloc1(*nproc,&*numprocs);CHKERRQ(ierr); 13316a818285SBarry Smith for (i=0; i<*nproc; i++) { 1332268a049cSStefano Zampini ierr = PetscMalloc1(bs*bnumprocs[i],&(*indices)[i]);CHKERRQ(ierr); 1333268a049cSStefano Zampini for (j=0; j<bnumprocs[i]; j++) { 13346a818285SBarry Smith for (k=0; k<bs; k++) { 13356a818285SBarry Smith (*indices)[i][j*bs+k] = bs*bindices[i][j] + k; 13366a818285SBarry Smith } 13376a818285SBarry Smith } 1338268a049cSStefano Zampini (*numprocs)[i] = bnumprocs[i]*bs; 13396a818285SBarry Smith } 1340268a049cSStefano Zampini mapping->info_free = PETSC_TRUE; 1341268a049cSStefano Zampini } else { 1342268a049cSStefano Zampini *numprocs = bnumprocs; 1343268a049cSStefano Zampini *indices = bindices; 13446a818285SBarry Smith } 13456a818285SBarry Smith PetscFunctionReturn(0); 13466a818285SBarry Smith } 13476a818285SBarry Smith 13486a818285SBarry Smith #undef __FUNCT__ 13494a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 135007b52d57SBarry Smith /*@C 135107b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 135289d82c54SBarry Smith 135307b52d57SBarry Smith Collective on ISLocalToGlobalMapping 135407b52d57SBarry Smith 135507b52d57SBarry Smith Input Parameters: 135607b52d57SBarry Smith . mapping - the mapping from local to global indexing 135707b52d57SBarry Smith 135807b52d57SBarry Smith Output Parameter: 135907b52d57SBarry Smith + nproc - number of processors that are connected to this one 136007b52d57SBarry Smith . proc - neighboring processors 136107b52d57SBarry Smith . numproc - number of indices for each processor 136207b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 136307b52d57SBarry Smith 136407b52d57SBarry Smith Level: advanced 136507b52d57SBarry Smith 136607b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 136707b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 136807b52d57SBarry Smith @*/ 13697087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 137007b52d57SBarry Smith { 13716849ba73SBarry Smith PetscErrorCode ierr; 137207b52d57SBarry Smith 137307b52d57SBarry Smith PetscFunctionBegin; 13746a818285SBarry Smith ierr = ISLocalToGlobalMappingRestoreBlockInfo(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 137507b52d57SBarry Smith PetscFunctionReturn(0); 137607b52d57SBarry Smith } 137786994e45SJed Brown 137886994e45SJed Brown #undef __FUNCT__ 137986994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingGetIndices" 138086994e45SJed Brown /*@C 1381107e9a97SBarry Smith ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped 138286994e45SJed Brown 138386994e45SJed Brown Not Collective 138486994e45SJed Brown 138586994e45SJed Brown Input Arguments: 138686994e45SJed Brown . ltog - local to global mapping 138786994e45SJed Brown 138886994e45SJed Brown Output Arguments: 1389565245c5SBarry Smith . array - array of indices, the length of this array may be obtained with ISLocalToGlobalMappingGetSize() 139086994e45SJed Brown 139186994e45SJed Brown Level: advanced 139286994e45SJed Brown 1393107e9a97SBarry Smith Notes: ISLocalToGlobalMappingGetSize() returns the length the this array 1394107e9a97SBarry Smith 1395107e9a97SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreIndices(), ISLocalToGlobalMappingGetBlockIndices(), ISLocalToGlobalMappingRestoreBlockIndices() 139686994e45SJed Brown @*/ 13977087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 139886994e45SJed Brown { 139986994e45SJed Brown PetscFunctionBegin; 140086994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 140186994e45SJed Brown PetscValidPointer(array,2); 140245b6f7e9SBarry Smith if (ltog->bs == 1) { 140386994e45SJed Brown *array = ltog->indices; 140445b6f7e9SBarry Smith } else { 140545b6f7e9SBarry Smith PetscInt *jj,k,i,j,n = ltog->n, bs = ltog->bs; 140645b6f7e9SBarry Smith const PetscInt *ii; 140745b6f7e9SBarry Smith PetscErrorCode ierr; 140845b6f7e9SBarry Smith 140945b6f7e9SBarry Smith ierr = PetscMalloc1(bs*n,&jj);CHKERRQ(ierr); 141045b6f7e9SBarry Smith *array = jj; 141145b6f7e9SBarry Smith k = 0; 141245b6f7e9SBarry Smith ii = ltog->indices; 141345b6f7e9SBarry Smith for (i=0; i<n; i++) 141445b6f7e9SBarry Smith for (j=0; j<bs; j++) 141545b6f7e9SBarry Smith jj[k++] = bs*ii[i] + j; 141645b6f7e9SBarry Smith } 141786994e45SJed Brown PetscFunctionReturn(0); 141886994e45SJed Brown } 141986994e45SJed Brown 142086994e45SJed Brown #undef __FUNCT__ 142186994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingRestoreIndices" 142286994e45SJed Brown /*@C 1423193a2b41SJulian Andrej ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with ISLocalToGlobalMappingGetIndices() 142486994e45SJed Brown 142586994e45SJed Brown Not Collective 142686994e45SJed Brown 142786994e45SJed Brown Input Arguments: 142886994e45SJed Brown + ltog - local to global mapping 142986994e45SJed Brown - array - array of indices 143086994e45SJed Brown 143186994e45SJed Brown Level: advanced 143286994e45SJed Brown 143386994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 143486994e45SJed Brown @*/ 14357087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 143686994e45SJed Brown { 143786994e45SJed Brown PetscFunctionBegin; 143886994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 143986994e45SJed Brown PetscValidPointer(array,2); 144045b6f7e9SBarry Smith if (ltog->bs == 1 && *array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 144145b6f7e9SBarry Smith 144245b6f7e9SBarry Smith if (ltog->bs > 1) { 144345b6f7e9SBarry Smith PetscErrorCode ierr; 144445b6f7e9SBarry Smith ierr = PetscFree(*(void**)array);CHKERRQ(ierr); 144545b6f7e9SBarry Smith } 144645b6f7e9SBarry Smith PetscFunctionReturn(0); 144745b6f7e9SBarry Smith } 144845b6f7e9SBarry Smith 144945b6f7e9SBarry Smith #undef __FUNCT__ 145045b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockIndices" 145145b6f7e9SBarry Smith /*@C 145245b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block 145345b6f7e9SBarry Smith 145445b6f7e9SBarry Smith Not Collective 145545b6f7e9SBarry Smith 145645b6f7e9SBarry Smith Input Arguments: 145745b6f7e9SBarry Smith . ltog - local to global mapping 145845b6f7e9SBarry Smith 145945b6f7e9SBarry Smith Output Arguments: 146045b6f7e9SBarry Smith . array - array of indices 146145b6f7e9SBarry Smith 146245b6f7e9SBarry Smith Level: advanced 146345b6f7e9SBarry Smith 146445b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreBlockIndices() 146545b6f7e9SBarry Smith @*/ 146645b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 146745b6f7e9SBarry Smith { 146845b6f7e9SBarry Smith PetscFunctionBegin; 146945b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 147045b6f7e9SBarry Smith PetscValidPointer(array,2); 147145b6f7e9SBarry Smith *array = ltog->indices; 147245b6f7e9SBarry Smith PetscFunctionReturn(0); 147345b6f7e9SBarry Smith } 147445b6f7e9SBarry Smith 147545b6f7e9SBarry Smith #undef __FUNCT__ 147645b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockIndices" 147745b6f7e9SBarry Smith /*@C 147845b6f7e9SBarry Smith ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with ISLocalToGlobalMappingGetBlockIndices() 147945b6f7e9SBarry Smith 148045b6f7e9SBarry Smith Not Collective 148145b6f7e9SBarry Smith 148245b6f7e9SBarry Smith Input Arguments: 148345b6f7e9SBarry Smith + ltog - local to global mapping 148445b6f7e9SBarry Smith - array - array of indices 148545b6f7e9SBarry Smith 148645b6f7e9SBarry Smith Level: advanced 148745b6f7e9SBarry Smith 148845b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 148945b6f7e9SBarry Smith @*/ 149045b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 149145b6f7e9SBarry Smith { 149245b6f7e9SBarry Smith PetscFunctionBegin; 149345b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 149445b6f7e9SBarry Smith PetscValidPointer(array,2); 149586994e45SJed Brown if (*array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 14960298fd71SBarry Smith *array = NULL; 149786994e45SJed Brown PetscFunctionReturn(0); 149886994e45SJed Brown } 1499f7efa3c7SJed Brown 1500f7efa3c7SJed Brown #undef __FUNCT__ 1501f7efa3c7SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingConcatenate" 1502f7efa3c7SJed Brown /*@C 1503f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1504f7efa3c7SJed Brown 1505f7efa3c7SJed Brown Not Collective 1506f7efa3c7SJed Brown 1507f7efa3c7SJed Brown Input Arguments: 1508f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1509f7efa3c7SJed Brown . n - number of mappings to concatenate 1510f7efa3c7SJed Brown - ltogs - local to global mappings 1511f7efa3c7SJed Brown 1512f7efa3c7SJed Brown Output Arguments: 1513f7efa3c7SJed Brown . ltogcat - new mapping 1514f7efa3c7SJed Brown 15159d90f715SBarry Smith Note: this currently always returns a mapping with block size of 1 15169d90f715SBarry Smith 15179d90f715SBarry Smith Developer Note: If all the input mapping have the same block size we could easily handle that as a special case 15189d90f715SBarry Smith 1519f7efa3c7SJed Brown Level: advanced 1520f7efa3c7SJed Brown 1521f7efa3c7SJed Brown .seealso: ISLocalToGlobalMappingCreate() 1522f7efa3c7SJed Brown @*/ 1523f7efa3c7SJed Brown PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping *ltogcat) 1524f7efa3c7SJed Brown { 1525f7efa3c7SJed Brown PetscInt i,cnt,m,*idx; 1526f7efa3c7SJed Brown PetscErrorCode ierr; 1527f7efa3c7SJed Brown 1528f7efa3c7SJed Brown PetscFunctionBegin; 1529f7efa3c7SJed Brown if (n < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have a non-negative number of mappings, given %D",n); 1530f7efa3c7SJed Brown if (n > 0) PetscValidPointer(ltogs,3); 1531f7efa3c7SJed Brown for (i=0; i<n; i++) PetscValidHeaderSpecific(ltogs[i],IS_LTOGM_CLASSID,3); 1532f7efa3c7SJed Brown PetscValidPointer(ltogcat,4); 1533f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1534f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1535f7efa3c7SJed Brown cnt += m; 1536f7efa3c7SJed Brown } 1537785e854fSJed Brown ierr = PetscMalloc1(cnt,&idx);CHKERRQ(ierr); 1538f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1539f7efa3c7SJed Brown const PetscInt *subidx; 1540f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1541f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1542f7efa3c7SJed Brown ierr = PetscMemcpy(&idx[cnt],subidx,m*sizeof(PetscInt));CHKERRQ(ierr); 1543f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1544f7efa3c7SJed Brown cnt += m; 1545f7efa3c7SJed Brown } 1546f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,cnt,idx,PETSC_OWN_POINTER,ltogcat);CHKERRQ(ierr); 1547f7efa3c7SJed Brown PetscFunctionReturn(0); 1548f7efa3c7SJed Brown } 154904a59952SBarry Smith 155004a59952SBarry Smith 1551