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 96658fb44Sstefano_zampini /*@ 106658fb44Sstefano_zampini ISLocalToGlobalMappingDuplicate - Duplicates the local to global mapping object 116658fb44Sstefano_zampini 126658fb44Sstefano_zampini Not Collective 136658fb44Sstefano_zampini 146658fb44Sstefano_zampini Input Parameter: 156658fb44Sstefano_zampini . ltog - local to global mapping 166658fb44Sstefano_zampini 176658fb44Sstefano_zampini Output Parameter: 186658fb44Sstefano_zampini . nltog - the duplicated local to global mapping 196658fb44Sstefano_zampini 206658fb44Sstefano_zampini Level: advanced 216658fb44Sstefano_zampini 226658fb44Sstefano_zampini Concepts: mapping^local to global 236658fb44Sstefano_zampini 246658fb44Sstefano_zampini .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 256658fb44Sstefano_zampini @*/ 266658fb44Sstefano_zampini PetscErrorCode ISLocalToGlobalMappingDuplicate(ISLocalToGlobalMapping ltog,ISLocalToGlobalMapping* nltog) 276658fb44Sstefano_zampini { 286658fb44Sstefano_zampini PetscErrorCode ierr; 296658fb44Sstefano_zampini 306658fb44Sstefano_zampini PetscFunctionBegin; 316658fb44Sstefano_zampini PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 326658fb44Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)ltog),ltog->bs,ltog->n,ltog->indices,PETSC_COPY_VALUES,nltog);CHKERRQ(ierr); 336658fb44Sstefano_zampini PetscFunctionReturn(0); 346658fb44Sstefano_zampini } 356658fb44Sstefano_zampini 36565245c5SBarry Smith /*@ 37107e9a97SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping 383b9aefa3SBarry Smith 393b9aefa3SBarry Smith Not Collective 403b9aefa3SBarry Smith 413b9aefa3SBarry Smith Input Parameter: 423b9aefa3SBarry Smith . ltog - local to global mapping 433b9aefa3SBarry Smith 443b9aefa3SBarry Smith Output Parameter: 45107e9a97SBarry Smith . n - the number of entries in the local mapping, ISLocalToGlobalMappingGetIndices() returns an array of this length 463b9aefa3SBarry Smith 473b9aefa3SBarry Smith Level: advanced 483b9aefa3SBarry Smith 49273d9f13SBarry Smith Concepts: mapping^local to global 503b9aefa3SBarry Smith 513b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 523b9aefa3SBarry Smith @*/ 537087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n) 543b9aefa3SBarry Smith { 553b9aefa3SBarry Smith PetscFunctionBegin; 560700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 574482741eSBarry Smith PetscValidIntPointer(n,2); 58107e9a97SBarry Smith *n = mapping->bs*mapping->n; 593b9aefa3SBarry Smith PetscFunctionReturn(0); 603b9aefa3SBarry Smith } 613b9aefa3SBarry Smith 625a5d4f66SBarry Smith /*@C 635a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 645a5d4f66SBarry Smith 65b9cd556bSLois Curfman McInnes Not Collective 66b9cd556bSLois Curfman McInnes 675a5d4f66SBarry Smith Input Parameters: 683b9aefa3SBarry Smith + ltog - local to global mapping 693b9aefa3SBarry Smith - viewer - viewer 705a5d4f66SBarry Smith 71a997ad1aSLois Curfman McInnes Level: advanced 72a997ad1aSLois Curfman McInnes 73273d9f13SBarry Smith Concepts: mapping^local to global 745a5d4f66SBarry Smith 755a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 765a5d4f66SBarry Smith @*/ 777087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 785a5d4f66SBarry Smith { 7932dcc486SBarry Smith PetscInt i; 8032dcc486SBarry Smith PetscMPIInt rank; 81ace3abfcSBarry Smith PetscBool iascii; 826849ba73SBarry Smith PetscErrorCode ierr; 835a5d4f66SBarry Smith 845a5d4f66SBarry Smith PetscFunctionBegin; 850700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 863050cee2SBarry Smith if (!viewer) { 87ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mapping),&viewer);CHKERRQ(ierr); 883050cee2SBarry Smith } 890700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 905a5d4f66SBarry Smith 91ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mapping),&rank);CHKERRQ(ierr); 92251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 9332077d6dSBarry Smith if (iascii) { 9498c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mapping,viewer);CHKERRQ(ierr); 951575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 965a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 977904a332SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %D %D\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 986831982aSBarry Smith } 99b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1001575c14dSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 1011575c14dSBarry Smith } 1025a5d4f66SBarry Smith PetscFunctionReturn(0); 1035a5d4f66SBarry Smith } 1045a5d4f66SBarry Smith 1051f428162SBarry Smith /*@ 1062bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 1072bdab257SBarry Smith ordering and a global parallel ordering. 1082bdab257SBarry Smith 1090f5bd95cSBarry Smith Not collective 110b9cd556bSLois Curfman McInnes 111a997ad1aSLois Curfman McInnes Input Parameter: 1128c03b21aSDmitry Karpeev . is - index set containing the global numbers for each local number 1132bdab257SBarry Smith 114a997ad1aSLois Curfman McInnes Output Parameter: 1152bdab257SBarry Smith . mapping - new mapping data structure 1162bdab257SBarry Smith 117f0413b6fSBarry Smith Notes: the block size of the IS determines the block size of the mapping 118a997ad1aSLois Curfman McInnes Level: advanced 119a997ad1aSLois Curfman McInnes 120273d9f13SBarry Smith Concepts: mapping^local to global 1212bdab257SBarry Smith 1222bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 1232bdab257SBarry Smith @*/ 1247087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 1252bdab257SBarry Smith { 1266849ba73SBarry Smith PetscErrorCode ierr; 1273bbf0e92SBarry Smith PetscInt n,bs; 1285d0c19d7SBarry Smith const PetscInt *indices; 1292bdab257SBarry Smith MPI_Comm comm; 1303bbf0e92SBarry Smith PetscBool isblock; 1313a40ed3dSBarry Smith 1323a40ed3dSBarry Smith PetscFunctionBegin; 1330700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,1); 1344482741eSBarry Smith PetscValidPointer(mapping,2); 1352bdab257SBarry Smith 1362bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1373b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1383bbf0e92SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)is,ISBLOCK,&isblock);CHKERRQ(ierr); 1396006e8d2SBarry Smith if (!isblock) { 140f0413b6fSBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 141f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,n,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 1422bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1436006e8d2SBarry Smith } else { 1446006e8d2SBarry Smith ierr = ISGetBlockSize(is,&bs);CHKERRQ(ierr); 145f0413b6fSBarry Smith ierr = ISBlockGetIndices(is,&indices);CHKERRQ(ierr); 14628bc9809SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,bs,n/bs,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 147f0413b6fSBarry Smith ierr = ISBlockRestoreIndices(is,&indices);CHKERRQ(ierr); 1486006e8d2SBarry Smith } 1493a40ed3dSBarry Smith PetscFunctionReturn(0); 1502bdab257SBarry Smith } 1515a5d4f66SBarry Smith 152a4d96a55SJed Brown /*@C 153a4d96a55SJed Brown ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n) 154a4d96a55SJed Brown ordering and a global parallel ordering. 155a4d96a55SJed Brown 156a4d96a55SJed Brown Collective 157a4d96a55SJed Brown 158a4d96a55SJed Brown Input Parameter: 159a4d96a55SJed Brown + sf - star forest mapping contiguous local indices to (rank, offset) 160a4d96a55SJed Brown - start - first global index on this process 161a4d96a55SJed Brown 162a4d96a55SJed Brown Output Parameter: 163a4d96a55SJed Brown . mapping - new mapping data structure 164a4d96a55SJed Brown 165a4d96a55SJed Brown Level: advanced 166a4d96a55SJed Brown 167a4d96a55SJed Brown Concepts: mapping^local to global 168a4d96a55SJed Brown 169a4d96a55SJed Brown .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 170a4d96a55SJed Brown @*/ 171a4d96a55SJed Brown PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf,PetscInt start,ISLocalToGlobalMapping *mapping) 172a4d96a55SJed Brown { 173a4d96a55SJed Brown PetscErrorCode ierr; 174a4d96a55SJed Brown PetscInt i,maxlocal,nroots,nleaves,*globals,*ltog; 175a4d96a55SJed Brown const PetscInt *ilocal; 176a4d96a55SJed Brown MPI_Comm comm; 177a4d96a55SJed Brown 178a4d96a55SJed Brown PetscFunctionBegin; 179a4d96a55SJed Brown PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 180a4d96a55SJed Brown PetscValidPointer(mapping,3); 181a4d96a55SJed Brown 182a4d96a55SJed Brown ierr = PetscObjectGetComm((PetscObject)sf,&comm);CHKERRQ(ierr); 1830298fd71SBarry Smith ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,NULL);CHKERRQ(ierr); 184f6e5521dSKarl Rupp if (ilocal) { 185f6e5521dSKarl Rupp for (i=0,maxlocal=0; i<nleaves; i++) maxlocal = PetscMax(maxlocal,ilocal[i]+1); 186f6e5521dSKarl Rupp } 187a4d96a55SJed Brown else maxlocal = nleaves; 188785e854fSJed Brown ierr = PetscMalloc1(nroots,&globals);CHKERRQ(ierr); 189785e854fSJed Brown ierr = PetscMalloc1(maxlocal,<og);CHKERRQ(ierr); 190a4d96a55SJed Brown for (i=0; i<nroots; i++) globals[i] = start + i; 191a4d96a55SJed Brown for (i=0; i<maxlocal; i++) ltog[i] = -1; 192a4d96a55SJed Brown ierr = PetscSFBcastBegin(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 193a4d96a55SJed Brown ierr = PetscSFBcastEnd(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 194f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,maxlocal,ltog,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 195a4d96a55SJed Brown ierr = PetscFree(globals);CHKERRQ(ierr); 196a4d96a55SJed Brown PetscFunctionReturn(0); 197a4d96a55SJed Brown } 198b46b645bSBarry Smith 19963fa5c83Sstefano_zampini /*@ 20063fa5c83Sstefano_zampini ISLocalToGlobalMappingSetBlockSize - Sets the blocksize of the mapping 20163fa5c83Sstefano_zampini 20263fa5c83Sstefano_zampini Not collective 20363fa5c83Sstefano_zampini 20463fa5c83Sstefano_zampini Input Parameters: 20563fa5c83Sstefano_zampini . mapping - mapping data structure 20663fa5c83Sstefano_zampini . bs - the blocksize 20763fa5c83Sstefano_zampini 20863fa5c83Sstefano_zampini Level: advanced 20963fa5c83Sstefano_zampini 21063fa5c83Sstefano_zampini Concepts: mapping^local to global 21163fa5c83Sstefano_zampini 21263fa5c83Sstefano_zampini .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 21363fa5c83Sstefano_zampini @*/ 21463fa5c83Sstefano_zampini PetscErrorCode ISLocalToGlobalMappingSetBlockSize(ISLocalToGlobalMapping mapping,PetscInt bs) 21563fa5c83Sstefano_zampini { 216a59f3c4dSstefano_zampini PetscInt *nid; 217a59f3c4dSstefano_zampini const PetscInt *oid; 218a59f3c4dSstefano_zampini PetscInt i,cn,on,obs,nn; 21963fa5c83Sstefano_zampini PetscErrorCode ierr; 22063fa5c83Sstefano_zampini 22163fa5c83Sstefano_zampini PetscFunctionBegin; 22263fa5c83Sstefano_zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 22363fa5c83Sstefano_zampini if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid block size %D",bs); 22463fa5c83Sstefano_zampini if (bs == mapping->bs) PetscFunctionReturn(0); 22563fa5c83Sstefano_zampini on = mapping->n; 22663fa5c83Sstefano_zampini obs = mapping->bs; 22763fa5c83Sstefano_zampini oid = mapping->indices; 22863fa5c83Sstefano_zampini nn = (on*obs)/bs; 22963fa5c83Sstefano_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); 230a59f3c4dSstefano_zampini 23163fa5c83Sstefano_zampini ierr = PetscMalloc1(nn,&nid);CHKERRQ(ierr); 232a59f3c4dSstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mapping,&oid);CHKERRQ(ierr); 233a59f3c4dSstefano_zampini for (i=0;i<nn;i++) { 234a59f3c4dSstefano_zampini PetscInt j; 235a59f3c4dSstefano_zampini for (j=0,cn=0;j<bs-1;j++) { 236a59f3c4dSstefano_zampini if (oid[i*bs+j] < 0) { cn++; continue; } 237a59f3c4dSstefano_zampini if (oid[i*bs+j] != oid[i*bs+j+1]-1) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices: non consecutive indices %D %D",bs,obs,oid[i*bs+j],oid[i*bs+j+1]); 238a59f3c4dSstefano_zampini } 239a59f3c4dSstefano_zampini if (oid[i*bs+j] < 0) cn++; 2408b7cb0e6Sstefano_zampini if (cn) { 241a59f3c4dSstefano_zampini if (cn != bs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices: invalid number of negative entries in block %D",bs,obs,cn); 242a59f3c4dSstefano_zampini nid[i] = -1; 2438b7cb0e6Sstefano_zampini } else { 244a59f3c4dSstefano_zampini nid[i] = oid[i*bs]/bs; 24563fa5c83Sstefano_zampini } 24663fa5c83Sstefano_zampini } 247a59f3c4dSstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(mapping,&oid);CHKERRQ(ierr); 248a59f3c4dSstefano_zampini 24963fa5c83Sstefano_zampini mapping->n = nn; 25063fa5c83Sstefano_zampini mapping->bs = bs; 25163fa5c83Sstefano_zampini ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 25263fa5c83Sstefano_zampini mapping->indices = nid; 253c9345713Sstefano_zampini ierr = PetscFree(mapping->globals);CHKERRQ(ierr); 254c9345713Sstefano_zampini mapping->globalstart = 0; 255c9345713Sstefano_zampini mapping->globalend = 0; 25663fa5c83Sstefano_zampini PetscFunctionReturn(0); 25763fa5c83Sstefano_zampini } 25863fa5c83Sstefano_zampini 25945b6f7e9SBarry Smith /*@ 26045b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping 26145b6f7e9SBarry Smith ordering and a global parallel ordering. 26245b6f7e9SBarry Smith 26345b6f7e9SBarry Smith Not Collective 26445b6f7e9SBarry Smith 26545b6f7e9SBarry Smith Input Parameters: 26645b6f7e9SBarry Smith . mapping - mapping data structure 26745b6f7e9SBarry Smith 26845b6f7e9SBarry Smith Output Parameter: 26945b6f7e9SBarry Smith . bs - the blocksize 27045b6f7e9SBarry Smith 27145b6f7e9SBarry Smith Level: advanced 27245b6f7e9SBarry Smith 27345b6f7e9SBarry Smith Concepts: mapping^local to global 27445b6f7e9SBarry Smith 27545b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 27645b6f7e9SBarry Smith @*/ 27745b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping,PetscInt *bs) 27845b6f7e9SBarry Smith { 27945b6f7e9SBarry Smith PetscFunctionBegin; 280cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 28145b6f7e9SBarry Smith *bs = mapping->bs; 28245b6f7e9SBarry Smith PetscFunctionReturn(0); 28345b6f7e9SBarry Smith } 28445b6f7e9SBarry Smith 285ba5bb76aSSatish Balay /*@ 28690f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 28790f02eecSBarry Smith ordering and a global parallel ordering. 2882362add9SBarry Smith 28989d82c54SBarry Smith Not Collective, but communicator may have more than one process 290b9cd556bSLois Curfman McInnes 2912362add9SBarry Smith Input Parameters: 29289d82c54SBarry Smith + comm - MPI communicator 293f0413b6fSBarry Smith . bs - the block size 29428bc9809SBarry Smith . n - the number of local elements divided by the block size, or equivalently the number of block indices 29528bc9809SBarry 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 296d5ad8652SBarry Smith - mode - see PetscCopyMode 2972362add9SBarry Smith 298a997ad1aSLois Curfman McInnes Output Parameter: 29990f02eecSBarry Smith . mapping - new mapping data structure 3002362add9SBarry Smith 301f0413b6fSBarry 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 302a997ad1aSLois Curfman McInnes Level: advanced 303a997ad1aSLois Curfman McInnes 304273d9f13SBarry Smith Concepts: mapping^local to global 3052362add9SBarry Smith 306d5ad8652SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 3072362add9SBarry Smith @*/ 30860c7cefcSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 3092362add9SBarry Smith { 3106849ba73SBarry Smith PetscErrorCode ierr; 31132dcc486SBarry Smith PetscInt *in; 312b46b645bSBarry Smith 313b46b645bSBarry Smith PetscFunctionBegin; 31473911063SBarry Smith if (n) PetscValidIntPointer(indices,3); 3154482741eSBarry Smith PetscValidPointer(mapping,4); 316b46b645bSBarry Smith 3170298fd71SBarry Smith *mapping = NULL; 318607a6623SBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 3192362add9SBarry Smith 32073107ff1SLisandro Dalcin ierr = PetscHeaderCreate(*mapping,IS_LTOGM_CLASSID,"ISLocalToGlobalMapping","Local to global mapping","IS", 32160c7cefcSBarry Smith comm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 322d4bb536fSBarry Smith (*mapping)->n = n; 323f0413b6fSBarry Smith (*mapping)->bs = bs; 324268a049cSStefano Zampini (*mapping)->info_cached = PETSC_FALSE; 325268a049cSStefano Zampini (*mapping)->info_free = PETSC_FALSE; 326268a049cSStefano Zampini (*mapping)->info_procs = NULL; 327268a049cSStefano Zampini (*mapping)->info_numprocs = NULL; 328268a049cSStefano Zampini (*mapping)->info_indices = NULL; 329d4bb536fSBarry Smith /* 330d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 331d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 332d4bb536fSBarry Smith */ 333d4bb536fSBarry Smith (*mapping)->globals = 0; 334*cd5a51dfSLawrence Mitchell (*mapping)->globalht = 0; 335*cd5a51dfSLawrence Mitchell (*mapping)->use_hash_table = PETSC_TRUE; 336d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 337785e854fSJed Brown ierr = PetscMalloc1(n,&in);CHKERRQ(ierr); 338d5ad8652SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 339d5ad8652SBarry Smith (*mapping)->indices = in; 3406389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 3416389a1a1SBarry Smith } else if (mode == PETSC_OWN_POINTER) { 3426389a1a1SBarry Smith (*mapping)->indices = (PetscInt*)indices; 3436389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 3446389a1a1SBarry Smith } 34560c7cefcSBarry Smith else SETERRQ(comm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 346d96308ebSBarry Smith ierr = PetscStrallocpy("basic",&((PetscObject)*mapping)->type_name);CHKERRQ(ierr); 3473a40ed3dSBarry Smith PetscFunctionReturn(0); 3482362add9SBarry Smith } 3492362add9SBarry Smith 35090f02eecSBarry Smith /*@ 35190f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 35290f02eecSBarry Smith ordering and a global parallel ordering. 35390f02eecSBarry Smith 3540f5bd95cSBarry Smith Note Collective 355b9cd556bSLois Curfman McInnes 35690f02eecSBarry Smith Input Parameters: 35790f02eecSBarry Smith . mapping - mapping data structure 35890f02eecSBarry Smith 359a997ad1aSLois Curfman McInnes Level: advanced 360a997ad1aSLois Curfman McInnes 3613acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 36290f02eecSBarry Smith @*/ 3636bf464f9SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 36490f02eecSBarry Smith { 365dfbe8321SBarry Smith PetscErrorCode ierr; 3665fd66863SKarl Rupp 3673a40ed3dSBarry Smith PetscFunctionBegin; 3686bf464f9SBarry Smith if (!*mapping) PetscFunctionReturn(0); 3696bf464f9SBarry Smith PetscValidHeaderSpecific((*mapping),IS_LTOGM_CLASSID,1); 370997056adSBarry Smith if (--((PetscObject)(*mapping))->refct > 0) {*mapping = 0;PetscFunctionReturn(0);} 3716bf464f9SBarry Smith ierr = PetscFree((*mapping)->indices);CHKERRQ(ierr); 3726bf464f9SBarry Smith ierr = PetscFree((*mapping)->globals);CHKERRQ(ierr); 373268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_procs);CHKERRQ(ierr); 374268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_numprocs);CHKERRQ(ierr); 375*cd5a51dfSLawrence Mitchell PetscHashIDestroy((*mapping)->globalht); 376268a049cSStefano Zampini if ((*mapping)->info_indices) { 377268a049cSStefano Zampini PetscInt i; 378268a049cSStefano Zampini 379268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[0]);CHKERRQ(ierr); 380268a049cSStefano Zampini for (i=1; i<(*mapping)->info_nproc; i++) { 381268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[i]);CHKERRQ(ierr); 382268a049cSStefano Zampini } 383268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_indices);CHKERRQ(ierr); 384268a049cSStefano Zampini } 385d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 386992144d0SBarry Smith *mapping = 0; 3873a40ed3dSBarry Smith PetscFunctionReturn(0); 38890f02eecSBarry Smith } 38990f02eecSBarry Smith 39090f02eecSBarry Smith /*@ 3913acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 3923acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 3933acfe500SLois Curfman McInnes context. 39490f02eecSBarry Smith 395b9cd556bSLois Curfman McInnes Not collective 396b9cd556bSLois Curfman McInnes 39790f02eecSBarry Smith Input Parameters: 398b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 399b9cd556bSLois Curfman McInnes - is - index set in local numbering 40090f02eecSBarry Smith 40190f02eecSBarry Smith Output Parameters: 40290f02eecSBarry Smith . newis - index set in global numbering 40390f02eecSBarry Smith 404a997ad1aSLois Curfman McInnes Level: advanced 405a997ad1aSLois Curfman McInnes 406273d9f13SBarry Smith Concepts: mapping^local to global 4073acfe500SLois Curfman McInnes 40890f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 409d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 41090f02eecSBarry Smith @*/ 4117087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 41290f02eecSBarry Smith { 4136849ba73SBarry Smith PetscErrorCode ierr; 414e24637baSBarry Smith PetscInt n,*idxout; 4155d0c19d7SBarry Smith const PetscInt *idxin; 4163a40ed3dSBarry Smith 4173a40ed3dSBarry Smith PetscFunctionBegin; 4180700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 4190700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 4204482741eSBarry Smith PetscValidPointer(newis,3); 42190f02eecSBarry Smith 4223b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 42390f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 424785e854fSJed Brown ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 425e24637baSBarry Smith ierr = ISLocalToGlobalMappingApply(mapping,n,idxin,idxout);CHKERRQ(ierr); 4263b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 427543f3098SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 4283a40ed3dSBarry Smith PetscFunctionReturn(0); 42990f02eecSBarry Smith } 43090f02eecSBarry Smith 431b89cb25eSSatish Balay /*@ 4323acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 4333acfe500SLois Curfman McInnes and converts them to the global numbering. 43490f02eecSBarry Smith 435b9cd556bSLois Curfman McInnes Not collective 436b9cd556bSLois Curfman McInnes 437bb25748dSBarry Smith Input Parameters: 438b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 439bb25748dSBarry Smith . N - number of integers 440b9cd556bSLois Curfman McInnes - in - input indices in local numbering 441bb25748dSBarry Smith 442bb25748dSBarry Smith Output Parameter: 443bb25748dSBarry Smith . out - indices in global numbering 444bb25748dSBarry Smith 445b9cd556bSLois Curfman McInnes Notes: 446b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 447d4bb536fSBarry Smith 448a997ad1aSLois Curfman McInnes Level: advanced 449a997ad1aSLois Curfman McInnes 45045b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApplyBlock(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 4510752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 452d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 453bb25748dSBarry Smith 454273d9f13SBarry Smith Concepts: mapping^local to global 455afcb2eb5SJed Brown @*/ 456afcb2eb5SJed Brown PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 457afcb2eb5SJed Brown { 458cbc1caf0SMatthew G. Knepley PetscInt i,bs,Nmax; 45945b6f7e9SBarry Smith 46045b6f7e9SBarry Smith PetscFunctionBegin; 461cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 462cbc1caf0SMatthew G. Knepley bs = mapping->bs; 463cbc1caf0SMatthew G. Knepley Nmax = bs*mapping->n; 46445b6f7e9SBarry Smith if (bs == 1) { 465cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 46645b6f7e9SBarry Smith for (i=0; i<N; i++) { 46745b6f7e9SBarry Smith if (in[i] < 0) { 46845b6f7e9SBarry Smith out[i] = in[i]; 46945b6f7e9SBarry Smith continue; 47045b6f7e9SBarry Smith } 471e24637baSBarry 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); 47245b6f7e9SBarry Smith out[i] = idx[in[i]]; 47345b6f7e9SBarry Smith } 47445b6f7e9SBarry Smith } else { 475cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 47645b6f7e9SBarry Smith for (i=0; i<N; i++) { 47745b6f7e9SBarry Smith if (in[i] < 0) { 47845b6f7e9SBarry Smith out[i] = in[i]; 47945b6f7e9SBarry Smith continue; 48045b6f7e9SBarry Smith } 481e24637baSBarry 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); 48245b6f7e9SBarry Smith out[i] = idx[in[i]/bs]*bs + (in[i] % bs); 48345b6f7e9SBarry Smith } 48445b6f7e9SBarry Smith } 48545b6f7e9SBarry Smith PetscFunctionReturn(0); 48645b6f7e9SBarry Smith } 48745b6f7e9SBarry Smith 48845b6f7e9SBarry Smith /*@ 4896006e8d2SBarry Smith ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering 49045b6f7e9SBarry Smith 49145b6f7e9SBarry Smith Not collective 49245b6f7e9SBarry Smith 49345b6f7e9SBarry Smith Input Parameters: 49445b6f7e9SBarry Smith + mapping - the local to global mapping context 49545b6f7e9SBarry Smith . N - number of integers 4966006e8d2SBarry Smith - in - input indices in local block numbering 49745b6f7e9SBarry Smith 49845b6f7e9SBarry Smith Output Parameter: 4996006e8d2SBarry Smith . out - indices in global block numbering 50045b6f7e9SBarry Smith 50145b6f7e9SBarry Smith Notes: 50245b6f7e9SBarry Smith The in and out array parameters may be identical. 50345b6f7e9SBarry Smith 5046006e8d2SBarry Smith Example: 5056006e8d2SBarry 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 5066006e8d2SBarry Smith (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3. 5076006e8d2SBarry Smith 50845b6f7e9SBarry Smith Level: advanced 50945b6f7e9SBarry Smith 51045b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 51145b6f7e9SBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 51245b6f7e9SBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 51345b6f7e9SBarry Smith 51445b6f7e9SBarry Smith Concepts: mapping^local to global 51545b6f7e9SBarry Smith @*/ 51645b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 51745b6f7e9SBarry Smith { 518cbc1caf0SMatthew G. Knepley 519cbc1caf0SMatthew G. Knepley PetscFunctionBegin; 520cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 521cbc1caf0SMatthew G. Knepley { 522afcb2eb5SJed Brown PetscInt i,Nmax = mapping->n; 523afcb2eb5SJed Brown const PetscInt *idx = mapping->indices; 524d4bb536fSBarry Smith 525afcb2eb5SJed Brown for (i=0; i<N; i++) { 526afcb2eb5SJed Brown if (in[i] < 0) { 527afcb2eb5SJed Brown out[i] = in[i]; 528afcb2eb5SJed Brown continue; 529afcb2eb5SJed Brown } 530e24637baSBarry 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); 531afcb2eb5SJed Brown out[i] = idx[in[i]]; 532afcb2eb5SJed Brown } 533cbc1caf0SMatthew G. Knepley } 534afcb2eb5SJed Brown PetscFunctionReturn(0); 535afcb2eb5SJed Brown } 536d4bb536fSBarry Smith 537d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 538d4bb536fSBarry Smith 539d4bb536fSBarry Smith /* 540d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 541d4bb536fSBarry Smith */ 5426849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 543d4bb536fSBarry Smith { 5446849ba73SBarry Smith PetscErrorCode ierr; 54532dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 546d4bb536fSBarry Smith 5473a40ed3dSBarry Smith PetscFunctionBegin; 548*cd5a51dfSLawrence Mitchell if (mapping->use_hash_table && mapping->globalht) PetscFunctionReturn(0); 549*cd5a51dfSLawrence Mitchell else if (mapping->globals) PetscFunctionReturn(0); 550d4bb536fSBarry Smith end = 0; 551ec268f7cSJed Brown start = PETSC_MAX_INT; 552d4bb536fSBarry Smith 553d4bb536fSBarry Smith for (i=0; i<n; i++) { 554d4bb536fSBarry Smith if (idx[i] < 0) continue; 555d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 556d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 557d4bb536fSBarry Smith } 558d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 559d4bb536fSBarry Smith mapping->globalstart = start; 560d4bb536fSBarry Smith mapping->globalend = end; 561d4bb536fSBarry Smith 562*cd5a51dfSLawrence Mitchell if (mapping->use_hash_table) { 563*cd5a51dfSLawrence Mitchell PetscHashICreate(mapping->globalht); 564*cd5a51dfSLawrence Mitchell for (i=0; i<n; i++ ) { 565*cd5a51dfSLawrence Mitchell if (idx[i] < 0) continue; 566*cd5a51dfSLawrence Mitchell PetscHashIAdd(mapping->globalht, idx[i], i); 567*cd5a51dfSLawrence Mitchell } 568*cd5a51dfSLawrence Mitchell ierr = PetscLogObjectMemory((PetscObject)mapping,2*n*sizeof(PetscInt));CHKERRQ(ierr); 569*cd5a51dfSLawrence Mitchell } else { 570854ce69bSBarry Smith ierr = PetscMalloc1(end-start+2,&globals);CHKERRQ(ierr); 571b0a32e0cSBarry Smith mapping->globals = globals; 572f6e5521dSKarl Rupp for (i=0; i<end-start+1; i++) globals[i] = -1; 573d4bb536fSBarry Smith for (i=0; i<n; i++) { 574d4bb536fSBarry Smith if (idx[i] < 0) continue; 575d4bb536fSBarry Smith globals[idx[i] - start] = i; 576d4bb536fSBarry Smith } 577d4bb536fSBarry Smith 5783bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 579*cd5a51dfSLawrence Mitchell } 5803a40ed3dSBarry Smith PetscFunctionReturn(0); 581d4bb536fSBarry Smith } 582d4bb536fSBarry Smith 583d4bb536fSBarry Smith /*@ 584a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 585a997ad1aSLois Curfman McInnes specified with a global numbering. 586d4bb536fSBarry Smith 587b9cd556bSLois Curfman McInnes Not collective 588b9cd556bSLois Curfman McInnes 589d4bb536fSBarry Smith Input Parameters: 590b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 591d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 592d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 593d4bb536fSBarry Smith . n - number of global indices to map 594b9cd556bSLois Curfman McInnes - idx - global indices to map 595d4bb536fSBarry Smith 596d4bb536fSBarry Smith Output Parameters: 597b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 598b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 599e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 6000298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 601e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 602e182c471SBarry Smith a second time to set the values. 603d4bb536fSBarry Smith 604b9cd556bSLois Curfman McInnes Notes: 6050298fd71SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 606d4bb536fSBarry Smith 6070f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 6080f5bd95cSBarry Smith array to compute these. 6090f5bd95cSBarry Smith 610a997ad1aSLois Curfman McInnes Level: advanced 611a997ad1aSLois Curfman McInnes 61232fd6b96SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 61332fd6b96SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 61432fd6b96SBarry Smith 615273d9f13SBarry Smith Concepts: mapping^global to local 616d4bb536fSBarry Smith 6179d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApplyBlock(), ISLocalToGlobalMappingCreate(), 618d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 619d4bb536fSBarry Smith @*/ 6207087cfbeSBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 62132dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 622d4bb536fSBarry Smith { 623*cd5a51dfSLawrence Mitchell PetscInt i,*globals,nf = 0,tmp,start,end,bs,local; 624*cd5a51dfSLawrence Mitchell const PetscBool use_hash_table = mapping->use_hash_table; 6259d90f715SBarry Smith PetscErrorCode ierr; 6269d90f715SBarry Smith 6279d90f715SBarry Smith PetscFunctionBegin; 6289d90f715SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 6299d90f715SBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 6309d90f715SBarry Smith globals = mapping->globals; 6319d90f715SBarry Smith start = mapping->globalstart; 6329d90f715SBarry Smith end = mapping->globalend; 6339d90f715SBarry Smith bs = mapping->bs; 6349d90f715SBarry Smith 635*cd5a51dfSLawrence Mitchell #define GTOL(g, local) do { \ 636*cd5a51dfSLawrence Mitchell if (use_hash_table) { \ 637*cd5a51dfSLawrence Mitchell PetscHashIMap(mapping->globalht,g/bs,local); \ 638*cd5a51dfSLawrence Mitchell } else { \ 639*cd5a51dfSLawrence Mitchell local = globals[g/bs - start]; \ 640*cd5a51dfSLawrence Mitchell } \ 641*cd5a51dfSLawrence Mitchell local = bs*local + (g % bs); \ 642*cd5a51dfSLawrence Mitchell } while (0) 643*cd5a51dfSLawrence Mitchell 6449d90f715SBarry Smith if (type == IS_GTOLM_MASK) { 6459d90f715SBarry Smith if (idxout) { 6469d90f715SBarry Smith for (i=0; i<n; i++) { 6479d90f715SBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 6489d90f715SBarry Smith else if (idx[i] < bs*start) idxout[i] = -1; 649663bb84eSBarry Smith else if (idx[i] > bs*(end+1)-1) idxout[i] = -1; 650*cd5a51dfSLawrence Mitchell else GTOL(idx[i], local); 6519d90f715SBarry Smith } 6529d90f715SBarry Smith } 6539d90f715SBarry Smith if (nout) *nout = n; 6549d90f715SBarry Smith } else { 6559d90f715SBarry Smith if (idxout) { 6569d90f715SBarry Smith for (i=0; i<n; i++) { 6579d90f715SBarry Smith if (idx[i] < 0) continue; 6589d90f715SBarry Smith if (idx[i] < bs*start) continue; 659663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 660*cd5a51dfSLawrence Mitchell GTOL(idx[i], tmp); 6619d90f715SBarry Smith if (tmp < 0) continue; 6629d90f715SBarry Smith idxout[nf++] = tmp; 6639d90f715SBarry Smith } 6649d90f715SBarry Smith } else { 6659d90f715SBarry Smith for (i=0; i<n; i++) { 6669d90f715SBarry Smith if (idx[i] < 0) continue; 6679d90f715SBarry Smith if (idx[i] < bs*start) continue; 668663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 669*cd5a51dfSLawrence Mitchell GTOL(idx[i], tmp); 6709d90f715SBarry Smith if (tmp < 0) continue; 6719d90f715SBarry Smith nf++; 6729d90f715SBarry Smith } 6739d90f715SBarry Smith } 6749d90f715SBarry Smith if (nout) *nout = nf; 6759d90f715SBarry Smith } 676*cd5a51dfSLawrence Mitchell #undef GTOL 6779d90f715SBarry Smith PetscFunctionReturn(0); 6789d90f715SBarry Smith } 6799d90f715SBarry Smith 680d4fe737eSStefano Zampini /*@ 681d4fe737eSStefano Zampini ISGlobalToLocalMappingApplyIS - Creates from an IS in the global numbering 682d4fe737eSStefano Zampini a new index set using the local numbering defined in an ISLocalToGlobalMapping 683d4fe737eSStefano Zampini context. 684d4fe737eSStefano Zampini 685d4fe737eSStefano Zampini Not collective 686d4fe737eSStefano Zampini 687d4fe737eSStefano Zampini Input Parameters: 688d4fe737eSStefano Zampini + mapping - mapping between local and global numbering 689d4fe737eSStefano Zampini - is - index set in global numbering 690d4fe737eSStefano Zampini 691d4fe737eSStefano Zampini Output Parameters: 692d4fe737eSStefano Zampini . newis - index set in local numbering 693d4fe737eSStefano Zampini 694d4fe737eSStefano Zampini Level: advanced 695d4fe737eSStefano Zampini 696d4fe737eSStefano Zampini Concepts: mapping^local to global 697d4fe737eSStefano Zampini 698d4fe737eSStefano Zampini .seealso: ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 699d4fe737eSStefano Zampini ISLocalToGlobalMappingDestroy() 700d4fe737eSStefano Zampini @*/ 701d4fe737eSStefano Zampini PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, IS is,IS *newis) 702d4fe737eSStefano Zampini { 703d4fe737eSStefano Zampini PetscErrorCode ierr; 704d4fe737eSStefano Zampini PetscInt n,nout,*idxout; 705d4fe737eSStefano Zampini const PetscInt *idxin; 706d4fe737eSStefano Zampini 707d4fe737eSStefano Zampini PetscFunctionBegin; 708d4fe737eSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 709d4fe737eSStefano Zampini PetscValidHeaderSpecific(is,IS_CLASSID,3); 710d4fe737eSStefano Zampini PetscValidPointer(newis,4); 711d4fe737eSStefano Zampini 712d4fe737eSStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 713d4fe737eSStefano Zampini ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 714d4fe737eSStefano Zampini if (type == IS_GTOLM_MASK) { 715d4fe737eSStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 716d4fe737eSStefano Zampini } else { 717d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,NULL);CHKERRQ(ierr); 718d4fe737eSStefano Zampini ierr = PetscMalloc1(nout,&idxout);CHKERRQ(ierr); 719d4fe737eSStefano Zampini } 720d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,idxout);CHKERRQ(ierr); 721d4fe737eSStefano Zampini ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 722d4fe737eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),nout,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 723d4fe737eSStefano Zampini PetscFunctionReturn(0); 724d4fe737eSStefano Zampini } 725d4fe737eSStefano Zampini 7269d90f715SBarry Smith /*@ 7279d90f715SBarry Smith ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers 7289d90f715SBarry Smith specified with a block global numbering. 7299d90f715SBarry Smith 7309d90f715SBarry Smith Not collective 7319d90f715SBarry Smith 7329d90f715SBarry Smith Input Parameters: 7339d90f715SBarry Smith + mapping - mapping between local and global numbering 7349d90f715SBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 7359d90f715SBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 7369d90f715SBarry Smith . n - number of global indices to map 7379d90f715SBarry Smith - idx - global indices to map 7389d90f715SBarry Smith 7399d90f715SBarry Smith Output Parameters: 7409d90f715SBarry Smith + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 7419d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough 7429d90f715SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApplyBlock() with 7439d90f715SBarry Smith idxout == NULL to determine the required length (returned in nout) 7449d90f715SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApplyBlock() 7459d90f715SBarry Smith a second time to set the values. 7469d90f715SBarry Smith 7479d90f715SBarry Smith Notes: 7489d90f715SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 7499d90f715SBarry Smith 7509d90f715SBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 7519d90f715SBarry Smith array to compute these. 7529d90f715SBarry Smith 7539d90f715SBarry Smith Level: advanced 7549d90f715SBarry Smith 7559d90f715SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 7569d90f715SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 7579d90f715SBarry Smith 7589d90f715SBarry Smith Concepts: mapping^global to local 7599d90f715SBarry Smith 7609d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 7619d90f715SBarry Smith ISLocalToGlobalMappingDestroy() 7629d90f715SBarry Smith @*/ 7639d90f715SBarry Smith PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 7649d90f715SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 7659d90f715SBarry Smith { 76632dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 767*cd5a51dfSLawrence Mitchell const PetscBool use_hash_table = mapping->use_hash_table; 7686849ba73SBarry Smith PetscErrorCode ierr; 769d4bb536fSBarry Smith 7703a40ed3dSBarry Smith PetscFunctionBegin; 7710700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 772d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 773d4bb536fSBarry Smith globals = mapping->globals; 774d4bb536fSBarry Smith start = mapping->globalstart; 775d4bb536fSBarry Smith end = mapping->globalend; 776d4bb536fSBarry Smith 777*cd5a51dfSLawrence Mitchell #define GTOL(g, local) do { \ 778*cd5a51dfSLawrence Mitchell if (use_hash_table) { \ 779*cd5a51dfSLawrence Mitchell PetscHashIMap(mapping->globalht,g,local); \ 780*cd5a51dfSLawrence Mitchell } else { \ 781*cd5a51dfSLawrence Mitchell local = globals[g - start]; \ 782*cd5a51dfSLawrence Mitchell } \ 783*cd5a51dfSLawrence Mitchell } while (0) 784*cd5a51dfSLawrence Mitchell 785d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 786d4bb536fSBarry Smith if (idxout) { 787d4bb536fSBarry Smith for (i=0; i<n; i++) { 788d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 789d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 790d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 791*cd5a51dfSLawrence Mitchell else GTOL(idx[i], idxout[i]); 792d4bb536fSBarry Smith } 793d4bb536fSBarry Smith } 794d4bb536fSBarry Smith if (nout) *nout = n; 795d4bb536fSBarry Smith } else { 796d4bb536fSBarry Smith if (idxout) { 797d4bb536fSBarry Smith for (i=0; i<n; i++) { 798d4bb536fSBarry Smith if (idx[i] < 0) continue; 799d4bb536fSBarry Smith if (idx[i] < start) continue; 800d4bb536fSBarry Smith if (idx[i] > end) continue; 801*cd5a51dfSLawrence Mitchell GTOL(idx[i], tmp); 802d4bb536fSBarry Smith if (tmp < 0) continue; 803d4bb536fSBarry Smith idxout[nf++] = tmp; 804d4bb536fSBarry Smith } 805d4bb536fSBarry Smith } else { 806d4bb536fSBarry Smith for (i=0; i<n; i++) { 807d4bb536fSBarry Smith if (idx[i] < 0) continue; 808d4bb536fSBarry Smith if (idx[i] < start) continue; 809d4bb536fSBarry Smith if (idx[i] > end) continue; 810*cd5a51dfSLawrence Mitchell GTOL(idx[i], tmp); 811d4bb536fSBarry Smith if (tmp < 0) continue; 812d4bb536fSBarry Smith nf++; 813d4bb536fSBarry Smith } 814d4bb536fSBarry Smith } 815d4bb536fSBarry Smith if (nout) *nout = nf; 816d4bb536fSBarry Smith } 817*cd5a51dfSLawrence Mitchell #undef GTOL 8183a40ed3dSBarry Smith PetscFunctionReturn(0); 819d4bb536fSBarry Smith } 82090f02eecSBarry Smith 82189d82c54SBarry Smith /*@C 8226a818285SBarry Smith ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information for each processor and 82389d82c54SBarry Smith each index shared by more than one processor 82489d82c54SBarry Smith 82589d82c54SBarry Smith Collective on ISLocalToGlobalMapping 82689d82c54SBarry Smith 82789d82c54SBarry Smith Input Parameters: 82889d82c54SBarry Smith . mapping - the mapping from local to global indexing 82989d82c54SBarry Smith 83089d82c54SBarry Smith Output Parameter: 83189d82c54SBarry Smith + nproc - number of processors that are connected to this one 83289d82c54SBarry Smith . proc - neighboring processors 83307b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 8343463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 83589d82c54SBarry Smith 83689d82c54SBarry Smith Level: advanced 83789d82c54SBarry Smith 838273d9f13SBarry Smith Concepts: mapping^local to global 83989d82c54SBarry Smith 8402cfcea29SBarry Smith Fortran Usage: 8412cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 8422cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 8432cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 8442cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 8452cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 8462cfcea29SBarry Smith 8472cfcea29SBarry Smith 84807b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 84907b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 85089d82c54SBarry Smith @*/ 8516a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 85289d82c54SBarry Smith { 8536849ba73SBarry Smith PetscErrorCode ierr; 854268a049cSStefano Zampini 855268a049cSStefano Zampini PetscFunctionBegin; 856268a049cSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 857268a049cSStefano Zampini if (mapping->info_cached) { 858268a049cSStefano Zampini *nproc = mapping->info_nproc; 859268a049cSStefano Zampini *procs = mapping->info_procs; 860268a049cSStefano Zampini *numprocs = mapping->info_numprocs; 861268a049cSStefano Zampini *indices = mapping->info_indices; 862268a049cSStefano Zampini } else { 863268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo_Private(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 864268a049cSStefano Zampini } 865268a049cSStefano Zampini PetscFunctionReturn(0); 866268a049cSStefano Zampini } 867268a049cSStefano Zampini 868268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 869268a049cSStefano Zampini { 870268a049cSStefano Zampini PetscErrorCode ierr; 87197f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 87232dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 87332dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 87497f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 87532dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 87632dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 87789d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 87830dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 879ce94432eSBarry Smith MPI_Comm comm; 880ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 88189d82c54SBarry Smith 88289d82c54SBarry Smith PetscFunctionBegin; 883ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)mapping,&comm);CHKERRQ(ierr); 88424cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 88524cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 88624cf384cSBarry Smith if (size == 1) { 88724cf384cSBarry Smith *nproc = 0; 8880298fd71SBarry Smith *procs = NULL; 88995dccacaSBarry Smith ierr = PetscNew(numprocs);CHKERRQ(ierr); 8901e2105dcSBarry Smith (*numprocs)[0] = 0; 89195dccacaSBarry Smith ierr = PetscNew(indices);CHKERRQ(ierr); 8920298fd71SBarry Smith (*indices)[0] = NULL; 893268a049cSStefano Zampini /* save info for reuse */ 894268a049cSStefano Zampini mapping->info_nproc = *nproc; 895268a049cSStefano Zampini mapping->info_procs = *procs; 896268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 897268a049cSStefano Zampini mapping->info_indices = *indices; 898268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 89924cf384cSBarry Smith PetscFunctionReturn(0); 90024cf384cSBarry Smith } 90124cf384cSBarry Smith 902c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)mapping)->options,NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,NULL);CHKERRQ(ierr); 90307b52d57SBarry Smith 9043677ff5aSBarry Smith /* 9056a818285SBarry Smith Notes on ISLocalToGlobalMappingGetBlockInfo 9063677ff5aSBarry Smith 9073677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 9083677ff5aSBarry Smith numbering, just for this routine. 9093677ff5aSBarry Smith 9103677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 9113677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 9123677ff5aSBarry Smith 9133677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 9143677ff5aSBarry Smith 9153677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 9163677ff5aSBarry Smith local subdomain 9173677ff5aSBarry Smith */ 91824cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 91924cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 92024cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 92189d82c54SBarry Smith 92289d82c54SBarry Smith for (i=0; i<n; i++) { 92389d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 92489d82c54SBarry Smith } 925b2566f29SBarry Smith ierr = MPIU_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 92678058e43SBarry Smith Ng++; 92789d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 92889d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 929bc8ff85bSBarry Smith scale = Ng/size + 1; 930a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 931caba0dd0SBarry Smith rstart = scale*rank; 93289d82c54SBarry Smith 93389d82c54SBarry Smith /* determine ownership ranges of global indices */ 934785e854fSJed Brown ierr = PetscMalloc1(2*size,&nprocs);CHKERRQ(ierr); 93532dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 93689d82c54SBarry Smith 93789d82c54SBarry Smith /* determine owners of each local node */ 938785e854fSJed Brown ierr = PetscMalloc1(n,&owner);CHKERRQ(ierr); 93989d82c54SBarry Smith for (i=0; i<n; i++) { 9403677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 94127c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 9423677ff5aSBarry Smith owner[i] = proc; 94327c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 94489d82c54SBarry Smith } 94527c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 9467904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %D\n",nsends);CHKERRQ(ierr); 94789d82c54SBarry Smith 94889d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 94927c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 9507904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %D\n",nrecvs);CHKERRQ(ierr); 95189d82c54SBarry Smith 95289d82c54SBarry Smith /* post receives for owned rows */ 953785e854fSJed Brown ierr = PetscMalloc1((2*nrecvs+1)*(nmax+1),&recvs);CHKERRQ(ierr); 954854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&recv_waits);CHKERRQ(ierr); 95589d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 95632dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 95789d82c54SBarry Smith } 95889d82c54SBarry Smith 95989d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 960854ce69bSBarry Smith ierr = PetscMalloc1(2*n+1,&sends);CHKERRQ(ierr); 961854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&starts);CHKERRQ(ierr); 96289d82c54SBarry Smith starts[0] = 0; 963f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 96489d82c54SBarry Smith for (i=0; i<n; i++) { 96589d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 96630dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 96789d82c54SBarry Smith } 96889d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 96989d82c54SBarry Smith starts[0] = 0; 970f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 97189d82c54SBarry Smith 97289d82c54SBarry Smith /* send the messages */ 973854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&send_waits);CHKERRQ(ierr); 974854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&dest);CHKERRQ(ierr); 97589d82c54SBarry Smith cnt = 0; 97689d82c54SBarry Smith for (i=0; i<size; i++) { 97727c402fcSBarry Smith if (nprocs[2*i]) { 97832dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 97930dcb7c9SBarry Smith dest[cnt] = i; 98089d82c54SBarry Smith cnt++; 98189d82c54SBarry Smith } 98289d82c54SBarry Smith } 98389d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 98489d82c54SBarry Smith 98589d82c54SBarry Smith /* wait on receives */ 986854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&source);CHKERRQ(ierr); 987854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&len);CHKERRQ(ierr); 98889d82c54SBarry Smith cnt = nrecvs; 989854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&nownedsenders);CHKERRQ(ierr); 99032dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 99189d82c54SBarry Smith while (cnt) { 99289d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 99389d82c54SBarry Smith /* unpack receives into our local space */ 99432dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 99589d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 99630dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 997caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 99830dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 99989d82c54SBarry Smith cnt--; 100089d82c54SBarry Smith } 100189d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 100289d82c54SBarry Smith 100330dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 1004bc8ff85bSBarry Smith nowned = 0; 1005bc8ff85bSBarry Smith nownedm = 0; 1006bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 1007bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 1008bc8ff85bSBarry Smith } 1009bc8ff85bSBarry Smith 1010bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 1011854ce69bSBarry Smith ierr = PetscMalloc1(nownedm+1,&ownedsenders);CHKERRQ(ierr); 1012854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&starts);CHKERRQ(ierr); 1013bc8ff85bSBarry Smith starts[0] = 0; 1014bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 1015bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 1016bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 1017bc8ff85bSBarry Smith } 1018bc8ff85bSBarry Smith 101930dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 1020bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 1021bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 102230dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 1023f6e5521dSKarl Rupp if (nownedsenders[node] > 1) ownedsenders[starts[node]++] = source[i]; 1024bc8ff85bSBarry Smith } 1025bc8ff85bSBarry Smith } 1026bc8ff85bSBarry Smith 102707b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 102830dcb7c9SBarry Smith starts[0] = 0; 102930dcb7c9SBarry Smith for (i=1; i<ng; i++) { 103030dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 103130dcb7c9SBarry Smith else starts[i] = starts[i-1]; 103230dcb7c9SBarry Smith } 103330dcb7c9SBarry Smith for (i=0; i<ng; i++) { 103430dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 10357904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %D local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 103630dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 10377904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 103830dcb7c9SBarry Smith } 103930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 104030dcb7c9SBarry Smith } 104130dcb7c9SBarry Smith } 10420ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 104307b52d57SBarry Smith } /* ----------------------------------- */ 104430dcb7c9SBarry Smith 10453677ff5aSBarry Smith /* wait on original sends */ 10463a96401aSBarry Smith if (nsends) { 1047785e854fSJed Brown ierr = PetscMalloc1(nsends,&send_status);CHKERRQ(ierr); 10483a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 10493a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 10503a96401aSBarry Smith } 105189d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 10523a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 10533677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 10543677ff5aSBarry Smith 10553677ff5aSBarry Smith /* pack messages to send back to local owners */ 105630dcb7c9SBarry Smith starts[0] = 0; 105730dcb7c9SBarry Smith for (i=1; i<ng; i++) { 105830dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 105930dcb7c9SBarry Smith else starts[i] = starts[i-1]; 106030dcb7c9SBarry Smith } 106130dcb7c9SBarry Smith nsends2 = nrecvs; 1062854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&nprocs);CHKERRQ(ierr); /* length of each message */ 106330dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 106430dcb7c9SBarry Smith nprocs[i] = 1; 106530dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 106630dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 1067f6e5521dSKarl Rupp if (nownedsenders[node] > 1) nprocs[i] += 2 + nownedsenders[node]; 106830dcb7c9SBarry Smith } 106930dcb7c9SBarry Smith } 1070f6e5521dSKarl Rupp nt = 0; 1071f6e5521dSKarl Rupp for (i=0; i<nsends2; i++) nt += nprocs[i]; 1072f6e5521dSKarl Rupp 1073854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&sends2);CHKERRQ(ierr); 1074854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&starts2);CHKERRQ(ierr); 1075f6e5521dSKarl Rupp 1076f6e5521dSKarl Rupp starts2[0] = 0; 1077f6e5521dSKarl Rupp for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 107830dcb7c9SBarry Smith /* 107930dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 108030dcb7c9SBarry Smith (0) the number of nodes being sent back 108130dcb7c9SBarry Smith (1) the local node number, 108230dcb7c9SBarry Smith (2) the number of processors sharing it, 108330dcb7c9SBarry Smith (3) the processors sharing it 108430dcb7c9SBarry Smith */ 108530dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 108630dcb7c9SBarry Smith cnt = 1; 108730dcb7c9SBarry Smith sends2[starts2[i]] = 0; 108830dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 108930dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 109030dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 109130dcb7c9SBarry Smith sends2[starts2[i]]++; 109230dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 109330dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 109432dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 109530dcb7c9SBarry Smith cnt += nownedsenders[node]; 109630dcb7c9SBarry Smith } 109730dcb7c9SBarry Smith } 109830dcb7c9SBarry Smith } 109930dcb7c9SBarry Smith 110030dcb7c9SBarry Smith /* receive the message lengths */ 110130dcb7c9SBarry Smith nrecvs2 = nsends; 1102854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&lens2);CHKERRQ(ierr); 1103854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&starts3);CHKERRQ(ierr); 1104854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 110530dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 1106d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 110730dcb7c9SBarry Smith } 1108d44834fbSBarry Smith 11098a8e0b3aSBarry Smith /* send the message lengths */ 11108a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 11118a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 11128a8e0b3aSBarry Smith } 11138a8e0b3aSBarry Smith 1114d44834fbSBarry Smith /* wait on receives of lens */ 11150c468ba9SBarry Smith if (nrecvs2) { 1116785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 1117d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 1118d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 11190c468ba9SBarry Smith } 1120a2ea699eSBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 1121d44834fbSBarry Smith 112230dcb7c9SBarry Smith starts3[0] = 0; 1123d44834fbSBarry Smith nt = 0; 112430dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 112530dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 1126d44834fbSBarry Smith nt += lens2[i]; 112730dcb7c9SBarry Smith } 112876466f69SStefano Zampini if (nrecvs2) nt += lens2[nrecvs2-1]; 1129d44834fbSBarry Smith 1130854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&recvs2);CHKERRQ(ierr); 1131854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 113252b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 113332dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 113430dcb7c9SBarry Smith } 113530dcb7c9SBarry Smith 113630dcb7c9SBarry Smith /* send the messages */ 1137854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&send_waits);CHKERRQ(ierr); 113830dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 113932dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 114030dcb7c9SBarry Smith } 114130dcb7c9SBarry Smith 114230dcb7c9SBarry Smith /* wait on receives */ 11430c468ba9SBarry Smith if (nrecvs2) { 1144785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 114530dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 114630dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 11470c468ba9SBarry Smith } 114830dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 114930dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 115030dcb7c9SBarry Smith 115107b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 115230dcb7c9SBarry Smith cnt = 0; 115330dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 115430dcb7c9SBarry Smith nt = recvs2[cnt++]; 115530dcb7c9SBarry Smith for (j=0; j<nt; j++) { 11567904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %D number of subdomains %D: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 115730dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 11587904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",recvs2[cnt+2+k]);CHKERRQ(ierr); 115930dcb7c9SBarry Smith } 116030dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 116130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 116230dcb7c9SBarry Smith } 116330dcb7c9SBarry Smith } 11640ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 116507b52d57SBarry Smith } /* ----------------------------------- */ 116630dcb7c9SBarry Smith 116730dcb7c9SBarry Smith /* count number subdomains for each local node */ 1168785e854fSJed Brown ierr = PetscMalloc1(size,&nprocs);CHKERRQ(ierr); 116932dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 117030dcb7c9SBarry Smith cnt = 0; 117130dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 117230dcb7c9SBarry Smith nt = recvs2[cnt++]; 117330dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1174f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) nprocs[recvs2[cnt+2+k]]++; 117530dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 117630dcb7c9SBarry Smith } 117730dcb7c9SBarry Smith } 117830dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 117930dcb7c9SBarry Smith *nproc = nt; 1180854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,procs);CHKERRQ(ierr); 1181854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,numprocs);CHKERRQ(ierr); 1182854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,indices);CHKERRQ(ierr); 11830298fd71SBarry Smith for (i=0;i<nt+1;i++) (*indices)[i]=NULL; 1184785e854fSJed Brown ierr = PetscMalloc1(size,&bprocs);CHKERRQ(ierr); 118530dcb7c9SBarry Smith cnt = 0; 118630dcb7c9SBarry Smith for (i=0; i<size; i++) { 118730dcb7c9SBarry Smith if (nprocs[i] > 0) { 118830dcb7c9SBarry Smith bprocs[i] = cnt; 118930dcb7c9SBarry Smith (*procs)[cnt] = i; 119030dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 1191785e854fSJed Brown ierr = PetscMalloc1(nprocs[i],&(*indices)[cnt]);CHKERRQ(ierr); 119230dcb7c9SBarry Smith cnt++; 119330dcb7c9SBarry Smith } 119430dcb7c9SBarry Smith } 119530dcb7c9SBarry Smith 119630dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 119732dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 119830dcb7c9SBarry Smith cnt = 0; 119930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 120030dcb7c9SBarry Smith nt = recvs2[cnt++]; 120130dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1202f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 120330dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 120430dcb7c9SBarry Smith } 120530dcb7c9SBarry Smith } 120630dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 120707b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 120830dcb7c9SBarry Smith 120907b52d57SBarry Smith /* sort the node indexing by their global numbers */ 121007b52d57SBarry Smith nt = *nproc; 121107b52d57SBarry Smith for (i=0; i<nt; i++) { 1212854ce69bSBarry Smith ierr = PetscMalloc1((*numprocs)[i],&tmp);CHKERRQ(ierr); 1213f6e5521dSKarl Rupp for (j=0; j<(*numprocs)[i]; j++) tmp[j] = lindices[(*indices)[i][j]]; 121407b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 121507b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 121607b52d57SBarry Smith } 121707b52d57SBarry Smith 121807b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 121930dcb7c9SBarry Smith nt = *nproc; 122030dcb7c9SBarry Smith for (i=0; i<nt; i++) { 12217904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %D number of indices %D: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 122230dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 12237904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",(*indices)[i][j]);CHKERRQ(ierr); 122430dcb7c9SBarry Smith } 122530dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 122630dcb7c9SBarry Smith } 12270ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 122807b52d57SBarry Smith } /* ----------------------------------- */ 122930dcb7c9SBarry Smith 123030dcb7c9SBarry Smith /* wait on sends */ 123130dcb7c9SBarry Smith if (nsends2) { 1232785e854fSJed Brown ierr = PetscMalloc1(nsends2,&send_status);CHKERRQ(ierr); 123330dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 123430dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 123530dcb7c9SBarry Smith } 123630dcb7c9SBarry Smith 123730dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 123830dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 123930dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 12403677ff5aSBarry Smith 1241bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 1242bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 1243bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 124430dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 124530dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 124689d82c54SBarry Smith 124789d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 124897f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 124989d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 12503a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 125130dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 125224cf384cSBarry Smith 125324cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 125424cf384cSBarry Smith first_procs = (*procs)[0]; 125524cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 125624cf384cSBarry Smith first_indices = (*indices)[0]; 125724cf384cSBarry Smith for (i=0; i<*nproc; i++) { 125824cf384cSBarry Smith if ((*procs)[i] == rank) { 125924cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 126024cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 126124cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 126224cf384cSBarry Smith (*procs)[i] = first_procs; 126324cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 126424cf384cSBarry Smith (*indices)[i] = first_indices; 126524cf384cSBarry Smith break; 126624cf384cSBarry Smith } 126724cf384cSBarry Smith } 1268268a049cSStefano Zampini 1269268a049cSStefano Zampini /* save info for reuse */ 1270268a049cSStefano Zampini mapping->info_nproc = *nproc; 1271268a049cSStefano Zampini mapping->info_procs = *procs; 1272268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 1273268a049cSStefano Zampini mapping->info_indices = *indices; 1274268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 127589d82c54SBarry Smith PetscFunctionReturn(0); 127689d82c54SBarry Smith } 127789d82c54SBarry Smith 12786a818285SBarry Smith /*@C 12796a818285SBarry Smith ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by ISLocalToGlobalMappingGetBlockInfo() 12806a818285SBarry Smith 12816a818285SBarry Smith Collective on ISLocalToGlobalMapping 12826a818285SBarry Smith 12836a818285SBarry Smith Input Parameters: 12846a818285SBarry Smith . mapping - the mapping from local to global indexing 12856a818285SBarry Smith 12866a818285SBarry Smith Output Parameter: 12876a818285SBarry Smith + nproc - number of processors that are connected to this one 12886a818285SBarry Smith . proc - neighboring processors 12896a818285SBarry Smith . numproc - number of indices for each processor 12906a818285SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 12916a818285SBarry Smith 12926a818285SBarry Smith Level: advanced 12936a818285SBarry Smith 12946a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 12956a818285SBarry Smith ISLocalToGlobalMappingGetInfo() 12966a818285SBarry Smith @*/ 12976a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 12986a818285SBarry Smith { 12996a818285SBarry Smith PetscErrorCode ierr; 13006a818285SBarry Smith 13016a818285SBarry Smith PetscFunctionBegin; 1302cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1303268a049cSStefano Zampini if (mapping->info_free) { 13046a818285SBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 13056a818285SBarry Smith if (*indices) { 1306268a049cSStefano Zampini PetscInt i; 1307268a049cSStefano Zampini 13086a818285SBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 13096a818285SBarry Smith for (i=1; i<*nproc; i++) { 13106a818285SBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 13116a818285SBarry Smith } 13126a818285SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 13136a818285SBarry Smith } 1314268a049cSStefano Zampini } 1315268a049cSStefano Zampini *nproc = 0; 1316268a049cSStefano Zampini *procs = NULL; 1317268a049cSStefano Zampini *numprocs = NULL; 1318268a049cSStefano Zampini *indices = NULL; 13196a818285SBarry Smith PetscFunctionReturn(0); 13206a818285SBarry Smith } 13216a818285SBarry Smith 13226a818285SBarry Smith /*@C 13236a818285SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 13246a818285SBarry Smith each index shared by more than one processor 13256a818285SBarry Smith 13266a818285SBarry Smith Collective on ISLocalToGlobalMapping 13276a818285SBarry Smith 13286a818285SBarry Smith Input Parameters: 13296a818285SBarry Smith . mapping - the mapping from local to global indexing 13306a818285SBarry Smith 13316a818285SBarry Smith Output Parameter: 13326a818285SBarry Smith + nproc - number of processors that are connected to this one 13336a818285SBarry Smith . proc - neighboring processors 13346a818285SBarry Smith . numproc - number of indices for each subdomain (processor) 13356a818285SBarry Smith - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 13366a818285SBarry Smith 13376a818285SBarry Smith Level: advanced 13386a818285SBarry Smith 13396a818285SBarry Smith Concepts: mapping^local to global 13406a818285SBarry Smith 13416a818285SBarry Smith Fortran Usage: 13426a818285SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 13436a818285SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 13446a818285SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 13456a818285SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 13466a818285SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 13476a818285SBarry Smith 13486a818285SBarry Smith 13496a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 13506a818285SBarry Smith ISLocalToGlobalMappingRestoreInfo() 13516a818285SBarry Smith @*/ 13526a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 13536a818285SBarry Smith { 13546a818285SBarry Smith PetscErrorCode ierr; 1355268a049cSStefano Zampini PetscInt **bindices = NULL,*bnumprocs = NULL,bs = mapping->bs,i,j,k; 13566a818285SBarry Smith 13576a818285SBarry Smith PetscFunctionBegin; 13586a818285SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1359268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo(mapping,nproc,procs,&bnumprocs,&bindices);CHKERRQ(ierr); 1360268a049cSStefano Zampini if (bs > 1) { /* we need to expand the cached info */ 1361732f65e3SBarry Smith ierr = PetscCalloc1(*nproc,&*indices);CHKERRQ(ierr); 1362268a049cSStefano Zampini ierr = PetscCalloc1(*nproc,&*numprocs);CHKERRQ(ierr); 13636a818285SBarry Smith for (i=0; i<*nproc; i++) { 1364268a049cSStefano Zampini ierr = PetscMalloc1(bs*bnumprocs[i],&(*indices)[i]);CHKERRQ(ierr); 1365268a049cSStefano Zampini for (j=0; j<bnumprocs[i]; j++) { 13666a818285SBarry Smith for (k=0; k<bs; k++) { 13676a818285SBarry Smith (*indices)[i][j*bs+k] = bs*bindices[i][j] + k; 13686a818285SBarry Smith } 13696a818285SBarry Smith } 1370268a049cSStefano Zampini (*numprocs)[i] = bnumprocs[i]*bs; 13716a818285SBarry Smith } 1372268a049cSStefano Zampini mapping->info_free = PETSC_TRUE; 1373268a049cSStefano Zampini } else { 1374268a049cSStefano Zampini *numprocs = bnumprocs; 1375268a049cSStefano Zampini *indices = bindices; 13766a818285SBarry Smith } 13776a818285SBarry Smith PetscFunctionReturn(0); 13786a818285SBarry Smith } 13796a818285SBarry Smith 138007b52d57SBarry Smith /*@C 138107b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 138289d82c54SBarry Smith 138307b52d57SBarry Smith Collective on ISLocalToGlobalMapping 138407b52d57SBarry Smith 138507b52d57SBarry Smith Input Parameters: 138607b52d57SBarry Smith . mapping - the mapping from local to global indexing 138707b52d57SBarry Smith 138807b52d57SBarry Smith Output Parameter: 138907b52d57SBarry Smith + nproc - number of processors that are connected to this one 139007b52d57SBarry Smith . proc - neighboring processors 139107b52d57SBarry Smith . numproc - number of indices for each processor 139207b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 139307b52d57SBarry Smith 139407b52d57SBarry Smith Level: advanced 139507b52d57SBarry Smith 139607b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 139707b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 139807b52d57SBarry Smith @*/ 13997087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 140007b52d57SBarry Smith { 14016849ba73SBarry Smith PetscErrorCode ierr; 140207b52d57SBarry Smith 140307b52d57SBarry Smith PetscFunctionBegin; 14046a818285SBarry Smith ierr = ISLocalToGlobalMappingRestoreBlockInfo(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 140507b52d57SBarry Smith PetscFunctionReturn(0); 140607b52d57SBarry Smith } 140786994e45SJed Brown 140886994e45SJed Brown /*@C 1409107e9a97SBarry Smith ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped 141086994e45SJed Brown 141186994e45SJed Brown Not Collective 141286994e45SJed Brown 141386994e45SJed Brown Input Arguments: 141486994e45SJed Brown . ltog - local to global mapping 141586994e45SJed Brown 141686994e45SJed Brown Output Arguments: 1417565245c5SBarry Smith . array - array of indices, the length of this array may be obtained with ISLocalToGlobalMappingGetSize() 141886994e45SJed Brown 141986994e45SJed Brown Level: advanced 142086994e45SJed Brown 1421107e9a97SBarry Smith Notes: ISLocalToGlobalMappingGetSize() returns the length the this array 1422107e9a97SBarry Smith 1423107e9a97SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreIndices(), ISLocalToGlobalMappingGetBlockIndices(), ISLocalToGlobalMappingRestoreBlockIndices() 142486994e45SJed Brown @*/ 14257087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 142686994e45SJed Brown { 142786994e45SJed Brown PetscFunctionBegin; 142886994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 142986994e45SJed Brown PetscValidPointer(array,2); 143045b6f7e9SBarry Smith if (ltog->bs == 1) { 143186994e45SJed Brown *array = ltog->indices; 143245b6f7e9SBarry Smith } else { 143345b6f7e9SBarry Smith PetscInt *jj,k,i,j,n = ltog->n, bs = ltog->bs; 143445b6f7e9SBarry Smith const PetscInt *ii; 143545b6f7e9SBarry Smith PetscErrorCode ierr; 143645b6f7e9SBarry Smith 143745b6f7e9SBarry Smith ierr = PetscMalloc1(bs*n,&jj);CHKERRQ(ierr); 143845b6f7e9SBarry Smith *array = jj; 143945b6f7e9SBarry Smith k = 0; 144045b6f7e9SBarry Smith ii = ltog->indices; 144145b6f7e9SBarry Smith for (i=0; i<n; i++) 144245b6f7e9SBarry Smith for (j=0; j<bs; j++) 144345b6f7e9SBarry Smith jj[k++] = bs*ii[i] + j; 144445b6f7e9SBarry Smith } 144586994e45SJed Brown PetscFunctionReturn(0); 144686994e45SJed Brown } 144786994e45SJed Brown 144886994e45SJed Brown /*@C 1449193a2b41SJulian Andrej ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with ISLocalToGlobalMappingGetIndices() 145086994e45SJed Brown 145186994e45SJed Brown Not Collective 145286994e45SJed Brown 145386994e45SJed Brown Input Arguments: 145486994e45SJed Brown + ltog - local to global mapping 145586994e45SJed Brown - array - array of indices 145686994e45SJed Brown 145786994e45SJed Brown Level: advanced 145886994e45SJed Brown 145986994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 146086994e45SJed Brown @*/ 14617087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 146286994e45SJed Brown { 146386994e45SJed Brown PetscFunctionBegin; 146486994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 146586994e45SJed Brown PetscValidPointer(array,2); 146645b6f7e9SBarry Smith if (ltog->bs == 1 && *array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 146745b6f7e9SBarry Smith 146845b6f7e9SBarry Smith if (ltog->bs > 1) { 146945b6f7e9SBarry Smith PetscErrorCode ierr; 147045b6f7e9SBarry Smith ierr = PetscFree(*(void**)array);CHKERRQ(ierr); 147145b6f7e9SBarry Smith } 147245b6f7e9SBarry Smith PetscFunctionReturn(0); 147345b6f7e9SBarry Smith } 147445b6f7e9SBarry Smith 147545b6f7e9SBarry Smith /*@C 147645b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block 147745b6f7e9SBarry Smith 147845b6f7e9SBarry Smith Not Collective 147945b6f7e9SBarry Smith 148045b6f7e9SBarry Smith Input Arguments: 148145b6f7e9SBarry Smith . ltog - local to global mapping 148245b6f7e9SBarry Smith 148345b6f7e9SBarry Smith Output Arguments: 148445b6f7e9SBarry Smith . array - array of indices 148545b6f7e9SBarry Smith 148645b6f7e9SBarry Smith Level: advanced 148745b6f7e9SBarry Smith 148845b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreBlockIndices() 148945b6f7e9SBarry Smith @*/ 149045b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 149145b6f7e9SBarry Smith { 149245b6f7e9SBarry Smith PetscFunctionBegin; 149345b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 149445b6f7e9SBarry Smith PetscValidPointer(array,2); 149545b6f7e9SBarry Smith *array = ltog->indices; 149645b6f7e9SBarry Smith PetscFunctionReturn(0); 149745b6f7e9SBarry Smith } 149845b6f7e9SBarry Smith 149945b6f7e9SBarry Smith /*@C 150045b6f7e9SBarry Smith ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with ISLocalToGlobalMappingGetBlockIndices() 150145b6f7e9SBarry Smith 150245b6f7e9SBarry Smith Not Collective 150345b6f7e9SBarry Smith 150445b6f7e9SBarry Smith Input Arguments: 150545b6f7e9SBarry Smith + ltog - local to global mapping 150645b6f7e9SBarry Smith - array - array of indices 150745b6f7e9SBarry Smith 150845b6f7e9SBarry Smith Level: advanced 150945b6f7e9SBarry Smith 151045b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 151145b6f7e9SBarry Smith @*/ 151245b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 151345b6f7e9SBarry Smith { 151445b6f7e9SBarry Smith PetscFunctionBegin; 151545b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 151645b6f7e9SBarry Smith PetscValidPointer(array,2); 151786994e45SJed Brown if (*array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 15180298fd71SBarry Smith *array = NULL; 151986994e45SJed Brown PetscFunctionReturn(0); 152086994e45SJed Brown } 1521f7efa3c7SJed Brown 1522f7efa3c7SJed Brown /*@C 1523f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1524f7efa3c7SJed Brown 1525f7efa3c7SJed Brown Not Collective 1526f7efa3c7SJed Brown 1527f7efa3c7SJed Brown Input Arguments: 1528f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1529f7efa3c7SJed Brown . n - number of mappings to concatenate 1530f7efa3c7SJed Brown - ltogs - local to global mappings 1531f7efa3c7SJed Brown 1532f7efa3c7SJed Brown Output Arguments: 1533f7efa3c7SJed Brown . ltogcat - new mapping 1534f7efa3c7SJed Brown 15359d90f715SBarry Smith Note: this currently always returns a mapping with block size of 1 15369d90f715SBarry Smith 15379d90f715SBarry Smith Developer Note: If all the input mapping have the same block size we could easily handle that as a special case 15389d90f715SBarry Smith 1539f7efa3c7SJed Brown Level: advanced 1540f7efa3c7SJed Brown 1541f7efa3c7SJed Brown .seealso: ISLocalToGlobalMappingCreate() 1542f7efa3c7SJed Brown @*/ 1543f7efa3c7SJed Brown PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping *ltogcat) 1544f7efa3c7SJed Brown { 1545f7efa3c7SJed Brown PetscInt i,cnt,m,*idx; 1546f7efa3c7SJed Brown PetscErrorCode ierr; 1547f7efa3c7SJed Brown 1548f7efa3c7SJed Brown PetscFunctionBegin; 1549f7efa3c7SJed Brown if (n < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have a non-negative number of mappings, given %D",n); 1550f7efa3c7SJed Brown if (n > 0) PetscValidPointer(ltogs,3); 1551f7efa3c7SJed Brown for (i=0; i<n; i++) PetscValidHeaderSpecific(ltogs[i],IS_LTOGM_CLASSID,3); 1552f7efa3c7SJed Brown PetscValidPointer(ltogcat,4); 1553f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1554f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1555f7efa3c7SJed Brown cnt += m; 1556f7efa3c7SJed Brown } 1557785e854fSJed Brown ierr = PetscMalloc1(cnt,&idx);CHKERRQ(ierr); 1558f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1559f7efa3c7SJed Brown const PetscInt *subidx; 1560f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1561f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1562f7efa3c7SJed Brown ierr = PetscMemcpy(&idx[cnt],subidx,m*sizeof(PetscInt));CHKERRQ(ierr); 1563f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1564f7efa3c7SJed Brown cnt += m; 1565f7efa3c7SJed Brown } 1566f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,cnt,idx,PETSC_OWN_POINTER,ltogcat);CHKERRQ(ierr); 1567f7efa3c7SJed Brown PetscFunctionReturn(0); 1568f7efa3c7SJed Brown } 156904a59952SBarry Smith 157004a59952SBarry Smith 1571