Actual source code: pmap.c

petsc-3.3-p7 2013-05-11
  2: /*
  3:    This file contains routines for basic map object implementation.
  4: */

  6: #include <petsc-private/vecimpl.h>   /*I  "petscvec.h"   I*/
  7: #include <petsc-private/threadcommimpl.h>
 10: /*@C
 11:      PetscLayoutCreate - Allocates PetscLayout space and sets the map contents to the default.

 13:     Collective on MPI_Comm

 15:    Input Parameters:
 16: +    comm - the MPI communicator
 17: -    map - pointer to the map

 19:    Level: developer

 21:     Notes: Typical calling sequence
 22:        PetscLayoutCreate(MPI_Comm,PetscLayout *);
 23:        PetscLayoutSetBlockSize(PetscLayout,1);
 24:        PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N);
 25:        PetscLayoutSetUp(PetscLayout);
 26:        Optionally use any of the following:
 27:           PetscLayoutGetSize(PetscLayout,PetscInt *); or PetscLayoutGetLocalSize(PetscLayout,PetscInt *;)
 28:           PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend); or PetscLayoutGetRanges(PetscLayout,const PetscInt *range[])
 29:        PetscLayoutDestroy(PetscLayout);

 31:       The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in  
 32:       user codes unless you really gain something in their use.

 34:     Fortran Notes: 
 35:       Not available from Fortran

 37: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
 38:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()

 40: @*/
 41: PetscErrorCode  PetscLayoutCreate(MPI_Comm comm,PetscLayout *map)
 42: {

 46:   PetscNew(struct _n_PetscLayout,map);
 47:   (*map)->comm   = comm;
 48:   (*map)->bs     = -1;
 49:   (*map)->n      = -1;
 50:   (*map)->N      = -1;
 51:   (*map)->range  = 0;
 52:   (*map)->rstart = 0;
 53:   (*map)->rend   = 0;
 54:   (*map)->trstarts = 0;
 55:   return(0);
 56: }

 58: /*@C
 59:      PetscLayoutDestroy - Frees a map object and frees its range if that exists. 

 61:     Collective on MPI_Comm

 63:    Input Parameters:
 64: .    map - the PetscLayout

 66:    Level: developer

 68:       The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is 
 69:       recommended they not be used in user codes unless you really gain something in their use.

 71:     Fortran Notes: 
 72:       Not available from Fortran

 74: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(),
 75:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()

 77: @*/
 80: PetscErrorCode  PetscLayoutDestroy(PetscLayout *map)
 81: {

 85:   if (!*map) return(0);
 86:   if (!(*map)->refcnt--) {
 87:     PetscFree((*map)->range);
 88:     ISLocalToGlobalMappingDestroy(&(*map)->mapping);
 89:     ISLocalToGlobalMappingDestroy(&(*map)->bmapping);
 90: #if defined(PETSC_HAVE_PTHREADCLASSES)
 91:     PetscThreadsLayoutDestroy(&(*map)->tmap);
 92: #endif
 93: #if defined(PETSC_THREADCOMM_ACTIVE)
 94:     PetscFree((*map)->trstarts);
 95: #endif

 97:     PetscFree((*map));
 98:   }
 99:   *map = PETSC_NULL;
100:   return(0);
101: }

103: /*@C
104:      PetscLayoutSetUp - given a map where you have set either the global or local
105:            size sets up the map so that it may be used.

107:     Collective on MPI_Comm

109:    Input Parameters:
110: .    map - pointer to the map

112:    Level: developer

114:     Notes: Typical calling sequence
115:        PetscLayoutCreate(MPI_Comm,PetscLayout *);
116:        PetscLayoutSetBlockSize(PetscLayout,1);
117:        PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
118:        PetscLayoutSetUp(PetscLayout);
119:        PetscLayoutGetSize(PetscLayout,PetscInt *);


122:        If the local size, global size are already set and range exists then this does nothing.

124:     Fortran Notes: 
125:       Not available from Fortran

127: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
128:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()

130: @*/
133: PetscErrorCode  PetscLayoutSetUp(PetscLayout map)
134: {
135:   PetscMPIInt    rank,size;
136:   PetscInt       p;

140:   if (map->bs <= 0) map->bs = 1;
141:   if ((map->n >= 0) && (map->N >= 0) && (map->range)) return(0);

143:   MPI_Comm_size(map->comm, &size);
144:   MPI_Comm_rank(map->comm, &rank);
145:   if (map->n > 0) map->n = map->n/map->bs;
146:   if (map->N > 0) map->N = map->N/map->bs;
147:   PetscSplitOwnership(map->comm,&map->n,&map->N);
148:   map->n = map->n*map->bs;
149:   map->N = map->N*map->bs;
150:   if (!map->range) {
151:     PetscMalloc((size+1)*sizeof(PetscInt), &map->range);
152:   }
153:   MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);

155:   map->range[0] = 0;
156:   for(p = 2; p <= size; p++) {
157:     map->range[p] += map->range[p-1];
158:   }

160:   map->rstart = map->range[rank];
161:   map->rend   = map->range[rank+1];
162: #if defined(PETSC_THREADCOMM_ACTIVE)
163:   /* Set the thread ownership ranges */
164:   PetscThreadCommGetOwnershipRanges(map->comm,map->n,&map->trstarts);
165: #endif

167:   return(0);
168: }

172: /*@C

174:     PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.

176:      Collective on PetscLayout

178:     Input Parameter:
179: .     in - input PetscLayout to be duplicated

181:     Output Parameter:
182: .     out - the copy

184:    Level: developer

186:     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout

188: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()

190: @*/
191: PetscErrorCode  PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
192: {
193:   PetscMPIInt    size;
195:   MPI_Comm       comm = in->comm;

198:   PetscLayoutDestroy(out);
199:   PetscLayoutCreate(comm,out);
200:   MPI_Comm_size(comm,&size);
201:   PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));
202:   PetscMalloc((size+1)*sizeof(PetscInt),&(*out)->range);
203:   PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));
204:   (*out)->refcnt = 0;
205:   return(0);
206: }

210: /*@C

212:     PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX() 

214:      Collective on PetscLayout

216:     Input Parameter:
217: .     in - input PetscLayout to be copied

219:     Output Parameter:
220: .     out - the reference location

222:    Level: developer

224:     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout

226:     If the out location already contains a PetscLayout it is destroyed

228: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()

230: @*/
231: PetscErrorCode  PetscLayoutReference(PetscLayout in,PetscLayout *out)
232: {

236:   in->refcnt++;
237:   PetscLayoutDestroy(out);
238:   *out = in;
239:   return(0);
240: }

244: /*@C

246:     PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout

248:      Collective on PetscLayout

250:     Input Parameter:
251: +     in - input PetscLayout
252: -     ltog - the local to global mapping


255:    Level: developer

257:     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout

259:     If the ltog location already contains a PetscLayout it is destroyed

261: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock()

263: @*/
264: PetscErrorCode  PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
265: {

269:   PetscObjectReference((PetscObject)ltog);
270:   ISLocalToGlobalMappingDestroy(&in->mapping);
271:   in->mapping = ltog;
272:   return(0);
273: }

277: /*@C

279:     PetscLayoutSetISLocalToGlobalMappingBlock - sets a ISLocalGlobalMapping into a PetscLayout

281:      Collective on PetscLayout

283:     Input Parameter:
284: +     in - input PetscLayout
285: -     ltog - the local to global block mapping


288:    Level: developer

290:     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout

292:     If the ltog location already contains a PetscLayout it is destroyed

294: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock()

296: @*/
297: PetscErrorCode  PetscLayoutSetISLocalToGlobalMappingBlock(PetscLayout in,ISLocalToGlobalMapping ltog)
298: {

302:   PetscObjectReference((PetscObject)ltog);
303:   ISLocalToGlobalMappingDestroy(&in->bmapping);
304:   in->bmapping = ltog;
305:   return(0);
306: }

308: /*@C
309:      PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.

311:     Collective on PetscLayout

313:    Input Parameters:
314: +    map - pointer to the map
315: -    n - the local size

317:    Level: developer

319:     Notes:
320:        Call this after the call to PetscLayoutCreate()

322:     Fortran Notes: 
323:       Not available from Fortran

325: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
326:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

328: @*/
331: PetscErrorCode  PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
332: {
334:   if (map->bs > 1 && n % map->bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Local size %D not compatible with block size %D",n,map->bs);
335:   map->n = n;
336:   return(0);
337: }

339: /*@C
340:      PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.

342:     Not Collective

344:    Input Parameters:
345: .    map - pointer to the map

347:    Output Parameters:
348: .    n - the local size

350:    Level: developer

352:     Notes:
353:        Call this after the call to PetscLayoutSetUp()

355:     Fortran Notes: 
356:       Not available from Fortran

358: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
359:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

361: @*/
364: PetscErrorCode  PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
365: {
367:   *n = map->n;
368:   return(0);
369: }

371: /*@C
372:      PetscLayoutSetSize - Sets the global size for a PetscLayout object.

374:     Logically Collective on PetscLayout

376:    Input Parameters:
377: +    map - pointer to the map
378: -    n - the global size

380:    Level: developer

382:     Notes:
383:        Call this after the call to PetscLayoutCreate()

385:     Fortran Notes: 
386:       Not available from Fortran

388: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
389:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

391: @*/
394: PetscErrorCode  PetscLayoutSetSize(PetscLayout map,PetscInt n)
395: {
397:   map->N = n;
398:   return(0);
399: }

401: /*@C
402:      PetscLayoutGetSize - Gets the global size for a PetscLayout object.

404:     Not Collective

406:    Input Parameters:
407: .    map - pointer to the map

409:    Output Parameters:
410: .    n - the global size

412:    Level: developer

414:     Notes:
415:        Call this after the call to PetscLayoutSetUp()

417:     Fortran Notes: 
418:       Not available from Fortran

420: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
421:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

423: @*/
426: PetscErrorCode  PetscLayoutGetSize(PetscLayout map,PetscInt *n)
427: {
429:   *n = map->N;
430:   return(0);
431: }

433: /*@C
434:      PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.

436:     Logically Collective on PetscLayout

438:    Input Parameters:
439: +    map - pointer to the map
440: -    bs - the size

442:    Level: developer

444:     Notes:
445:        Call this after the call to PetscLayoutCreate()

447:     Fortran Notes: 
448:       Not available from Fortran

450: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
451:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

453: @*/
456: PetscErrorCode  PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
457: {
459:   if (map->n > 0 && map->n % bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Local size %D not compatible with block size %D",map->n,bs);
460:   if (map->bs > 0 && map->bs != bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Cannot change block size %D to %D",map->bs,bs);
461:   map->bs = bs;
462:   return(0);
463: }

465: /*@C
466:      PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.

468:     Not Collective

470:    Input Parameters:
471: .    map - pointer to the map

473:    Output Parameters:
474: .    bs - the size

476:    Level: developer

478:     Notes:
479:        Call this after the call to PetscLayoutSetUp()

481:     Fortran Notes: 
482:       Not available from Fortran

484: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
485:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()

487: @*/
490: PetscErrorCode  PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
491: {
493:   *bs = map->bs;
494:   return(0);
495: }


498: /*@C
499:      PetscLayoutGetRange - gets the range of values owned by this process

501:     Not Collective

503:    Input Parameters:
504: .    map - pointer to the map

506:    Output Parameters:
507: +    rstart - first index owned by this process
508: -    rend - one more than the last index owned by this process

510:    Level: developer

512:     Notes:
513:        Call this after the call to PetscLayoutSetUp()

515:     Fortran Notes: 
516:       Not available from Fortran

518: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
519:           PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

521: @*/
524: PetscErrorCode  PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
525: {
527:   if (rstart) *rstart = map->rstart;
528:   if (rend)   *rend   = map->rend;
529:   return(0);
530: }

532: /*@C
533:      PetscLayoutGetRanges - gets the range of values owned by all processes

535:     Not Collective

537:    Input Parameters:
538: .    map - pointer to the map

540:    Output Parameters:
541: .    range - start of each processors range of indices (the final entry is one more then the
542:              last index on the last process)

544:    Level: developer

546:     Notes:
547:        Call this after the call to PetscLayoutSetUp()

549:     Fortran Notes: 
550:       Not available from Fortran

552: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
553:           PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

555: @*/
558: PetscErrorCode  PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
559: {
561:   *range = map->range;
562:   return(0);
563: }