1af0996ceSBarry Smith #include <petsc/private/isimpl.h> /*I "petscis.h" I*/ 2e8f14785SLisandro Dalcin #include <petsc/private/hashmapi.h> 30c312b8eSJed Brown #include <petscsf.h> 4665c2dedSJed Brown #include <petscviewer.h> 5*633354d9SStefano Zampini #include <petscbt.h> 62362add9SBarry Smith 77087cfbeSBarry Smith PetscClassId IS_LTOGM_CLASSID; 8*633354d9SStefano Zampini static PetscErrorCode ISLocalToGlobalMappingSetUpBlockInfo_Private(ISLocalToGlobalMapping); 98e58c17dSMatthew Knepley 10413f72f0SBarry Smith typedef struct { 11413f72f0SBarry Smith PetscInt *globals; 12413f72f0SBarry Smith } ISLocalToGlobalMapping_Basic; 13413f72f0SBarry Smith 14413f72f0SBarry Smith typedef struct { 15e8f14785SLisandro Dalcin PetscHMapI globalht; 16413f72f0SBarry Smith } ISLocalToGlobalMapping_Hash; 17413f72f0SBarry Smith 186528b96dSMatthew G. Knepley /*@C 19cab54364SBarry Smith ISGetPointRange - Returns a description of the points in an `IS` suitable for traversal 20413f72f0SBarry Smith 2120662ed9SBarry Smith Not Collective 226528b96dSMatthew G. Knepley 236528b96dSMatthew G. Knepley Input Parameter: 24cab54364SBarry Smith . pointIS - The `IS` object 256528b96dSMatthew G. Knepley 266528b96dSMatthew G. Knepley Output Parameters: 276528b96dSMatthew G. Knepley + pStart - The first index, see notes 286528b96dSMatthew G. Knepley . pEnd - One past the last index, see notes 296528b96dSMatthew G. Knepley - points - The indices, see notes 306528b96dSMatthew G. Knepley 316528b96dSMatthew G. Knepley Level: intermediate 326528b96dSMatthew G. Knepley 33cab54364SBarry Smith Notes: 3420662ed9SBarry Smith If the `IS` contains contiguous indices in an `ISSTRIDE`, then the indices are contained in [pStart, pEnd) and points = `NULL`. 3520662ed9SBarry Smith Otherwise, `pStart = 0`, `pEnd = numIndices`, and points is an array of the indices. This supports the following pattern 36cab54364SBarry Smith .vb 37cab54364SBarry Smith ISGetPointRange(is, &pStart, &pEnd, &points); 38cab54364SBarry Smith for (p = pStart; p < pEnd; ++p) { 39cab54364SBarry Smith const PetscInt point = points ? points[p] : p; 4020662ed9SBarry Smith // use point 41cab54364SBarry Smith } 42cab54364SBarry Smith ISRestorePointRange(is, &pstart, &pEnd, &points); 43cab54364SBarry Smith .ve 4420662ed9SBarry Smith Hence the same code can be written for `pointIS` being a `ISSTRIDE` or `ISGENERAL` 45cab54364SBarry Smith 46cab54364SBarry Smith .seealso: [](sec_scatter), `IS`, `ISRestorePointRange()`, `ISGetPointSubrange()`, `ISGetIndices()`, `ISCreateStride()` 476528b96dSMatthew G. Knepley @*/ 48d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGetPointRange(IS pointIS, PetscInt *pStart, PetscInt *pEnd, const PetscInt **points) 49d71ae5a4SJacob Faibussowitsch { 509305a4c7SMatthew G. Knepley PetscInt numCells, step = 1; 519305a4c7SMatthew G. Knepley PetscBool isStride; 529305a4c7SMatthew G. Knepley 539305a4c7SMatthew G. Knepley PetscFunctionBeginHot; 549305a4c7SMatthew G. Knepley *pStart = 0; 559305a4c7SMatthew G. Knepley *points = NULL; 569566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(pointIS, &numCells)); 579566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pointIS, ISSTRIDE, &isStride)); 589566063dSJacob Faibussowitsch if (isStride) PetscCall(ISStrideGetInfo(pointIS, pStart, &step)); 599305a4c7SMatthew G. Knepley *pEnd = *pStart + numCells; 609566063dSJacob Faibussowitsch if (!isStride || step != 1) PetscCall(ISGetIndices(pointIS, points)); 613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 629305a4c7SMatthew G. Knepley } 639305a4c7SMatthew G. Knepley 646528b96dSMatthew G. Knepley /*@C 65cab54364SBarry Smith ISRestorePointRange - Destroys the traversal description created with `ISGetPointRange()` 666528b96dSMatthew G. Knepley 6720662ed9SBarry Smith Not Collective 686528b96dSMatthew G. Knepley 696528b96dSMatthew G. Knepley Input Parameters: 70cab54364SBarry Smith + pointIS - The `IS` object 71cab54364SBarry Smith . pStart - The first index, from `ISGetPointRange()` 72cab54364SBarry Smith . pEnd - One past the last index, from `ISGetPointRange()` 73cab54364SBarry Smith - points - The indices, from `ISGetPointRange()` 746528b96dSMatthew G. Knepley 756528b96dSMatthew G. Knepley Level: intermediate 766528b96dSMatthew G. Knepley 77cab54364SBarry Smith .seealso: [](sec_scatter), `IS`, `ISGetPointRange()`, `ISGetPointSubrange()`, `ISGetIndices()`, `ISCreateStride()` 786528b96dSMatthew G. Knepley @*/ 79d71ae5a4SJacob Faibussowitsch PetscErrorCode ISRestorePointRange(IS pointIS, PetscInt *pStart, PetscInt *pEnd, const PetscInt **points) 80d71ae5a4SJacob Faibussowitsch { 819305a4c7SMatthew G. Knepley PetscInt step = 1; 829305a4c7SMatthew G. Knepley PetscBool isStride; 839305a4c7SMatthew G. Knepley 849305a4c7SMatthew G. Knepley PetscFunctionBeginHot; 859566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pointIS, ISSTRIDE, &isStride)); 869566063dSJacob Faibussowitsch if (isStride) PetscCall(ISStrideGetInfo(pointIS, pStart, &step)); 879566063dSJacob Faibussowitsch if (!isStride || step != 1) PetscCall(ISGetIndices(pointIS, points)); 883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 899305a4c7SMatthew G. Knepley } 909305a4c7SMatthew G. Knepley 916528b96dSMatthew G. Knepley /*@C 92cab54364SBarry Smith ISGetPointSubrange - Configures the input `IS` to be a subrange for the traversal information given 936528b96dSMatthew G. Knepley 9420662ed9SBarry Smith Not Collective 956528b96dSMatthew G. Knepley 966528b96dSMatthew G. Knepley Input Parameters: 97cab54364SBarry Smith + subpointIS - The `IS` object to be configured 986528b96dSMatthew G. Knepley . pStart - The first index of the subrange 996528b96dSMatthew G. Knepley . pEnd - One past the last index for the subrange 100cab54364SBarry Smith - points - The indices for the entire range, from `ISGetPointRange()` 1016528b96dSMatthew G. Knepley 1026528b96dSMatthew G. Knepley Output Parameters: 103cab54364SBarry Smith . subpointIS - The `IS` object now configured to be a subrange 1046528b96dSMatthew G. Knepley 1056528b96dSMatthew G. Knepley Level: intermediate 1066528b96dSMatthew G. Knepley 107cab54364SBarry Smith Note: 108cab54364SBarry Smith The input `IS` will now respond properly to calls to `ISGetPointRange()` and return the subrange. 109cab54364SBarry Smith 110cab54364SBarry Smith .seealso: [](sec_scatter), `IS`, `ISGetPointRange()`, `ISRestorePointRange()`, `ISGetIndices()`, `ISCreateStride()` 1116528b96dSMatthew G. Knepley @*/ 112d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGetPointSubrange(IS subpointIS, PetscInt pStart, PetscInt pEnd, const PetscInt *points) 113d71ae5a4SJacob Faibussowitsch { 1149305a4c7SMatthew G. Knepley PetscFunctionBeginHot; 1159305a4c7SMatthew G. Knepley if (points) { 1169566063dSJacob Faibussowitsch PetscCall(ISSetType(subpointIS, ISGENERAL)); 1179566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(subpointIS, pEnd - pStart, &points[pStart], PETSC_USE_POINTER)); 1189305a4c7SMatthew G. Knepley } else { 1199566063dSJacob Faibussowitsch PetscCall(ISSetType(subpointIS, ISSTRIDE)); 1209566063dSJacob Faibussowitsch PetscCall(ISStrideSetStride(subpointIS, pEnd - pStart, pStart, 1)); 1219305a4c7SMatthew G. Knepley } 1223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1239305a4c7SMatthew G. Knepley } 1249305a4c7SMatthew G. Knepley 125413f72f0SBarry Smith /* -----------------------------------------------------------------------------------------*/ 126413f72f0SBarry Smith 127413f72f0SBarry Smith /* 128413f72f0SBarry Smith Creates the global mapping information in the ISLocalToGlobalMapping structure 129413f72f0SBarry Smith 130413f72f0SBarry Smith If the user has not selected how to handle the global to local mapping then use HASH for "large" problems 131413f72f0SBarry Smith */ 132d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISGlobalToLocalMappingSetUp(ISLocalToGlobalMapping mapping) 133d71ae5a4SJacob Faibussowitsch { 134413f72f0SBarry Smith PetscInt i, *idx = mapping->indices, n = mapping->n, end, start; 135413f72f0SBarry Smith 136413f72f0SBarry Smith PetscFunctionBegin; 1373ba16761SJacob Faibussowitsch if (mapping->data) PetscFunctionReturn(PETSC_SUCCESS); 138413f72f0SBarry Smith end = 0; 139413f72f0SBarry Smith start = PETSC_MAX_INT; 140413f72f0SBarry Smith 141413f72f0SBarry Smith for (i = 0; i < n; i++) { 142413f72f0SBarry Smith if (idx[i] < 0) continue; 143413f72f0SBarry Smith if (idx[i] < start) start = idx[i]; 144413f72f0SBarry Smith if (idx[i] > end) end = idx[i]; 145413f72f0SBarry Smith } 1469371c9d4SSatish Balay if (start > end) { 1479371c9d4SSatish Balay start = 0; 1489371c9d4SSatish Balay end = -1; 1499371c9d4SSatish Balay } 150413f72f0SBarry Smith mapping->globalstart = start; 151413f72f0SBarry Smith mapping->globalend = end; 152413f72f0SBarry Smith if (!((PetscObject)mapping)->type_name) { 153413f72f0SBarry Smith if ((end - start) > PetscMax(4 * n, 1000000)) { 1549566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingSetType(mapping, ISLOCALTOGLOBALMAPPINGHASH)); 155413f72f0SBarry Smith } else { 1569566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingSetType(mapping, ISLOCALTOGLOBALMAPPINGBASIC)); 157413f72f0SBarry Smith } 158413f72f0SBarry Smith } 159dbbe0bcdSBarry Smith PetscTryTypeMethod(mapping, globaltolocalmappingsetup); 1603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 161413f72f0SBarry Smith } 162413f72f0SBarry Smith 163d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISGlobalToLocalMappingSetUp_Basic(ISLocalToGlobalMapping mapping) 164d71ae5a4SJacob Faibussowitsch { 165413f72f0SBarry Smith PetscInt i, *idx = mapping->indices, n = mapping->n, end, start, *globals; 166413f72f0SBarry Smith ISLocalToGlobalMapping_Basic *map; 167413f72f0SBarry Smith 168413f72f0SBarry Smith PetscFunctionBegin; 169413f72f0SBarry Smith start = mapping->globalstart; 170413f72f0SBarry Smith end = mapping->globalend; 1719566063dSJacob Faibussowitsch PetscCall(PetscNew(&map)); 1729566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(end - start + 2, &globals)); 173413f72f0SBarry Smith map->globals = globals; 174413f72f0SBarry Smith for (i = 0; i < end - start + 1; i++) globals[i] = -1; 175413f72f0SBarry Smith for (i = 0; i < n; i++) { 176413f72f0SBarry Smith if (idx[i] < 0) continue; 177413f72f0SBarry Smith globals[idx[i] - start] = i; 178413f72f0SBarry Smith } 179413f72f0SBarry Smith mapping->data = (void *)map; 1803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 181413f72f0SBarry Smith } 182413f72f0SBarry Smith 183d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISGlobalToLocalMappingSetUp_Hash(ISLocalToGlobalMapping mapping) 184d71ae5a4SJacob Faibussowitsch { 185413f72f0SBarry Smith PetscInt i, *idx = mapping->indices, n = mapping->n; 186413f72f0SBarry Smith ISLocalToGlobalMapping_Hash *map; 187413f72f0SBarry Smith 188413f72f0SBarry Smith PetscFunctionBegin; 1899566063dSJacob Faibussowitsch PetscCall(PetscNew(&map)); 1909566063dSJacob Faibussowitsch PetscCall(PetscHMapICreate(&map->globalht)); 191413f72f0SBarry Smith for (i = 0; i < n; i++) { 192413f72f0SBarry Smith if (idx[i] < 0) continue; 1939566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(map->globalht, idx[i], i)); 194413f72f0SBarry Smith } 195413f72f0SBarry Smith mapping->data = (void *)map; 1963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 197413f72f0SBarry Smith } 198413f72f0SBarry Smith 199d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISLocalToGlobalMappingDestroy_Basic(ISLocalToGlobalMapping mapping) 200d71ae5a4SJacob Faibussowitsch { 201413f72f0SBarry Smith ISLocalToGlobalMapping_Basic *map = (ISLocalToGlobalMapping_Basic *)mapping->data; 202413f72f0SBarry Smith 203413f72f0SBarry Smith PetscFunctionBegin; 2043ba16761SJacob Faibussowitsch if (!map) PetscFunctionReturn(PETSC_SUCCESS); 2059566063dSJacob Faibussowitsch PetscCall(PetscFree(map->globals)); 2069566063dSJacob Faibussowitsch PetscCall(PetscFree(mapping->data)); 2073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208413f72f0SBarry Smith } 209413f72f0SBarry Smith 210d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISLocalToGlobalMappingDestroy_Hash(ISLocalToGlobalMapping mapping) 211d71ae5a4SJacob Faibussowitsch { 212413f72f0SBarry Smith ISLocalToGlobalMapping_Hash *map = (ISLocalToGlobalMapping_Hash *)mapping->data; 213413f72f0SBarry Smith 214413f72f0SBarry Smith PetscFunctionBegin; 2153ba16761SJacob Faibussowitsch if (!map) PetscFunctionReturn(PETSC_SUCCESS); 2169566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&map->globalht)); 2179566063dSJacob Faibussowitsch PetscCall(PetscFree(mapping->data)); 2183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 219413f72f0SBarry Smith } 220413f72f0SBarry Smith 221413f72f0SBarry Smith #define GTOLTYPE _Basic 222413f72f0SBarry Smith #define GTOLNAME _Basic 223541bf97eSAdrian Croucher #define GTOLBS mapping->bs 2249371c9d4SSatish Balay #define GTOL(g, local) \ 2259371c9d4SSatish Balay do { \ 226413f72f0SBarry Smith local = map->globals[g / bs - start]; \ 2270040bde1SJunchao Zhang if (local >= 0) local = bs * local + (g % bs); \ 228413f72f0SBarry Smith } while (0) 229541bf97eSAdrian Croucher 230413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h> 231413f72f0SBarry Smith 232413f72f0SBarry Smith #define GTOLTYPE _Basic 233413f72f0SBarry Smith #define GTOLNAME Block_Basic 234541bf97eSAdrian Croucher #define GTOLBS 1 2359371c9d4SSatish Balay #define GTOL(g, local) \ 236d71ae5a4SJacob Faibussowitsch do { \ 237d71ae5a4SJacob Faibussowitsch local = map->globals[g - start]; \ 238d71ae5a4SJacob Faibussowitsch } while (0) 239413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h> 240413f72f0SBarry Smith 241413f72f0SBarry Smith #define GTOLTYPE _Hash 242413f72f0SBarry Smith #define GTOLNAME _Hash 243541bf97eSAdrian Croucher #define GTOLBS mapping->bs 2449371c9d4SSatish Balay #define GTOL(g, local) \ 2459371c9d4SSatish Balay do { \ 246e8f14785SLisandro Dalcin (void)PetscHMapIGet(map->globalht, g / bs, &local); \ 2470040bde1SJunchao Zhang if (local >= 0) local = bs * local + (g % bs); \ 248413f72f0SBarry Smith } while (0) 249413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h> 250413f72f0SBarry Smith 251413f72f0SBarry Smith #define GTOLTYPE _Hash 252413f72f0SBarry Smith #define GTOLNAME Block_Hash 253541bf97eSAdrian Croucher #define GTOLBS 1 2549371c9d4SSatish Balay #define GTOL(g, local) \ 255d71ae5a4SJacob Faibussowitsch do { \ 256d71ae5a4SJacob Faibussowitsch (void)PetscHMapIGet(map->globalht, g, &local); \ 257d71ae5a4SJacob Faibussowitsch } while (0) 258413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h> 259413f72f0SBarry Smith 2606658fb44Sstefano_zampini /*@ 2616658fb44Sstefano_zampini ISLocalToGlobalMappingDuplicate - Duplicates the local to global mapping object 2626658fb44Sstefano_zampini 2636658fb44Sstefano_zampini Not Collective 2646658fb44Sstefano_zampini 2656658fb44Sstefano_zampini Input Parameter: 2666658fb44Sstefano_zampini . ltog - local to global mapping 2676658fb44Sstefano_zampini 2686658fb44Sstefano_zampini Output Parameter: 2696658fb44Sstefano_zampini . nltog - the duplicated local to global mapping 2706658fb44Sstefano_zampini 2716658fb44Sstefano_zampini Level: advanced 2726658fb44Sstefano_zampini 273cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()` 2746658fb44Sstefano_zampini @*/ 275d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingDuplicate(ISLocalToGlobalMapping ltog, ISLocalToGlobalMapping *nltog) 276d71ae5a4SJacob Faibussowitsch { 277a0d79125SStefano Zampini ISLocalToGlobalMappingType l2gtype; 2786658fb44Sstefano_zampini 2796658fb44Sstefano_zampini PetscFunctionBegin; 2806658fb44Sstefano_zampini PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1); 2819566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)ltog), ltog->bs, ltog->n, ltog->indices, PETSC_COPY_VALUES, nltog)); 2829566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetType(ltog, &l2gtype)); 2839566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingSetType(*nltog, l2gtype)); 2843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2856658fb44Sstefano_zampini } 2866658fb44Sstefano_zampini 287565245c5SBarry Smith /*@ 288107e9a97SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping 2893b9aefa3SBarry Smith 2903b9aefa3SBarry Smith Not Collective 2913b9aefa3SBarry Smith 2923b9aefa3SBarry Smith Input Parameter: 29338b5cf2dSJacob Faibussowitsch . mapping - local to global mapping 2943b9aefa3SBarry Smith 2953b9aefa3SBarry Smith Output Parameter: 296cab54364SBarry Smith . n - the number of entries in the local mapping, `ISLocalToGlobalMappingGetIndices()` returns an array of this length 2973b9aefa3SBarry Smith 2983b9aefa3SBarry Smith Level: advanced 2993b9aefa3SBarry Smith 300cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()` 3013b9aefa3SBarry Smith @*/ 302d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping, PetscInt *n) 303d71ae5a4SJacob Faibussowitsch { 3043b9aefa3SBarry Smith PetscFunctionBegin; 3050700a824SBarry Smith PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 3064f572ea9SToby Isaac PetscAssertPointer(n, 2); 307107e9a97SBarry Smith *n = mapping->bs * mapping->n; 3083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3093b9aefa3SBarry Smith } 3103b9aefa3SBarry Smith 3115a5d4f66SBarry Smith /*@C 312cab54364SBarry Smith ISLocalToGlobalMappingViewFromOptions - View an `ISLocalToGlobalMapping` based on values in the options database 313fe2efc57SMark 314c3339decSBarry Smith Collective 315fe2efc57SMark 316fe2efc57SMark Input Parameters: 317fe2efc57SMark + A - the local to global mapping object 31820662ed9SBarry Smith . obj - Optional object that provides the options prefix used for the options database query 319736c3998SJose E. Roman - name - command line option 320fe2efc57SMark 321fe2efc57SMark Level: intermediate 322cab54364SBarry Smith 32320662ed9SBarry Smith Note: 32420662ed9SBarry Smith See `PetscObjectViewFromOptions()` for the available `PetscViewer` and `PetscViewerFormat` 32520662ed9SBarry Smith 32620662ed9SBarry Smith .seealso: [](sec_scatter), `PetscViewer`, ``ISLocalToGlobalMapping`, `ISLocalToGlobalMappingView`, `PetscObjectViewFromOptions()`, `ISLocalToGlobalMappingCreate()` 327fe2efc57SMark @*/ 328d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingViewFromOptions(ISLocalToGlobalMapping A, PetscObject obj, const char name[]) 329d71ae5a4SJacob Faibussowitsch { 330fe2efc57SMark PetscFunctionBegin; 331fe2efc57SMark PetscValidHeaderSpecific(A, IS_LTOGM_CLASSID, 1); 3329566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 3333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 334fe2efc57SMark } 335fe2efc57SMark 336fe2efc57SMark /*@C 3375a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 3385a5d4f66SBarry Smith 339b9cd556bSLois Curfman McInnes Not Collective 340b9cd556bSLois Curfman McInnes 3415a5d4f66SBarry Smith Input Parameters: 34238b5cf2dSJacob Faibussowitsch + mapping - local to global mapping 3433b9aefa3SBarry Smith - viewer - viewer 3445a5d4f66SBarry Smith 345a997ad1aSLois Curfman McInnes Level: advanced 346a997ad1aSLois Curfman McInnes 34720662ed9SBarry Smith .seealso: [](sec_scatter), `PetscViewer`, `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()` 3485a5d4f66SBarry Smith @*/ 349d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping, PetscViewer viewer) 350d71ae5a4SJacob Faibussowitsch { 35132dcc486SBarry Smith PetscInt i; 35232dcc486SBarry Smith PetscMPIInt rank; 353ace3abfcSBarry Smith PetscBool iascii; 3545a5d4f66SBarry Smith 3555a5d4f66SBarry Smith PetscFunctionBegin; 3560700a824SBarry Smith PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 35748a46eb9SPierre Jolivet if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mapping), &viewer)); 3580700a824SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 3595a5d4f66SBarry Smith 3609566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)mapping), &rank)); 3619566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 36232077d6dSBarry Smith if (iascii) { 3639566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mapping, viewer)); 3649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 365f2c6b1a2SJed Brown for (i = 0; i < mapping->n; i++) { 366f2c6b1a2SJed Brown PetscInt bs = mapping->bs, g = mapping->indices[i]; 367f2c6b1a2SJed Brown if (bs == 1) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT " %" PetscInt_FMT "\n", rank, i, g)); 368f2c6b1a2SJed Brown else PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":%" PetscInt_FMT " %" PetscInt_FMT ":%" PetscInt_FMT "\n", rank, i * bs, (i + 1) * bs, g * bs, (g + 1) * bs)); 369f2c6b1a2SJed Brown } 3709566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 3719566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 3721575c14dSBarry Smith } 3733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3745a5d4f66SBarry Smith } 3755a5d4f66SBarry Smith 3761f428162SBarry Smith /*@ 3772bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 3782bdab257SBarry Smith ordering and a global parallel ordering. 3792bdab257SBarry Smith 38020662ed9SBarry Smith Not Collective 381b9cd556bSLois Curfman McInnes 382a997ad1aSLois Curfman McInnes Input Parameter: 3838c03b21aSDmitry Karpeev . is - index set containing the global numbers for each local number 3842bdab257SBarry Smith 385a997ad1aSLois Curfman McInnes Output Parameter: 3862bdab257SBarry Smith . mapping - new mapping data structure 3872bdab257SBarry Smith 388a997ad1aSLois Curfman McInnes Level: advanced 389a997ad1aSLois Curfman McInnes 390cab54364SBarry Smith Note: 391cab54364SBarry Smith the block size of the `IS` determines the block size of the mapping 392cab54364SBarry Smith 393cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetFromOptions()` 3942bdab257SBarry Smith @*/ 395d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is, ISLocalToGlobalMapping *mapping) 396d71ae5a4SJacob Faibussowitsch { 3973bbf0e92SBarry Smith PetscInt n, bs; 3985d0c19d7SBarry Smith const PetscInt *indices; 3992bdab257SBarry Smith MPI_Comm comm; 4003bbf0e92SBarry Smith PetscBool isblock; 4013a40ed3dSBarry Smith 4023a40ed3dSBarry Smith PetscFunctionBegin; 4030700a824SBarry Smith PetscValidHeaderSpecific(is, IS_CLASSID, 1); 4044f572ea9SToby Isaac PetscAssertPointer(mapping, 2); 4052bdab257SBarry Smith 4069566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)is, &comm)); 4079566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 4089566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)is, ISBLOCK, &isblock)); 4096006e8d2SBarry Smith if (!isblock) { 4109566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &indices)); 4119566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(comm, 1, n, indices, PETSC_COPY_VALUES, mapping)); 4129566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &indices)); 4136006e8d2SBarry Smith } else { 4149566063dSJacob Faibussowitsch PetscCall(ISGetBlockSize(is, &bs)); 4159566063dSJacob Faibussowitsch PetscCall(ISBlockGetIndices(is, &indices)); 4169566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(comm, bs, n / bs, indices, PETSC_COPY_VALUES, mapping)); 4179566063dSJacob Faibussowitsch PetscCall(ISBlockRestoreIndices(is, &indices)); 4186006e8d2SBarry Smith } 4193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4202bdab257SBarry Smith } 4215a5d4f66SBarry Smith 422a4d96a55SJed Brown /*@C 423a4d96a55SJed Brown ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n) 424a4d96a55SJed Brown ordering and a global parallel ordering. 425a4d96a55SJed Brown 426a4d96a55SJed Brown Collective 427a4d96a55SJed Brown 428d8d19677SJose E. Roman Input Parameters: 429a4d96a55SJed Brown + sf - star forest mapping contiguous local indices to (rank, offset) 430cab54364SBarry Smith - start - first global index on this process, or `PETSC_DECIDE` to compute contiguous global numbering automatically 431a4d96a55SJed Brown 432a4d96a55SJed Brown Output Parameter: 433a4d96a55SJed Brown . mapping - new mapping data structure 434a4d96a55SJed Brown 435a4d96a55SJed Brown Level: advanced 436a4d96a55SJed Brown 43720662ed9SBarry Smith Note: 438*633354d9SStefano Zampini If a process calls this function with `start` = `PETSC_DECIDE` then all processes must, otherwise the program will hang. 4399a535bafSVaclav Hapla 440cab54364SBarry Smith .seealso: [](sec_scatter), `PetscSF`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingSetFromOptions()` 441a4d96a55SJed Brown @*/ 442d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf, PetscInt start, ISLocalToGlobalMapping *mapping) 443d71ae5a4SJacob Faibussowitsch { 444a4d96a55SJed Brown PetscInt i, maxlocal, nroots, nleaves, *globals, *ltog; 445a4d96a55SJed Brown MPI_Comm comm; 446a4d96a55SJed Brown 447a4d96a55SJed Brown PetscFunctionBegin; 448a4d96a55SJed Brown PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1); 4494f572ea9SToby Isaac PetscAssertPointer(mapping, 3); 4509566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 45141f4c31fSVaclav Hapla PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 4529a535bafSVaclav Hapla if (start == PETSC_DECIDE) { 4539a535bafSVaclav Hapla start = 0; 4549566063dSJacob Faibussowitsch PetscCallMPI(MPI_Exscan(&nroots, &start, 1, MPIU_INT, MPI_SUM, comm)); 45541f4c31fSVaclav Hapla } else PetscCheck(start >= 0, comm, PETSC_ERR_ARG_OUTOFRANGE, "start must be nonnegative or PETSC_DECIDE"); 45641f4c31fSVaclav Hapla PetscCall(PetscSFGetLeafRange(sf, NULL, &maxlocal)); 45741f4c31fSVaclav Hapla ++maxlocal; 4589566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &globals)); 4599566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(maxlocal, <og)); 460a4d96a55SJed Brown for (i = 0; i < nroots; i++) globals[i] = start + i; 461a4d96a55SJed Brown for (i = 0; i < maxlocal; i++) ltog[i] = -1; 4629566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, globals, ltog, MPI_REPLACE)); 4639566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, globals, ltog, MPI_REPLACE)); 4649566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(comm, 1, maxlocal, ltog, PETSC_OWN_POINTER, mapping)); 4659566063dSJacob Faibussowitsch PetscCall(PetscFree(globals)); 4663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 467a4d96a55SJed Brown } 468b46b645bSBarry Smith 469*633354d9SStefano Zampini static PetscErrorCode ISLocalToGlobalMappingResetBlockInfo_Private(ISLocalToGlobalMapping mapping) 470*633354d9SStefano Zampini { 471*633354d9SStefano Zampini PetscFunctionBegin; 472*633354d9SStefano Zampini PetscCall(PetscFree(mapping->info_procs)); 473*633354d9SStefano Zampini PetscCall(PetscFree(mapping->info_numprocs)); 474*633354d9SStefano Zampini if (mapping->info_indices) { 475*633354d9SStefano Zampini for (PetscInt i = 0; i < mapping->info_nproc; i++) PetscCall(PetscFree(mapping->info_indices[i])); 476*633354d9SStefano Zampini PetscCall(PetscFree(mapping->info_indices)); 477*633354d9SStefano Zampini } 478*633354d9SStefano Zampini if (mapping->info_nodei) PetscCall(PetscFree(mapping->info_nodei[0])); 479*633354d9SStefano Zampini PetscCall(PetscFree2(mapping->info_nodec, mapping->info_nodei)); 480*633354d9SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 481*633354d9SStefano Zampini } 482*633354d9SStefano Zampini 48363fa5c83Sstefano_zampini /*@ 48463fa5c83Sstefano_zampini ISLocalToGlobalMappingSetBlockSize - Sets the blocksize of the mapping 48563fa5c83Sstefano_zampini 48620662ed9SBarry Smith Not Collective 48763fa5c83Sstefano_zampini 48863fa5c83Sstefano_zampini Input Parameters: 489a2b725a8SWilliam Gropp + mapping - mapping data structure 490a2b725a8SWilliam Gropp - bs - the blocksize 49163fa5c83Sstefano_zampini 49263fa5c83Sstefano_zampini Level: advanced 49363fa5c83Sstefano_zampini 494cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()` 49563fa5c83Sstefano_zampini @*/ 496d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingSetBlockSize(ISLocalToGlobalMapping mapping, PetscInt bs) 497d71ae5a4SJacob Faibussowitsch { 498a59f3c4dSstefano_zampini PetscInt *nid; 499a59f3c4dSstefano_zampini const PetscInt *oid; 500a59f3c4dSstefano_zampini PetscInt i, cn, on, obs, nn; 50163fa5c83Sstefano_zampini 50263fa5c83Sstefano_zampini PetscFunctionBegin; 50363fa5c83Sstefano_zampini PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 50408401ef6SPierre Jolivet PetscCheck(bs >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid block size %" PetscInt_FMT, bs); 5053ba16761SJacob Faibussowitsch if (bs == mapping->bs) PetscFunctionReturn(PETSC_SUCCESS); 50663fa5c83Sstefano_zampini on = mapping->n; 50763fa5c83Sstefano_zampini obs = mapping->bs; 50863fa5c83Sstefano_zampini oid = mapping->indices; 50963fa5c83Sstefano_zampini nn = (on * obs) / bs; 51008401ef6SPierre Jolivet PetscCheck((on * obs) % bs == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Block size %" PetscInt_FMT " is inconsistent with block size %" PetscInt_FMT " and number of block indices %" PetscInt_FMT, bs, obs, on); 511a59f3c4dSstefano_zampini 5129566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nn, &nid)); 5139566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetIndices(mapping, &oid)); 514a59f3c4dSstefano_zampini for (i = 0; i < nn; i++) { 515a59f3c4dSstefano_zampini PetscInt j; 516a59f3c4dSstefano_zampini for (j = 0, cn = 0; j < bs - 1; j++) { 5179371c9d4SSatish Balay if (oid[i * bs + j] < 0) { 5189371c9d4SSatish Balay cn++; 5199371c9d4SSatish Balay continue; 5209371c9d4SSatish Balay } 52108401ef6SPierre Jolivet PetscCheck(oid[i * bs + j] == oid[i * bs + j + 1] - 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Block sizes %" PetscInt_FMT " and %" PetscInt_FMT " are incompatible with the block indices: non consecutive indices %" PetscInt_FMT " %" PetscInt_FMT, bs, obs, oid[i * bs + j], oid[i * bs + j + 1]); 522a59f3c4dSstefano_zampini } 523a59f3c4dSstefano_zampini if (oid[i * bs + j] < 0) cn++; 5248b7cb0e6Sstefano_zampini if (cn) { 52508401ef6SPierre Jolivet PetscCheck(cn == bs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Block sizes %" PetscInt_FMT " and %" PetscInt_FMT " are incompatible with the block indices: invalid number of negative entries in block %" PetscInt_FMT, bs, obs, cn); 526a59f3c4dSstefano_zampini nid[i] = -1; 5278b7cb0e6Sstefano_zampini } else { 528a59f3c4dSstefano_zampini nid[i] = oid[i * bs] / bs; 52963fa5c83Sstefano_zampini } 53063fa5c83Sstefano_zampini } 5319566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingRestoreIndices(mapping, &oid)); 532a59f3c4dSstefano_zampini 53363fa5c83Sstefano_zampini mapping->n = nn; 53463fa5c83Sstefano_zampini mapping->bs = bs; 5359566063dSJacob Faibussowitsch PetscCall(PetscFree(mapping->indices)); 53663fa5c83Sstefano_zampini mapping->indices = nid; 537c9345713Sstefano_zampini mapping->globalstart = 0; 538c9345713Sstefano_zampini mapping->globalend = 0; 5391bd0b88eSStefano Zampini 5401bd0b88eSStefano Zampini /* reset the cached information */ 541*633354d9SStefano Zampini PetscCall(ISLocalToGlobalMappingResetBlockInfo_Private(mapping)); 542dbbe0bcdSBarry Smith PetscTryTypeMethod(mapping, destroy); 5433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 54463fa5c83Sstefano_zampini } 54563fa5c83Sstefano_zampini 54645b6f7e9SBarry Smith /*@ 54745b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping 54845b6f7e9SBarry Smith ordering and a global parallel ordering. 54945b6f7e9SBarry Smith 55045b6f7e9SBarry Smith Not Collective 55145b6f7e9SBarry Smith 5522fe279fdSBarry Smith Input Parameter: 55345b6f7e9SBarry Smith . mapping - mapping data structure 55445b6f7e9SBarry Smith 55545b6f7e9SBarry Smith Output Parameter: 55645b6f7e9SBarry Smith . bs - the blocksize 55745b6f7e9SBarry Smith 55845b6f7e9SBarry Smith Level: advanced 55945b6f7e9SBarry Smith 560cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()` 56145b6f7e9SBarry Smith @*/ 562d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping, PetscInt *bs) 563d71ae5a4SJacob Faibussowitsch { 56445b6f7e9SBarry Smith PetscFunctionBegin; 565cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 56645b6f7e9SBarry Smith *bs = mapping->bs; 5673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56845b6f7e9SBarry Smith } 56945b6f7e9SBarry Smith 570ba5bb76aSSatish Balay /*@ 57190f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 57290f02eecSBarry Smith ordering and a global parallel ordering. 5732362add9SBarry Smith 57489d82c54SBarry Smith Not Collective, but communicator may have more than one process 575b9cd556bSLois Curfman McInnes 5762362add9SBarry Smith Input Parameters: 57789d82c54SBarry Smith + comm - MPI communicator 578f0413b6fSBarry Smith . bs - the block size 57928bc9809SBarry Smith . n - the number of local elements divided by the block size, or equivalently the number of block indices 58028bc9809SBarry 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 581d5ad8652SBarry Smith - mode - see PetscCopyMode 5822362add9SBarry Smith 583a997ad1aSLois Curfman McInnes Output Parameter: 58490f02eecSBarry Smith . mapping - new mapping data structure 5852362add9SBarry Smith 586cab54364SBarry Smith Level: advanced 587cab54364SBarry Smith 58895452b02SPatrick Sanan Notes: 58995452b02SPatrick Sanan There is one integer value in indices per block and it represents the actual indices bs*idx + j, where j=0,..,bs-1 590413f72f0SBarry Smith 591cab54364SBarry Smith For "small" problems when using `ISGlobalToLocalMappingApply()` and `ISGlobalToLocalMappingApplyBlock()`, the `ISLocalToGlobalMappingType` 592cab54364SBarry Smith of `ISLOCALTOGLOBALMAPPINGBASIC` will be used; this uses more memory but is faster; this approach is not scalable for extremely large mappings. 593413f72f0SBarry Smith 594cab54364SBarry Smith For large problems `ISLOCALTOGLOBALMAPPINGHASH` is used, this is scalable. 59520662ed9SBarry Smith Use `ISLocalToGlobalMappingSetType()` or call `ISLocalToGlobalMappingSetFromOptions()` with the option 59620662ed9SBarry Smith `-islocaltoglobalmapping_type` <`basic`,`hash`> to control which is used. 597a997ad1aSLois Curfman McInnes 59820662ed9SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingSetFromOptions()`, 59920662ed9SBarry Smith `ISLOCALTOGLOBALMAPPINGBASIC`, `ISLOCALTOGLOBALMAPPINGHASH` 600db781477SPatrick Sanan `ISLocalToGlobalMappingSetType()`, `ISLocalToGlobalMappingType` 6012362add9SBarry Smith @*/ 602d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm comm, PetscInt bs, PetscInt n, const PetscInt indices[], PetscCopyMode mode, ISLocalToGlobalMapping *mapping) 603d71ae5a4SJacob Faibussowitsch { 60432dcc486SBarry Smith PetscInt *in; 605b46b645bSBarry Smith 606b46b645bSBarry Smith PetscFunctionBegin; 6074f572ea9SToby Isaac if (n) PetscAssertPointer(indices, 4); 6084f572ea9SToby Isaac PetscAssertPointer(mapping, 6); 609b46b645bSBarry Smith 6100298fd71SBarry Smith *mapping = NULL; 6119566063dSJacob Faibussowitsch PetscCall(ISInitializePackage()); 6122362add9SBarry Smith 6139566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(*mapping, IS_LTOGM_CLASSID, "ISLocalToGlobalMapping", "Local to global mapping", "IS", comm, ISLocalToGlobalMappingDestroy, ISLocalToGlobalMappingView)); 614d4bb536fSBarry Smith (*mapping)->n = n; 615f0413b6fSBarry Smith (*mapping)->bs = bs; 616d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 6179566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &in)); 6189566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(in, indices, n)); 619d5ad8652SBarry Smith (*mapping)->indices = in; 62071910c26SVaclav Hapla (*mapping)->dealloc_indices = PETSC_TRUE; 6216389a1a1SBarry Smith } else if (mode == PETSC_OWN_POINTER) { 6226389a1a1SBarry Smith (*mapping)->indices = (PetscInt *)indices; 62371910c26SVaclav Hapla (*mapping)->dealloc_indices = PETSC_TRUE; 62471910c26SVaclav Hapla } else if (mode == PETSC_USE_POINTER) { 62571910c26SVaclav Hapla (*mapping)->indices = (PetscInt *)indices; 6269371c9d4SSatish Balay } else SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid mode %d", mode); 6273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6282362add9SBarry Smith } 6292362add9SBarry Smith 630413f72f0SBarry Smith PetscFunctionList ISLocalToGlobalMappingList = NULL; 631413f72f0SBarry Smith 63290f02eecSBarry Smith /*@ 6337e99dc12SLawrence Mitchell ISLocalToGlobalMappingSetFromOptions - Set mapping options from the options database. 6347e99dc12SLawrence Mitchell 63520662ed9SBarry Smith Not Collective 6367e99dc12SLawrence Mitchell 6372fe279fdSBarry Smith Input Parameter: 6387e99dc12SLawrence Mitchell . mapping - mapping data structure 6397e99dc12SLawrence Mitchell 64020662ed9SBarry Smith Options Database Key: 64120662ed9SBarry Smith . -islocaltoglobalmapping_type - <basic,hash> nonscalable and scalable versions 64220662ed9SBarry Smith 6437e99dc12SLawrence Mitchell Level: advanced 6447e99dc12SLawrence Mitchell 64542747ad1SJacob Faibussowitsch .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, 64642747ad1SJacob Faibussowitsch `ISLocalToGlobalMappingCreateIS()`, `ISLOCALTOGLOBALMAPPINGBASIC`, 64742747ad1SJacob Faibussowitsch `ISLOCALTOGLOBALMAPPINGHASH`, `ISLocalToGlobalMappingSetType()`, `ISLocalToGlobalMappingType` 6487e99dc12SLawrence Mitchell @*/ 649d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingSetFromOptions(ISLocalToGlobalMapping mapping) 650d71ae5a4SJacob Faibussowitsch { 651413f72f0SBarry Smith char type[256]; 652413f72f0SBarry Smith ISLocalToGlobalMappingType defaulttype = "Not set"; 6537e99dc12SLawrence Mitchell PetscBool flg; 6547e99dc12SLawrence Mitchell 6557e99dc12SLawrence Mitchell PetscFunctionBegin; 6567e99dc12SLawrence Mitchell PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 6579566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingRegisterAll()); 658d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)mapping); 6599566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-islocaltoglobalmapping_type", "ISLocalToGlobalMapping method", "ISLocalToGlobalMappingSetType", ISLocalToGlobalMappingList, (char *)(((PetscObject)mapping)->type_name) ? ((PetscObject)mapping)->type_name : defaulttype, type, 256, &flg)); 6601baa6e33SBarry Smith if (flg) PetscCall(ISLocalToGlobalMappingSetType(mapping, type)); 661d0609cedSBarry Smith PetscOptionsEnd(); 6623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6637e99dc12SLawrence Mitchell } 6647e99dc12SLawrence Mitchell 6657e99dc12SLawrence Mitchell /*@ 66690f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 66790f02eecSBarry Smith ordering and a global parallel ordering. 66890f02eecSBarry Smith 66920662ed9SBarry Smith Not Collective 670b9cd556bSLois Curfman McInnes 6712fe279fdSBarry Smith Input Parameter: 67290f02eecSBarry Smith . mapping - mapping data structure 67390f02eecSBarry Smith 674a997ad1aSLois Curfman McInnes Level: advanced 675a997ad1aSLois Curfman McInnes 676cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingCreate()` 67790f02eecSBarry Smith @*/ 678d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 679d71ae5a4SJacob Faibussowitsch { 6803a40ed3dSBarry Smith PetscFunctionBegin; 6813ba16761SJacob Faibussowitsch if (!*mapping) PetscFunctionReturn(PETSC_SUCCESS); 682f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*mapping, IS_LTOGM_CLASSID, 1); 683f4f49eeaSPierre Jolivet if (--((PetscObject)*mapping)->refct > 0) { 6849371c9d4SSatish Balay *mapping = NULL; 6853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 68671910c26SVaclav Hapla } 68748a46eb9SPierre Jolivet if ((*mapping)->dealloc_indices) PetscCall(PetscFree((*mapping)->indices)); 688*633354d9SStefano Zampini PetscCall(ISLocalToGlobalMappingResetBlockInfo_Private(*mapping)); 689213acdd3SPierre Jolivet PetscTryTypeMethod(*mapping, destroy); 6909566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(mapping)); 6913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 69290f02eecSBarry Smith } 69390f02eecSBarry Smith 69490f02eecSBarry Smith /*@ 695cab54364SBarry Smith ISLocalToGlobalMappingApplyIS - Creates from an `IS` in the local numbering 696cab54364SBarry Smith a new index set using the global numbering defined in an `ISLocalToGlobalMapping` 6973acfe500SLois Curfman McInnes context. 69890f02eecSBarry Smith 699c3339decSBarry Smith Collective 700b9cd556bSLois Curfman McInnes 70190f02eecSBarry Smith Input Parameters: 702b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 703b9cd556bSLois Curfman McInnes - is - index set in local numbering 70490f02eecSBarry Smith 705cab54364SBarry Smith Output Parameter: 70690f02eecSBarry Smith . newis - index set in global numbering 70790f02eecSBarry Smith 708a997ad1aSLois Curfman McInnes Level: advanced 709a997ad1aSLois Curfman McInnes 710cab54364SBarry Smith Note: 71120662ed9SBarry Smith The output `IS` will have the same communicator as the input `IS`. 712cab54364SBarry Smith 713cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingCreate()`, 714db781477SPatrick Sanan `ISLocalToGlobalMappingDestroy()`, `ISGlobalToLocalMappingApply()` 71590f02eecSBarry Smith @*/ 716d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping, IS is, IS *newis) 717d71ae5a4SJacob Faibussowitsch { 718e24637baSBarry Smith PetscInt n, *idxout; 7195d0c19d7SBarry Smith const PetscInt *idxin; 7203a40ed3dSBarry Smith 7213a40ed3dSBarry Smith PetscFunctionBegin; 7220700a824SBarry Smith PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 7230700a824SBarry Smith PetscValidHeaderSpecific(is, IS_CLASSID, 2); 7244f572ea9SToby Isaac PetscAssertPointer(newis, 3); 72590f02eecSBarry Smith 7269566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 7279566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &idxin)); 7289566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &idxout)); 7299566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingApply(mapping, n, idxin, idxout)); 7309566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &idxin)); 7319566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)is), n, idxout, PETSC_OWN_POINTER, newis)); 7323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 73390f02eecSBarry Smith } 73490f02eecSBarry Smith 735b89cb25eSSatish Balay /*@ 7363acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 7373acfe500SLois Curfman McInnes and converts them to the global numbering. 73890f02eecSBarry Smith 73920662ed9SBarry Smith Not Collective 740b9cd556bSLois Curfman McInnes 741bb25748dSBarry Smith Input Parameters: 742b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 743bb25748dSBarry Smith . N - number of integers 744b9cd556bSLois Curfman McInnes - in - input indices in local numbering 745bb25748dSBarry Smith 746bb25748dSBarry Smith Output Parameter: 747bb25748dSBarry Smith . out - indices in global numbering 748bb25748dSBarry Smith 749a997ad1aSLois Curfman McInnes Level: advanced 750a997ad1aSLois Curfman McInnes 751cab54364SBarry Smith Note: 75220662ed9SBarry Smith The `in` and `out` array parameters may be identical. 753cab54364SBarry Smith 754cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApplyBlock()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingDestroy()`, 755c2e3fba1SPatrick Sanan `ISLocalToGlobalMappingApplyIS()`, `AOCreateBasic()`, `AOApplicationToPetsc()`, 756db781477SPatrick Sanan `AOPetscToApplication()`, `ISGlobalToLocalMappingApply()` 757afcb2eb5SJed Brown @*/ 758d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping, PetscInt N, const PetscInt in[], PetscInt out[]) 759d71ae5a4SJacob Faibussowitsch { 760cbc1caf0SMatthew G. Knepley PetscInt i, bs, Nmax; 76145b6f7e9SBarry Smith 76245b6f7e9SBarry Smith PetscFunctionBegin; 763cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 764cbc1caf0SMatthew G. Knepley bs = mapping->bs; 765cbc1caf0SMatthew G. Knepley Nmax = bs * mapping->n; 76645b6f7e9SBarry Smith if (bs == 1) { 767cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 76845b6f7e9SBarry Smith for (i = 0; i < N; i++) { 76945b6f7e9SBarry Smith if (in[i] < 0) { 77045b6f7e9SBarry Smith out[i] = in[i]; 77145b6f7e9SBarry Smith continue; 77245b6f7e9SBarry Smith } 77308401ef6SPierre Jolivet PetscCheck(in[i] < Nmax, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local index %" PetscInt_FMT " too large %" PetscInt_FMT " (max) at %" PetscInt_FMT, in[i], Nmax - 1, i); 77445b6f7e9SBarry Smith out[i] = idx[in[i]]; 77545b6f7e9SBarry Smith } 77645b6f7e9SBarry Smith } else { 777cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 77845b6f7e9SBarry Smith for (i = 0; i < N; i++) { 77945b6f7e9SBarry Smith if (in[i] < 0) { 78045b6f7e9SBarry Smith out[i] = in[i]; 78145b6f7e9SBarry Smith continue; 78245b6f7e9SBarry Smith } 78308401ef6SPierre Jolivet PetscCheck(in[i] < Nmax, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local index %" PetscInt_FMT " too large %" PetscInt_FMT " (max) at %" PetscInt_FMT, in[i], Nmax - 1, i); 78445b6f7e9SBarry Smith out[i] = idx[in[i] / bs] * bs + (in[i] % bs); 78545b6f7e9SBarry Smith } 78645b6f7e9SBarry Smith } 7873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 78845b6f7e9SBarry Smith } 78945b6f7e9SBarry Smith 79045b6f7e9SBarry Smith /*@ 7916006e8d2SBarry Smith ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering 79245b6f7e9SBarry Smith 79320662ed9SBarry Smith Not Collective 79445b6f7e9SBarry Smith 79545b6f7e9SBarry Smith Input Parameters: 79645b6f7e9SBarry Smith + mapping - the local to global mapping context 79745b6f7e9SBarry Smith . N - number of integers 7986006e8d2SBarry Smith - in - input indices in local block numbering 79945b6f7e9SBarry Smith 80045b6f7e9SBarry Smith Output Parameter: 8016006e8d2SBarry Smith . out - indices in global block numbering 80245b6f7e9SBarry Smith 8036006e8d2SBarry Smith Example: 804cab54364SBarry 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 8056006e8d2SBarry Smith (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3. 8066006e8d2SBarry Smith 80720662ed9SBarry Smith Level: advanced 80820662ed9SBarry Smith 80920662ed9SBarry Smith Note: 81020662ed9SBarry Smith The `in` and `out` array parameters may be identical. 81120662ed9SBarry Smith 812cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingDestroy()`, 813c2e3fba1SPatrick Sanan `ISLocalToGlobalMappingApplyIS()`, `AOCreateBasic()`, `AOApplicationToPetsc()`, 814db781477SPatrick Sanan `AOPetscToApplication()`, `ISGlobalToLocalMappingApply()` 81545b6f7e9SBarry Smith @*/ 816d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping, PetscInt N, const PetscInt in[], PetscInt out[]) 817d71ae5a4SJacob Faibussowitsch { 8188a1f772fSStefano Zampini PetscInt i, Nmax; 8198a1f772fSStefano Zampini const PetscInt *idx; 820d4bb536fSBarry Smith 821a0d79125SStefano Zampini PetscFunctionBegin; 822a0d79125SStefano Zampini PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 8238a1f772fSStefano Zampini Nmax = mapping->n; 8248a1f772fSStefano Zampini idx = mapping->indices; 825afcb2eb5SJed Brown for (i = 0; i < N; i++) { 826afcb2eb5SJed Brown if (in[i] < 0) { 827afcb2eb5SJed Brown out[i] = in[i]; 828afcb2eb5SJed Brown continue; 829afcb2eb5SJed Brown } 83008401ef6SPierre Jolivet PetscCheck(in[i] < Nmax, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local block index %" PetscInt_FMT " too large %" PetscInt_FMT " (max) at %" PetscInt_FMT, in[i], Nmax - 1, i); 831afcb2eb5SJed Brown out[i] = idx[in[i]]; 832afcb2eb5SJed Brown } 8333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 834afcb2eb5SJed Brown } 835d4bb536fSBarry Smith 8367e99dc12SLawrence Mitchell /*@ 837a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 838a997ad1aSLois Curfman McInnes specified with a global numbering. 839d4bb536fSBarry Smith 84020662ed9SBarry Smith Not Collective 841b9cd556bSLois Curfman McInnes 842d4bb536fSBarry Smith Input Parameters: 843b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 844cab54364SBarry Smith . type - `IS_GTOLM_MASK` - maps global indices with no local value to -1 in the output list (i.e., mask them) 845cab54364SBarry Smith `IS_GTOLM_DROP` - drops the indices with no local value from the output list 846d4bb536fSBarry Smith . n - number of global indices to map 847b9cd556bSLois Curfman McInnes - idx - global indices to map 848d4bb536fSBarry Smith 849d4bb536fSBarry Smith Output Parameters: 850cab54364SBarry Smith + nout - number of indices in output array (if type == `IS_GTOLM_MASK` then nout = n) 851b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 852cab54364SBarry Smith to hold all the indices. You can call `ISGlobalToLocalMappingApply()` with 8530298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 854cab54364SBarry Smith and then allocate the required space and call `ISGlobalToLocalMappingApply()` 855e182c471SBarry Smith a second time to set the values. 856d4bb536fSBarry Smith 857cab54364SBarry Smith Level: advanced 858cab54364SBarry Smith 859b9cd556bSLois Curfman McInnes Notes: 86020662ed9SBarry Smith Either `nout` or `idxout` may be `NULL`. `idx` and `idxout` may be identical. 861d4bb536fSBarry Smith 86220662ed9SBarry Smith For "small" problems when using `ISGlobalToLocalMappingApply()` and `ISGlobalToLocalMappingApplyBlock()`, the `ISLocalToGlobalMappingType` of 86320662ed9SBarry Smith `ISLOCALTOGLOBALMAPPINGBASIC` will be used; 864cab54364SBarry Smith this uses more memory but is faster; this approach is not scalable for extremely large mappings. For large problems `ISLOCALTOGLOBALMAPPINGHASH` is used, this is scalable. 865cab54364SBarry Smith Use `ISLocalToGlobalMappingSetType()` or call `ISLocalToGlobalMappingSetFromOptions()` with the option -islocaltoglobalmapping_type <basic,hash> to control which is used. 8660f5bd95cSBarry Smith 86738b5cf2dSJacob Faibussowitsch Developer Notes: 86820662ed9SBarry Smith The manual page states that `idx` and `idxout` may be identical but the calling 86920662ed9SBarry Smith sequence declares `idx` as const so it cannot be the same as `idxout`. 87032fd6b96SBarry Smith 871cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApply()`, `ISGlobalToLocalMappingApplyBlock()`, `ISLocalToGlobalMappingCreate()`, 872db781477SPatrick Sanan `ISLocalToGlobalMappingDestroy()` 873d4bb536fSBarry Smith @*/ 874d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingMode type, PetscInt n, const PetscInt idx[], PetscInt *nout, PetscInt idxout[]) 875d71ae5a4SJacob Faibussowitsch { 8769d90f715SBarry Smith PetscFunctionBegin; 8779d90f715SBarry Smith PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 87848a46eb9SPierre Jolivet if (!mapping->data) PetscCall(ISGlobalToLocalMappingSetUp(mapping)); 879dbbe0bcdSBarry Smith PetscUseTypeMethod(mapping, globaltolocalmappingapply, type, n, idx, nout, idxout); 8803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8819d90f715SBarry Smith } 8829d90f715SBarry Smith 883d4fe737eSStefano Zampini /*@ 884cab54364SBarry Smith ISGlobalToLocalMappingApplyIS - Creates from an `IS` in the global numbering 885cab54364SBarry Smith a new index set using the local numbering defined in an `ISLocalToGlobalMapping` 886d4fe737eSStefano Zampini context. 887d4fe737eSStefano Zampini 88820662ed9SBarry Smith Not Collective 889d4fe737eSStefano Zampini 890d4fe737eSStefano Zampini Input Parameters: 891d4fe737eSStefano Zampini + mapping - mapping between local and global numbering 892cab54364SBarry Smith . type - `IS_GTOLM_MASK` - maps global indices with no local value to -1 in the output list (i.e., mask them) 893cab54364SBarry Smith `IS_GTOLM_DROP` - drops the indices with no local value from the output list 894d4fe737eSStefano Zampini - is - index set in global numbering 895d4fe737eSStefano Zampini 8962fe279fdSBarry Smith Output Parameter: 897d4fe737eSStefano Zampini . newis - index set in local numbering 898d4fe737eSStefano Zampini 899d4fe737eSStefano Zampini Level: advanced 900d4fe737eSStefano Zampini 901cab54364SBarry Smith Note: 902cab54364SBarry Smith The output `IS` will be sequential, as it encodes a purely local operation 903cab54364SBarry Smith 904cab54364SBarry Smith .seealso: [](sec_scatter), `ISGlobalToLocalMapping`, `ISGlobalToLocalMappingApply()`, `ISLocalToGlobalMappingCreate()`, 905db781477SPatrick Sanan `ISLocalToGlobalMappingDestroy()` 906d4fe737eSStefano Zampini @*/ 907d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingMode type, IS is, IS *newis) 908d71ae5a4SJacob Faibussowitsch { 909d4fe737eSStefano Zampini PetscInt n, nout, *idxout; 910d4fe737eSStefano Zampini const PetscInt *idxin; 911d4fe737eSStefano Zampini 912d4fe737eSStefano Zampini PetscFunctionBegin; 913d4fe737eSStefano Zampini PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 914d4fe737eSStefano Zampini PetscValidHeaderSpecific(is, IS_CLASSID, 3); 9154f572ea9SToby Isaac PetscAssertPointer(newis, 4); 916d4fe737eSStefano Zampini 9179566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 9189566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &idxin)); 919d4fe737eSStefano Zampini if (type == IS_GTOLM_MASK) { 9209566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &idxout)); 921d4fe737eSStefano Zampini } else { 9229566063dSJacob Faibussowitsch PetscCall(ISGlobalToLocalMappingApply(mapping, type, n, idxin, &nout, NULL)); 9239566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nout, &idxout)); 924d4fe737eSStefano Zampini } 9259566063dSJacob Faibussowitsch PetscCall(ISGlobalToLocalMappingApply(mapping, type, n, idxin, &nout, idxout)); 9269566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &idxin)); 9279566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, nout, idxout, PETSC_OWN_POINTER, newis)); 9283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 929d4fe737eSStefano Zampini } 930d4fe737eSStefano Zampini 9319d90f715SBarry Smith /*@ 9329d90f715SBarry Smith ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers 9339d90f715SBarry Smith specified with a block global numbering. 9349d90f715SBarry Smith 93520662ed9SBarry Smith Not Collective 9369d90f715SBarry Smith 9379d90f715SBarry Smith Input Parameters: 9389d90f715SBarry Smith + mapping - mapping between local and global numbering 939cab54364SBarry Smith . type - `IS_GTOLM_MASK` - maps global indices with no local value to -1 in the output list (i.e., mask them) 940cab54364SBarry Smith `IS_GTOLM_DROP` - drops the indices with no local value from the output list 9419d90f715SBarry Smith . n - number of global indices to map 9429d90f715SBarry Smith - idx - global indices to map 9439d90f715SBarry Smith 9449d90f715SBarry Smith Output Parameters: 945cab54364SBarry Smith + nout - number of indices in output array (if type == `IS_GTOLM_MASK` then nout = n) 9469d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough 947cab54364SBarry Smith to hold all the indices. You can call `ISGlobalToLocalMappingApplyBlock()` with 9489d90f715SBarry Smith idxout == NULL to determine the required length (returned in nout) 949cab54364SBarry Smith and then allocate the required space and call `ISGlobalToLocalMappingApplyBlock()` 9509d90f715SBarry Smith a second time to set the values. 9519d90f715SBarry Smith 952cab54364SBarry Smith Level: advanced 953cab54364SBarry Smith 9549d90f715SBarry Smith Notes: 95520662ed9SBarry Smith Either `nout` or `idxout` may be `NULL`. `idx` and `idxout` may be identical. 9569d90f715SBarry Smith 95720662ed9SBarry Smith For "small" problems when using `ISGlobalToLocalMappingApply()` and `ISGlobalToLocalMappingApplyBlock()`, the `ISLocalToGlobalMappingType` of 95820662ed9SBarry Smith `ISLOCALTOGLOBALMAPPINGBASIC` will be used; 959cab54364SBarry Smith this uses more memory but is faster; this approach is not scalable for extremely large mappings. For large problems `ISLOCALTOGLOBALMAPPINGHASH` is used, this is scalable. 960cab54364SBarry Smith Use `ISLocalToGlobalMappingSetType()` or call `ISLocalToGlobalMappingSetFromOptions()` with the option -islocaltoglobalmapping_type <basic,hash> to control which is used. 9619d90f715SBarry Smith 96238b5cf2dSJacob Faibussowitsch Developer Notes: 96320662ed9SBarry Smith The manual page states that `idx` and `idxout` may be identical but the calling 96420662ed9SBarry Smith sequence declares `idx` as const so it cannot be the same as `idxout`. 9659d90f715SBarry Smith 966cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApply()`, `ISGlobalToLocalMappingApply()`, `ISLocalToGlobalMappingCreate()`, 967db781477SPatrick Sanan `ISLocalToGlobalMappingDestroy()` 9689d90f715SBarry Smith @*/ 969d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingMode type, PetscInt n, const PetscInt idx[], PetscInt *nout, PetscInt idxout[]) 970d71ae5a4SJacob Faibussowitsch { 9713a40ed3dSBarry Smith PetscFunctionBegin; 9720700a824SBarry Smith PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 97348a46eb9SPierre Jolivet if (!mapping->data) PetscCall(ISGlobalToLocalMappingSetUp(mapping)); 974dbbe0bcdSBarry Smith PetscUseTypeMethod(mapping, globaltolocalmappingapplyblock, type, n, idx, nout, idxout); 9753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 976d4bb536fSBarry Smith } 97790f02eecSBarry Smith 97889d82c54SBarry Smith /*@C 979*633354d9SStefano Zampini ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information 98089d82c54SBarry Smith 981*633354d9SStefano Zampini Collective the first time it is called 98289d82c54SBarry Smith 983f899ff85SJose E. Roman Input Parameter: 98489d82c54SBarry Smith . mapping - the mapping from local to global indexing 98589d82c54SBarry Smith 986d8d19677SJose E. Roman Output Parameters: 987*633354d9SStefano Zampini + nproc - number of processes that are connected to the calling process 988*633354d9SStefano Zampini . procs - neighboring processes 989*633354d9SStefano Zampini . numprocs - number of block indices for each process 990*633354d9SStefano Zampini - indices - block indices (in local numbering) shared with neighbors (sorted by global numbering) 99189d82c54SBarry Smith 99289d82c54SBarry Smith Level: advanced 99389d82c54SBarry Smith 994cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`, 995*633354d9SStefano Zampini `ISLocalToGlobalMappingRestoreBlockInfo()` 99689d82c54SBarry Smith @*/ 997d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[]) 998d71ae5a4SJacob Faibussowitsch { 999268a049cSStefano Zampini PetscFunctionBegin; 1000268a049cSStefano Zampini PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 1001*633354d9SStefano Zampini PetscCall(ISLocalToGlobalMappingSetUpBlockInfo_Private(mapping)); 1002*633354d9SStefano Zampini if (nproc) *nproc = mapping->info_nproc; 1003*633354d9SStefano Zampini if (procs) *procs = mapping->info_procs; 1004*633354d9SStefano Zampini if (numprocs) *numprocs = mapping->info_numprocs; 1005*633354d9SStefano Zampini if (indices) *indices = mapping->info_indices; 10063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1007268a049cSStefano Zampini } 1008268a049cSStefano Zampini 1009*633354d9SStefano Zampini /*@C 1010*633354d9SStefano Zampini ISLocalToGlobalMappingGetBlockNodeInfo - Gets the neighbor information for each local block index 1011*633354d9SStefano Zampini 1012*633354d9SStefano Zampini Collective the first time it is called 1013*633354d9SStefano Zampini 1014*633354d9SStefano Zampini Input Parameter: 1015*633354d9SStefano Zampini . mapping - the mapping from local to global indexing 1016*633354d9SStefano Zampini 1017*633354d9SStefano Zampini Output Parameter: 1018*633354d9SStefano Zampini + n - number of local block nodes 1019*633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local block node (including self) 1020*633354d9SStefano Zampini - procs - the processes' rank for each local block node (sorted, self is first) 1021*633354d9SStefano Zampini 1022*633354d9SStefano Zampini Level: advanced 1023*633354d9SStefano Zampini 1024*633354d9SStefano Zampini Notes: 1025*633354d9SStefano Zampini The user needs to call `ISLocalToGlobalMappingRestoreBlockNodeInfo()` when the data is no longer needed. 1026*633354d9SStefano Zampini The information returned by this function complements that of `ISLocalToGlobalMappingGetBlockInfo()`. 1027*633354d9SStefano Zampini The latter only provides local information, and the neighboring information 1028*633354d9SStefano Zampini cannot be inferred in the general case, unless the mapping is locally one-to-one on each process. 1029*633354d9SStefano Zampini 1030*633354d9SStefano Zampini .seealso: `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`, 1031*633354d9SStefano Zampini `ISLocalToGlobalMappingGetBlockInfo()`, `ISLocalToGlobalMappingRestoreBlockNodeInfo()`, `ISLocalToGlobalMappingGetNodeInfo()` 1032*633354d9SStefano Zampini @*/ 1033*633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingGetBlockNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[]) 1034d71ae5a4SJacob Faibussowitsch { 1035*633354d9SStefano Zampini PetscFunctionBegin; 1036*633354d9SStefano Zampini PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 1037*633354d9SStefano Zampini PetscCall(ISLocalToGlobalMappingSetUpBlockInfo_Private(mapping)); 1038*633354d9SStefano Zampini if (n) *n = mapping->n; 1039*633354d9SStefano Zampini if (n_procs) *n_procs = mapping->info_nodec; 1040*633354d9SStefano Zampini if (procs) *procs = mapping->info_nodei; 1041*633354d9SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 1042*633354d9SStefano Zampini } 1043*633354d9SStefano Zampini 1044*633354d9SStefano Zampini /*@C 1045*633354d9SStefano Zampini ISLocalToGlobalMappingRestoreBlockNodeInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetBlockNodeInfo()` 1046*633354d9SStefano Zampini 1047*633354d9SStefano Zampini Not Collective 1048*633354d9SStefano Zampini 1049*633354d9SStefano Zampini Input Parameters: 1050*633354d9SStefano Zampini + mapping - the mapping from local to global indexing 1051*633354d9SStefano Zampini . n - number of local block nodes 1052*633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local block nodes (including self) 1053*633354d9SStefano Zampini - procs - the processes' rank for each local block node (sorted, self is first) 1054*633354d9SStefano Zampini 1055*633354d9SStefano Zampini Level: advanced 1056*633354d9SStefano Zampini 1057*633354d9SStefano Zampini .seealso: `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`, 1058*633354d9SStefano Zampini `ISLocalToGlobalMappingGetBlockNodeInfo()` 1059*633354d9SStefano Zampini @*/ 1060*633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingRestoreBlockNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[]) 1061*633354d9SStefano Zampini { 1062*633354d9SStefano Zampini PetscFunctionBegin; 1063*633354d9SStefano Zampini PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 1064*633354d9SStefano Zampini if (n) *n = 0; 1065*633354d9SStefano Zampini if (n_procs) *n_procs = NULL; 1066*633354d9SStefano Zampini if (procs) *procs = NULL; 1067*633354d9SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 1068*633354d9SStefano Zampini } 1069*633354d9SStefano Zampini 1070*633354d9SStefano Zampini static PetscErrorCode ISLocalToGlobalMappingSetUpBlockInfo_Private(ISLocalToGlobalMapping mapping) 1071*633354d9SStefano Zampini { 1072*633354d9SStefano Zampini PetscSF sf; 1073ce94432eSBarry Smith MPI_Comm comm; 1074*633354d9SStefano Zampini const PetscSFNode *sfnode; 1075*633354d9SStefano Zampini PetscSFNode *newsfnode; 1076*633354d9SStefano Zampini PetscLayout layout; 1077*633354d9SStefano Zampini PetscHMapI neighs; 1078*633354d9SStefano Zampini PetscHashIter iter; 1079*633354d9SStefano Zampini PetscBool missing; 1080*633354d9SStefano Zampini const PetscInt *gidxs, *rootdegree; 1081*633354d9SStefano Zampini PetscInt *mask, *mrootdata, *leafdata, *newleafdata, *leafrd, *tmpg; 1082*633354d9SStefano Zampini PetscInt nroots, nleaves, newnleaves, bs, i, j, m, mnroots, p; 1083*633354d9SStefano Zampini PetscMPIInt rank, size; 108489d82c54SBarry Smith 108589d82c54SBarry Smith PetscFunctionBegin; 1086*633354d9SStefano Zampini if (mapping->info_numprocs) PetscFunctionReturn(PETSC_SUCCESS); 10879566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)mapping, &comm)); 10889566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 10899566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1090*633354d9SStefano Zampini 1091*633354d9SStefano Zampini /* Get mapping indices */ 1092*633354d9SStefano Zampini PetscCall(ISLocalToGlobalMappingGetBlockSize(mapping, &bs)); 1093*633354d9SStefano Zampini PetscCall(ISLocalToGlobalMappingGetBlockIndices(mapping, &gidxs)); 1094*633354d9SStefano Zampini PetscCall(ISLocalToGlobalMappingGetSize(mapping, &nleaves)); 1095*633354d9SStefano Zampini nleaves /= bs; 1096*633354d9SStefano Zampini 1097*633354d9SStefano Zampini /* Create layout for global indices */ 1098*633354d9SStefano Zampini for (i = 0, m = 0; i < nleaves; i++) m = PetscMax(m, gidxs[i]); 1099*633354d9SStefano Zampini PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &m, 1, MPIU_INT, MPI_MAX, comm)); 1100*633354d9SStefano Zampini PetscCall(PetscLayoutCreate(comm, &layout)); 1101*633354d9SStefano Zampini PetscCall(PetscLayoutSetSize(layout, m + 1)); 1102*633354d9SStefano Zampini PetscCall(PetscLayoutSetUp(layout)); 1103*633354d9SStefano Zampini 1104*633354d9SStefano Zampini /* Create SF to share global indices */ 1105*633354d9SStefano Zampini PetscCall(PetscSFCreate(comm, &sf)); 1106*633354d9SStefano Zampini PetscCall(PetscSFSetGraphLayout(sf, layout, nleaves, NULL, PETSC_OWN_POINTER, gidxs)); 1107*633354d9SStefano Zampini PetscCall(PetscSFSetUp(sf)); 1108*633354d9SStefano Zampini PetscCall(PetscLayoutDestroy(&layout)); 1109*633354d9SStefano Zampini 1110*633354d9SStefano Zampini /* communicate root degree to leaves */ 1111*633354d9SStefano Zampini PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, &sfnode)); 1112*633354d9SStefano Zampini PetscCall(PetscSFComputeDegreeBegin(sf, &rootdegree)); 1113*633354d9SStefano Zampini PetscCall(PetscSFComputeDegreeEnd(sf, &rootdegree)); 1114*633354d9SStefano Zampini for (i = 0, mnroots = 0; i < nroots; i++) mnroots += rootdegree[i]; 1115*633354d9SStefano Zampini PetscCall(PetscMalloc3(2 * PetscMax(mnroots, nroots), &mrootdata, 2 * nleaves, &leafdata, nleaves, &leafrd)); 1116*633354d9SStefano Zampini for (i = 0, m = 0; i < nroots; i++) { 1117*633354d9SStefano Zampini mrootdata[2 * i + 0] = rootdegree[i]; 1118*633354d9SStefano Zampini mrootdata[2 * i + 1] = m; 1119*633354d9SStefano Zampini m += rootdegree[i]; 1120*633354d9SStefano Zampini } 1121*633354d9SStefano Zampini PetscCall(PetscSFBcastBegin(sf, MPIU_2INT, mrootdata, leafdata, MPI_REPLACE)); 1122*633354d9SStefano Zampini PetscCall(PetscSFBcastEnd(sf, MPIU_2INT, mrootdata, leafdata, MPI_REPLACE)); 1123*633354d9SStefano Zampini 1124*633354d9SStefano Zampini /* allocate enough space to store ranks */ 1125*633354d9SStefano Zampini for (i = 0, newnleaves = 0; i < nleaves; i++) { 1126*633354d9SStefano Zampini newnleaves += leafdata[2 * i]; 1127*633354d9SStefano Zampini leafrd[i] = leafdata[2 * i]; 112824cf384cSBarry Smith } 112924cf384cSBarry Smith 1130*633354d9SStefano Zampini /* create new SF nodes to collect multi-root data at leaves */ 1131*633354d9SStefano Zampini PetscCall(PetscMalloc1(newnleaves, &newsfnode)); 1132*633354d9SStefano Zampini for (i = 0, m = 0; i < nleaves; i++) { 1133*633354d9SStefano Zampini for (j = 0; j < leafrd[i]; j++) { 1134*633354d9SStefano Zampini newsfnode[m].rank = sfnode[i].rank; 1135*633354d9SStefano Zampini newsfnode[m].index = leafdata[2 * i + 1] + j; 1136*633354d9SStefano Zampini m++; 1137bc8ff85bSBarry Smith } 1138bc8ff85bSBarry Smith } 1139bc8ff85bSBarry Smith 1140*633354d9SStefano Zampini /* gather ranks at multi roots */ 1141*633354d9SStefano Zampini for (i = 0; i < mnroots; i++) mrootdata[i] = -1; 1142*633354d9SStefano Zampini for (i = 0; i < nleaves; i++) leafdata[i] = (PetscInt)rank; 114330dcb7c9SBarry Smith 1144*633354d9SStefano Zampini PetscCall(PetscSFGatherBegin(sf, MPIU_INT, leafdata, mrootdata)); 1145*633354d9SStefano Zampini PetscCall(PetscSFGatherEnd(sf, MPIU_INT, leafdata, mrootdata)); 11463677ff5aSBarry Smith 1147*633354d9SStefano Zampini /* set new multi-leaves graph into the SF */ 1148*633354d9SStefano Zampini PetscCall(PetscSFSetGraph(sf, mnroots, newnleaves, NULL, PETSC_OWN_POINTER, newsfnode, PETSC_OWN_POINTER)); 1149*633354d9SStefano Zampini PetscCall(PetscSFSetUp(sf)); 1150f6e5521dSKarl Rupp 1151*633354d9SStefano Zampini /* broadcast multi-root data to multi-leaves */ 1152*633354d9SStefano Zampini PetscCall(PetscMalloc1(newnleaves, &newleafdata)); 1153*633354d9SStefano Zampini PetscCall(PetscSFBcastBegin(sf, MPIU_INT, mrootdata, newleafdata, MPI_REPLACE)); 1154*633354d9SStefano Zampini PetscCall(PetscSFBcastEnd(sf, MPIU_INT, mrootdata, newleafdata, MPI_REPLACE)); 1155f6e5521dSKarl Rupp 1156*633354d9SStefano Zampini /* sort sharing ranks */ 1157*633354d9SStefano Zampini for (i = 0, m = 0; i < nleaves; i++) { 1158*633354d9SStefano Zampini PetscCall(PetscSortInt(leafrd[i], newleafdata + m)); 1159*633354d9SStefano Zampini m += leafrd[i]; 116030dcb7c9SBarry Smith } 116130dcb7c9SBarry Smith 1162*633354d9SStefano Zampini /* Number of neighbors and their ranks */ 1163*633354d9SStefano Zampini PetscCall(PetscHMapICreate(&neighs)); 1164*633354d9SStefano Zampini for (i = 0; i < newnleaves; i++) PetscCall(PetscHMapIPut(neighs, newleafdata[i], &iter, &missing)); 1165*633354d9SStefano Zampini PetscCall(PetscHMapIGetSize(neighs, &mapping->info_nproc)); 1166*633354d9SStefano Zampini PetscCall(PetscMalloc1(mapping->info_nproc + 1, &mapping->info_procs)); 1167*633354d9SStefano Zampini PetscCall(PetscHMapIGetKeys(neighs, (i = 0, &i), mapping->info_procs)); 1168*633354d9SStefano Zampini for (i = 0; i < mapping->info_nproc; i++) { /* put info for self first */ 1169*633354d9SStefano Zampini if (mapping->info_procs[i] == rank) { 1170*633354d9SStefano Zampini PetscInt newr = mapping->info_procs[0]; 1171d44834fbSBarry Smith 1172*633354d9SStefano Zampini mapping->info_procs[0] = rank; 1173*633354d9SStefano Zampini mapping->info_procs[i] = newr; 117424cf384cSBarry Smith break; 117524cf384cSBarry Smith } 117624cf384cSBarry Smith } 1177*633354d9SStefano Zampini if (mapping->info_nproc) PetscCall(PetscSortInt(mapping->info_nproc - 1, mapping->info_procs + 1)); 1178*633354d9SStefano Zampini PetscCall(PetscHMapIDestroy(&neighs)); 1179268a049cSStefano Zampini 1180*633354d9SStefano Zampini /* collect info data */ 1181*633354d9SStefano Zampini PetscCall(PetscMalloc1(mapping->info_nproc + 1, &mapping->info_numprocs)); 1182*633354d9SStefano Zampini PetscCall(PetscMalloc1(mapping->info_nproc + 1, &mapping->info_indices)); 1183*633354d9SStefano Zampini for (i = 0; i < mapping->info_nproc + 1; i++) mapping->info_indices[i] = NULL; 1184*633354d9SStefano Zampini 1185*633354d9SStefano Zampini PetscCall(PetscMalloc1(nleaves, &mask)); 1186*633354d9SStefano Zampini PetscCall(PetscMalloc1(nleaves, &tmpg)); 1187*633354d9SStefano Zampini for (p = 0; p < mapping->info_nproc; p++) { 1188*633354d9SStefano Zampini PetscInt *tmp, trank = mapping->info_procs[p]; 1189*633354d9SStefano Zampini 1190*633354d9SStefano Zampini PetscCall(PetscMemzero(mask, nleaves * sizeof(*mask))); 1191*633354d9SStefano Zampini for (i = 0, m = 0; i < nleaves; i++) { 1192*633354d9SStefano Zampini for (j = 0; j < leafrd[i]; j++) { 1193*633354d9SStefano Zampini if (newleafdata[m] == trank) mask[i]++; 1194*633354d9SStefano Zampini if (!p && newleafdata[m] != rank) mask[i]++; 1195*633354d9SStefano Zampini m++; 1196*633354d9SStefano Zampini } 1197*633354d9SStefano Zampini } 1198*633354d9SStefano Zampini for (i = 0, m = 0; i < nleaves; i++) 1199*633354d9SStefano Zampini if (mask[i] > (!p ? 1 : 0)) m++; 1200*633354d9SStefano Zampini 1201*633354d9SStefano Zampini PetscCall(PetscMalloc1(m, &tmp)); 1202*633354d9SStefano Zampini for (i = 0, m = 0; i < nleaves; i++) 1203*633354d9SStefano Zampini if (mask[i] > (!p ? 1 : 0)) { 1204*633354d9SStefano Zampini tmp[m] = i; 1205*633354d9SStefano Zampini tmpg[m] = gidxs[i]; 1206*633354d9SStefano Zampini m++; 1207*633354d9SStefano Zampini } 1208*633354d9SStefano Zampini PetscCall(PetscSortIntWithArray(m, tmpg, tmp)); 1209*633354d9SStefano Zampini mapping->info_indices[p] = tmp; 1210*633354d9SStefano Zampini mapping->info_numprocs[p] = m; 1211*633354d9SStefano Zampini } 1212*633354d9SStefano Zampini 1213*633354d9SStefano Zampini /* Node info */ 1214*633354d9SStefano Zampini PetscCall(PetscMalloc2(nleaves, &mapping->info_nodec, nleaves + 1, &mapping->info_nodei)); 1215*633354d9SStefano Zampini PetscCall(PetscArraycpy(mapping->info_nodec, leafrd, nleaves)); 1216*633354d9SStefano Zampini PetscCall(PetscMalloc1(newnleaves, &mapping->info_nodei[0])); 1217*633354d9SStefano Zampini for (i = 0; i < nleaves - 1; i++) mapping->info_nodei[i + 1] = mapping->info_nodei[i] + mapping->info_nodec[i]; 1218*633354d9SStefano Zampini PetscCall(PetscArraycpy(mapping->info_nodei[0], newleafdata, newnleaves)); 1219*633354d9SStefano Zampini 1220*633354d9SStefano Zampini PetscCall(ISLocalToGlobalMappingRestoreBlockIndices(mapping, &gidxs)); 1221*633354d9SStefano Zampini PetscCall(PetscFree(tmpg)); 1222*633354d9SStefano Zampini PetscCall(PetscFree(mask)); 1223*633354d9SStefano Zampini PetscCall(PetscSFDestroy(&sf)); 1224*633354d9SStefano Zampini PetscCall(PetscFree3(mrootdata, leafdata, leafrd)); 1225*633354d9SStefano Zampini PetscCall(PetscFree(newleafdata)); 12263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 122789d82c54SBarry Smith } 122889d82c54SBarry Smith 12296a818285SBarry Smith /*@C 1230cab54364SBarry Smith ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetBlockInfo()` 12316a818285SBarry Smith 1232*633354d9SStefano Zampini Not Collective 12336a818285SBarry Smith 1234*633354d9SStefano Zampini Input Parameters: 1235*633354d9SStefano Zampini + mapping - the mapping from local to global indexing 1236*633354d9SStefano Zampini . nproc - number of processes that are connected to the calling process 1237*633354d9SStefano Zampini . procs - neighboring processes 1238*633354d9SStefano Zampini . numprocs - number of block indices for each process 1239*633354d9SStefano Zampini - indices - block indices (in local numbering) shared with neighbors (sorted by global numbering) 12406a818285SBarry Smith 12416a818285SBarry Smith Level: advanced 12426a818285SBarry Smith 1243cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`, 1244db781477SPatrick Sanan `ISLocalToGlobalMappingGetInfo()` 12456a818285SBarry Smith @*/ 1246d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[]) 1247d71ae5a4SJacob Faibussowitsch { 12486a818285SBarry Smith PetscFunctionBegin; 1249cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 1250*633354d9SStefano Zampini if (nproc) *nproc = 0; 1251*633354d9SStefano Zampini if (procs) *procs = NULL; 1252*633354d9SStefano Zampini if (numprocs) *numprocs = NULL; 1253*633354d9SStefano Zampini if (indices) *indices = NULL; 12543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12556a818285SBarry Smith } 12566a818285SBarry Smith 12576a818285SBarry Smith /*@C 1258*633354d9SStefano Zampini ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each process 12596a818285SBarry Smith 1260*633354d9SStefano Zampini Collective the first time it is called 12616a818285SBarry Smith 1262f899ff85SJose E. Roman Input Parameter: 12636a818285SBarry Smith . mapping - the mapping from local to global indexing 12646a818285SBarry Smith 1265d8d19677SJose E. Roman Output Parameters: 1266*633354d9SStefano Zampini + nproc - number of processes that are connected to the calling process 1267*633354d9SStefano Zampini . procs - neighboring processes 1268*633354d9SStefano Zampini . numprocs - number of indices for each process 1269*633354d9SStefano Zampini - indices - indices (in local numbering) shared with neighbors (sorted by global numbering) 12706a818285SBarry Smith 12716a818285SBarry Smith Level: advanced 12726a818285SBarry Smith 1273cab54364SBarry Smith Note: 1274cab54364SBarry Smith The user needs to call `ISLocalToGlobalMappingRestoreInfo()` when the data is no longer needed. 12751bd0b88eSStefano Zampini 127638b5cf2dSJacob Faibussowitsch Fortran Notes: 1277e33f79d8SJacob Faibussowitsch There is no `ISLocalToGlobalMappingRestoreInfo()` in Fortran. You must make sure that 1278e33f79d8SJacob Faibussowitsch `procs`[], `numprocs`[] and `indices`[][] are large enough arrays, either by allocating them 1279e33f79d8SJacob Faibussowitsch dynamically or defining static ones large enough. 1280e33f79d8SJacob Faibussowitsch 1281cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`, 1282*633354d9SStefano Zampini `ISLocalToGlobalMappingRestoreInfo()`, `ISLocalToGlobalMappingGetNodeInfo()` 12836a818285SBarry Smith @*/ 1284d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[]) 1285d71ae5a4SJacob Faibussowitsch { 1286*633354d9SStefano Zampini PetscInt **bindices = NULL, *bnumprocs = NULL, bs, i, j, k, n, *bprocs; 12876a818285SBarry Smith 12886a818285SBarry Smith PetscFunctionBegin; 12896a818285SBarry Smith PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 12908a1f772fSStefano Zampini bs = mapping->bs; 1291*633354d9SStefano Zampini PetscCall(ISLocalToGlobalMappingGetBlockInfo(mapping, &n, &bprocs, &bnumprocs, &bindices)); 1292268a049cSStefano Zampini if (bs > 1) { /* we need to expand the cached info */ 1293*633354d9SStefano Zampini if (indices) PetscCall(PetscCalloc1(n, indices)); 1294*633354d9SStefano Zampini if (numprocs) PetscCall(PetscCalloc1(n, numprocs)); 1295*633354d9SStefano Zampini if (indices || numprocs) { 1296*633354d9SStefano Zampini for (i = 0; i < n; i++) { 1297*633354d9SStefano Zampini if (indices) { 12989566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(bs * bnumprocs[i], &(*indices)[i])); 1299268a049cSStefano Zampini for (j = 0; j < bnumprocs[i]; j++) { 1300ad540459SPierre Jolivet for (k = 0; k < bs; k++) (*indices)[i][j * bs + k] = bs * bindices[i][j] + k; 13016a818285SBarry Smith } 13026a818285SBarry Smith } 1303*633354d9SStefano Zampini if (numprocs) (*numprocs)[i] = bnumprocs[i] * bs; 1304*633354d9SStefano Zampini } 1305*633354d9SStefano Zampini } 1306268a049cSStefano Zampini } else { 1307*633354d9SStefano Zampini if (numprocs) *numprocs = bnumprocs; 1308*633354d9SStefano Zampini if (indices) *indices = bindices; 13096a818285SBarry Smith } 1310*633354d9SStefano Zampini if (nproc) *nproc = n; 1311*633354d9SStefano Zampini if (procs) *procs = bprocs; 13123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13136a818285SBarry Smith } 13146a818285SBarry Smith 131507b52d57SBarry Smith /*@C 1316cab54364SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetInfo()` 131789d82c54SBarry Smith 1318*633354d9SStefano Zampini Not Collective 131907b52d57SBarry Smith 1320*633354d9SStefano Zampini Input Parameters: 1321*633354d9SStefano Zampini + mapping - the mapping from local to global indexing 1322*633354d9SStefano Zampini . nproc - number of processes that are connected to the calling process 1323*633354d9SStefano Zampini . procs - neighboring processes 1324*633354d9SStefano Zampini . numprocs - number of indices for each process 1325*633354d9SStefano Zampini - indices - indices (in local numbering) shared with neighbors (sorted by global numbering) 132607b52d57SBarry Smith 132707b52d57SBarry Smith Level: advanced 132807b52d57SBarry Smith 1329cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`, 1330db781477SPatrick Sanan `ISLocalToGlobalMappingGetInfo()` 133107b52d57SBarry Smith @*/ 1332d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[]) 1333d71ae5a4SJacob Faibussowitsch { 133407b52d57SBarry Smith PetscFunctionBegin; 1335*633354d9SStefano Zampini PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 1336*633354d9SStefano Zampini if (mapping->bs > 1) { 1337*633354d9SStefano Zampini if (numprocs) PetscCall(PetscFree(*numprocs)); 1338*633354d9SStefano Zampini if (indices) { 1339*633354d9SStefano Zampini if (*indices) 1340*633354d9SStefano Zampini for (PetscInt i = 0; i < *nproc; i++) PetscCall(PetscFree((*indices)[i])); 1341*633354d9SStefano Zampini PetscCall(PetscFree(*indices)); 1342*633354d9SStefano Zampini } 1343*633354d9SStefano Zampini } 13443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 134507b52d57SBarry Smith } 134686994e45SJed Brown 134786994e45SJed Brown /*@C 1348*633354d9SStefano Zampini ISLocalToGlobalMappingGetNodeInfo - Gets the neighbor information of local nodes 13491bd0b88eSStefano Zampini 1350*633354d9SStefano Zampini Collective the first time it is called 13511bd0b88eSStefano Zampini 1352f899ff85SJose E. Roman Input Parameter: 13531bd0b88eSStefano Zampini . mapping - the mapping from local to global indexing 13541bd0b88eSStefano Zampini 1355d8d19677SJose E. Roman Output Parameters: 1356*633354d9SStefano Zampini + n - number of local nodes 1357*633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local node (including self) 1358*633354d9SStefano Zampini - procs - the processes' rank for each local node (sorted, self is first) 13591bd0b88eSStefano Zampini 13601bd0b88eSStefano Zampini Level: advanced 13611bd0b88eSStefano Zampini 1362cab54364SBarry Smith Note: 1363*633354d9SStefano Zampini The user needs to call `ISLocalToGlobalMappingRestoreNodeInfo()` when the data is no longer needed. 13641bd0b88eSStefano Zampini 1365cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`, 1366*633354d9SStefano Zampini `ISLocalToGlobalMappingGetInfo()`, `ISLocalToGlobalMappingRestoreNodeInfo()`, `ISLocalToGlobalMappingGetBlockNodeInfo()` 13671bd0b88eSStefano Zampini @*/ 1368*633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingGetNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[]) 1369d71ae5a4SJacob Faibussowitsch { 1370*633354d9SStefano Zampini PetscInt **bprocs = NULL, *bn_procs = NULL, bs, i, j, k, bn; 13711bd0b88eSStefano Zampini 13721bd0b88eSStefano Zampini PetscFunctionBegin; 13731bd0b88eSStefano Zampini PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 1374*633354d9SStefano Zampini bs = mapping->bs; 1375*633354d9SStefano Zampini PetscCall(ISLocalToGlobalMappingGetBlockNodeInfo(mapping, &bn, &bn_procs, &bprocs)); 1376*633354d9SStefano Zampini if (bs > 1) { /* we need to expand the cached info */ 1377*633354d9SStefano Zampini PetscInt *tn_procs; 1378*633354d9SStefano Zampini PetscInt c; 13791bd0b88eSStefano Zampini 1380*633354d9SStefano Zampini PetscCall(PetscMalloc1(bn * bs, &tn_procs)); 1381*633354d9SStefano Zampini for (i = 0, c = 0; i < bn; i++) { 1382*633354d9SStefano Zampini for (k = 0; k < bs; k++) tn_procs[i * bs + k] = bn_procs[i]; 1383*633354d9SStefano Zampini c += bs * bn_procs[i]; 1384*633354d9SStefano Zampini } 1385*633354d9SStefano Zampini if (n) *n = bn * bs; 1386*633354d9SStefano Zampini if (procs) { 1387*633354d9SStefano Zampini PetscInt **tprocs; 1388*633354d9SStefano Zampini PetscInt tn = bn * bs; 13891bd0b88eSStefano Zampini 1390*633354d9SStefano Zampini PetscCall(PetscMalloc1(tn, &tprocs)); 1391*633354d9SStefano Zampini if (tn) PetscCall(PetscMalloc1(c, &tprocs[0])); 1392*633354d9SStefano Zampini for (i = 0; i < tn - 1; i++) tprocs[i + 1] = tprocs[i] + tn_procs[i]; 1393*633354d9SStefano Zampini for (i = 0; i < bn; i++) { 1394*633354d9SStefano Zampini for (k = 0; k < bs; k++) { 1395*633354d9SStefano Zampini for (j = 0; j < bn_procs[i]; j++) tprocs[i * bs + k][j] = bprocs[i][j]; 13961bd0b88eSStefano Zampini } 13971bd0b88eSStefano Zampini } 1398*633354d9SStefano Zampini *procs = tprocs; 13991bd0b88eSStefano Zampini } 1400*633354d9SStefano Zampini if (n_procs) *n_procs = tn_procs; 1401*633354d9SStefano Zampini else PetscCall(PetscFree(tn_procs)); 1402*633354d9SStefano Zampini } else { 1403*633354d9SStefano Zampini if (n) *n = bn; 1404*633354d9SStefano Zampini if (n_procs) *n_procs = bn_procs; 1405*633354d9SStefano Zampini if (procs) *procs = bprocs; 1406*633354d9SStefano Zampini } 14073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14081bd0b88eSStefano Zampini } 14091bd0b88eSStefano Zampini 14101bd0b88eSStefano Zampini /*@C 1411cab54364SBarry Smith ISLocalToGlobalMappingRestoreNodeInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetNodeInfo()` 14121bd0b88eSStefano Zampini 1413*633354d9SStefano Zampini Not Collective 14141bd0b88eSStefano Zampini 1415*633354d9SStefano Zampini Input Parameters: 1416*633354d9SStefano Zampini + mapping - the mapping from local to global indexing 1417*633354d9SStefano Zampini . n - number of local nodes 1418*633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local node (including self) 1419*633354d9SStefano Zampini - procs - the processes' rank for each local node (sorted, self is first) 14201bd0b88eSStefano Zampini 14211bd0b88eSStefano Zampini Level: advanced 14221bd0b88eSStefano Zampini 1423cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`, 1424db781477SPatrick Sanan `ISLocalToGlobalMappingGetInfo()` 14251bd0b88eSStefano Zampini @*/ 1426*633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingRestoreNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[]) 1427d71ae5a4SJacob Faibussowitsch { 14281bd0b88eSStefano Zampini PetscFunctionBegin; 14291bd0b88eSStefano Zampini PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1); 1430*633354d9SStefano Zampini if (mapping->bs > 1) { 1431*633354d9SStefano Zampini if (n_procs) PetscCall(PetscFree(*n_procs)); 1432*633354d9SStefano Zampini if (procs) { 1433*633354d9SStefano Zampini if (*procs) PetscCall(PetscFree((*procs)[0])); 1434*633354d9SStefano Zampini PetscCall(PetscFree(*procs)); 1435*633354d9SStefano Zampini } 1436*633354d9SStefano Zampini } 1437*633354d9SStefano Zampini PetscCall(ISLocalToGlobalMappingRestoreBlockNodeInfo(mapping, n, n_procs, procs)); 14383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14391bd0b88eSStefano Zampini } 14401bd0b88eSStefano Zampini 14416ce40d10SBarry Smith /*MC 14426ce40d10SBarry Smith ISLocalToGlobalMappingGetIndicesF90 - Get global indices for every local point that is mapped 14436ce40d10SBarry Smith 14446ce40d10SBarry Smith Synopsis: 14456ce40d10SBarry Smith ISLocalToGlobalMappingGetIndicesF90(ISLocalToGlobalMapping ltog, PetscInt, pointer :: array(:)}, integer ierr) 14466ce40d10SBarry Smith 14476ce40d10SBarry Smith Not Collective 14486ce40d10SBarry Smith 14496ce40d10SBarry Smith Input Parameter: 14506ce40d10SBarry Smith . A - the matrix 14516ce40d10SBarry Smith 14522fe279fdSBarry Smith Output Parameter: 14536ce40d10SBarry Smith . array - array of indices, the length of this array may be obtained with `ISLocalToGlobalMappingGetSize()` 14546ce40d10SBarry Smith 14556ce40d10SBarry Smith Level: advanced 14566ce40d10SBarry Smith 14576ce40d10SBarry Smith Note: 14586ce40d10SBarry Smith Use `ISLocalToGlobalMappingGetIndicesF90()` when you no longer need access to the data 14596ce40d10SBarry Smith 146020662ed9SBarry Smith .seealso: [](sec_fortranarrays), [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingGetIndices()`, `ISLocalToGlobalMappingRestoreIndices()`, 146120662ed9SBarry Smith `ISLocalToGlobalMappingRestoreIndicesF90()` 14626ce40d10SBarry Smith M*/ 14636ce40d10SBarry Smith 14646ce40d10SBarry Smith /*MC 14656ce40d10SBarry Smith ISLocalToGlobalMappingRestoreIndicesF90 - restores the global indices for every local point that is mapped obtained with `ISLocalToGlobalMappingGetIndicesF90()` 14666ce40d10SBarry Smith 14676ce40d10SBarry Smith Synopsis: 14686ce40d10SBarry Smith ISLocalToGlobalMappingRestoreIndicesF90(ISLocalToGlobalMapping ltog, PetscInt, pointer :: array(:)}, integer ierr) 14696ce40d10SBarry Smith 14706ce40d10SBarry Smith Not Collective 14716ce40d10SBarry Smith 14726ce40d10SBarry Smith Input Parameters: 14736ce40d10SBarry Smith + A - the matrix 14746ce40d10SBarry Smith - array - array of indices, the length of this array may be obtained with `ISLocalToGlobalMappingGetSize()` 14756ce40d10SBarry Smith 14766ce40d10SBarry Smith Level: advanced 14776ce40d10SBarry Smith 147820662ed9SBarry Smith .seealso: [](sec_fortranarrays), [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingGetIndices()`, `ISLocalToGlobalMappingRestoreIndices()`, 147920662ed9SBarry Smith `ISLocalToGlobalMappingGetIndicesF90()` 14806ce40d10SBarry Smith M*/ 14816ce40d10SBarry Smith 14821bd0b88eSStefano Zampini /*@C 1483107e9a97SBarry Smith ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped 148486994e45SJed Brown 148586994e45SJed Brown Not Collective 148686994e45SJed Brown 14874165533cSJose E. Roman Input Parameter: 148886994e45SJed Brown . ltog - local to global mapping 148986994e45SJed Brown 14904165533cSJose E. Roman Output Parameter: 1491cab54364SBarry Smith . array - array of indices, the length of this array may be obtained with `ISLocalToGlobalMappingGetSize()` 149286994e45SJed Brown 149386994e45SJed Brown Level: advanced 149486994e45SJed Brown 1495cab54364SBarry Smith Note: 1496cab54364SBarry Smith `ISLocalToGlobalMappingGetSize()` returns the length the this array 1497107e9a97SBarry Smith 149820662ed9SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingRestoreIndices()`, 149920662ed9SBarry Smith `ISLocalToGlobalMappingGetBlockIndices()`, `ISLocalToGlobalMappingRestoreBlockIndices()` 150086994e45SJed Brown @*/ 1501d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog, const PetscInt **array) 1502d71ae5a4SJacob Faibussowitsch { 150386994e45SJed Brown PetscFunctionBegin; 150486994e45SJed Brown PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1); 15054f572ea9SToby Isaac PetscAssertPointer(array, 2); 150645b6f7e9SBarry Smith if (ltog->bs == 1) { 150786994e45SJed Brown *array = ltog->indices; 150845b6f7e9SBarry Smith } else { 150945b6f7e9SBarry Smith PetscInt *jj, k, i, j, n = ltog->n, bs = ltog->bs; 151045b6f7e9SBarry Smith const PetscInt *ii; 151145b6f7e9SBarry Smith 15129566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(bs * n, &jj)); 151345b6f7e9SBarry Smith *array = jj; 151445b6f7e9SBarry Smith k = 0; 151545b6f7e9SBarry Smith ii = ltog->indices; 151645b6f7e9SBarry Smith for (i = 0; i < n; i++) 15179371c9d4SSatish Balay for (j = 0; j < bs; j++) jj[k++] = bs * ii[i] + j; 151845b6f7e9SBarry Smith } 15193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 152086994e45SJed Brown } 152186994e45SJed Brown 152286994e45SJed Brown /*@C 1523cab54364SBarry Smith ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with `ISLocalToGlobalMappingGetIndices()` 152486994e45SJed Brown 152586994e45SJed Brown Not Collective 152686994e45SJed Brown 15274165533cSJose E. Roman Input Parameters: 152886994e45SJed Brown + ltog - local to global mapping 152986994e45SJed Brown - array - array of indices 153086994e45SJed Brown 153186994e45SJed Brown Level: advanced 153286994e45SJed Brown 1533cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingGetIndices()` 153486994e45SJed Brown @*/ 1535d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog, const PetscInt **array) 1536d71ae5a4SJacob Faibussowitsch { 153786994e45SJed Brown PetscFunctionBegin; 153886994e45SJed Brown PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1); 15394f572ea9SToby Isaac PetscAssertPointer(array, 2); 1540c9cc58a2SBarry Smith PetscCheck(ltog->bs != 1 || *array == ltog->indices, PETSC_COMM_SELF, PETSC_ERR_ARG_BADPTR, "Trying to return mismatched pointer"); 154148a46eb9SPierre Jolivet if (ltog->bs > 1) PetscCall(PetscFree(*(void **)array)); 15423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 154345b6f7e9SBarry Smith } 154445b6f7e9SBarry Smith 154545b6f7e9SBarry Smith /*@C 154645b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block 154745b6f7e9SBarry Smith 154845b6f7e9SBarry Smith Not Collective 154945b6f7e9SBarry Smith 15504165533cSJose E. Roman Input Parameter: 155145b6f7e9SBarry Smith . ltog - local to global mapping 155245b6f7e9SBarry Smith 15534165533cSJose E. Roman Output Parameter: 155445b6f7e9SBarry Smith . array - array of indices 155545b6f7e9SBarry Smith 155645b6f7e9SBarry Smith Level: advanced 155745b6f7e9SBarry Smith 1558cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingRestoreBlockIndices()` 155945b6f7e9SBarry Smith @*/ 1560d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog, const PetscInt **array) 1561d71ae5a4SJacob Faibussowitsch { 156245b6f7e9SBarry Smith PetscFunctionBegin; 156345b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1); 15644f572ea9SToby Isaac PetscAssertPointer(array, 2); 156545b6f7e9SBarry Smith *array = ltog->indices; 15663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 156745b6f7e9SBarry Smith } 156845b6f7e9SBarry Smith 156945b6f7e9SBarry Smith /*@C 1570cab54364SBarry Smith ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with `ISLocalToGlobalMappingGetBlockIndices()` 157145b6f7e9SBarry Smith 157245b6f7e9SBarry Smith Not Collective 157345b6f7e9SBarry Smith 15744165533cSJose E. Roman Input Parameters: 157545b6f7e9SBarry Smith + ltog - local to global mapping 157645b6f7e9SBarry Smith - array - array of indices 157745b6f7e9SBarry Smith 157845b6f7e9SBarry Smith Level: advanced 157945b6f7e9SBarry Smith 1580cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingGetIndices()` 158145b6f7e9SBarry Smith @*/ 1582d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog, const PetscInt **array) 1583d71ae5a4SJacob Faibussowitsch { 158445b6f7e9SBarry Smith PetscFunctionBegin; 158545b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1); 15864f572ea9SToby Isaac PetscAssertPointer(array, 2); 158708401ef6SPierre Jolivet PetscCheck(*array == ltog->indices, PETSC_COMM_SELF, PETSC_ERR_ARG_BADPTR, "Trying to return mismatched pointer"); 15880298fd71SBarry Smith *array = NULL; 15893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 159086994e45SJed Brown } 1591f7efa3c7SJed Brown 1592f7efa3c7SJed Brown /*@C 1593f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1594f7efa3c7SJed Brown 1595f7efa3c7SJed Brown Not Collective 1596f7efa3c7SJed Brown 15974165533cSJose E. Roman Input Parameters: 1598f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1599f7efa3c7SJed Brown . n - number of mappings to concatenate 1600f7efa3c7SJed Brown - ltogs - local to global mappings 1601f7efa3c7SJed Brown 16024165533cSJose E. Roman Output Parameter: 1603f7efa3c7SJed Brown . ltogcat - new mapping 1604f7efa3c7SJed Brown 1605f7efa3c7SJed Brown Level: advanced 1606f7efa3c7SJed Brown 1607cab54364SBarry Smith Note: 1608cab54364SBarry Smith This currently always returns a mapping with block size of 1 1609cab54364SBarry Smith 161038b5cf2dSJacob Faibussowitsch Developer Notes: 1611cab54364SBarry Smith If all the input mapping have the same block size we could easily handle that as a special case 1612cab54364SBarry Smith 1613cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingCreate()` 1614f7efa3c7SJed Brown @*/ 1615d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm, PetscInt n, const ISLocalToGlobalMapping ltogs[], ISLocalToGlobalMapping *ltogcat) 1616d71ae5a4SJacob Faibussowitsch { 1617f7efa3c7SJed Brown PetscInt i, cnt, m, *idx; 1618f7efa3c7SJed Brown 1619f7efa3c7SJed Brown PetscFunctionBegin; 162008401ef6SPierre Jolivet PetscCheck(n >= 0, comm, PETSC_ERR_ARG_OUTOFRANGE, "Must have a non-negative number of mappings, given %" PetscInt_FMT, n); 16214f572ea9SToby Isaac if (n > 0) PetscAssertPointer(ltogs, 3); 1622f7efa3c7SJed Brown for (i = 0; i < n; i++) PetscValidHeaderSpecific(ltogs[i], IS_LTOGM_CLASSID, 3); 16234f572ea9SToby Isaac PetscAssertPointer(ltogcat, 4); 1624f7efa3c7SJed Brown for (cnt = 0, i = 0; i < n; i++) { 16259566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetSize(ltogs[i], &m)); 1626f7efa3c7SJed Brown cnt += m; 1627f7efa3c7SJed Brown } 16289566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(cnt, &idx)); 1629f7efa3c7SJed Brown for (cnt = 0, i = 0; i < n; i++) { 1630f7efa3c7SJed Brown const PetscInt *subidx; 16319566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetSize(ltogs[i], &m)); 16329566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetIndices(ltogs[i], &subidx)); 16339566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(&idx[cnt], subidx, m)); 16349566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingRestoreIndices(ltogs[i], &subidx)); 1635f7efa3c7SJed Brown cnt += m; 1636f7efa3c7SJed Brown } 16379566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(comm, 1, cnt, idx, PETSC_OWN_POINTER, ltogcat)); 16383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1639f7efa3c7SJed Brown } 164004a59952SBarry Smith 1641413f72f0SBarry Smith /*MC 1642cab54364SBarry Smith ISLOCALTOGLOBALMAPPINGBASIC - basic implementation of the `ISLocalToGlobalMapping` object. When `ISGlobalToLocalMappingApply()` is 1643413f72f0SBarry Smith used this is good for only small and moderate size problems. 1644413f72f0SBarry Smith 164520662ed9SBarry Smith Options Database Key: 1646a2b725a8SWilliam Gropp . -islocaltoglobalmapping_type basic - select this method 1647413f72f0SBarry Smith 1648413f72f0SBarry Smith Level: beginner 1649413f72f0SBarry Smith 1650cab54364SBarry Smith Developer Note: 1651cab54364SBarry Smith This stores all the mapping information on each MPI rank. 1652cab54364SBarry Smith 1653cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetType()`, `ISLOCALTOGLOBALMAPPINGHASH` 1654413f72f0SBarry Smith M*/ 1655d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingCreate_Basic(ISLocalToGlobalMapping ltog) 1656d71ae5a4SJacob Faibussowitsch { 1657413f72f0SBarry Smith PetscFunctionBegin; 1658413f72f0SBarry Smith ltog->ops->globaltolocalmappingapply = ISGlobalToLocalMappingApply_Basic; 1659413f72f0SBarry Smith ltog->ops->globaltolocalmappingsetup = ISGlobalToLocalMappingSetUp_Basic; 1660413f72f0SBarry Smith ltog->ops->globaltolocalmappingapplyblock = ISGlobalToLocalMappingApplyBlock_Basic; 1661413f72f0SBarry Smith ltog->ops->destroy = ISLocalToGlobalMappingDestroy_Basic; 16623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1663413f72f0SBarry Smith } 1664413f72f0SBarry Smith 1665413f72f0SBarry Smith /*MC 1666cab54364SBarry Smith ISLOCALTOGLOBALMAPPINGHASH - hash implementation of the `ISLocalToGlobalMapping` object. When `ISGlobalToLocalMappingApply()` is 1667ed56e8eaSBarry Smith used this is good for large memory problems. 1668413f72f0SBarry Smith 166920662ed9SBarry Smith Options Database Key: 1670a2b725a8SWilliam Gropp . -islocaltoglobalmapping_type hash - select this method 1671413f72f0SBarry Smith 1672413f72f0SBarry Smith Level: beginner 1673413f72f0SBarry Smith 1674cab54364SBarry Smith Note: 1675cab54364SBarry Smith This is selected automatically for large problems if the user does not set the type. 1676cab54364SBarry Smith 1677cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetType()`, `ISLOCALTOGLOBALMAPPINGBASIC` 1678413f72f0SBarry Smith M*/ 1679d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingCreate_Hash(ISLocalToGlobalMapping ltog) 1680d71ae5a4SJacob Faibussowitsch { 1681413f72f0SBarry Smith PetscFunctionBegin; 1682413f72f0SBarry Smith ltog->ops->globaltolocalmappingapply = ISGlobalToLocalMappingApply_Hash; 1683413f72f0SBarry Smith ltog->ops->globaltolocalmappingsetup = ISGlobalToLocalMappingSetUp_Hash; 1684413f72f0SBarry Smith ltog->ops->globaltolocalmappingapplyblock = ISGlobalToLocalMappingApplyBlock_Hash; 1685413f72f0SBarry Smith ltog->ops->destroy = ISLocalToGlobalMappingDestroy_Hash; 16863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1687413f72f0SBarry Smith } 1688413f72f0SBarry Smith 1689413f72f0SBarry Smith /*@C 1690cab54364SBarry Smith ISLocalToGlobalMappingRegister - Registers a method for applying a global to local mapping with an `ISLocalToGlobalMapping` 1691413f72f0SBarry Smith 1692413f72f0SBarry Smith Not Collective 1693413f72f0SBarry Smith 1694413f72f0SBarry Smith Input Parameters: 1695413f72f0SBarry Smith + sname - name of a new method 16962fe279fdSBarry Smith - function - routine to create method context 1697413f72f0SBarry Smith 169838b5cf2dSJacob Faibussowitsch Example Usage: 1699413f72f0SBarry Smith .vb 1700413f72f0SBarry Smith ISLocalToGlobalMappingRegister("my_mapper", MyCreate); 1701413f72f0SBarry Smith .ve 1702413f72f0SBarry Smith 1703ed56e8eaSBarry Smith Then, your mapping can be chosen with the procedural interface via 1704413f72f0SBarry Smith $ ISLocalToGlobalMappingSetType(ltog, "my_mapper") 1705413f72f0SBarry Smith or at runtime via the option 1706ed56e8eaSBarry Smith $ -islocaltoglobalmapping_type my_mapper 1707413f72f0SBarry Smith 1708413f72f0SBarry Smith Level: advanced 1709413f72f0SBarry Smith 1710cab54364SBarry Smith Note: 1711cab54364SBarry Smith `ISLocalToGlobalMappingRegister()` may be called multiple times to add several user-defined mappings. 1712413f72f0SBarry Smith 1713cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingRegisterAll()`, `ISLocalToGlobalMappingRegisterDestroy()`, `ISLOCALTOGLOBALMAPPINGBASIC`, 1714cab54364SBarry Smith `ISLOCALTOGLOBALMAPPINGHASH`, `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApply()` 1715413f72f0SBarry Smith @*/ 1716d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRegister(const char sname[], PetscErrorCode (*function)(ISLocalToGlobalMapping)) 1717d71ae5a4SJacob Faibussowitsch { 1718413f72f0SBarry Smith PetscFunctionBegin; 17199566063dSJacob Faibussowitsch PetscCall(ISInitializePackage()); 17209566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&ISLocalToGlobalMappingList, sname, function)); 17213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1722413f72f0SBarry Smith } 1723413f72f0SBarry Smith 1724413f72f0SBarry Smith /*@C 1725cab54364SBarry Smith ISLocalToGlobalMappingSetType - Sets the implementation type `ISLocalToGlobalMapping` will use 1726413f72f0SBarry Smith 1727c3339decSBarry Smith Logically Collective 1728413f72f0SBarry Smith 1729413f72f0SBarry Smith Input Parameters: 1730cab54364SBarry Smith + ltog - the `ISLocalToGlobalMapping` object 1731413f72f0SBarry Smith - type - a known method 1732413f72f0SBarry Smith 1733413f72f0SBarry Smith Options Database Key: 1734cab54364SBarry Smith . -islocaltoglobalmapping_type <method> - Sets the method; use -help for a list of available methods (for instance, basic or hash) 1735cab54364SBarry Smith 1736cab54364SBarry Smith Level: intermediate 1737413f72f0SBarry Smith 1738413f72f0SBarry Smith Notes: 173920662ed9SBarry Smith See `ISLocalToGlobalMappingType` for available methods 1740413f72f0SBarry Smith 1741cab54364SBarry Smith Normally, it is best to use the `ISLocalToGlobalMappingSetFromOptions()` command and 1742cab54364SBarry Smith then set the `ISLocalToGlobalMappingType` from the options database rather than by using 1743413f72f0SBarry Smith this routine. 1744413f72f0SBarry Smith 174538b5cf2dSJacob Faibussowitsch Developer Notes: 1746cab54364SBarry Smith `ISLocalToGlobalMappingRegister()` is used to add new types to `ISLocalToGlobalMappingList` from which they 1747cab54364SBarry Smith are accessed by `ISLocalToGlobalMappingSetType()`. 1748413f72f0SBarry Smith 174938b5cf2dSJacob Faibussowitsch .seealso: [](sec_scatter), `ISLocalToGlobalMappingType`, `ISLocalToGlobalMappingRegister()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingGetType()` 1750413f72f0SBarry Smith @*/ 1751d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingSetType(ISLocalToGlobalMapping ltog, ISLocalToGlobalMappingType type) 1752d71ae5a4SJacob Faibussowitsch { 1753413f72f0SBarry Smith PetscBool match; 17545f80ce2aSJacob Faibussowitsch PetscErrorCode (*r)(ISLocalToGlobalMapping) = NULL; 1755413f72f0SBarry Smith 1756413f72f0SBarry Smith PetscFunctionBegin; 1757413f72f0SBarry Smith PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1); 17584f572ea9SToby Isaac if (type) PetscAssertPointer(type, 2); 1759413f72f0SBarry Smith 17609566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ltog, type, &match)); 17613ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 1762413f72f0SBarry Smith 1763a0d79125SStefano Zampini /* L2G maps defer type setup at globaltolocal calls, allow passing NULL here */ 1764a0d79125SStefano Zampini if (type) { 17659566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(ISLocalToGlobalMappingList, type, &r)); 1766a0d79125SStefano Zampini PetscCheck(r, PetscObjectComm((PetscObject)ltog), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested ISLocalToGlobalMapping type %s", type); 1767a0d79125SStefano Zampini } 1768413f72f0SBarry Smith /* Destroy the previous private LTOG context */ 1769dbbe0bcdSBarry Smith PetscTryTypeMethod(ltog, destroy); 1770413f72f0SBarry Smith ltog->ops->destroy = NULL; 1771dbbe0bcdSBarry Smith 17729566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)ltog, type)); 17739566063dSJacob Faibussowitsch if (r) PetscCall((*r)(ltog)); 17743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1775a0d79125SStefano Zampini } 1776a0d79125SStefano Zampini 1777a0d79125SStefano Zampini /*@C 1778cab54364SBarry Smith ISLocalToGlobalMappingGetType - Get the type of the `ISLocalToGlobalMapping` 1779a0d79125SStefano Zampini 1780a0d79125SStefano Zampini Not Collective 1781a0d79125SStefano Zampini 1782a0d79125SStefano Zampini Input Parameter: 1783cab54364SBarry Smith . ltog - the `ISLocalToGlobalMapping` object 1784a0d79125SStefano Zampini 1785a0d79125SStefano Zampini Output Parameter: 1786a0d79125SStefano Zampini . type - the type 1787a0d79125SStefano Zampini 178849762cbcSSatish Balay Level: intermediate 178949762cbcSSatish Balay 179038b5cf2dSJacob Faibussowitsch .seealso: [](sec_scatter), `ISLocalToGlobalMappingType`, `ISLocalToGlobalMappingRegister()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetType()` 1791a0d79125SStefano Zampini @*/ 1792d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetType(ISLocalToGlobalMapping ltog, ISLocalToGlobalMappingType *type) 1793d71ae5a4SJacob Faibussowitsch { 1794a0d79125SStefano Zampini PetscFunctionBegin; 1795a0d79125SStefano Zampini PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1); 17964f572ea9SToby Isaac PetscAssertPointer(type, 2); 1797a0d79125SStefano Zampini *type = ((PetscObject)ltog)->type_name; 17983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1799413f72f0SBarry Smith } 1800413f72f0SBarry Smith 1801413f72f0SBarry Smith PetscBool ISLocalToGlobalMappingRegisterAllCalled = PETSC_FALSE; 1802413f72f0SBarry Smith 1803413f72f0SBarry Smith /*@C 1804cab54364SBarry Smith ISLocalToGlobalMappingRegisterAll - Registers all of the local to global mapping components in the `IS` package. 1805413f72f0SBarry Smith 1806413f72f0SBarry Smith Not Collective 1807413f72f0SBarry Smith 1808413f72f0SBarry Smith Level: advanced 1809413f72f0SBarry Smith 1810cab54364SBarry Smith .seealso: [](sec_scatter), `ISRegister()`, `ISLocalToGlobalRegister()` 1811413f72f0SBarry Smith @*/ 1812d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRegisterAll(void) 1813d71ae5a4SJacob Faibussowitsch { 1814413f72f0SBarry Smith PetscFunctionBegin; 18153ba16761SJacob Faibussowitsch if (ISLocalToGlobalMappingRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 1816413f72f0SBarry Smith ISLocalToGlobalMappingRegisterAllCalled = PETSC_TRUE; 18179566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingRegister(ISLOCALTOGLOBALMAPPINGBASIC, ISLocalToGlobalMappingCreate_Basic)); 18189566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingRegister(ISLOCALTOGLOBALMAPPINGHASH, ISLocalToGlobalMappingCreate_Hash)); 18193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1820413f72f0SBarry Smith } 1821