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; 7*268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping,PetscInt*,PetscInt**,PetscInt**,PetscInt***); 88e58c17dSMatthew Knepley 904a59952SBarry Smith 104a2ae208SSatish Balay #undef __FUNCT__ 11743c9b42SStefano Zampini #define __FUNCT__ "ISG2LMapApply" 12186d4ecdSBarry Smith PetscErrorCode ISG2LMapApply(ISLocalToGlobalMapping mapping,PetscInt n,const PetscInt in[],PetscInt out[]) 13186d4ecdSBarry Smith { 14186d4ecdSBarry Smith PetscErrorCode ierr; 15743c9b42SStefano Zampini PetscInt i,start,end; 16186d4ecdSBarry Smith 17186d4ecdSBarry Smith PetscFunctionBegin; 18186d4ecdSBarry Smith if (!mapping->globals) { 19186d4ecdSBarry Smith ierr = ISGlobalToLocalMappingApply(mapping,IS_GTOLM_MASK,0,0,0,0);CHKERRQ(ierr); 20186d4ecdSBarry Smith } 21743c9b42SStefano Zampini start = mapping->globalstart; 22743c9b42SStefano Zampini end = mapping->globalend; 23186d4ecdSBarry Smith for (i=0; i<n; i++) { 24186d4ecdSBarry Smith if (in[i] < 0) out[i] = in[i]; 25186d4ecdSBarry Smith else if (in[i] < start) out[i] = -1; 26186d4ecdSBarry Smith else if (in[i] > end) out[i] = -1; 27743c9b42SStefano Zampini else out[i] = mapping->globals[in[i] - start]; 28186d4ecdSBarry Smith } 29186d4ecdSBarry Smith PetscFunctionReturn(0); 30186d4ecdSBarry Smith } 31186d4ecdSBarry Smith 32186d4ecdSBarry Smith 33186d4ecdSBarry Smith #undef __FUNCT__ 344a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize" 35565245c5SBarry Smith /*@ 36107e9a97SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping 373b9aefa3SBarry Smith 383b9aefa3SBarry Smith Not Collective 393b9aefa3SBarry Smith 403b9aefa3SBarry Smith Input Parameter: 413b9aefa3SBarry Smith . ltog - local to global mapping 423b9aefa3SBarry Smith 433b9aefa3SBarry Smith Output Parameter: 44107e9a97SBarry Smith . n - the number of entries in the local mapping, ISLocalToGlobalMappingGetIndices() returns an array of this length 453b9aefa3SBarry Smith 463b9aefa3SBarry Smith Level: advanced 473b9aefa3SBarry Smith 48273d9f13SBarry Smith Concepts: mapping^local to global 493b9aefa3SBarry Smith 503b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 513b9aefa3SBarry Smith @*/ 527087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n) 533b9aefa3SBarry Smith { 543b9aefa3SBarry Smith PetscFunctionBegin; 550700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 564482741eSBarry Smith PetscValidIntPointer(n,2); 57107e9a97SBarry Smith *n = mapping->bs*mapping->n; 583b9aefa3SBarry Smith PetscFunctionReturn(0); 593b9aefa3SBarry Smith } 603b9aefa3SBarry Smith 614a2ae208SSatish Balay #undef __FUNCT__ 624a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 635a5d4f66SBarry Smith /*@C 645a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 655a5d4f66SBarry Smith 66b9cd556bSLois Curfman McInnes Not Collective 67b9cd556bSLois Curfman McInnes 685a5d4f66SBarry Smith Input Parameters: 693b9aefa3SBarry Smith + ltog - local to global mapping 703b9aefa3SBarry Smith - viewer - viewer 715a5d4f66SBarry Smith 72a997ad1aSLois Curfman McInnes Level: advanced 73a997ad1aSLois Curfman McInnes 74273d9f13SBarry Smith Concepts: mapping^local to global 755a5d4f66SBarry Smith 765a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 775a5d4f66SBarry Smith @*/ 787087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 795a5d4f66SBarry Smith { 8032dcc486SBarry Smith PetscInt i; 8132dcc486SBarry Smith PetscMPIInt rank; 82ace3abfcSBarry Smith PetscBool iascii; 836849ba73SBarry Smith PetscErrorCode ierr; 845a5d4f66SBarry Smith 855a5d4f66SBarry Smith PetscFunctionBegin; 860700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 873050cee2SBarry Smith if (!viewer) { 88ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mapping),&viewer);CHKERRQ(ierr); 893050cee2SBarry Smith } 900700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 915a5d4f66SBarry Smith 92ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mapping),&rank);CHKERRQ(ierr); 93251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 9432077d6dSBarry Smith if (iascii) { 9598c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mapping,viewer);CHKERRQ(ierr); 967b23a99aSBarry Smith ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 975a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 987904a332SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %D %D\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 996831982aSBarry Smith } 100b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1017b23a99aSBarry Smith ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 1027b23a99aSBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 1035a5d4f66SBarry Smith PetscFunctionReturn(0); 1045a5d4f66SBarry Smith } 1055a5d4f66SBarry Smith 1064a2ae208SSatish Balay #undef __FUNCT__ 1074a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 1081f428162SBarry Smith /*@ 1092bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 1102bdab257SBarry Smith ordering and a global parallel ordering. 1112bdab257SBarry Smith 1120f5bd95cSBarry Smith Not collective 113b9cd556bSLois Curfman McInnes 114a997ad1aSLois Curfman McInnes Input Parameter: 1158c03b21aSDmitry Karpeev . is - index set containing the global numbers for each local number 1162bdab257SBarry Smith 117a997ad1aSLois Curfman McInnes Output Parameter: 1182bdab257SBarry Smith . mapping - new mapping data structure 1192bdab257SBarry Smith 120f0413b6fSBarry Smith Notes: the block size of the IS determines the block size of the mapping 121a997ad1aSLois Curfman McInnes Level: advanced 122a997ad1aSLois Curfman McInnes 123273d9f13SBarry Smith Concepts: mapping^local to global 1242bdab257SBarry Smith 1252bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 1262bdab257SBarry Smith @*/ 1277087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 1282bdab257SBarry Smith { 1296849ba73SBarry Smith PetscErrorCode ierr; 1303bbf0e92SBarry Smith PetscInt n,bs; 1315d0c19d7SBarry Smith const PetscInt *indices; 1322bdab257SBarry Smith MPI_Comm comm; 1333bbf0e92SBarry Smith PetscBool isblock; 1343a40ed3dSBarry Smith 1353a40ed3dSBarry Smith PetscFunctionBegin; 1360700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,1); 1374482741eSBarry Smith PetscValidPointer(mapping,2); 1382bdab257SBarry Smith 1392bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1403b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1413bbf0e92SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)is,ISBLOCK,&isblock);CHKERRQ(ierr); 1426006e8d2SBarry Smith if (!isblock) { 143f0413b6fSBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 144f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,n,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 1452bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1466006e8d2SBarry Smith } else { 1476006e8d2SBarry Smith ierr = ISGetBlockSize(is,&bs);CHKERRQ(ierr); 148f0413b6fSBarry Smith ierr = ISBlockGetIndices(is,&indices);CHKERRQ(ierr); 14928bc9809SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,bs,n/bs,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 150f0413b6fSBarry Smith ierr = ISBlockRestoreIndices(is,&indices);CHKERRQ(ierr); 1516006e8d2SBarry Smith } 1523a40ed3dSBarry Smith PetscFunctionReturn(0); 1532bdab257SBarry Smith } 1545a5d4f66SBarry Smith 155a4d96a55SJed Brown #undef __FUNCT__ 156a4d96a55SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingCreateSF" 157a4d96a55SJed Brown /*@C 158a4d96a55SJed Brown ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n) 159a4d96a55SJed Brown ordering and a global parallel ordering. 160a4d96a55SJed Brown 161a4d96a55SJed Brown Collective 162a4d96a55SJed Brown 163a4d96a55SJed Brown Input Parameter: 164a4d96a55SJed Brown + sf - star forest mapping contiguous local indices to (rank, offset) 165a4d96a55SJed Brown - start - first global index on this process 166a4d96a55SJed Brown 167a4d96a55SJed Brown Output Parameter: 168a4d96a55SJed Brown . mapping - new mapping data structure 169a4d96a55SJed Brown 170a4d96a55SJed Brown Level: advanced 171a4d96a55SJed Brown 172a4d96a55SJed Brown Concepts: mapping^local to global 173a4d96a55SJed Brown 174a4d96a55SJed Brown .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 175a4d96a55SJed Brown @*/ 176a4d96a55SJed Brown PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf,PetscInt start,ISLocalToGlobalMapping *mapping) 177a4d96a55SJed Brown { 178a4d96a55SJed Brown PetscErrorCode ierr; 179a4d96a55SJed Brown PetscInt i,maxlocal,nroots,nleaves,*globals,*ltog; 180a4d96a55SJed Brown const PetscInt *ilocal; 181a4d96a55SJed Brown MPI_Comm comm; 182a4d96a55SJed Brown 183a4d96a55SJed Brown PetscFunctionBegin; 184a4d96a55SJed Brown PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 185a4d96a55SJed Brown PetscValidPointer(mapping,3); 186a4d96a55SJed Brown 187a4d96a55SJed Brown ierr = PetscObjectGetComm((PetscObject)sf,&comm);CHKERRQ(ierr); 1880298fd71SBarry Smith ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,NULL);CHKERRQ(ierr); 189f6e5521dSKarl Rupp if (ilocal) { 190f6e5521dSKarl Rupp for (i=0,maxlocal=0; i<nleaves; i++) maxlocal = PetscMax(maxlocal,ilocal[i]+1); 191f6e5521dSKarl Rupp } 192a4d96a55SJed Brown else maxlocal = nleaves; 193785e854fSJed Brown ierr = PetscMalloc1(nroots,&globals);CHKERRQ(ierr); 194785e854fSJed Brown ierr = PetscMalloc1(maxlocal,<og);CHKERRQ(ierr); 195a4d96a55SJed Brown for (i=0; i<nroots; i++) globals[i] = start + i; 196a4d96a55SJed Brown for (i=0; i<maxlocal; i++) ltog[i] = -1; 197a4d96a55SJed Brown ierr = PetscSFBcastBegin(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 198a4d96a55SJed Brown ierr = PetscSFBcastEnd(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 199f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,maxlocal,ltog,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 200a4d96a55SJed Brown ierr = PetscFree(globals);CHKERRQ(ierr); 201a4d96a55SJed Brown PetscFunctionReturn(0); 202a4d96a55SJed Brown } 203b46b645bSBarry Smith 2044a2ae208SSatish Balay #undef __FUNCT__ 20545b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockSize" 20645b6f7e9SBarry Smith /*@ 20745b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping 20845b6f7e9SBarry Smith ordering and a global parallel ordering. 20945b6f7e9SBarry Smith 21045b6f7e9SBarry Smith Not Collective 21145b6f7e9SBarry Smith 21245b6f7e9SBarry Smith Input Parameters: 21345b6f7e9SBarry Smith . mapping - mapping data structure 21445b6f7e9SBarry Smith 21545b6f7e9SBarry Smith Output Parameter: 21645b6f7e9SBarry Smith . bs - the blocksize 21745b6f7e9SBarry Smith 21845b6f7e9SBarry Smith Level: advanced 21945b6f7e9SBarry Smith 22045b6f7e9SBarry Smith Concepts: mapping^local to global 22145b6f7e9SBarry Smith 22245b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 22345b6f7e9SBarry Smith @*/ 22445b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping,PetscInt *bs) 22545b6f7e9SBarry Smith { 22645b6f7e9SBarry Smith PetscFunctionBegin; 227cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 22845b6f7e9SBarry Smith *bs = mapping->bs; 22945b6f7e9SBarry Smith PetscFunctionReturn(0); 23045b6f7e9SBarry Smith } 23145b6f7e9SBarry Smith 23245b6f7e9SBarry Smith #undef __FUNCT__ 2334a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 234ba5bb76aSSatish Balay /*@ 23590f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 23690f02eecSBarry Smith ordering and a global parallel ordering. 2372362add9SBarry Smith 23889d82c54SBarry Smith Not Collective, but communicator may have more than one process 239b9cd556bSLois Curfman McInnes 2402362add9SBarry Smith Input Parameters: 24189d82c54SBarry Smith + comm - MPI communicator 242f0413b6fSBarry Smith . bs - the block size 24328bc9809SBarry Smith . n - the number of local elements divided by the block size, or equivalently the number of block indices 24428bc9809SBarry 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 245d5ad8652SBarry Smith - mode - see PetscCopyMode 2462362add9SBarry Smith 247a997ad1aSLois Curfman McInnes Output Parameter: 24890f02eecSBarry Smith . mapping - new mapping data structure 2492362add9SBarry Smith 250f0413b6fSBarry 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 251a997ad1aSLois Curfman McInnes Level: advanced 252a997ad1aSLois Curfman McInnes 253273d9f13SBarry Smith Concepts: mapping^local to global 2542362add9SBarry Smith 255d5ad8652SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 2562362add9SBarry Smith @*/ 257f0413b6fSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm cm,PetscInt bs,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 2582362add9SBarry Smith { 2596849ba73SBarry Smith PetscErrorCode ierr; 26032dcc486SBarry Smith PetscInt *in; 261b46b645bSBarry Smith 262b46b645bSBarry Smith PetscFunctionBegin; 26373911063SBarry Smith if (n) PetscValidIntPointer(indices,3); 2644482741eSBarry Smith PetscValidPointer(mapping,4); 265b46b645bSBarry Smith 2660298fd71SBarry Smith *mapping = NULL; 267607a6623SBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 2682362add9SBarry Smith 26973107ff1SLisandro Dalcin ierr = PetscHeaderCreate(*mapping,IS_LTOGM_CLASSID,"ISLocalToGlobalMapping","Local to global mapping","IS", 27052e6d16bSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 271d4bb536fSBarry Smith (*mapping)->n = n; 272f0413b6fSBarry Smith (*mapping)->bs = bs; 273*268a049cSStefano Zampini (*mapping)->info_cached = PETSC_FALSE; 274*268a049cSStefano Zampini (*mapping)->info_free = PETSC_FALSE; 275*268a049cSStefano Zampini (*mapping)->info_procs = NULL; 276*268a049cSStefano Zampini (*mapping)->info_numprocs = NULL; 277*268a049cSStefano Zampini (*mapping)->info_indices = NULL; 278d4bb536fSBarry Smith /* 279d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 280d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 281d4bb536fSBarry Smith */ 282d4bb536fSBarry Smith (*mapping)->globals = 0; 283d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 284785e854fSJed Brown ierr = PetscMalloc1(n,&in);CHKERRQ(ierr); 285d5ad8652SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 286d5ad8652SBarry Smith (*mapping)->indices = in; 2876389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 2886389a1a1SBarry Smith } else if (mode == PETSC_OWN_POINTER) { 2896389a1a1SBarry Smith (*mapping)->indices = (PetscInt*)indices; 2906389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 2916389a1a1SBarry Smith } 292f6e5521dSKarl Rupp else SETERRQ(cm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 293d96308ebSBarry Smith ierr = PetscStrallocpy("basic",&((PetscObject)*mapping)->type_name);CHKERRQ(ierr); 2943a40ed3dSBarry Smith PetscFunctionReturn(0); 2952362add9SBarry Smith } 2962362add9SBarry Smith 2974a2ae208SSatish Balay #undef __FUNCT__ 2984a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 29990f02eecSBarry Smith /*@ 30090f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 30190f02eecSBarry Smith ordering and a global parallel ordering. 30290f02eecSBarry Smith 3030f5bd95cSBarry Smith Note Collective 304b9cd556bSLois Curfman McInnes 30590f02eecSBarry Smith Input Parameters: 30690f02eecSBarry Smith . mapping - mapping data structure 30790f02eecSBarry Smith 308a997ad1aSLois Curfman McInnes Level: advanced 309a997ad1aSLois Curfman McInnes 3103acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 31190f02eecSBarry Smith @*/ 3126bf464f9SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 31390f02eecSBarry Smith { 314dfbe8321SBarry Smith PetscErrorCode ierr; 3155fd66863SKarl Rupp 3163a40ed3dSBarry Smith PetscFunctionBegin; 3176bf464f9SBarry Smith if (!*mapping) PetscFunctionReturn(0); 3186bf464f9SBarry Smith PetscValidHeaderSpecific((*mapping),IS_LTOGM_CLASSID,1); 319997056adSBarry Smith if (--((PetscObject)(*mapping))->refct > 0) {*mapping = 0;PetscFunctionReturn(0);} 3206bf464f9SBarry Smith ierr = PetscFree((*mapping)->indices);CHKERRQ(ierr); 3216bf464f9SBarry Smith ierr = PetscFree((*mapping)->globals);CHKERRQ(ierr); 322*268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_procs);CHKERRQ(ierr); 323*268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_numprocs);CHKERRQ(ierr); 324*268a049cSStefano Zampini if ((*mapping)->info_indices) { 325*268a049cSStefano Zampini PetscInt i; 326*268a049cSStefano Zampini 327*268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[0]);CHKERRQ(ierr); 328*268a049cSStefano Zampini for (i=1; i<(*mapping)->info_nproc; i++) { 329*268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[i]);CHKERRQ(ierr); 330*268a049cSStefano Zampini } 331*268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_indices);CHKERRQ(ierr); 332*268a049cSStefano Zampini } 333d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 334992144d0SBarry Smith *mapping = 0; 3353a40ed3dSBarry Smith PetscFunctionReturn(0); 33690f02eecSBarry Smith } 33790f02eecSBarry Smith 3384a2ae208SSatish Balay #undef __FUNCT__ 3394a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 34090f02eecSBarry Smith /*@ 3413acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 3423acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 3433acfe500SLois Curfman McInnes context. 34490f02eecSBarry Smith 345b9cd556bSLois Curfman McInnes Not collective 346b9cd556bSLois Curfman McInnes 34790f02eecSBarry Smith Input Parameters: 348b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 349b9cd556bSLois Curfman McInnes - is - index set in local numbering 35090f02eecSBarry Smith 35190f02eecSBarry Smith Output Parameters: 35290f02eecSBarry Smith . newis - index set in global numbering 35390f02eecSBarry Smith 354a997ad1aSLois Curfman McInnes Level: advanced 355a997ad1aSLois Curfman McInnes 356273d9f13SBarry Smith Concepts: mapping^local to global 3573acfe500SLois Curfman McInnes 35890f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 359d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 36090f02eecSBarry Smith @*/ 3617087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 36290f02eecSBarry Smith { 3636849ba73SBarry Smith PetscErrorCode ierr; 364e24637baSBarry Smith PetscInt n,*idxout; 3655d0c19d7SBarry Smith const PetscInt *idxin; 3663a40ed3dSBarry Smith 3673a40ed3dSBarry Smith PetscFunctionBegin; 3680700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 3690700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 3704482741eSBarry Smith PetscValidPointer(newis,3); 37190f02eecSBarry Smith 3723b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 37390f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 374785e854fSJed Brown ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 375e24637baSBarry Smith ierr = ISLocalToGlobalMappingApply(mapping,n,idxin,idxout);CHKERRQ(ierr); 3763b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 377543f3098SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 3783a40ed3dSBarry Smith PetscFunctionReturn(0); 37990f02eecSBarry Smith } 38090f02eecSBarry Smith 381afcb2eb5SJed Brown #undef __FUNCT__ 382afcb2eb5SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingApply" 383b89cb25eSSatish Balay /*@ 3843acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 3853acfe500SLois Curfman McInnes and converts them to the global numbering. 38690f02eecSBarry Smith 387b9cd556bSLois Curfman McInnes Not collective 388b9cd556bSLois Curfman McInnes 389bb25748dSBarry Smith Input Parameters: 390b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 391bb25748dSBarry Smith . N - number of integers 392b9cd556bSLois Curfman McInnes - in - input indices in local numbering 393bb25748dSBarry Smith 394bb25748dSBarry Smith Output Parameter: 395bb25748dSBarry Smith . out - indices in global numbering 396bb25748dSBarry Smith 397b9cd556bSLois Curfman McInnes Notes: 398b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 399d4bb536fSBarry Smith 400a997ad1aSLois Curfman McInnes Level: advanced 401a997ad1aSLois Curfman McInnes 40245b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApplyBlock(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 4030752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 404d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 405bb25748dSBarry Smith 406273d9f13SBarry Smith Concepts: mapping^local to global 407afcb2eb5SJed Brown @*/ 408afcb2eb5SJed Brown PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 409afcb2eb5SJed Brown { 410cbc1caf0SMatthew G. Knepley PetscInt i,bs,Nmax; 41145b6f7e9SBarry Smith 41245b6f7e9SBarry Smith PetscFunctionBegin; 413cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 414cbc1caf0SMatthew G. Knepley bs = mapping->bs; 415cbc1caf0SMatthew G. Knepley Nmax = bs*mapping->n; 41645b6f7e9SBarry Smith if (bs == 1) { 417cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 41845b6f7e9SBarry Smith for (i=0; i<N; i++) { 41945b6f7e9SBarry Smith if (in[i] < 0) { 42045b6f7e9SBarry Smith out[i] = in[i]; 42145b6f7e9SBarry Smith continue; 42245b6f7e9SBarry Smith } 423e24637baSBarry 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); 42445b6f7e9SBarry Smith out[i] = idx[in[i]]; 42545b6f7e9SBarry Smith } 42645b6f7e9SBarry Smith } else { 427cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 42845b6f7e9SBarry Smith for (i=0; i<N; i++) { 42945b6f7e9SBarry Smith if (in[i] < 0) { 43045b6f7e9SBarry Smith out[i] = in[i]; 43145b6f7e9SBarry Smith continue; 43245b6f7e9SBarry Smith } 433e24637baSBarry 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); 43445b6f7e9SBarry Smith out[i] = idx[in[i]/bs]*bs + (in[i] % bs); 43545b6f7e9SBarry Smith } 43645b6f7e9SBarry Smith } 43745b6f7e9SBarry Smith PetscFunctionReturn(0); 43845b6f7e9SBarry Smith } 43945b6f7e9SBarry Smith 44045b6f7e9SBarry Smith #undef __FUNCT__ 44145b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingApplyBlock" 44245b6f7e9SBarry Smith /*@ 4436006e8d2SBarry Smith ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering 44445b6f7e9SBarry Smith 44545b6f7e9SBarry Smith Not collective 44645b6f7e9SBarry Smith 44745b6f7e9SBarry Smith Input Parameters: 44845b6f7e9SBarry Smith + mapping - the local to global mapping context 44945b6f7e9SBarry Smith . N - number of integers 4506006e8d2SBarry Smith - in - input indices in local block numbering 45145b6f7e9SBarry Smith 45245b6f7e9SBarry Smith Output Parameter: 4536006e8d2SBarry Smith . out - indices in global block numbering 45445b6f7e9SBarry Smith 45545b6f7e9SBarry Smith Notes: 45645b6f7e9SBarry Smith The in and out array parameters may be identical. 45745b6f7e9SBarry Smith 4586006e8d2SBarry Smith Example: 4596006e8d2SBarry 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 4606006e8d2SBarry Smith (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3. 4616006e8d2SBarry Smith 46245b6f7e9SBarry Smith Level: advanced 46345b6f7e9SBarry Smith 46445b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 46545b6f7e9SBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 46645b6f7e9SBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 46745b6f7e9SBarry Smith 46845b6f7e9SBarry Smith Concepts: mapping^local to global 46945b6f7e9SBarry Smith @*/ 47045b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 47145b6f7e9SBarry Smith { 472cbc1caf0SMatthew G. Knepley 473cbc1caf0SMatthew G. Knepley PetscFunctionBegin; 474cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 475cbc1caf0SMatthew G. Knepley { 476afcb2eb5SJed Brown PetscInt i,Nmax = mapping->n; 477afcb2eb5SJed Brown const PetscInt *idx = mapping->indices; 478d4bb536fSBarry Smith 479afcb2eb5SJed Brown for (i=0; i<N; i++) { 480afcb2eb5SJed Brown if (in[i] < 0) { 481afcb2eb5SJed Brown out[i] = in[i]; 482afcb2eb5SJed Brown continue; 483afcb2eb5SJed Brown } 484e24637baSBarry 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); 485afcb2eb5SJed Brown out[i] = idx[in[i]]; 486afcb2eb5SJed Brown } 487cbc1caf0SMatthew G. Knepley } 488afcb2eb5SJed Brown PetscFunctionReturn(0); 489afcb2eb5SJed Brown } 490d4bb536fSBarry Smith 491d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 492d4bb536fSBarry Smith 4934a2ae208SSatish Balay #undef __FUNCT__ 4944a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 495d4bb536fSBarry Smith /* 496d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 497d4bb536fSBarry Smith */ 4986849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 499d4bb536fSBarry Smith { 5006849ba73SBarry Smith PetscErrorCode ierr; 50132dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 502d4bb536fSBarry Smith 5033a40ed3dSBarry Smith PetscFunctionBegin; 504d4bb536fSBarry Smith end = 0; 505ec268f7cSJed Brown start = PETSC_MAX_INT; 506d4bb536fSBarry Smith 507d4bb536fSBarry Smith for (i=0; i<n; i++) { 508d4bb536fSBarry Smith if (idx[i] < 0) continue; 509d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 510d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 511d4bb536fSBarry Smith } 512d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 513d4bb536fSBarry Smith mapping->globalstart = start; 514d4bb536fSBarry Smith mapping->globalend = end; 515d4bb536fSBarry Smith 516854ce69bSBarry Smith ierr = PetscMalloc1(end-start+2,&globals);CHKERRQ(ierr); 517b0a32e0cSBarry Smith mapping->globals = globals; 518f6e5521dSKarl Rupp for (i=0; i<end-start+1; i++) globals[i] = -1; 519d4bb536fSBarry Smith for (i=0; i<n; i++) { 520d4bb536fSBarry Smith if (idx[i] < 0) continue; 521d4bb536fSBarry Smith globals[idx[i] - start] = i; 522d4bb536fSBarry Smith } 523d4bb536fSBarry Smith 5243bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 5253a40ed3dSBarry Smith PetscFunctionReturn(0); 526d4bb536fSBarry Smith } 527d4bb536fSBarry Smith 5284a2ae208SSatish Balay #undef __FUNCT__ 5294a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 530d4bb536fSBarry Smith /*@ 531a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 532a997ad1aSLois Curfman McInnes specified with a global numbering. 533d4bb536fSBarry Smith 534b9cd556bSLois Curfman McInnes Not collective 535b9cd556bSLois Curfman McInnes 536d4bb536fSBarry Smith Input Parameters: 537b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 538d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 539d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 540d4bb536fSBarry Smith . n - number of global indices to map 541b9cd556bSLois Curfman McInnes - idx - global indices to map 542d4bb536fSBarry Smith 543d4bb536fSBarry Smith Output Parameters: 544b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 545b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 546e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 5470298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 548e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 549e182c471SBarry Smith a second time to set the values. 550d4bb536fSBarry Smith 551b9cd556bSLois Curfman McInnes Notes: 5520298fd71SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 553d4bb536fSBarry Smith 5540f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 5550f5bd95cSBarry Smith array to compute these. 5560f5bd95cSBarry Smith 557a997ad1aSLois Curfman McInnes Level: advanced 558a997ad1aSLois Curfman McInnes 55932fd6b96SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 56032fd6b96SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 56132fd6b96SBarry Smith 562273d9f13SBarry Smith Concepts: mapping^global to local 563d4bb536fSBarry Smith 5649d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApplyBlock(), ISLocalToGlobalMappingCreate(), 565d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 566d4bb536fSBarry Smith @*/ 5677087cfbeSBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 56832dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 569d4bb536fSBarry Smith { 5709d90f715SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end,bs; 5719d90f715SBarry Smith PetscErrorCode ierr; 5729d90f715SBarry Smith 5739d90f715SBarry Smith PetscFunctionBegin; 5749d90f715SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 5759d90f715SBarry Smith if (!mapping->globals) { 5769d90f715SBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 5779d90f715SBarry Smith } 5789d90f715SBarry Smith globals = mapping->globals; 5799d90f715SBarry Smith start = mapping->globalstart; 5809d90f715SBarry Smith end = mapping->globalend; 5819d90f715SBarry Smith bs = mapping->bs; 5829d90f715SBarry Smith 5839d90f715SBarry Smith if (type == IS_GTOLM_MASK) { 5849d90f715SBarry Smith if (idxout) { 5859d90f715SBarry Smith for (i=0; i<n; i++) { 5869d90f715SBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 5879d90f715SBarry Smith else if (idx[i] < bs*start) idxout[i] = -1; 588663bb84eSBarry Smith else if (idx[i] > bs*(end+1)-1) idxout[i] = -1; 5899d90f715SBarry Smith else idxout[i] = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 5909d90f715SBarry Smith } 5919d90f715SBarry Smith } 5929d90f715SBarry Smith if (nout) *nout = n; 5939d90f715SBarry Smith } else { 5949d90f715SBarry Smith if (idxout) { 5959d90f715SBarry Smith for (i=0; i<n; i++) { 5969d90f715SBarry Smith if (idx[i] < 0) continue; 5979d90f715SBarry Smith if (idx[i] < bs*start) continue; 598663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 5999d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6009d90f715SBarry Smith if (tmp < 0) continue; 6019d90f715SBarry Smith idxout[nf++] = tmp; 6029d90f715SBarry Smith } 6039d90f715SBarry Smith } else { 6049d90f715SBarry Smith for (i=0; i<n; i++) { 6059d90f715SBarry Smith if (idx[i] < 0) continue; 6069d90f715SBarry Smith if (idx[i] < bs*start) continue; 607663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 6089d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6099d90f715SBarry Smith if (tmp < 0) continue; 6109d90f715SBarry Smith nf++; 6119d90f715SBarry Smith } 6129d90f715SBarry Smith } 6139d90f715SBarry Smith if (nout) *nout = nf; 6149d90f715SBarry Smith } 6159d90f715SBarry Smith PetscFunctionReturn(0); 6169d90f715SBarry Smith } 6179d90f715SBarry Smith 6189d90f715SBarry Smith #undef __FUNCT__ 619d4fe737eSStefano Zampini #define __FUNCT__ "ISGlobalToLocalMappingApplyIS" 620d4fe737eSStefano Zampini /*@ 621d4fe737eSStefano Zampini ISGlobalToLocalMappingApplyIS - Creates from an IS in the global numbering 622d4fe737eSStefano Zampini a new index set using the local numbering defined in an ISLocalToGlobalMapping 623d4fe737eSStefano Zampini context. 624d4fe737eSStefano Zampini 625d4fe737eSStefano Zampini Not collective 626d4fe737eSStefano Zampini 627d4fe737eSStefano Zampini Input Parameters: 628d4fe737eSStefano Zampini + mapping - mapping between local and global numbering 629d4fe737eSStefano Zampini - is - index set in global numbering 630d4fe737eSStefano Zampini 631d4fe737eSStefano Zampini Output Parameters: 632d4fe737eSStefano Zampini . newis - index set in local numbering 633d4fe737eSStefano Zampini 634d4fe737eSStefano Zampini Level: advanced 635d4fe737eSStefano Zampini 636d4fe737eSStefano Zampini Concepts: mapping^local to global 637d4fe737eSStefano Zampini 638d4fe737eSStefano Zampini .seealso: ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 639d4fe737eSStefano Zampini ISLocalToGlobalMappingDestroy() 640d4fe737eSStefano Zampini @*/ 641d4fe737eSStefano Zampini PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, IS is,IS *newis) 642d4fe737eSStefano Zampini { 643d4fe737eSStefano Zampini PetscErrorCode ierr; 644d4fe737eSStefano Zampini PetscInt n,nout,*idxout; 645d4fe737eSStefano Zampini const PetscInt *idxin; 646d4fe737eSStefano Zampini 647d4fe737eSStefano Zampini PetscFunctionBegin; 648d4fe737eSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 649d4fe737eSStefano Zampini PetscValidHeaderSpecific(is,IS_CLASSID,3); 650d4fe737eSStefano Zampini PetscValidPointer(newis,4); 651d4fe737eSStefano Zampini 652d4fe737eSStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 653d4fe737eSStefano Zampini ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 654d4fe737eSStefano Zampini if (type == IS_GTOLM_MASK) { 655d4fe737eSStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 656d4fe737eSStefano Zampini } else { 657d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,NULL);CHKERRQ(ierr); 658d4fe737eSStefano Zampini ierr = PetscMalloc1(nout,&idxout);CHKERRQ(ierr); 659d4fe737eSStefano Zampini } 660d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,idxout);CHKERRQ(ierr); 661d4fe737eSStefano Zampini ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 662d4fe737eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),nout,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 663d4fe737eSStefano Zampini PetscFunctionReturn(0); 664d4fe737eSStefano Zampini } 665d4fe737eSStefano Zampini 666d4fe737eSStefano Zampini #undef __FUNCT__ 6679d90f715SBarry Smith #define __FUNCT__ "ISGlobalToLocalMappingApplyBlock" 6689d90f715SBarry Smith /*@ 6699d90f715SBarry Smith ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers 6709d90f715SBarry Smith specified with a block global numbering. 6719d90f715SBarry Smith 6729d90f715SBarry Smith Not collective 6739d90f715SBarry Smith 6749d90f715SBarry Smith Input Parameters: 6759d90f715SBarry Smith + mapping - mapping between local and global numbering 6769d90f715SBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 6779d90f715SBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 6789d90f715SBarry Smith . n - number of global indices to map 6799d90f715SBarry Smith - idx - global indices to map 6809d90f715SBarry Smith 6819d90f715SBarry Smith Output Parameters: 6829d90f715SBarry Smith + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 6839d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough 6849d90f715SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApplyBlock() with 6859d90f715SBarry Smith idxout == NULL to determine the required length (returned in nout) 6869d90f715SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApplyBlock() 6879d90f715SBarry Smith a second time to set the values. 6889d90f715SBarry Smith 6899d90f715SBarry Smith Notes: 6909d90f715SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 6919d90f715SBarry Smith 6929d90f715SBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 6939d90f715SBarry Smith array to compute these. 6949d90f715SBarry Smith 6959d90f715SBarry Smith Level: advanced 6969d90f715SBarry Smith 6979d90f715SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 6989d90f715SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 6999d90f715SBarry Smith 7009d90f715SBarry Smith Concepts: mapping^global to local 7019d90f715SBarry Smith 7029d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 7039d90f715SBarry Smith ISLocalToGlobalMappingDestroy() 7049d90f715SBarry Smith @*/ 7059d90f715SBarry Smith PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 7069d90f715SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 7079d90f715SBarry Smith { 70832dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 7096849ba73SBarry Smith PetscErrorCode ierr; 710d4bb536fSBarry Smith 7113a40ed3dSBarry Smith PetscFunctionBegin; 7120700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 713d4bb536fSBarry Smith if (!mapping->globals) { 714d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 715d4bb536fSBarry Smith } 716d4bb536fSBarry Smith globals = mapping->globals; 717d4bb536fSBarry Smith start = mapping->globalstart; 718d4bb536fSBarry Smith end = mapping->globalend; 719d4bb536fSBarry Smith 720d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 721d4bb536fSBarry Smith if (idxout) { 722d4bb536fSBarry Smith for (i=0; i<n; i++) { 723d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 724d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 725d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 726d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 727d4bb536fSBarry Smith } 728d4bb536fSBarry Smith } 729d4bb536fSBarry Smith if (nout) *nout = n; 730d4bb536fSBarry Smith } else { 731d4bb536fSBarry Smith if (idxout) { 732d4bb536fSBarry Smith for (i=0; i<n; i++) { 733d4bb536fSBarry Smith if (idx[i] < 0) continue; 734d4bb536fSBarry Smith if (idx[i] < start) continue; 735d4bb536fSBarry Smith if (idx[i] > end) continue; 736d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 737d4bb536fSBarry Smith if (tmp < 0) continue; 738d4bb536fSBarry Smith idxout[nf++] = tmp; 739d4bb536fSBarry Smith } 740d4bb536fSBarry Smith } else { 741d4bb536fSBarry Smith for (i=0; i<n; i++) { 742d4bb536fSBarry Smith if (idx[i] < 0) continue; 743d4bb536fSBarry Smith if (idx[i] < start) continue; 744d4bb536fSBarry Smith if (idx[i] > end) continue; 745d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 746d4bb536fSBarry Smith if (tmp < 0) continue; 747d4bb536fSBarry Smith nf++; 748d4bb536fSBarry Smith } 749d4bb536fSBarry Smith } 750d4bb536fSBarry Smith if (nout) *nout = nf; 751d4bb536fSBarry Smith } 7523a40ed3dSBarry Smith PetscFunctionReturn(0); 753d4bb536fSBarry Smith } 75490f02eecSBarry Smith 7554a2ae208SSatish Balay #undef __FUNCT__ 7566a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo" 75789d82c54SBarry Smith /*@C 7586a818285SBarry Smith ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information for each processor and 75989d82c54SBarry Smith each index shared by more than one processor 76089d82c54SBarry Smith 76189d82c54SBarry Smith Collective on ISLocalToGlobalMapping 76289d82c54SBarry Smith 76389d82c54SBarry Smith Input Parameters: 76489d82c54SBarry Smith . mapping - the mapping from local to global indexing 76589d82c54SBarry Smith 76689d82c54SBarry Smith Output Parameter: 76789d82c54SBarry Smith + nproc - number of processors that are connected to this one 76889d82c54SBarry Smith . proc - neighboring processors 76907b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 7703463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 77189d82c54SBarry Smith 77289d82c54SBarry Smith Level: advanced 77389d82c54SBarry Smith 774273d9f13SBarry Smith Concepts: mapping^local to global 77589d82c54SBarry Smith 7762cfcea29SBarry Smith Fortran Usage: 7772cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 7782cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 7792cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 7802cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 7812cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 7822cfcea29SBarry Smith 7832cfcea29SBarry Smith 78407b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 78507b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 78689d82c54SBarry Smith @*/ 7876a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 78889d82c54SBarry Smith { 7896849ba73SBarry Smith PetscErrorCode ierr; 790*268a049cSStefano Zampini 791*268a049cSStefano Zampini PetscFunctionBegin; 792*268a049cSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 793*268a049cSStefano Zampini if (mapping->info_cached) { 794*268a049cSStefano Zampini *nproc = mapping->info_nproc; 795*268a049cSStefano Zampini *procs = mapping->info_procs; 796*268a049cSStefano Zampini *numprocs = mapping->info_numprocs; 797*268a049cSStefano Zampini *indices = mapping->info_indices; 798*268a049cSStefano Zampini } else { 799*268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo_Private(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 800*268a049cSStefano Zampini } 801*268a049cSStefano Zampini PetscFunctionReturn(0); 802*268a049cSStefano Zampini } 803*268a049cSStefano Zampini 804*268a049cSStefano Zampini #undef __FUNCT__ 805*268a049cSStefano Zampini #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo_Private" 806*268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 807*268a049cSStefano Zampini { 808*268a049cSStefano Zampini PetscErrorCode ierr; 80997f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 81032dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 81132dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 81297f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 81332dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 81432dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 81589d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 81630dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 817ce94432eSBarry Smith MPI_Comm comm; 818ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 81989d82c54SBarry Smith 82089d82c54SBarry Smith PetscFunctionBegin; 821ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)mapping,&comm);CHKERRQ(ierr); 82224cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 82324cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 82424cf384cSBarry Smith if (size == 1) { 82524cf384cSBarry Smith *nproc = 0; 8260298fd71SBarry Smith *procs = NULL; 82732dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt),numprocs);CHKERRQ(ierr); 8281e2105dcSBarry Smith (*numprocs)[0] = 0; 82932dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt*),indices);CHKERRQ(ierr); 8300298fd71SBarry Smith (*indices)[0] = NULL; 831*268a049cSStefano Zampini /* save info for reuse */ 832*268a049cSStefano Zampini mapping->info_nproc = *nproc; 833*268a049cSStefano Zampini mapping->info_procs = *procs; 834*268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 835*268a049cSStefano Zampini mapping->info_indices = *indices; 836*268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 83724cf384cSBarry Smith PetscFunctionReturn(0); 83824cf384cSBarry Smith } 83924cf384cSBarry Smith 8400298fd71SBarry Smith ierr = PetscOptionsGetBool(NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,NULL);CHKERRQ(ierr); 84107b52d57SBarry Smith 8423677ff5aSBarry Smith /* 8436a818285SBarry Smith Notes on ISLocalToGlobalMappingGetBlockInfo 8443677ff5aSBarry Smith 8453677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 8463677ff5aSBarry Smith numbering, just for this routine. 8473677ff5aSBarry Smith 8483677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 8493677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 8503677ff5aSBarry Smith 8513677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 8523677ff5aSBarry Smith 8533677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 8543677ff5aSBarry Smith local subdomain 8553677ff5aSBarry Smith */ 85624cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 85724cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 85824cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 85989d82c54SBarry Smith 86089d82c54SBarry Smith for (i=0; i<n; i++) { 86189d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 86289d82c54SBarry Smith } 86332dcc486SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 86478058e43SBarry Smith Ng++; 86589d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 86689d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 867bc8ff85bSBarry Smith scale = Ng/size + 1; 868a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 869caba0dd0SBarry Smith rstart = scale*rank; 87089d82c54SBarry Smith 87189d82c54SBarry Smith /* determine ownership ranges of global indices */ 872785e854fSJed Brown ierr = PetscMalloc1(2*size,&nprocs);CHKERRQ(ierr); 87332dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 87489d82c54SBarry Smith 87589d82c54SBarry Smith /* determine owners of each local node */ 876785e854fSJed Brown ierr = PetscMalloc1(n,&owner);CHKERRQ(ierr); 87789d82c54SBarry Smith for (i=0; i<n; i++) { 8783677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 87927c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 8803677ff5aSBarry Smith owner[i] = proc; 88127c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 88289d82c54SBarry Smith } 88327c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 8847904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %D\n",nsends);CHKERRQ(ierr); 88589d82c54SBarry Smith 88689d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 88727c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 8887904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %D\n",nrecvs);CHKERRQ(ierr); 88989d82c54SBarry Smith 89089d82c54SBarry Smith /* post receives for owned rows */ 891785e854fSJed Brown ierr = PetscMalloc1((2*nrecvs+1)*(nmax+1),&recvs);CHKERRQ(ierr); 892854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&recv_waits);CHKERRQ(ierr); 89389d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 89432dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 89589d82c54SBarry Smith } 89689d82c54SBarry Smith 89789d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 898854ce69bSBarry Smith ierr = PetscMalloc1(2*n+1,&sends);CHKERRQ(ierr); 899854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&starts);CHKERRQ(ierr); 90089d82c54SBarry Smith starts[0] = 0; 901f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 90289d82c54SBarry Smith for (i=0; i<n; i++) { 90389d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 90430dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 90589d82c54SBarry Smith } 90689d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 90789d82c54SBarry Smith starts[0] = 0; 908f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 90989d82c54SBarry Smith 91089d82c54SBarry Smith /* send the messages */ 911854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&send_waits);CHKERRQ(ierr); 912854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&dest);CHKERRQ(ierr); 91389d82c54SBarry Smith cnt = 0; 91489d82c54SBarry Smith for (i=0; i<size; i++) { 91527c402fcSBarry Smith if (nprocs[2*i]) { 91632dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 91730dcb7c9SBarry Smith dest[cnt] = i; 91889d82c54SBarry Smith cnt++; 91989d82c54SBarry Smith } 92089d82c54SBarry Smith } 92189d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 92289d82c54SBarry Smith 92389d82c54SBarry Smith /* wait on receives */ 924854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&source);CHKERRQ(ierr); 925854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&len);CHKERRQ(ierr); 92689d82c54SBarry Smith cnt = nrecvs; 927854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&nownedsenders);CHKERRQ(ierr); 92832dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 92989d82c54SBarry Smith while (cnt) { 93089d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 93189d82c54SBarry Smith /* unpack receives into our local space */ 93232dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 93389d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 93430dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 935caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 93630dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 93789d82c54SBarry Smith cnt--; 93889d82c54SBarry Smith } 93989d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 94089d82c54SBarry Smith 94130dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 942bc8ff85bSBarry Smith nowned = 0; 943bc8ff85bSBarry Smith nownedm = 0; 944bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 945bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 946bc8ff85bSBarry Smith } 947bc8ff85bSBarry Smith 948bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 949854ce69bSBarry Smith ierr = PetscMalloc1(nownedm+1,&ownedsenders);CHKERRQ(ierr); 950854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&starts);CHKERRQ(ierr); 951bc8ff85bSBarry Smith starts[0] = 0; 952bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 953bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 954bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 955bc8ff85bSBarry Smith } 956bc8ff85bSBarry Smith 95730dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 958bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 959bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 96030dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 961f6e5521dSKarl Rupp if (nownedsenders[node] > 1) ownedsenders[starts[node]++] = source[i]; 962bc8ff85bSBarry Smith } 963bc8ff85bSBarry Smith } 964bc8ff85bSBarry Smith 96507b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 96630dcb7c9SBarry Smith starts[0] = 0; 96730dcb7c9SBarry Smith for (i=1; i<ng; i++) { 96830dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 96930dcb7c9SBarry Smith else starts[i] = starts[i-1]; 97030dcb7c9SBarry Smith } 97130dcb7c9SBarry Smith for (i=0; i<ng; i++) { 97230dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 9737904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %D local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 97430dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 9757904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 97630dcb7c9SBarry Smith } 97730dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 97830dcb7c9SBarry Smith } 97930dcb7c9SBarry Smith } 9800ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 98107b52d57SBarry Smith } /* ----------------------------------- */ 98230dcb7c9SBarry Smith 9833677ff5aSBarry Smith /* wait on original sends */ 9843a96401aSBarry Smith if (nsends) { 985785e854fSJed Brown ierr = PetscMalloc1(nsends,&send_status);CHKERRQ(ierr); 9863a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 9873a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 9883a96401aSBarry Smith } 98989d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 9903a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 9913677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 9923677ff5aSBarry Smith 9933677ff5aSBarry Smith /* pack messages to send back to local owners */ 99430dcb7c9SBarry Smith starts[0] = 0; 99530dcb7c9SBarry Smith for (i=1; i<ng; i++) { 99630dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 99730dcb7c9SBarry Smith else starts[i] = starts[i-1]; 99830dcb7c9SBarry Smith } 99930dcb7c9SBarry Smith nsends2 = nrecvs; 1000854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&nprocs);CHKERRQ(ierr); /* length of each message */ 100130dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 100230dcb7c9SBarry Smith nprocs[i] = 1; 100330dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 100430dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 1005f6e5521dSKarl Rupp if (nownedsenders[node] > 1) nprocs[i] += 2 + nownedsenders[node]; 100630dcb7c9SBarry Smith } 100730dcb7c9SBarry Smith } 1008f6e5521dSKarl Rupp nt = 0; 1009f6e5521dSKarl Rupp for (i=0; i<nsends2; i++) nt += nprocs[i]; 1010f6e5521dSKarl Rupp 1011854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&sends2);CHKERRQ(ierr); 1012854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&starts2);CHKERRQ(ierr); 1013f6e5521dSKarl Rupp 1014f6e5521dSKarl Rupp starts2[0] = 0; 1015f6e5521dSKarl Rupp for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 101630dcb7c9SBarry Smith /* 101730dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 101830dcb7c9SBarry Smith (0) the number of nodes being sent back 101930dcb7c9SBarry Smith (1) the local node number, 102030dcb7c9SBarry Smith (2) the number of processors sharing it, 102130dcb7c9SBarry Smith (3) the processors sharing it 102230dcb7c9SBarry Smith */ 102330dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 102430dcb7c9SBarry Smith cnt = 1; 102530dcb7c9SBarry Smith sends2[starts2[i]] = 0; 102630dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 102730dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 102830dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 102930dcb7c9SBarry Smith sends2[starts2[i]]++; 103030dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 103130dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 103232dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 103330dcb7c9SBarry Smith cnt += nownedsenders[node]; 103430dcb7c9SBarry Smith } 103530dcb7c9SBarry Smith } 103630dcb7c9SBarry Smith } 103730dcb7c9SBarry Smith 103830dcb7c9SBarry Smith /* receive the message lengths */ 103930dcb7c9SBarry Smith nrecvs2 = nsends; 1040854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&lens2);CHKERRQ(ierr); 1041854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&starts3);CHKERRQ(ierr); 1042854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 104330dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 1044d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 104530dcb7c9SBarry Smith } 1046d44834fbSBarry Smith 10478a8e0b3aSBarry Smith /* send the message lengths */ 10488a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 10498a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 10508a8e0b3aSBarry Smith } 10518a8e0b3aSBarry Smith 1052d44834fbSBarry Smith /* wait on receives of lens */ 10530c468ba9SBarry Smith if (nrecvs2) { 1054785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 1055d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 1056d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 10570c468ba9SBarry Smith } 1058a2ea699eSBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 1059d44834fbSBarry Smith 106030dcb7c9SBarry Smith starts3[0] = 0; 1061d44834fbSBarry Smith nt = 0; 106230dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 106330dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 1064d44834fbSBarry Smith nt += lens2[i]; 106530dcb7c9SBarry Smith } 106676466f69SStefano Zampini if (nrecvs2) nt += lens2[nrecvs2-1]; 1067d44834fbSBarry Smith 1068854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&recvs2);CHKERRQ(ierr); 1069854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 107052b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 107132dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 107230dcb7c9SBarry Smith } 107330dcb7c9SBarry Smith 107430dcb7c9SBarry Smith /* send the messages */ 1075854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&send_waits);CHKERRQ(ierr); 107630dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 107732dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 107830dcb7c9SBarry Smith } 107930dcb7c9SBarry Smith 108030dcb7c9SBarry Smith /* wait on receives */ 10810c468ba9SBarry Smith if (nrecvs2) { 1082785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 108330dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 108430dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 10850c468ba9SBarry Smith } 108630dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 108730dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 108830dcb7c9SBarry Smith 108907b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 109030dcb7c9SBarry Smith cnt = 0; 109130dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 109230dcb7c9SBarry Smith nt = recvs2[cnt++]; 109330dcb7c9SBarry Smith for (j=0; j<nt; j++) { 10947904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %D number of subdomains %D: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 109530dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 10967904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",recvs2[cnt+2+k]);CHKERRQ(ierr); 109730dcb7c9SBarry Smith } 109830dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 109930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 110030dcb7c9SBarry Smith } 110130dcb7c9SBarry Smith } 11020ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 110307b52d57SBarry Smith } /* ----------------------------------- */ 110430dcb7c9SBarry Smith 110530dcb7c9SBarry Smith /* count number subdomains for each local node */ 1106785e854fSJed Brown ierr = PetscMalloc1(size,&nprocs);CHKERRQ(ierr); 110732dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 110830dcb7c9SBarry Smith cnt = 0; 110930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 111030dcb7c9SBarry Smith nt = recvs2[cnt++]; 111130dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1112f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) nprocs[recvs2[cnt+2+k]]++; 111330dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 111430dcb7c9SBarry Smith } 111530dcb7c9SBarry Smith } 111630dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 111730dcb7c9SBarry Smith *nproc = nt; 1118854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,procs);CHKERRQ(ierr); 1119854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,numprocs);CHKERRQ(ierr); 1120854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,indices);CHKERRQ(ierr); 11210298fd71SBarry Smith for (i=0;i<nt+1;i++) (*indices)[i]=NULL; 1122785e854fSJed Brown ierr = PetscMalloc1(size,&bprocs);CHKERRQ(ierr); 112330dcb7c9SBarry Smith cnt = 0; 112430dcb7c9SBarry Smith for (i=0; i<size; i++) { 112530dcb7c9SBarry Smith if (nprocs[i] > 0) { 112630dcb7c9SBarry Smith bprocs[i] = cnt; 112730dcb7c9SBarry Smith (*procs)[cnt] = i; 112830dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 1129785e854fSJed Brown ierr = PetscMalloc1(nprocs[i],&(*indices)[cnt]);CHKERRQ(ierr); 113030dcb7c9SBarry Smith cnt++; 113130dcb7c9SBarry Smith } 113230dcb7c9SBarry Smith } 113330dcb7c9SBarry Smith 113430dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 113532dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 113630dcb7c9SBarry Smith cnt = 0; 113730dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 113830dcb7c9SBarry Smith nt = recvs2[cnt++]; 113930dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1140f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 114130dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 114230dcb7c9SBarry Smith } 114330dcb7c9SBarry Smith } 114430dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 114507b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 114630dcb7c9SBarry Smith 114707b52d57SBarry Smith /* sort the node indexing by their global numbers */ 114807b52d57SBarry Smith nt = *nproc; 114907b52d57SBarry Smith for (i=0; i<nt; i++) { 1150854ce69bSBarry Smith ierr = PetscMalloc1((*numprocs)[i],&tmp);CHKERRQ(ierr); 1151f6e5521dSKarl Rupp for (j=0; j<(*numprocs)[i]; j++) tmp[j] = lindices[(*indices)[i][j]]; 115207b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 115307b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 115407b52d57SBarry Smith } 115507b52d57SBarry Smith 115607b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 115730dcb7c9SBarry Smith nt = *nproc; 115830dcb7c9SBarry Smith for (i=0; i<nt; i++) { 11597904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %D number of indices %D: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 116030dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 11617904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",(*indices)[i][j]);CHKERRQ(ierr); 116230dcb7c9SBarry Smith } 116330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 116430dcb7c9SBarry Smith } 11650ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 116607b52d57SBarry Smith } /* ----------------------------------- */ 116730dcb7c9SBarry Smith 116830dcb7c9SBarry Smith /* wait on sends */ 116930dcb7c9SBarry Smith if (nsends2) { 1170785e854fSJed Brown ierr = PetscMalloc1(nsends2,&send_status);CHKERRQ(ierr); 117130dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 117230dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 117330dcb7c9SBarry Smith } 117430dcb7c9SBarry Smith 117530dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 117630dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 117730dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 11783677ff5aSBarry Smith 1179bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 1180bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 1181bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 118230dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 118330dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 118489d82c54SBarry Smith 118589d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 118697f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 118789d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 11883a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 118930dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 119024cf384cSBarry Smith 119124cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 119224cf384cSBarry Smith first_procs = (*procs)[0]; 119324cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 119424cf384cSBarry Smith first_indices = (*indices)[0]; 119524cf384cSBarry Smith for (i=0; i<*nproc; i++) { 119624cf384cSBarry Smith if ((*procs)[i] == rank) { 119724cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 119824cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 119924cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 120024cf384cSBarry Smith (*procs)[i] = first_procs; 120124cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 120224cf384cSBarry Smith (*indices)[i] = first_indices; 120324cf384cSBarry Smith break; 120424cf384cSBarry Smith } 120524cf384cSBarry Smith } 1206*268a049cSStefano Zampini 1207*268a049cSStefano Zampini /* save info for reuse */ 1208*268a049cSStefano Zampini mapping->info_nproc = *nproc; 1209*268a049cSStefano Zampini mapping->info_procs = *procs; 1210*268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 1211*268a049cSStefano Zampini mapping->info_indices = *indices; 1212*268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 121389d82c54SBarry Smith PetscFunctionReturn(0); 121489d82c54SBarry Smith } 121589d82c54SBarry Smith 12164a2ae208SSatish Balay #undef __FUNCT__ 12176a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockInfo" 12186a818285SBarry Smith /*@C 12196a818285SBarry Smith ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by ISLocalToGlobalMappingGetBlockInfo() 12206a818285SBarry Smith 12216a818285SBarry Smith Collective on ISLocalToGlobalMapping 12226a818285SBarry Smith 12236a818285SBarry Smith Input Parameters: 12246a818285SBarry Smith . mapping - the mapping from local to global indexing 12256a818285SBarry Smith 12266a818285SBarry Smith Output Parameter: 12276a818285SBarry Smith + nproc - number of processors that are connected to this one 12286a818285SBarry Smith . proc - neighboring processors 12296a818285SBarry Smith . numproc - number of indices for each processor 12306a818285SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 12316a818285SBarry Smith 12326a818285SBarry Smith Level: advanced 12336a818285SBarry Smith 12346a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 12356a818285SBarry Smith ISLocalToGlobalMappingGetInfo() 12366a818285SBarry Smith @*/ 12376a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 12386a818285SBarry Smith { 12396a818285SBarry Smith PetscErrorCode ierr; 12406a818285SBarry Smith 12416a818285SBarry Smith PetscFunctionBegin; 1242cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1243*268a049cSStefano Zampini if (mapping->info_free) { 12446a818285SBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 12456a818285SBarry Smith if (*indices) { 1246*268a049cSStefano Zampini PetscInt i; 1247*268a049cSStefano Zampini 12486a818285SBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 12496a818285SBarry Smith for (i=1; i<*nproc; i++) { 12506a818285SBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 12516a818285SBarry Smith } 12526a818285SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 12536a818285SBarry Smith } 1254*268a049cSStefano Zampini } 1255*268a049cSStefano Zampini *nproc = 0; 1256*268a049cSStefano Zampini *procs = NULL; 1257*268a049cSStefano Zampini *numprocs = NULL; 1258*268a049cSStefano Zampini *indices = NULL; 12596a818285SBarry Smith PetscFunctionReturn(0); 12606a818285SBarry Smith } 12616a818285SBarry Smith 12626a818285SBarry Smith #undef __FUNCT__ 12636a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 12646a818285SBarry Smith /*@C 12656a818285SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 12666a818285SBarry Smith each index shared by more than one processor 12676a818285SBarry Smith 12686a818285SBarry Smith Collective on ISLocalToGlobalMapping 12696a818285SBarry Smith 12706a818285SBarry Smith Input Parameters: 12716a818285SBarry Smith . mapping - the mapping from local to global indexing 12726a818285SBarry Smith 12736a818285SBarry Smith Output Parameter: 12746a818285SBarry Smith + nproc - number of processors that are connected to this one 12756a818285SBarry Smith . proc - neighboring processors 12766a818285SBarry Smith . numproc - number of indices for each subdomain (processor) 12776a818285SBarry Smith - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 12786a818285SBarry Smith 12796a818285SBarry Smith Level: advanced 12806a818285SBarry Smith 12816a818285SBarry Smith Concepts: mapping^local to global 12826a818285SBarry Smith 12836a818285SBarry Smith Fortran Usage: 12846a818285SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 12856a818285SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 12866a818285SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 12876a818285SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 12886a818285SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 12896a818285SBarry Smith 12906a818285SBarry Smith 12916a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 12926a818285SBarry Smith ISLocalToGlobalMappingRestoreInfo() 12936a818285SBarry Smith @*/ 12946a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 12956a818285SBarry Smith { 12966a818285SBarry Smith PetscErrorCode ierr; 1297*268a049cSStefano Zampini PetscInt **bindices = NULL,*bnumprocs = NULL,bs = mapping->bs,i,j,k; 12986a818285SBarry Smith 12996a818285SBarry Smith PetscFunctionBegin; 13006a818285SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1301*268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo(mapping,nproc,procs,&bnumprocs,&bindices);CHKERRQ(ierr); 1302*268a049cSStefano Zampini if (bs > 1) { /* we need to expand the cached info */ 1303732f65e3SBarry Smith ierr = PetscCalloc1(*nproc,&*indices);CHKERRQ(ierr); 1304*268a049cSStefano Zampini ierr = PetscCalloc1(*nproc,&*numprocs);CHKERRQ(ierr); 13056a818285SBarry Smith for (i=0; i<*nproc; i++) { 1306*268a049cSStefano Zampini ierr = PetscMalloc1(bs*bnumprocs[i],&(*indices)[i]);CHKERRQ(ierr); 1307*268a049cSStefano Zampini for (j=0; j<bnumprocs[i]; j++) { 13086a818285SBarry Smith for (k=0; k<bs; k++) { 13096a818285SBarry Smith (*indices)[i][j*bs+k] = bs*bindices[i][j] + k; 13106a818285SBarry Smith } 13116a818285SBarry Smith } 1312*268a049cSStefano Zampini (*numprocs)[i] = bnumprocs[i]*bs; 13136a818285SBarry Smith } 1314*268a049cSStefano Zampini mapping->info_free = PETSC_TRUE; 1315*268a049cSStefano Zampini } else { 1316*268a049cSStefano Zampini *numprocs = bnumprocs; 1317*268a049cSStefano Zampini *indices = bindices; 13186a818285SBarry Smith } 13196a818285SBarry Smith PetscFunctionReturn(0); 13206a818285SBarry Smith } 13216a818285SBarry Smith 13226a818285SBarry Smith #undef __FUNCT__ 13234a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 132407b52d57SBarry Smith /*@C 132507b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 132689d82c54SBarry Smith 132707b52d57SBarry Smith Collective on ISLocalToGlobalMapping 132807b52d57SBarry Smith 132907b52d57SBarry Smith Input Parameters: 133007b52d57SBarry Smith . mapping - the mapping from local to global indexing 133107b52d57SBarry Smith 133207b52d57SBarry Smith Output Parameter: 133307b52d57SBarry Smith + nproc - number of processors that are connected to this one 133407b52d57SBarry Smith . proc - neighboring processors 133507b52d57SBarry Smith . numproc - number of indices for each processor 133607b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 133707b52d57SBarry Smith 133807b52d57SBarry Smith Level: advanced 133907b52d57SBarry Smith 134007b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 134107b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 134207b52d57SBarry Smith @*/ 13437087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 134407b52d57SBarry Smith { 13456849ba73SBarry Smith PetscErrorCode ierr; 134607b52d57SBarry Smith 134707b52d57SBarry Smith PetscFunctionBegin; 13486a818285SBarry Smith ierr = ISLocalToGlobalMappingRestoreBlockInfo(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 134907b52d57SBarry Smith PetscFunctionReturn(0); 135007b52d57SBarry Smith } 135186994e45SJed Brown 135286994e45SJed Brown #undef __FUNCT__ 135386994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingGetIndices" 135486994e45SJed Brown /*@C 1355107e9a97SBarry Smith ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped 135686994e45SJed Brown 135786994e45SJed Brown Not Collective 135886994e45SJed Brown 135986994e45SJed Brown Input Arguments: 136086994e45SJed Brown . ltog - local to global mapping 136186994e45SJed Brown 136286994e45SJed Brown Output Arguments: 1363565245c5SBarry Smith . array - array of indices, the length of this array may be obtained with ISLocalToGlobalMappingGetSize() 136486994e45SJed Brown 136586994e45SJed Brown Level: advanced 136686994e45SJed Brown 1367107e9a97SBarry Smith Notes: ISLocalToGlobalMappingGetSize() returns the length the this array 1368107e9a97SBarry Smith 1369107e9a97SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreIndices(), ISLocalToGlobalMappingGetBlockIndices(), ISLocalToGlobalMappingRestoreBlockIndices() 137086994e45SJed Brown @*/ 13717087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 137286994e45SJed Brown { 137386994e45SJed Brown PetscFunctionBegin; 137486994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 137586994e45SJed Brown PetscValidPointer(array,2); 137645b6f7e9SBarry Smith if (ltog->bs == 1) { 137786994e45SJed Brown *array = ltog->indices; 137845b6f7e9SBarry Smith } else { 137945b6f7e9SBarry Smith PetscInt *jj,k,i,j,n = ltog->n, bs = ltog->bs; 138045b6f7e9SBarry Smith const PetscInt *ii; 138145b6f7e9SBarry Smith PetscErrorCode ierr; 138245b6f7e9SBarry Smith 138345b6f7e9SBarry Smith ierr = PetscMalloc1(bs*n,&jj);CHKERRQ(ierr); 138445b6f7e9SBarry Smith *array = jj; 138545b6f7e9SBarry Smith k = 0; 138645b6f7e9SBarry Smith ii = ltog->indices; 138745b6f7e9SBarry Smith for (i=0; i<n; i++) 138845b6f7e9SBarry Smith for (j=0; j<bs; j++) 138945b6f7e9SBarry Smith jj[k++] = bs*ii[i] + j; 139045b6f7e9SBarry Smith } 139186994e45SJed Brown PetscFunctionReturn(0); 139286994e45SJed Brown } 139386994e45SJed Brown 139486994e45SJed Brown #undef __FUNCT__ 139586994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingRestoreIndices" 139686994e45SJed Brown /*@C 139786994e45SJed Brown ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with ISLocalToGlobalMappingRestoreIndices() 139886994e45SJed Brown 139986994e45SJed Brown Not Collective 140086994e45SJed Brown 140186994e45SJed Brown Input Arguments: 140286994e45SJed Brown + ltog - local to global mapping 140386994e45SJed Brown - array - array of indices 140486994e45SJed Brown 140586994e45SJed Brown Level: advanced 140686994e45SJed Brown 140786994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 140886994e45SJed Brown @*/ 14097087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 141086994e45SJed Brown { 141186994e45SJed Brown PetscFunctionBegin; 141286994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 141386994e45SJed Brown PetscValidPointer(array,2); 141445b6f7e9SBarry Smith if (ltog->bs == 1 && *array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 141545b6f7e9SBarry Smith 141645b6f7e9SBarry Smith if (ltog->bs > 1) { 141745b6f7e9SBarry Smith PetscErrorCode ierr; 141845b6f7e9SBarry Smith ierr = PetscFree(*(void**)array);CHKERRQ(ierr); 141945b6f7e9SBarry Smith } 142045b6f7e9SBarry Smith PetscFunctionReturn(0); 142145b6f7e9SBarry Smith } 142245b6f7e9SBarry Smith 142345b6f7e9SBarry Smith #undef __FUNCT__ 142445b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockIndices" 142545b6f7e9SBarry Smith /*@C 142645b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block 142745b6f7e9SBarry Smith 142845b6f7e9SBarry Smith Not Collective 142945b6f7e9SBarry Smith 143045b6f7e9SBarry Smith Input Arguments: 143145b6f7e9SBarry Smith . ltog - local to global mapping 143245b6f7e9SBarry Smith 143345b6f7e9SBarry Smith Output Arguments: 143445b6f7e9SBarry Smith . array - array of indices 143545b6f7e9SBarry Smith 143645b6f7e9SBarry Smith Level: advanced 143745b6f7e9SBarry Smith 143845b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreBlockIndices() 143945b6f7e9SBarry Smith @*/ 144045b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 144145b6f7e9SBarry Smith { 144245b6f7e9SBarry Smith PetscFunctionBegin; 144345b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 144445b6f7e9SBarry Smith PetscValidPointer(array,2); 144545b6f7e9SBarry Smith *array = ltog->indices; 144645b6f7e9SBarry Smith PetscFunctionReturn(0); 144745b6f7e9SBarry Smith } 144845b6f7e9SBarry Smith 144945b6f7e9SBarry Smith #undef __FUNCT__ 145045b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockIndices" 145145b6f7e9SBarry Smith /*@C 145245b6f7e9SBarry Smith ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with ISLocalToGlobalMappingGetBlockIndices() 145345b6f7e9SBarry Smith 145445b6f7e9SBarry Smith Not Collective 145545b6f7e9SBarry Smith 145645b6f7e9SBarry Smith Input Arguments: 145745b6f7e9SBarry Smith + ltog - local to global mapping 145845b6f7e9SBarry Smith - array - array of indices 145945b6f7e9SBarry Smith 146045b6f7e9SBarry Smith Level: advanced 146145b6f7e9SBarry Smith 146245b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 146345b6f7e9SBarry Smith @*/ 146445b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 146545b6f7e9SBarry Smith { 146645b6f7e9SBarry Smith PetscFunctionBegin; 146745b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 146845b6f7e9SBarry Smith PetscValidPointer(array,2); 146986994e45SJed Brown if (*array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 14700298fd71SBarry Smith *array = NULL; 147186994e45SJed Brown PetscFunctionReturn(0); 147286994e45SJed Brown } 1473f7efa3c7SJed Brown 1474f7efa3c7SJed Brown #undef __FUNCT__ 1475f7efa3c7SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingConcatenate" 1476f7efa3c7SJed Brown /*@C 1477f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1478f7efa3c7SJed Brown 1479f7efa3c7SJed Brown Not Collective 1480f7efa3c7SJed Brown 1481f7efa3c7SJed Brown Input Arguments: 1482f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1483f7efa3c7SJed Brown . n - number of mappings to concatenate 1484f7efa3c7SJed Brown - ltogs - local to global mappings 1485f7efa3c7SJed Brown 1486f7efa3c7SJed Brown Output Arguments: 1487f7efa3c7SJed Brown . ltogcat - new mapping 1488f7efa3c7SJed Brown 14899d90f715SBarry Smith Note: this currently always returns a mapping with block size of 1 14909d90f715SBarry Smith 14919d90f715SBarry Smith Developer Note: If all the input mapping have the same block size we could easily handle that as a special case 14929d90f715SBarry Smith 1493f7efa3c7SJed Brown Level: advanced 1494f7efa3c7SJed Brown 1495f7efa3c7SJed Brown .seealso: ISLocalToGlobalMappingCreate() 1496f7efa3c7SJed Brown @*/ 1497f7efa3c7SJed Brown PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping *ltogcat) 1498f7efa3c7SJed Brown { 1499f7efa3c7SJed Brown PetscInt i,cnt,m,*idx; 1500f7efa3c7SJed Brown PetscErrorCode ierr; 1501f7efa3c7SJed Brown 1502f7efa3c7SJed Brown PetscFunctionBegin; 1503f7efa3c7SJed Brown if (n < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have a non-negative number of mappings, given %D",n); 1504f7efa3c7SJed Brown if (n > 0) PetscValidPointer(ltogs,3); 1505f7efa3c7SJed Brown for (i=0; i<n; i++) PetscValidHeaderSpecific(ltogs[i],IS_LTOGM_CLASSID,3); 1506f7efa3c7SJed Brown PetscValidPointer(ltogcat,4); 1507f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1508f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1509f7efa3c7SJed Brown cnt += m; 1510f7efa3c7SJed Brown } 1511785e854fSJed Brown ierr = PetscMalloc1(cnt,&idx);CHKERRQ(ierr); 1512f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1513f7efa3c7SJed Brown const PetscInt *subidx; 1514f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1515f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1516f7efa3c7SJed Brown ierr = PetscMemcpy(&idx[cnt],subidx,m*sizeof(PetscInt));CHKERRQ(ierr); 1517f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1518f7efa3c7SJed Brown cnt += m; 1519f7efa3c7SJed Brown } 1520f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,cnt,idx,PETSC_OWN_POINTER,ltogcat);CHKERRQ(ierr); 1521f7efa3c7SJed Brown PetscFunctionReturn(0); 1522f7efa3c7SJed Brown } 152304a59952SBarry Smith 152404a59952SBarry Smith 1525