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__ 18145b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockSize" 18245b6f7e9SBarry Smith /*@ 18345b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping 18445b6f7e9SBarry Smith ordering and a global parallel ordering. 18545b6f7e9SBarry Smith 18645b6f7e9SBarry Smith Not Collective 18745b6f7e9SBarry Smith 18845b6f7e9SBarry Smith Input Parameters: 18945b6f7e9SBarry Smith . mapping - mapping data structure 19045b6f7e9SBarry Smith 19145b6f7e9SBarry Smith Output Parameter: 19245b6f7e9SBarry Smith . bs - the blocksize 19345b6f7e9SBarry Smith 19445b6f7e9SBarry Smith Level: advanced 19545b6f7e9SBarry Smith 19645b6f7e9SBarry Smith Concepts: mapping^local to global 19745b6f7e9SBarry Smith 19845b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 19945b6f7e9SBarry Smith @*/ 20045b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping,PetscInt *bs) 20145b6f7e9SBarry Smith { 20245b6f7e9SBarry Smith PetscFunctionBegin; 203cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 20445b6f7e9SBarry Smith *bs = mapping->bs; 20545b6f7e9SBarry Smith PetscFunctionReturn(0); 20645b6f7e9SBarry Smith } 20745b6f7e9SBarry Smith 20845b6f7e9SBarry Smith #undef __FUNCT__ 2094a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 210ba5bb76aSSatish Balay /*@ 21190f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 21290f02eecSBarry Smith ordering and a global parallel ordering. 2132362add9SBarry Smith 21489d82c54SBarry Smith Not Collective, but communicator may have more than one process 215b9cd556bSLois Curfman McInnes 2162362add9SBarry Smith Input Parameters: 21789d82c54SBarry Smith + comm - MPI communicator 218f0413b6fSBarry Smith . bs - the block size 21928bc9809SBarry Smith . n - the number of local elements divided by the block size, or equivalently the number of block indices 22028bc9809SBarry 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 221d5ad8652SBarry Smith - mode - see PetscCopyMode 2222362add9SBarry Smith 223a997ad1aSLois Curfman McInnes Output Parameter: 22490f02eecSBarry Smith . mapping - new mapping data structure 2252362add9SBarry Smith 226f0413b6fSBarry 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 227a997ad1aSLois Curfman McInnes Level: advanced 228a997ad1aSLois Curfman McInnes 229273d9f13SBarry Smith Concepts: mapping^local to global 2302362add9SBarry Smith 231d5ad8652SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 2322362add9SBarry Smith @*/ 23360c7cefcSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 2342362add9SBarry Smith { 2356849ba73SBarry Smith PetscErrorCode ierr; 23632dcc486SBarry Smith PetscInt *in; 237b46b645bSBarry Smith 238b46b645bSBarry Smith PetscFunctionBegin; 23973911063SBarry Smith if (n) PetscValidIntPointer(indices,3); 2404482741eSBarry Smith PetscValidPointer(mapping,4); 241b46b645bSBarry Smith 2420298fd71SBarry Smith *mapping = NULL; 243607a6623SBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 2442362add9SBarry Smith 24573107ff1SLisandro Dalcin ierr = PetscHeaderCreate(*mapping,IS_LTOGM_CLASSID,"ISLocalToGlobalMapping","Local to global mapping","IS", 24660c7cefcSBarry Smith comm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 247d4bb536fSBarry Smith (*mapping)->n = n; 248f0413b6fSBarry Smith (*mapping)->bs = bs; 249268a049cSStefano Zampini (*mapping)->info_cached = PETSC_FALSE; 250268a049cSStefano Zampini (*mapping)->info_free = PETSC_FALSE; 251268a049cSStefano Zampini (*mapping)->info_procs = NULL; 252268a049cSStefano Zampini (*mapping)->info_numprocs = NULL; 253268a049cSStefano Zampini (*mapping)->info_indices = NULL; 254d4bb536fSBarry Smith /* 255d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 256d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 257d4bb536fSBarry Smith */ 258d4bb536fSBarry Smith (*mapping)->globals = 0; 259d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 260785e854fSJed Brown ierr = PetscMalloc1(n,&in);CHKERRQ(ierr); 261d5ad8652SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 262d5ad8652SBarry Smith (*mapping)->indices = in; 2636389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 2646389a1a1SBarry Smith } else if (mode == PETSC_OWN_POINTER) { 2656389a1a1SBarry Smith (*mapping)->indices = (PetscInt*)indices; 2666389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 2676389a1a1SBarry Smith } 26860c7cefcSBarry Smith else SETERRQ(comm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 269d96308ebSBarry Smith ierr = PetscStrallocpy("basic",&((PetscObject)*mapping)->type_name);CHKERRQ(ierr); 2703a40ed3dSBarry Smith PetscFunctionReturn(0); 2712362add9SBarry Smith } 2722362add9SBarry Smith 2734a2ae208SSatish Balay #undef __FUNCT__ 2744a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 27590f02eecSBarry Smith /*@ 27690f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 27790f02eecSBarry Smith ordering and a global parallel ordering. 27890f02eecSBarry Smith 2790f5bd95cSBarry Smith Note Collective 280b9cd556bSLois Curfman McInnes 28190f02eecSBarry Smith Input Parameters: 28290f02eecSBarry Smith . mapping - mapping data structure 28390f02eecSBarry Smith 284a997ad1aSLois Curfman McInnes Level: advanced 285a997ad1aSLois Curfman McInnes 2863acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 28790f02eecSBarry Smith @*/ 2886bf464f9SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 28990f02eecSBarry Smith { 290dfbe8321SBarry Smith PetscErrorCode ierr; 2915fd66863SKarl Rupp 2923a40ed3dSBarry Smith PetscFunctionBegin; 2936bf464f9SBarry Smith if (!*mapping) PetscFunctionReturn(0); 2946bf464f9SBarry Smith PetscValidHeaderSpecific((*mapping),IS_LTOGM_CLASSID,1); 295997056adSBarry Smith if (--((PetscObject)(*mapping))->refct > 0) {*mapping = 0;PetscFunctionReturn(0);} 2966bf464f9SBarry Smith ierr = PetscFree((*mapping)->indices);CHKERRQ(ierr); 2976bf464f9SBarry Smith ierr = PetscFree((*mapping)->globals);CHKERRQ(ierr); 298268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_procs);CHKERRQ(ierr); 299268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_numprocs);CHKERRQ(ierr); 300268a049cSStefano Zampini if ((*mapping)->info_indices) { 301268a049cSStefano Zampini PetscInt i; 302268a049cSStefano Zampini 303268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[0]);CHKERRQ(ierr); 304268a049cSStefano Zampini for (i=1; i<(*mapping)->info_nproc; i++) { 305268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[i]);CHKERRQ(ierr); 306268a049cSStefano Zampini } 307268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_indices);CHKERRQ(ierr); 308268a049cSStefano Zampini } 309d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 310992144d0SBarry Smith *mapping = 0; 3113a40ed3dSBarry Smith PetscFunctionReturn(0); 31290f02eecSBarry Smith } 31390f02eecSBarry Smith 3144a2ae208SSatish Balay #undef __FUNCT__ 3154a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 31690f02eecSBarry Smith /*@ 3173acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 3183acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 3193acfe500SLois Curfman McInnes context. 32090f02eecSBarry Smith 321b9cd556bSLois Curfman McInnes Not collective 322b9cd556bSLois Curfman McInnes 32390f02eecSBarry Smith Input Parameters: 324b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 325b9cd556bSLois Curfman McInnes - is - index set in local numbering 32690f02eecSBarry Smith 32790f02eecSBarry Smith Output Parameters: 32890f02eecSBarry Smith . newis - index set in global numbering 32990f02eecSBarry Smith 330a997ad1aSLois Curfman McInnes Level: advanced 331a997ad1aSLois Curfman McInnes 332273d9f13SBarry Smith Concepts: mapping^local to global 3333acfe500SLois Curfman McInnes 33490f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 335d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 33690f02eecSBarry Smith @*/ 3377087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 33890f02eecSBarry Smith { 3396849ba73SBarry Smith PetscErrorCode ierr; 340e24637baSBarry Smith PetscInt n,*idxout; 3415d0c19d7SBarry Smith const PetscInt *idxin; 3423a40ed3dSBarry Smith 3433a40ed3dSBarry Smith PetscFunctionBegin; 3440700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 3450700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 3464482741eSBarry Smith PetscValidPointer(newis,3); 34790f02eecSBarry Smith 3483b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 34990f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 350785e854fSJed Brown ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 351e24637baSBarry Smith ierr = ISLocalToGlobalMappingApply(mapping,n,idxin,idxout);CHKERRQ(ierr); 3523b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 353543f3098SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 3543a40ed3dSBarry Smith PetscFunctionReturn(0); 35590f02eecSBarry Smith } 35690f02eecSBarry Smith 357afcb2eb5SJed Brown #undef __FUNCT__ 358afcb2eb5SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingApply" 359b89cb25eSSatish Balay /*@ 3603acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 3613acfe500SLois Curfman McInnes and converts them to the global numbering. 36290f02eecSBarry Smith 363b9cd556bSLois Curfman McInnes Not collective 364b9cd556bSLois Curfman McInnes 365bb25748dSBarry Smith Input Parameters: 366b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 367bb25748dSBarry Smith . N - number of integers 368b9cd556bSLois Curfman McInnes - in - input indices in local numbering 369bb25748dSBarry Smith 370bb25748dSBarry Smith Output Parameter: 371bb25748dSBarry Smith . out - indices in global numbering 372bb25748dSBarry Smith 373b9cd556bSLois Curfman McInnes Notes: 374b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 375d4bb536fSBarry Smith 376a997ad1aSLois Curfman McInnes Level: advanced 377a997ad1aSLois Curfman McInnes 37845b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApplyBlock(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 3790752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 380d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 381bb25748dSBarry Smith 382273d9f13SBarry Smith Concepts: mapping^local to global 383afcb2eb5SJed Brown @*/ 384afcb2eb5SJed Brown PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 385afcb2eb5SJed Brown { 386cbc1caf0SMatthew G. Knepley PetscInt i,bs,Nmax; 38745b6f7e9SBarry Smith 38845b6f7e9SBarry Smith PetscFunctionBegin; 389cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 390cbc1caf0SMatthew G. Knepley bs = mapping->bs; 391cbc1caf0SMatthew G. Knepley Nmax = bs*mapping->n; 39245b6f7e9SBarry Smith if (bs == 1) { 393cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 39445b6f7e9SBarry Smith for (i=0; i<N; i++) { 39545b6f7e9SBarry Smith if (in[i] < 0) { 39645b6f7e9SBarry Smith out[i] = in[i]; 39745b6f7e9SBarry Smith continue; 39845b6f7e9SBarry Smith } 399e24637baSBarry 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); 40045b6f7e9SBarry Smith out[i] = idx[in[i]]; 40145b6f7e9SBarry Smith } 40245b6f7e9SBarry Smith } else { 403cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 40445b6f7e9SBarry Smith for (i=0; i<N; i++) { 40545b6f7e9SBarry Smith if (in[i] < 0) { 40645b6f7e9SBarry Smith out[i] = in[i]; 40745b6f7e9SBarry Smith continue; 40845b6f7e9SBarry Smith } 409e24637baSBarry 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); 41045b6f7e9SBarry Smith out[i] = idx[in[i]/bs]*bs + (in[i] % bs); 41145b6f7e9SBarry Smith } 41245b6f7e9SBarry Smith } 41345b6f7e9SBarry Smith PetscFunctionReturn(0); 41445b6f7e9SBarry Smith } 41545b6f7e9SBarry Smith 41645b6f7e9SBarry Smith #undef __FUNCT__ 41745b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingApplyBlock" 41845b6f7e9SBarry Smith /*@ 4196006e8d2SBarry Smith ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering 42045b6f7e9SBarry Smith 42145b6f7e9SBarry Smith Not collective 42245b6f7e9SBarry Smith 42345b6f7e9SBarry Smith Input Parameters: 42445b6f7e9SBarry Smith + mapping - the local to global mapping context 42545b6f7e9SBarry Smith . N - number of integers 4266006e8d2SBarry Smith - in - input indices in local block numbering 42745b6f7e9SBarry Smith 42845b6f7e9SBarry Smith Output Parameter: 4296006e8d2SBarry Smith . out - indices in global block numbering 43045b6f7e9SBarry Smith 43145b6f7e9SBarry Smith Notes: 43245b6f7e9SBarry Smith The in and out array parameters may be identical. 43345b6f7e9SBarry Smith 4346006e8d2SBarry Smith Example: 4356006e8d2SBarry 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 4366006e8d2SBarry Smith (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3. 4376006e8d2SBarry Smith 43845b6f7e9SBarry Smith Level: advanced 43945b6f7e9SBarry Smith 44045b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 44145b6f7e9SBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 44245b6f7e9SBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 44345b6f7e9SBarry Smith 44445b6f7e9SBarry Smith Concepts: mapping^local to global 44545b6f7e9SBarry Smith @*/ 44645b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 44745b6f7e9SBarry Smith { 448cbc1caf0SMatthew G. Knepley 449cbc1caf0SMatthew G. Knepley PetscFunctionBegin; 450cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 451cbc1caf0SMatthew G. Knepley { 452afcb2eb5SJed Brown PetscInt i,Nmax = mapping->n; 453afcb2eb5SJed Brown const PetscInt *idx = mapping->indices; 454d4bb536fSBarry Smith 455afcb2eb5SJed Brown for (i=0; i<N; i++) { 456afcb2eb5SJed Brown if (in[i] < 0) { 457afcb2eb5SJed Brown out[i] = in[i]; 458afcb2eb5SJed Brown continue; 459afcb2eb5SJed Brown } 460e24637baSBarry 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); 461afcb2eb5SJed Brown out[i] = idx[in[i]]; 462afcb2eb5SJed Brown } 463cbc1caf0SMatthew G. Knepley } 464afcb2eb5SJed Brown PetscFunctionReturn(0); 465afcb2eb5SJed Brown } 466d4bb536fSBarry Smith 467d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 468d4bb536fSBarry Smith 4694a2ae208SSatish Balay #undef __FUNCT__ 4704a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 471d4bb536fSBarry Smith /* 472d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 473d4bb536fSBarry Smith */ 4746849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 475d4bb536fSBarry Smith { 4766849ba73SBarry Smith PetscErrorCode ierr; 47732dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 478d4bb536fSBarry Smith 4793a40ed3dSBarry Smith PetscFunctionBegin; 480d4bb536fSBarry Smith end = 0; 481ec268f7cSJed Brown start = PETSC_MAX_INT; 482d4bb536fSBarry Smith 483d4bb536fSBarry Smith for (i=0; i<n; i++) { 484d4bb536fSBarry Smith if (idx[i] < 0) continue; 485d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 486d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 487d4bb536fSBarry Smith } 488d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 489d4bb536fSBarry Smith mapping->globalstart = start; 490d4bb536fSBarry Smith mapping->globalend = end; 491d4bb536fSBarry Smith 492854ce69bSBarry Smith ierr = PetscMalloc1(end-start+2,&globals);CHKERRQ(ierr); 493b0a32e0cSBarry Smith mapping->globals = globals; 494f6e5521dSKarl Rupp for (i=0; i<end-start+1; i++) globals[i] = -1; 495d4bb536fSBarry Smith for (i=0; i<n; i++) { 496d4bb536fSBarry Smith if (idx[i] < 0) continue; 497d4bb536fSBarry Smith globals[idx[i] - start] = i; 498d4bb536fSBarry Smith } 499d4bb536fSBarry Smith 5003bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 5013a40ed3dSBarry Smith PetscFunctionReturn(0); 502d4bb536fSBarry Smith } 503d4bb536fSBarry Smith 5044a2ae208SSatish Balay #undef __FUNCT__ 5054a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 506d4bb536fSBarry Smith /*@ 507a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 508a997ad1aSLois Curfman McInnes specified with a global numbering. 509d4bb536fSBarry Smith 510b9cd556bSLois Curfman McInnes Not collective 511b9cd556bSLois Curfman McInnes 512d4bb536fSBarry Smith Input Parameters: 513b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 514d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 515d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 516d4bb536fSBarry Smith . n - number of global indices to map 517b9cd556bSLois Curfman McInnes - idx - global indices to map 518d4bb536fSBarry Smith 519d4bb536fSBarry Smith Output Parameters: 520b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 521b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 522e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 5230298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 524e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 525e182c471SBarry Smith a second time to set the values. 526d4bb536fSBarry Smith 527b9cd556bSLois Curfman McInnes Notes: 5280298fd71SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 529d4bb536fSBarry Smith 5300f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 5310f5bd95cSBarry Smith array to compute these. 5320f5bd95cSBarry Smith 533a997ad1aSLois Curfman McInnes Level: advanced 534a997ad1aSLois Curfman McInnes 53532fd6b96SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 53632fd6b96SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 53732fd6b96SBarry Smith 538273d9f13SBarry Smith Concepts: mapping^global to local 539d4bb536fSBarry Smith 5409d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApplyBlock(), ISLocalToGlobalMappingCreate(), 541d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 542d4bb536fSBarry Smith @*/ 5437087cfbeSBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 54432dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 545d4bb536fSBarry Smith { 5469d90f715SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end,bs; 5479d90f715SBarry Smith PetscErrorCode ierr; 5489d90f715SBarry Smith 5499d90f715SBarry Smith PetscFunctionBegin; 5509d90f715SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 5519d90f715SBarry Smith if (!mapping->globals) { 5529d90f715SBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 5539d90f715SBarry Smith } 5549d90f715SBarry Smith globals = mapping->globals; 5559d90f715SBarry Smith start = mapping->globalstart; 5569d90f715SBarry Smith end = mapping->globalend; 5579d90f715SBarry Smith bs = mapping->bs; 5589d90f715SBarry Smith 5599d90f715SBarry Smith if (type == IS_GTOLM_MASK) { 5609d90f715SBarry Smith if (idxout) { 5619d90f715SBarry Smith for (i=0; i<n; i++) { 5629d90f715SBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 5639d90f715SBarry Smith else if (idx[i] < bs*start) idxout[i] = -1; 564663bb84eSBarry Smith else if (idx[i] > bs*(end+1)-1) idxout[i] = -1; 5659d90f715SBarry Smith else idxout[i] = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 5669d90f715SBarry Smith } 5679d90f715SBarry Smith } 5689d90f715SBarry Smith if (nout) *nout = n; 5699d90f715SBarry Smith } else { 5709d90f715SBarry Smith if (idxout) { 5719d90f715SBarry Smith for (i=0; i<n; i++) { 5729d90f715SBarry Smith if (idx[i] < 0) continue; 5739d90f715SBarry Smith if (idx[i] < bs*start) continue; 574663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 5759d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 5769d90f715SBarry Smith if (tmp < 0) continue; 5779d90f715SBarry Smith idxout[nf++] = tmp; 5789d90f715SBarry Smith } 5799d90f715SBarry Smith } else { 5809d90f715SBarry Smith for (i=0; i<n; i++) { 5819d90f715SBarry Smith if (idx[i] < 0) continue; 5829d90f715SBarry Smith if (idx[i] < bs*start) continue; 583663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 5849d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 5859d90f715SBarry Smith if (tmp < 0) continue; 5869d90f715SBarry Smith nf++; 5879d90f715SBarry Smith } 5889d90f715SBarry Smith } 5899d90f715SBarry Smith if (nout) *nout = nf; 5909d90f715SBarry Smith } 5919d90f715SBarry Smith PetscFunctionReturn(0); 5929d90f715SBarry Smith } 5939d90f715SBarry Smith 5949d90f715SBarry Smith #undef __FUNCT__ 595d4fe737eSStefano Zampini #define __FUNCT__ "ISGlobalToLocalMappingApplyIS" 596d4fe737eSStefano Zampini /*@ 597d4fe737eSStefano Zampini ISGlobalToLocalMappingApplyIS - Creates from an IS in the global numbering 598d4fe737eSStefano Zampini a new index set using the local numbering defined in an ISLocalToGlobalMapping 599d4fe737eSStefano Zampini context. 600d4fe737eSStefano Zampini 601d4fe737eSStefano Zampini Not collective 602d4fe737eSStefano Zampini 603d4fe737eSStefano Zampini Input Parameters: 604d4fe737eSStefano Zampini + mapping - mapping between local and global numbering 605d4fe737eSStefano Zampini - is - index set in global numbering 606d4fe737eSStefano Zampini 607d4fe737eSStefano Zampini Output Parameters: 608d4fe737eSStefano Zampini . newis - index set in local numbering 609d4fe737eSStefano Zampini 610d4fe737eSStefano Zampini Level: advanced 611d4fe737eSStefano Zampini 612d4fe737eSStefano Zampini Concepts: mapping^local to global 613d4fe737eSStefano Zampini 614d4fe737eSStefano Zampini .seealso: ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 615d4fe737eSStefano Zampini ISLocalToGlobalMappingDestroy() 616d4fe737eSStefano Zampini @*/ 617d4fe737eSStefano Zampini PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, IS is,IS *newis) 618d4fe737eSStefano Zampini { 619d4fe737eSStefano Zampini PetscErrorCode ierr; 620d4fe737eSStefano Zampini PetscInt n,nout,*idxout; 621d4fe737eSStefano Zampini const PetscInt *idxin; 622d4fe737eSStefano Zampini 623d4fe737eSStefano Zampini PetscFunctionBegin; 624d4fe737eSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 625d4fe737eSStefano Zampini PetscValidHeaderSpecific(is,IS_CLASSID,3); 626d4fe737eSStefano Zampini PetscValidPointer(newis,4); 627d4fe737eSStefano Zampini 628d4fe737eSStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 629d4fe737eSStefano Zampini ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 630d4fe737eSStefano Zampini if (type == IS_GTOLM_MASK) { 631d4fe737eSStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 632d4fe737eSStefano Zampini } else { 633d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,NULL);CHKERRQ(ierr); 634d4fe737eSStefano Zampini ierr = PetscMalloc1(nout,&idxout);CHKERRQ(ierr); 635d4fe737eSStefano Zampini } 636d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,idxout);CHKERRQ(ierr); 637d4fe737eSStefano Zampini ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 638d4fe737eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),nout,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 639d4fe737eSStefano Zampini PetscFunctionReturn(0); 640d4fe737eSStefano Zampini } 641d4fe737eSStefano Zampini 642d4fe737eSStefano Zampini #undef __FUNCT__ 6439d90f715SBarry Smith #define __FUNCT__ "ISGlobalToLocalMappingApplyBlock" 6449d90f715SBarry Smith /*@ 6459d90f715SBarry Smith ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers 6469d90f715SBarry Smith specified with a block global numbering. 6479d90f715SBarry Smith 6489d90f715SBarry Smith Not collective 6499d90f715SBarry Smith 6509d90f715SBarry Smith Input Parameters: 6519d90f715SBarry Smith + mapping - mapping between local and global numbering 6529d90f715SBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 6539d90f715SBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 6549d90f715SBarry Smith . n - number of global indices to map 6559d90f715SBarry Smith - idx - global indices to map 6569d90f715SBarry Smith 6579d90f715SBarry Smith Output Parameters: 6589d90f715SBarry Smith + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 6599d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough 6609d90f715SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApplyBlock() with 6619d90f715SBarry Smith idxout == NULL to determine the required length (returned in nout) 6629d90f715SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApplyBlock() 6639d90f715SBarry Smith a second time to set the values. 6649d90f715SBarry Smith 6659d90f715SBarry Smith Notes: 6669d90f715SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 6679d90f715SBarry Smith 6689d90f715SBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 6699d90f715SBarry Smith array to compute these. 6709d90f715SBarry Smith 6719d90f715SBarry Smith Level: advanced 6729d90f715SBarry Smith 6739d90f715SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 6749d90f715SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 6759d90f715SBarry Smith 6769d90f715SBarry Smith Concepts: mapping^global to local 6779d90f715SBarry Smith 6789d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 6799d90f715SBarry Smith ISLocalToGlobalMappingDestroy() 6809d90f715SBarry Smith @*/ 6819d90f715SBarry Smith PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 6829d90f715SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 6839d90f715SBarry Smith { 68432dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 6856849ba73SBarry Smith PetscErrorCode ierr; 686d4bb536fSBarry Smith 6873a40ed3dSBarry Smith PetscFunctionBegin; 6880700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 689d4bb536fSBarry Smith if (!mapping->globals) { 690d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 691d4bb536fSBarry Smith } 692d4bb536fSBarry Smith globals = mapping->globals; 693d4bb536fSBarry Smith start = mapping->globalstart; 694d4bb536fSBarry Smith end = mapping->globalend; 695d4bb536fSBarry Smith 696d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 697d4bb536fSBarry Smith if (idxout) { 698d4bb536fSBarry Smith for (i=0; i<n; i++) { 699d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 700d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 701d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 702d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 703d4bb536fSBarry Smith } 704d4bb536fSBarry Smith } 705d4bb536fSBarry Smith if (nout) *nout = n; 706d4bb536fSBarry Smith } else { 707d4bb536fSBarry Smith if (idxout) { 708d4bb536fSBarry Smith for (i=0; i<n; i++) { 709d4bb536fSBarry Smith if (idx[i] < 0) continue; 710d4bb536fSBarry Smith if (idx[i] < start) continue; 711d4bb536fSBarry Smith if (idx[i] > end) continue; 712d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 713d4bb536fSBarry Smith if (tmp < 0) continue; 714d4bb536fSBarry Smith idxout[nf++] = tmp; 715d4bb536fSBarry Smith } 716d4bb536fSBarry Smith } else { 717d4bb536fSBarry Smith for (i=0; i<n; i++) { 718d4bb536fSBarry Smith if (idx[i] < 0) continue; 719d4bb536fSBarry Smith if (idx[i] < start) continue; 720d4bb536fSBarry Smith if (idx[i] > end) continue; 721d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 722d4bb536fSBarry Smith if (tmp < 0) continue; 723d4bb536fSBarry Smith nf++; 724d4bb536fSBarry Smith } 725d4bb536fSBarry Smith } 726d4bb536fSBarry Smith if (nout) *nout = nf; 727d4bb536fSBarry Smith } 7283a40ed3dSBarry Smith PetscFunctionReturn(0); 729d4bb536fSBarry Smith } 73090f02eecSBarry Smith 7314a2ae208SSatish Balay #undef __FUNCT__ 7326a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo" 73389d82c54SBarry Smith /*@C 7346a818285SBarry Smith ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information for each processor and 73589d82c54SBarry Smith each index shared by more than one processor 73689d82c54SBarry Smith 73789d82c54SBarry Smith Collective on ISLocalToGlobalMapping 73889d82c54SBarry Smith 73989d82c54SBarry Smith Input Parameters: 74089d82c54SBarry Smith . mapping - the mapping from local to global indexing 74189d82c54SBarry Smith 74289d82c54SBarry Smith Output Parameter: 74389d82c54SBarry Smith + nproc - number of processors that are connected to this one 74489d82c54SBarry Smith . proc - neighboring processors 74507b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 7463463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 74789d82c54SBarry Smith 74889d82c54SBarry Smith Level: advanced 74989d82c54SBarry Smith 750273d9f13SBarry Smith Concepts: mapping^local to global 75189d82c54SBarry Smith 7522cfcea29SBarry Smith Fortran Usage: 7532cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 7542cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 7552cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 7562cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 7572cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 7582cfcea29SBarry Smith 7592cfcea29SBarry Smith 76007b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 76107b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 76289d82c54SBarry Smith @*/ 7636a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 76489d82c54SBarry Smith { 7656849ba73SBarry Smith PetscErrorCode ierr; 766268a049cSStefano Zampini 767268a049cSStefano Zampini PetscFunctionBegin; 768268a049cSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 769268a049cSStefano Zampini if (mapping->info_cached) { 770268a049cSStefano Zampini *nproc = mapping->info_nproc; 771268a049cSStefano Zampini *procs = mapping->info_procs; 772268a049cSStefano Zampini *numprocs = mapping->info_numprocs; 773268a049cSStefano Zampini *indices = mapping->info_indices; 774268a049cSStefano Zampini } else { 775268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo_Private(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 776268a049cSStefano Zampini } 777268a049cSStefano Zampini PetscFunctionReturn(0); 778268a049cSStefano Zampini } 779268a049cSStefano Zampini 780268a049cSStefano Zampini #undef __FUNCT__ 781268a049cSStefano Zampini #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo_Private" 782268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 783268a049cSStefano Zampini { 784268a049cSStefano Zampini PetscErrorCode ierr; 78597f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 78632dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 78732dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 78897f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 78932dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 79032dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 79189d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 79230dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 793ce94432eSBarry Smith MPI_Comm comm; 794ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 79589d82c54SBarry Smith 79689d82c54SBarry Smith PetscFunctionBegin; 797ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)mapping,&comm);CHKERRQ(ierr); 79824cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 79924cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 80024cf384cSBarry Smith if (size == 1) { 80124cf384cSBarry Smith *nproc = 0; 8020298fd71SBarry Smith *procs = NULL; 80395dccacaSBarry Smith ierr = PetscNew(numprocs);CHKERRQ(ierr); 8041e2105dcSBarry Smith (*numprocs)[0] = 0; 80595dccacaSBarry Smith ierr = PetscNew(indices);CHKERRQ(ierr); 8060298fd71SBarry Smith (*indices)[0] = NULL; 807268a049cSStefano Zampini /* save info for reuse */ 808268a049cSStefano Zampini mapping->info_nproc = *nproc; 809268a049cSStefano Zampini mapping->info_procs = *procs; 810268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 811268a049cSStefano Zampini mapping->info_indices = *indices; 812268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 81324cf384cSBarry Smith PetscFunctionReturn(0); 81424cf384cSBarry Smith } 81524cf384cSBarry Smith 816c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)mapping)->options,NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,NULL);CHKERRQ(ierr); 81707b52d57SBarry Smith 8183677ff5aSBarry Smith /* 8196a818285SBarry Smith Notes on ISLocalToGlobalMappingGetBlockInfo 8203677ff5aSBarry Smith 8213677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 8223677ff5aSBarry Smith numbering, just for this routine. 8233677ff5aSBarry Smith 8243677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 8253677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 8263677ff5aSBarry Smith 8273677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 8283677ff5aSBarry Smith 8293677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 8303677ff5aSBarry Smith local subdomain 8313677ff5aSBarry Smith */ 83224cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 83324cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 83424cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 83589d82c54SBarry Smith 83689d82c54SBarry Smith for (i=0; i<n; i++) { 83789d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 83889d82c54SBarry Smith } 839b2566f29SBarry Smith ierr = MPIU_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 84078058e43SBarry Smith Ng++; 84189d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 84289d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 843bc8ff85bSBarry Smith scale = Ng/size + 1; 844a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 845caba0dd0SBarry Smith rstart = scale*rank; 84689d82c54SBarry Smith 84789d82c54SBarry Smith /* determine ownership ranges of global indices */ 848785e854fSJed Brown ierr = PetscMalloc1(2*size,&nprocs);CHKERRQ(ierr); 84932dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 85089d82c54SBarry Smith 85189d82c54SBarry Smith /* determine owners of each local node */ 852785e854fSJed Brown ierr = PetscMalloc1(n,&owner);CHKERRQ(ierr); 85389d82c54SBarry Smith for (i=0; i<n; i++) { 8543677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 85527c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 8563677ff5aSBarry Smith owner[i] = proc; 85727c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 85889d82c54SBarry Smith } 85927c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 8607904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %D\n",nsends);CHKERRQ(ierr); 86189d82c54SBarry Smith 86289d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 86327c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 8647904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %D\n",nrecvs);CHKERRQ(ierr); 86589d82c54SBarry Smith 86689d82c54SBarry Smith /* post receives for owned rows */ 867785e854fSJed Brown ierr = PetscMalloc1((2*nrecvs+1)*(nmax+1),&recvs);CHKERRQ(ierr); 868854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&recv_waits);CHKERRQ(ierr); 86989d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 87032dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 87189d82c54SBarry Smith } 87289d82c54SBarry Smith 87389d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 874854ce69bSBarry Smith ierr = PetscMalloc1(2*n+1,&sends);CHKERRQ(ierr); 875854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&starts);CHKERRQ(ierr); 87689d82c54SBarry Smith starts[0] = 0; 877f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 87889d82c54SBarry Smith for (i=0; i<n; i++) { 87989d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 88030dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 88189d82c54SBarry Smith } 88289d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 88389d82c54SBarry Smith starts[0] = 0; 884f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 88589d82c54SBarry Smith 88689d82c54SBarry Smith /* send the messages */ 887854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&send_waits);CHKERRQ(ierr); 888854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&dest);CHKERRQ(ierr); 88989d82c54SBarry Smith cnt = 0; 89089d82c54SBarry Smith for (i=0; i<size; i++) { 89127c402fcSBarry Smith if (nprocs[2*i]) { 89232dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 89330dcb7c9SBarry Smith dest[cnt] = i; 89489d82c54SBarry Smith cnt++; 89589d82c54SBarry Smith } 89689d82c54SBarry Smith } 89789d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 89889d82c54SBarry Smith 89989d82c54SBarry Smith /* wait on receives */ 900854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&source);CHKERRQ(ierr); 901854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&len);CHKERRQ(ierr); 90289d82c54SBarry Smith cnt = nrecvs; 903854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&nownedsenders);CHKERRQ(ierr); 90432dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 90589d82c54SBarry Smith while (cnt) { 90689d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 90789d82c54SBarry Smith /* unpack receives into our local space */ 90832dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 90989d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 91030dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 911caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 91230dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 91389d82c54SBarry Smith cnt--; 91489d82c54SBarry Smith } 91589d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 91689d82c54SBarry Smith 91730dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 918bc8ff85bSBarry Smith nowned = 0; 919bc8ff85bSBarry Smith nownedm = 0; 920bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 921bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 922bc8ff85bSBarry Smith } 923bc8ff85bSBarry Smith 924bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 925854ce69bSBarry Smith ierr = PetscMalloc1(nownedm+1,&ownedsenders);CHKERRQ(ierr); 926854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&starts);CHKERRQ(ierr); 927bc8ff85bSBarry Smith starts[0] = 0; 928bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 929bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 930bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 931bc8ff85bSBarry Smith } 932bc8ff85bSBarry Smith 93330dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 934bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 935bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 93630dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 937f6e5521dSKarl Rupp if (nownedsenders[node] > 1) ownedsenders[starts[node]++] = source[i]; 938bc8ff85bSBarry Smith } 939bc8ff85bSBarry Smith } 940bc8ff85bSBarry Smith 94107b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 94230dcb7c9SBarry Smith starts[0] = 0; 94330dcb7c9SBarry Smith for (i=1; i<ng; i++) { 94430dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 94530dcb7c9SBarry Smith else starts[i] = starts[i-1]; 94630dcb7c9SBarry Smith } 94730dcb7c9SBarry Smith for (i=0; i<ng; i++) { 94830dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 9497904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %D local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 95030dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 9517904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 95230dcb7c9SBarry Smith } 95330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 95430dcb7c9SBarry Smith } 95530dcb7c9SBarry Smith } 9560ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 95707b52d57SBarry Smith } /* ----------------------------------- */ 95830dcb7c9SBarry Smith 9593677ff5aSBarry Smith /* wait on original sends */ 9603a96401aSBarry Smith if (nsends) { 961785e854fSJed Brown ierr = PetscMalloc1(nsends,&send_status);CHKERRQ(ierr); 9623a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 9633a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 9643a96401aSBarry Smith } 96589d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 9663a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 9673677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 9683677ff5aSBarry Smith 9693677ff5aSBarry Smith /* pack messages to send back to local owners */ 97030dcb7c9SBarry Smith starts[0] = 0; 97130dcb7c9SBarry Smith for (i=1; i<ng; i++) { 97230dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 97330dcb7c9SBarry Smith else starts[i] = starts[i-1]; 97430dcb7c9SBarry Smith } 97530dcb7c9SBarry Smith nsends2 = nrecvs; 976854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&nprocs);CHKERRQ(ierr); /* length of each message */ 97730dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 97830dcb7c9SBarry Smith nprocs[i] = 1; 97930dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 98030dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 981f6e5521dSKarl Rupp if (nownedsenders[node] > 1) nprocs[i] += 2 + nownedsenders[node]; 98230dcb7c9SBarry Smith } 98330dcb7c9SBarry Smith } 984f6e5521dSKarl Rupp nt = 0; 985f6e5521dSKarl Rupp for (i=0; i<nsends2; i++) nt += nprocs[i]; 986f6e5521dSKarl Rupp 987854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&sends2);CHKERRQ(ierr); 988854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&starts2);CHKERRQ(ierr); 989f6e5521dSKarl Rupp 990f6e5521dSKarl Rupp starts2[0] = 0; 991f6e5521dSKarl Rupp for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 99230dcb7c9SBarry Smith /* 99330dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 99430dcb7c9SBarry Smith (0) the number of nodes being sent back 99530dcb7c9SBarry Smith (1) the local node number, 99630dcb7c9SBarry Smith (2) the number of processors sharing it, 99730dcb7c9SBarry Smith (3) the processors sharing it 99830dcb7c9SBarry Smith */ 99930dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 100030dcb7c9SBarry Smith cnt = 1; 100130dcb7c9SBarry Smith sends2[starts2[i]] = 0; 100230dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 100330dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 100430dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 100530dcb7c9SBarry Smith sends2[starts2[i]]++; 100630dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 100730dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 100832dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 100930dcb7c9SBarry Smith cnt += nownedsenders[node]; 101030dcb7c9SBarry Smith } 101130dcb7c9SBarry Smith } 101230dcb7c9SBarry Smith } 101330dcb7c9SBarry Smith 101430dcb7c9SBarry Smith /* receive the message lengths */ 101530dcb7c9SBarry Smith nrecvs2 = nsends; 1016854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&lens2);CHKERRQ(ierr); 1017854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&starts3);CHKERRQ(ierr); 1018854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 101930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 1020d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 102130dcb7c9SBarry Smith } 1022d44834fbSBarry Smith 10238a8e0b3aSBarry Smith /* send the message lengths */ 10248a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 10258a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 10268a8e0b3aSBarry Smith } 10278a8e0b3aSBarry Smith 1028d44834fbSBarry Smith /* wait on receives of lens */ 10290c468ba9SBarry Smith if (nrecvs2) { 1030785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 1031d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 1032d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 10330c468ba9SBarry Smith } 1034a2ea699eSBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 1035d44834fbSBarry Smith 103630dcb7c9SBarry Smith starts3[0] = 0; 1037d44834fbSBarry Smith nt = 0; 103830dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 103930dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 1040d44834fbSBarry Smith nt += lens2[i]; 104130dcb7c9SBarry Smith } 104276466f69SStefano Zampini if (nrecvs2) nt += lens2[nrecvs2-1]; 1043d44834fbSBarry Smith 1044854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&recvs2);CHKERRQ(ierr); 1045854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 104652b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 104732dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 104830dcb7c9SBarry Smith } 104930dcb7c9SBarry Smith 105030dcb7c9SBarry Smith /* send the messages */ 1051854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&send_waits);CHKERRQ(ierr); 105230dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 105332dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 105430dcb7c9SBarry Smith } 105530dcb7c9SBarry Smith 105630dcb7c9SBarry Smith /* wait on receives */ 10570c468ba9SBarry Smith if (nrecvs2) { 1058785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 105930dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 106030dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 10610c468ba9SBarry Smith } 106230dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 106330dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 106430dcb7c9SBarry Smith 106507b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 106630dcb7c9SBarry Smith cnt = 0; 106730dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 106830dcb7c9SBarry Smith nt = recvs2[cnt++]; 106930dcb7c9SBarry Smith for (j=0; j<nt; j++) { 10707904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %D number of subdomains %D: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 107130dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 10727904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",recvs2[cnt+2+k]);CHKERRQ(ierr); 107330dcb7c9SBarry Smith } 107430dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 107530dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 107630dcb7c9SBarry Smith } 107730dcb7c9SBarry Smith } 10780ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 107907b52d57SBarry Smith } /* ----------------------------------- */ 108030dcb7c9SBarry Smith 108130dcb7c9SBarry Smith /* count number subdomains for each local node */ 1082785e854fSJed Brown ierr = PetscMalloc1(size,&nprocs);CHKERRQ(ierr); 108332dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 108430dcb7c9SBarry Smith cnt = 0; 108530dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 108630dcb7c9SBarry Smith nt = recvs2[cnt++]; 108730dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1088f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) nprocs[recvs2[cnt+2+k]]++; 108930dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 109030dcb7c9SBarry Smith } 109130dcb7c9SBarry Smith } 109230dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 109330dcb7c9SBarry Smith *nproc = nt; 1094854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,procs);CHKERRQ(ierr); 1095854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,numprocs);CHKERRQ(ierr); 1096854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,indices);CHKERRQ(ierr); 10970298fd71SBarry Smith for (i=0;i<nt+1;i++) (*indices)[i]=NULL; 1098785e854fSJed Brown ierr = PetscMalloc1(size,&bprocs);CHKERRQ(ierr); 109930dcb7c9SBarry Smith cnt = 0; 110030dcb7c9SBarry Smith for (i=0; i<size; i++) { 110130dcb7c9SBarry Smith if (nprocs[i] > 0) { 110230dcb7c9SBarry Smith bprocs[i] = cnt; 110330dcb7c9SBarry Smith (*procs)[cnt] = i; 110430dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 1105785e854fSJed Brown ierr = PetscMalloc1(nprocs[i],&(*indices)[cnt]);CHKERRQ(ierr); 110630dcb7c9SBarry Smith cnt++; 110730dcb7c9SBarry Smith } 110830dcb7c9SBarry Smith } 110930dcb7c9SBarry Smith 111030dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 111132dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 111230dcb7c9SBarry Smith cnt = 0; 111330dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 111430dcb7c9SBarry Smith nt = recvs2[cnt++]; 111530dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1116f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 111730dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 111830dcb7c9SBarry Smith } 111930dcb7c9SBarry Smith } 112030dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 112107b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 112230dcb7c9SBarry Smith 112307b52d57SBarry Smith /* sort the node indexing by their global numbers */ 112407b52d57SBarry Smith nt = *nproc; 112507b52d57SBarry Smith for (i=0; i<nt; i++) { 1126854ce69bSBarry Smith ierr = PetscMalloc1((*numprocs)[i],&tmp);CHKERRQ(ierr); 1127f6e5521dSKarl Rupp for (j=0; j<(*numprocs)[i]; j++) tmp[j] = lindices[(*indices)[i][j]]; 112807b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 112907b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 113007b52d57SBarry Smith } 113107b52d57SBarry Smith 113207b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 113330dcb7c9SBarry Smith nt = *nproc; 113430dcb7c9SBarry Smith for (i=0; i<nt; i++) { 11357904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %D number of indices %D: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 113630dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 11377904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",(*indices)[i][j]);CHKERRQ(ierr); 113830dcb7c9SBarry Smith } 113930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 114030dcb7c9SBarry Smith } 11410ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 114207b52d57SBarry Smith } /* ----------------------------------- */ 114330dcb7c9SBarry Smith 114430dcb7c9SBarry Smith /* wait on sends */ 114530dcb7c9SBarry Smith if (nsends2) { 1146785e854fSJed Brown ierr = PetscMalloc1(nsends2,&send_status);CHKERRQ(ierr); 114730dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 114830dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 114930dcb7c9SBarry Smith } 115030dcb7c9SBarry Smith 115130dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 115230dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 115330dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 11543677ff5aSBarry Smith 1155bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 1156bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 1157bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 115830dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 115930dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 116089d82c54SBarry Smith 116189d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 116297f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 116389d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 11643a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 116530dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 116624cf384cSBarry Smith 116724cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 116824cf384cSBarry Smith first_procs = (*procs)[0]; 116924cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 117024cf384cSBarry Smith first_indices = (*indices)[0]; 117124cf384cSBarry Smith for (i=0; i<*nproc; i++) { 117224cf384cSBarry Smith if ((*procs)[i] == rank) { 117324cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 117424cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 117524cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 117624cf384cSBarry Smith (*procs)[i] = first_procs; 117724cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 117824cf384cSBarry Smith (*indices)[i] = first_indices; 117924cf384cSBarry Smith break; 118024cf384cSBarry Smith } 118124cf384cSBarry Smith } 1182268a049cSStefano Zampini 1183268a049cSStefano Zampini /* save info for reuse */ 1184268a049cSStefano Zampini mapping->info_nproc = *nproc; 1185268a049cSStefano Zampini mapping->info_procs = *procs; 1186268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 1187268a049cSStefano Zampini mapping->info_indices = *indices; 1188268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 118989d82c54SBarry Smith PetscFunctionReturn(0); 119089d82c54SBarry Smith } 119189d82c54SBarry Smith 11924a2ae208SSatish Balay #undef __FUNCT__ 11936a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockInfo" 11946a818285SBarry Smith /*@C 11956a818285SBarry Smith ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by ISLocalToGlobalMappingGetBlockInfo() 11966a818285SBarry Smith 11976a818285SBarry Smith Collective on ISLocalToGlobalMapping 11986a818285SBarry Smith 11996a818285SBarry Smith Input Parameters: 12006a818285SBarry Smith . mapping - the mapping from local to global indexing 12016a818285SBarry Smith 12026a818285SBarry Smith Output Parameter: 12036a818285SBarry Smith + nproc - number of processors that are connected to this one 12046a818285SBarry Smith . proc - neighboring processors 12056a818285SBarry Smith . numproc - number of indices for each processor 12066a818285SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 12076a818285SBarry Smith 12086a818285SBarry Smith Level: advanced 12096a818285SBarry Smith 12106a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 12116a818285SBarry Smith ISLocalToGlobalMappingGetInfo() 12126a818285SBarry Smith @*/ 12136a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 12146a818285SBarry Smith { 12156a818285SBarry Smith PetscErrorCode ierr; 12166a818285SBarry Smith 12176a818285SBarry Smith PetscFunctionBegin; 1218cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1219268a049cSStefano Zampini if (mapping->info_free) { 12206a818285SBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 12216a818285SBarry Smith if (*indices) { 1222268a049cSStefano Zampini PetscInt i; 1223268a049cSStefano Zampini 12246a818285SBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 12256a818285SBarry Smith for (i=1; i<*nproc; i++) { 12266a818285SBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 12276a818285SBarry Smith } 12286a818285SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 12296a818285SBarry Smith } 1230268a049cSStefano Zampini } 1231268a049cSStefano Zampini *nproc = 0; 1232268a049cSStefano Zampini *procs = NULL; 1233268a049cSStefano Zampini *numprocs = NULL; 1234268a049cSStefano Zampini *indices = NULL; 12356a818285SBarry Smith PetscFunctionReturn(0); 12366a818285SBarry Smith } 12376a818285SBarry Smith 12386a818285SBarry Smith #undef __FUNCT__ 12396a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 12406a818285SBarry Smith /*@C 12416a818285SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 12426a818285SBarry Smith each index shared by more than one processor 12436a818285SBarry Smith 12446a818285SBarry Smith Collective on ISLocalToGlobalMapping 12456a818285SBarry Smith 12466a818285SBarry Smith Input Parameters: 12476a818285SBarry Smith . mapping - the mapping from local to global indexing 12486a818285SBarry Smith 12496a818285SBarry Smith Output Parameter: 12506a818285SBarry Smith + nproc - number of processors that are connected to this one 12516a818285SBarry Smith . proc - neighboring processors 12526a818285SBarry Smith . numproc - number of indices for each subdomain (processor) 12536a818285SBarry Smith - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 12546a818285SBarry Smith 12556a818285SBarry Smith Level: advanced 12566a818285SBarry Smith 12576a818285SBarry Smith Concepts: mapping^local to global 12586a818285SBarry Smith 12596a818285SBarry Smith Fortran Usage: 12606a818285SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 12616a818285SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 12626a818285SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 12636a818285SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 12646a818285SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 12656a818285SBarry Smith 12666a818285SBarry Smith 12676a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 12686a818285SBarry Smith ISLocalToGlobalMappingRestoreInfo() 12696a818285SBarry Smith @*/ 12706a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 12716a818285SBarry Smith { 12726a818285SBarry Smith PetscErrorCode ierr; 1273268a049cSStefano Zampini PetscInt **bindices = NULL,*bnumprocs = NULL,bs = mapping->bs,i,j,k; 12746a818285SBarry Smith 12756a818285SBarry Smith PetscFunctionBegin; 12766a818285SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1277268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo(mapping,nproc,procs,&bnumprocs,&bindices);CHKERRQ(ierr); 1278268a049cSStefano Zampini if (bs > 1) { /* we need to expand the cached info */ 1279732f65e3SBarry Smith ierr = PetscCalloc1(*nproc,&*indices);CHKERRQ(ierr); 1280268a049cSStefano Zampini ierr = PetscCalloc1(*nproc,&*numprocs);CHKERRQ(ierr); 12816a818285SBarry Smith for (i=0; i<*nproc; i++) { 1282268a049cSStefano Zampini ierr = PetscMalloc1(bs*bnumprocs[i],&(*indices)[i]);CHKERRQ(ierr); 1283268a049cSStefano Zampini for (j=0; j<bnumprocs[i]; j++) { 12846a818285SBarry Smith for (k=0; k<bs; k++) { 12856a818285SBarry Smith (*indices)[i][j*bs+k] = bs*bindices[i][j] + k; 12866a818285SBarry Smith } 12876a818285SBarry Smith } 1288268a049cSStefano Zampini (*numprocs)[i] = bnumprocs[i]*bs; 12896a818285SBarry Smith } 1290268a049cSStefano Zampini mapping->info_free = PETSC_TRUE; 1291268a049cSStefano Zampini } else { 1292268a049cSStefano Zampini *numprocs = bnumprocs; 1293268a049cSStefano Zampini *indices = bindices; 12946a818285SBarry Smith } 12956a818285SBarry Smith PetscFunctionReturn(0); 12966a818285SBarry Smith } 12976a818285SBarry Smith 12986a818285SBarry Smith #undef __FUNCT__ 12994a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 130007b52d57SBarry Smith /*@C 130107b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 130289d82c54SBarry Smith 130307b52d57SBarry Smith Collective on ISLocalToGlobalMapping 130407b52d57SBarry Smith 130507b52d57SBarry Smith Input Parameters: 130607b52d57SBarry Smith . mapping - the mapping from local to global indexing 130707b52d57SBarry Smith 130807b52d57SBarry Smith Output Parameter: 130907b52d57SBarry Smith + nproc - number of processors that are connected to this one 131007b52d57SBarry Smith . proc - neighboring processors 131107b52d57SBarry Smith . numproc - number of indices for each processor 131207b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 131307b52d57SBarry Smith 131407b52d57SBarry Smith Level: advanced 131507b52d57SBarry Smith 131607b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 131707b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 131807b52d57SBarry Smith @*/ 13197087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 132007b52d57SBarry Smith { 13216849ba73SBarry Smith PetscErrorCode ierr; 132207b52d57SBarry Smith 132307b52d57SBarry Smith PetscFunctionBegin; 13246a818285SBarry Smith ierr = ISLocalToGlobalMappingRestoreBlockInfo(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 132507b52d57SBarry Smith PetscFunctionReturn(0); 132607b52d57SBarry Smith } 132786994e45SJed Brown 132886994e45SJed Brown #undef __FUNCT__ 132986994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingGetIndices" 133086994e45SJed Brown /*@C 1331107e9a97SBarry Smith ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped 133286994e45SJed Brown 133386994e45SJed Brown Not Collective 133486994e45SJed Brown 133586994e45SJed Brown Input Arguments: 133686994e45SJed Brown . ltog - local to global mapping 133786994e45SJed Brown 133886994e45SJed Brown Output Arguments: 1339565245c5SBarry Smith . array - array of indices, the length of this array may be obtained with ISLocalToGlobalMappingGetSize() 134086994e45SJed Brown 134186994e45SJed Brown Level: advanced 134286994e45SJed Brown 1343107e9a97SBarry Smith Notes: ISLocalToGlobalMappingGetSize() returns the length the this array 1344107e9a97SBarry Smith 1345107e9a97SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreIndices(), ISLocalToGlobalMappingGetBlockIndices(), ISLocalToGlobalMappingRestoreBlockIndices() 134686994e45SJed Brown @*/ 13477087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 134886994e45SJed Brown { 134986994e45SJed Brown PetscFunctionBegin; 135086994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 135186994e45SJed Brown PetscValidPointer(array,2); 135245b6f7e9SBarry Smith if (ltog->bs == 1) { 135386994e45SJed Brown *array = ltog->indices; 135445b6f7e9SBarry Smith } else { 135545b6f7e9SBarry Smith PetscInt *jj,k,i,j,n = ltog->n, bs = ltog->bs; 135645b6f7e9SBarry Smith const PetscInt *ii; 135745b6f7e9SBarry Smith PetscErrorCode ierr; 135845b6f7e9SBarry Smith 135945b6f7e9SBarry Smith ierr = PetscMalloc1(bs*n,&jj);CHKERRQ(ierr); 136045b6f7e9SBarry Smith *array = jj; 136145b6f7e9SBarry Smith k = 0; 136245b6f7e9SBarry Smith ii = ltog->indices; 136345b6f7e9SBarry Smith for (i=0; i<n; i++) 136445b6f7e9SBarry Smith for (j=0; j<bs; j++) 136545b6f7e9SBarry Smith jj[k++] = bs*ii[i] + j; 136645b6f7e9SBarry Smith } 136786994e45SJed Brown PetscFunctionReturn(0); 136886994e45SJed Brown } 136986994e45SJed Brown 137086994e45SJed Brown #undef __FUNCT__ 137186994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingRestoreIndices" 137286994e45SJed Brown /*@C 1373*193a2b41SJulian Andrej ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with ISLocalToGlobalMappingGetIndices() 137486994e45SJed Brown 137586994e45SJed Brown Not Collective 137686994e45SJed Brown 137786994e45SJed Brown Input Arguments: 137886994e45SJed Brown + ltog - local to global mapping 137986994e45SJed Brown - array - array of indices 138086994e45SJed Brown 138186994e45SJed Brown Level: advanced 138286994e45SJed Brown 138386994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 138486994e45SJed Brown @*/ 13857087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 138686994e45SJed Brown { 138786994e45SJed Brown PetscFunctionBegin; 138886994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 138986994e45SJed Brown PetscValidPointer(array,2); 139045b6f7e9SBarry Smith if (ltog->bs == 1 && *array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 139145b6f7e9SBarry Smith 139245b6f7e9SBarry Smith if (ltog->bs > 1) { 139345b6f7e9SBarry Smith PetscErrorCode ierr; 139445b6f7e9SBarry Smith ierr = PetscFree(*(void**)array);CHKERRQ(ierr); 139545b6f7e9SBarry Smith } 139645b6f7e9SBarry Smith PetscFunctionReturn(0); 139745b6f7e9SBarry Smith } 139845b6f7e9SBarry Smith 139945b6f7e9SBarry Smith #undef __FUNCT__ 140045b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockIndices" 140145b6f7e9SBarry Smith /*@C 140245b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block 140345b6f7e9SBarry Smith 140445b6f7e9SBarry Smith Not Collective 140545b6f7e9SBarry Smith 140645b6f7e9SBarry Smith Input Arguments: 140745b6f7e9SBarry Smith . ltog - local to global mapping 140845b6f7e9SBarry Smith 140945b6f7e9SBarry Smith Output Arguments: 141045b6f7e9SBarry Smith . array - array of indices 141145b6f7e9SBarry Smith 141245b6f7e9SBarry Smith Level: advanced 141345b6f7e9SBarry Smith 141445b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreBlockIndices() 141545b6f7e9SBarry Smith @*/ 141645b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 141745b6f7e9SBarry Smith { 141845b6f7e9SBarry Smith PetscFunctionBegin; 141945b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 142045b6f7e9SBarry Smith PetscValidPointer(array,2); 142145b6f7e9SBarry Smith *array = ltog->indices; 142245b6f7e9SBarry Smith PetscFunctionReturn(0); 142345b6f7e9SBarry Smith } 142445b6f7e9SBarry Smith 142545b6f7e9SBarry Smith #undef __FUNCT__ 142645b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockIndices" 142745b6f7e9SBarry Smith /*@C 142845b6f7e9SBarry Smith ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with ISLocalToGlobalMappingGetBlockIndices() 142945b6f7e9SBarry Smith 143045b6f7e9SBarry Smith Not Collective 143145b6f7e9SBarry Smith 143245b6f7e9SBarry Smith Input Arguments: 143345b6f7e9SBarry Smith + ltog - local to global mapping 143445b6f7e9SBarry Smith - array - array of indices 143545b6f7e9SBarry Smith 143645b6f7e9SBarry Smith Level: advanced 143745b6f7e9SBarry Smith 143845b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 143945b6f7e9SBarry Smith @*/ 144045b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 144145b6f7e9SBarry Smith { 144245b6f7e9SBarry Smith PetscFunctionBegin; 144345b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 144445b6f7e9SBarry Smith PetscValidPointer(array,2); 144586994e45SJed Brown if (*array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 14460298fd71SBarry Smith *array = NULL; 144786994e45SJed Brown PetscFunctionReturn(0); 144886994e45SJed Brown } 1449f7efa3c7SJed Brown 1450f7efa3c7SJed Brown #undef __FUNCT__ 1451f7efa3c7SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingConcatenate" 1452f7efa3c7SJed Brown /*@C 1453f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1454f7efa3c7SJed Brown 1455f7efa3c7SJed Brown Not Collective 1456f7efa3c7SJed Brown 1457f7efa3c7SJed Brown Input Arguments: 1458f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1459f7efa3c7SJed Brown . n - number of mappings to concatenate 1460f7efa3c7SJed Brown - ltogs - local to global mappings 1461f7efa3c7SJed Brown 1462f7efa3c7SJed Brown Output Arguments: 1463f7efa3c7SJed Brown . ltogcat - new mapping 1464f7efa3c7SJed Brown 14659d90f715SBarry Smith Note: this currently always returns a mapping with block size of 1 14669d90f715SBarry Smith 14679d90f715SBarry Smith Developer Note: If all the input mapping have the same block size we could easily handle that as a special case 14689d90f715SBarry Smith 1469f7efa3c7SJed Brown Level: advanced 1470f7efa3c7SJed Brown 1471f7efa3c7SJed Brown .seealso: ISLocalToGlobalMappingCreate() 1472f7efa3c7SJed Brown @*/ 1473f7efa3c7SJed Brown PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping *ltogcat) 1474f7efa3c7SJed Brown { 1475f7efa3c7SJed Brown PetscInt i,cnt,m,*idx; 1476f7efa3c7SJed Brown PetscErrorCode ierr; 1477f7efa3c7SJed Brown 1478f7efa3c7SJed Brown PetscFunctionBegin; 1479f7efa3c7SJed Brown if (n < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have a non-negative number of mappings, given %D",n); 1480f7efa3c7SJed Brown if (n > 0) PetscValidPointer(ltogs,3); 1481f7efa3c7SJed Brown for (i=0; i<n; i++) PetscValidHeaderSpecific(ltogs[i],IS_LTOGM_CLASSID,3); 1482f7efa3c7SJed Brown PetscValidPointer(ltogcat,4); 1483f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1484f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1485f7efa3c7SJed Brown cnt += m; 1486f7efa3c7SJed Brown } 1487785e854fSJed Brown ierr = PetscMalloc1(cnt,&idx);CHKERRQ(ierr); 1488f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1489f7efa3c7SJed Brown const PetscInt *subidx; 1490f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1491f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1492f7efa3c7SJed Brown ierr = PetscMemcpy(&idx[cnt],subidx,m*sizeof(PetscInt));CHKERRQ(ierr); 1493f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1494f7efa3c7SJed Brown cnt += m; 1495f7efa3c7SJed Brown } 1496f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,cnt,idx,PETSC_OWN_POINTER,ltogcat);CHKERRQ(ierr); 1497f7efa3c7SJed Brown PetscFunctionReturn(0); 1498f7efa3c7SJed Brown } 149904a59952SBarry Smith 150004a59952SBarry Smith 1501