Actual source code: general.c
petsc-3.10.5 2019-03-28
2: /*
3: Provides the functions for index sets (IS) defined by a list of integers.
4: */
5: #include <../src/vec/is/is/impls/general/general.h>
6: #include <petscvec.h>
7: #include <petscviewer.h>
8: #include <petscviewerhdf5.h>
10: static PetscErrorCode ISDuplicate_General(IS is,IS *newIS)
11: {
13: IS_General *sub = (IS_General*)is->data;
14: PetscInt n;
17: PetscLayoutGetLocalSize(is->map, &n);
18: ISCreateGeneral(PetscObjectComm((PetscObject) is), n, sub->idx, PETSC_COPY_VALUES, newIS);
19: return(0);
20: }
22: static PetscErrorCode ISDestroy_General(IS is)
23: {
24: IS_General *is_general = (IS_General*)is->data;
28: if (is_general->allocated) {PetscFree(is_general->idx);}
29: PetscObjectComposeFunction((PetscObject)is,"ISGeneralSetIndices_C",NULL);
30: PetscFree(is->data);
31: return(0);
32: }
34: static PetscErrorCode ISIdentity_General(IS is, PetscBool *ident)
35: {
36: IS_General *is_general = (IS_General*)is->data;
37: PetscInt i,n,*idx = is_general->idx;
41: PetscLayoutGetLocalSize(is->map, &n);
42: is->isidentity = PETSC_TRUE;
43: *ident = PETSC_TRUE;
44: for (i=0; i<n; i++) {
45: if (idx[i] != i) {
46: is->isidentity = PETSC_FALSE;
47: *ident = PETSC_FALSE;
48: break;
49: }
50: }
51: return(0);
52: }
54: static PetscErrorCode ISCopy_General(IS is,IS isy)
55: {
56: IS_General *is_general = (IS_General*)is->data,*isy_general = (IS_General*)isy->data;
57: PetscInt n, N, ny, Ny;
61: PetscLayoutGetLocalSize(is->map, &n);
62: PetscLayoutGetSize(is->map, &N);
63: PetscLayoutGetLocalSize(isy->map, &ny);
64: PetscLayoutGetSize(isy->map, &Ny);
65: if (n != ny || N != Ny) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Index sets incompatible");
66: isy_general->sorted = is_general->sorted;
67: PetscMemcpy(isy_general->idx,is_general->idx,n*sizeof(PetscInt));
68: return(0);
69: }
71: static PetscErrorCode ISOnComm_General(IS is,MPI_Comm comm,PetscCopyMode mode,IS *newis)
72: {
74: IS_General *sub = (IS_General*)is->data;
75: PetscInt n;
78: if (mode == PETSC_OWN_POINTER) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"Cannot use PETSC_OWN_POINTER");
79: PetscLayoutGetLocalSize(is->map, &n);
80: ISCreateGeneral(comm,n,sub->idx,mode,newis);
81: return(0);
82: }
84: static PetscErrorCode ISSetBlockSize_General(IS is,PetscInt bs)
85: {
89: PetscLayoutSetBlockSize(is->map, bs);
90: return(0);
91: }
93: static PetscErrorCode ISContiguousLocal_General(IS is,PetscInt gstart,PetscInt gend,PetscInt *start,PetscBool *contig)
94: {
95: IS_General *sub = (IS_General*)is->data;
96: PetscInt n,i,p;
100: *start = 0;
101: *contig = PETSC_TRUE;
102: PetscLayoutGetLocalSize(is->map, &n);
103: if (!n) return(0);
104: p = sub->idx[0];
105: if (p < gstart) goto nomatch;
106: *start = p - gstart;
107: if (n > gend-p) goto nomatch;
108: for (i=1; i<n; i++,p++) {
109: if (sub->idx[i] != p+1) goto nomatch;
110: }
111: return(0);
112: nomatch:
113: *start = -1;
114: *contig = PETSC_FALSE;
115: return(0);
116: }
118: static PetscErrorCode ISLocate_General(IS is,PetscInt key,PetscInt *location)
119: {
120: IS_General *sub = (IS_General*)is->data;
121: PetscInt numIdx, i;
125: PetscLayoutGetLocalSize(is->map,&numIdx);
126: if (sub->sorted) { PetscFindInt(key,numIdx,sub->idx,location);}
127: else {
128: const PetscInt *idx = sub->idx;
130: *location = -1;
131: for (i = 0; i < numIdx; i++) {
132: if (idx[i] == key) {
133: *location = i;
134: return(0);
135: }
136: }
137: }
138: return(0);
139: }
141: static PetscErrorCode ISGetIndices_General(IS in,const PetscInt *idx[])
142: {
143: IS_General *sub = (IS_General*)in->data;
146: *idx = sub->idx;
147: return(0);
148: }
150: static PetscErrorCode ISRestoreIndices_General(IS in,const PetscInt *idx[])
151: {
152: IS_General *sub = (IS_General*)in->data;
155: if (*idx != sub->idx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must restore with value from ISGetIndices()");
156: return(0);
157: }
159: static PetscErrorCode ISGetSize_General(IS is,PetscInt *size)
160: {
164: PetscLayoutGetSize(is->map, size);
165: return(0);
166: }
168: static PetscErrorCode ISGetLocalSize_General(IS is,PetscInt *size)
169: {
173: PetscLayoutGetLocalSize(is->map, size);
174: return(0);
175: }
177: static PetscErrorCode ISInvertPermutation_General(IS is,PetscInt nlocal,IS *isout)
178: {
179: IS_General *sub = (IS_General*)is->data;
180: PetscInt i,*ii,n,nstart;
181: const PetscInt *idx = sub->idx;
182: PetscMPIInt size;
183: IS istmp,nistmp;
187: PetscLayoutGetLocalSize(is->map, &n);
188: MPI_Comm_size(PetscObjectComm((PetscObject)is),&size);
189: if (size == 1) {
190: PetscMalloc1(n,&ii);
191: for (i=0; i<n; i++) ii[idx[i]] = i;
192: ISCreateGeneral(PETSC_COMM_SELF,n,ii,PETSC_OWN_POINTER,isout);
193: ISSetPermutation(*isout);
194: } else {
195: /* crude, nonscalable get entire IS on each processor */
196: ISAllGather(is,&istmp);
197: ISSetPermutation(istmp);
198: ISInvertPermutation(istmp,PETSC_DECIDE,&nistmp);
199: ISDestroy(&istmp);
200: /* get the part we need */
201: if (nlocal == PETSC_DECIDE) nlocal = n;
202: MPI_Scan(&nlocal,&nstart,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)is));
203: #if defined(PETSC_USE_DEBUG)
204: {
205: PetscInt N;
206: PetscMPIInt rank;
207: MPI_Comm_rank(PetscObjectComm((PetscObject)is),&rank);
208: PetscLayoutGetSize(is->map, &N);
209: if (rank == size-1) {
210: if (nstart != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Sum of nlocal lengths %d != total IS length %d",nstart,N);
211: }
212: }
213: #endif
214: nstart -= nlocal;
215: ISGetIndices(nistmp,&idx);
216: ISCreateGeneral(PetscObjectComm((PetscObject)is),nlocal,idx+nstart,PETSC_COPY_VALUES,isout);
217: ISRestoreIndices(nistmp,&idx);
218: ISDestroy(&nistmp);
219: }
220: return(0);
221: }
223: #if defined(PETSC_HAVE_HDF5)
224: static PetscErrorCode ISView_General_HDF5(IS is, PetscViewer viewer)
225: {
226: hid_t filespace; /* file dataspace identifier */
227: hid_t chunkspace; /* chunk dataset property identifier */
228: hid_t plist_id; /* property list identifier */
229: hid_t dset_id; /* dataset identifier */
230: hid_t memspace; /* memory dataspace identifier */
231: hid_t inttype; /* int type (H5T_NATIVE_INT or H5T_NATIVE_LLONG) */
232: hid_t file_id, group;
233: hsize_t dim, maxDims[3], dims[3], chunkDims[3], count[3],offset[3];
234: PetscInt bs, N, n, timestep, low;
235: const PetscInt *ind;
236: const char *isname;
237: PetscErrorCode ierr;
240: ISGetBlockSize(is,&bs);
241: PetscViewerHDF5OpenGroup(viewer, &file_id, &group);
242: PetscViewerHDF5GetTimestep(viewer, ×tep);
244: /* Create the dataspace for the dataset.
245: *
246: * dims - holds the current dimensions of the dataset
247: *
248: * maxDims - holds the maximum dimensions of the dataset (unlimited
249: * for the number of time steps with the current dimensions for the
250: * other dimensions; so only additional time steps can be added).
251: *
252: * chunkDims - holds the size of a single time step (required to
253: * permit extending dataset).
254: */
255: dim = 0;
256: if (timestep >= 0) {
257: dims[dim] = timestep+1;
258: maxDims[dim] = H5S_UNLIMITED;
259: chunkDims[dim] = 1;
260: ++dim;
261: }
262: ISGetSize(is, &N);
263: ISGetLocalSize(is, &n);
264: PetscHDF5IntCast(N/bs,dims + dim);
266: maxDims[dim] = dims[dim];
267: chunkDims[dim] = dims[dim];
268: ++dim;
269: if (bs >= 1) {
270: dims[dim] = bs;
271: maxDims[dim] = dims[dim];
272: chunkDims[dim] = dims[dim];
273: ++dim;
274: }
275: PetscStackCallHDF5Return(filespace,H5Screate_simple,(dim, dims, maxDims));
277: #if defined(PETSC_USE_64BIT_INDICES)
278: inttype = H5T_NATIVE_LLONG;
279: #else
280: inttype = H5T_NATIVE_INT;
281: #endif
283: /* Create the dataset with default properties and close filespace */
284: PetscObjectGetName((PetscObject) is, &isname);
285: if (!H5Lexists(group, isname, H5P_DEFAULT)) {
286: /* Create chunk */
287: PetscStackCallHDF5Return(chunkspace,H5Pcreate,(H5P_DATASET_CREATE));
288: PetscStackCallHDF5(H5Pset_chunk,(chunkspace, dim, chunkDims));
290: #if (H5_VERS_MAJOR * 10000 + H5_VERS_MINOR * 100 + H5_VERS_RELEASE >= 10800)
291: PetscStackCallHDF5Return(dset_id,H5Dcreate2,(group, isname, inttype, filespace, H5P_DEFAULT, chunkspace, H5P_DEFAULT));
292: #else
293: PetscStackCallHDF5Return(dset_id,H5Dcreate,(group, isname, inttype, filespace, H5P_DEFAULT));
294: #endif
295: PetscStackCallHDF5(H5Pclose,(chunkspace));
296: } else {
297: PetscStackCallHDF5Return(dset_id,H5Dopen2,(group, isname, H5P_DEFAULT));
298: PetscStackCallHDF5(H5Dset_extent,(dset_id, dims));
299: }
300: PetscStackCallHDF5(H5Sclose,(filespace));
302: /* Each process defines a dataset and writes it to the hyperslab in the file */
303: dim = 0;
304: if (timestep >= 0) {
305: count[dim] = 1;
306: ++dim;
307: }
308: PetscHDF5IntCast(n/bs,count + dim);
309: ++dim;
310: if (bs >= 1) {
311: count[dim] = bs;
312: ++dim;
313: }
314: if (n > 0) {
315: PetscStackCallHDF5Return(memspace,H5Screate_simple,(dim, count, NULL));
316: } else {
317: /* Can't create dataspace with zero for any dimension, so create null dataspace. */
318: PetscStackCallHDF5Return(memspace,H5Screate,(H5S_NULL));
319: }
321: /* Select hyperslab in the file */
322: PetscLayoutGetRange(is->map, &low, NULL);
323: dim = 0;
324: if (timestep >= 0) {
325: offset[dim] = timestep;
326: ++dim;
327: }
328: PetscHDF5IntCast(low/bs,offset + dim);
329: ++dim;
330: if (bs >= 1) {
331: offset[dim] = 0;
332: ++dim;
333: }
334: if (n > 0) {
335: PetscStackCallHDF5Return(filespace,H5Dget_space,(dset_id));
336: PetscStackCallHDF5(H5Sselect_hyperslab,(filespace, H5S_SELECT_SET, offset, NULL, count, NULL));
337: } else {
338: /* Create null filespace to match null memspace. */
339: PetscStackCallHDF5Return(filespace,H5Screate,(H5S_NULL));
340: }
342: /* Create property list for collective dataset write */
343: PetscStackCallHDF5Return(plist_id,H5Pcreate,(H5P_DATASET_XFER));
344: #if defined(PETSC_HAVE_H5PSET_FAPL_MPIO)
345: PetscStackCallHDF5(H5Pset_dxpl_mpio,(plist_id, H5FD_MPIO_COLLECTIVE));
346: #endif
347: /* To write dataset independently use H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_INDEPENDENT) */
349: ISGetIndices(is, &ind);
350: PetscStackCallHDF5(H5Dwrite,(dset_id, inttype, memspace, filespace, plist_id, ind));
351: PetscStackCallHDF5(H5Fflush,(file_id, H5F_SCOPE_GLOBAL));
352: ISRestoreIndices(is, &ind);
354: /* Close/release resources */
355: if (group != file_id) PetscStackCallHDF5(H5Gclose,(group));
356: PetscStackCallHDF5(H5Pclose,(plist_id));
357: PetscStackCallHDF5(H5Sclose,(filespace));
358: PetscStackCallHDF5(H5Sclose,(memspace));
359: PetscStackCallHDF5(H5Dclose,(dset_id));
360: PetscInfo1(is, "Wrote IS object with name %s\n", isname);
361: return(0);
362: }
363: #endif
365: static PetscErrorCode ISView_General_Binary(IS is,PetscViewer viewer)
366: {
368: PetscBool skipHeader,useMPIIO;
369: IS_General *isa = (IS_General*) is->data;
370: PetscMPIInt rank,size,mesgsize,tag = ((PetscObject)viewer)->tag, mesglen;
371: PetscInt n,N,len,j,tr[2];
372: int fdes;
373: MPI_Status status;
374: PetscInt message_count,flowcontrolcount,*values;
377: /* ISGetLayout(is,&map); */
378: PetscLayoutGetLocalSize(is->map, &n);
379: PetscLayoutGetSize(is->map, &N);
381: tr[0] = IS_FILE_CLASSID;
382: tr[1] = N;
384: PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);
385: if (!skipHeader) {
386: PetscViewerBinaryWrite(viewer,tr,2,PETSC_INT,PETSC_FALSE);
387: }
389: PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);
390: #if defined(PETSC_HAVE_MPIIO)
391: if (useMPIIO) {
392: MPI_File mfdes;
393: MPI_Offset off;
394: PetscMPIInt lsize;
395: PetscInt rstart;
396: const PetscInt *iarray;
398: PetscMPIIntCast(n,&lsize);
399: PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);
400: PetscViewerBinaryGetMPIIOOffset(viewer,&off);
401: PetscLayoutGetRange(is->map,&rstart,NULL);
402: off += rstart*(MPI_Offset)sizeof(PetscInt); /* off is MPI_Offset, not PetscMPIInt */
403: MPI_File_set_view(mfdes,off,MPIU_INT,MPIU_INT,(char*)"native",MPI_INFO_NULL);
404: ISGetIndices(is,&iarray);
405: MPIU_File_write_all(mfdes,(void*)iarray,lsize,MPIU_INT,MPI_STATUS_IGNORE);
406: ISRestoreIndices(is,&iarray);
407: PetscViewerBinaryAddMPIIOOffset(viewer,N*(MPI_Offset)sizeof(PetscInt));
408: return(0);
409: }
410: #endif
412: PetscViewerBinaryGetDescriptor(viewer,&fdes);
413: MPI_Comm_rank(PetscObjectComm((PetscObject)is),&rank);
414: MPI_Comm_size(PetscObjectComm((PetscObject)is),&size);
416: /* determine maximum message to arrive */
417: MPI_Reduce(&n,&len,1,MPIU_INT,MPI_MAX,0,PetscObjectComm((PetscObject)is));
419: PetscViewerFlowControlStart(viewer,&message_count,&flowcontrolcount);
420: if (!rank) {
421: PetscBinaryWrite(fdes,isa->idx,n,PETSC_INT,PETSC_FALSE);
423: PetscMalloc1(len,&values);
424: PetscMPIIntCast(len,&mesgsize);
425: /* receive and save messages */
426: for (j=1; j<size; j++) {
427: PetscViewerFlowControlStepMaster(viewer,j,&message_count,flowcontrolcount);
428: MPI_Recv(values,mesgsize,MPIU_INT,j,tag,PetscObjectComm((PetscObject)is),&status);
429: MPI_Get_count(&status,MPIU_INT,&mesglen);
430: PetscBinaryWrite(fdes,values,(PetscInt)mesglen,PETSC_INT,PETSC_TRUE);
431: }
432: PetscViewerFlowControlEndMaster(viewer,&message_count);
433: PetscFree(values);
434: } else {
435: PetscViewerFlowControlStepWorker(viewer,rank,&message_count);
436: PetscMPIIntCast(n,&mesgsize);
437: MPI_Send(isa->idx,mesgsize,MPIU_INT,0,tag,PetscObjectComm((PetscObject)is));
438: PetscViewerFlowControlEndWorker(viewer,&message_count);
439: }
440: return(0);
441: }
443: static PetscErrorCode ISView_General(IS is,PetscViewer viewer)
444: {
445: IS_General *sub = (IS_General*)is->data;
447: PetscInt i,n,*idx = sub->idx;
448: PetscBool iascii,isbinary,ishdf5;
451: PetscLayoutGetLocalSize(is->map, &n);
452: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
453: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
454: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);
455: if (iascii) {
456: MPI_Comm comm;
457: PetscMPIInt rank,size;
458: PetscViewerFormat fmt;
460: PetscObjectGetComm((PetscObject)viewer,&comm);
461: MPI_Comm_rank(comm,&rank);
462: MPI_Comm_size(comm,&size);
464: PetscViewerGetFormat(viewer,&fmt);
465: PetscViewerASCIIPushSynchronized(viewer);
466: if (size > 1) {
467: if (fmt == PETSC_VIEWER_ASCII_MATLAB) {
468: const char* name;
470: PetscObjectGetName((PetscObject)is,&name);
471: PetscViewerASCIISynchronizedPrintf(viewer,"%s_%d = [...\n",name,rank);
472: for (i=0; i<n; i++) {
473: PetscViewerASCIISynchronizedPrintf(viewer,"%D\n",idx[i]+1);
474: }
475: PetscViewerASCIISynchronizedPrintf(viewer,"];\n");
476: } else {
477: PetscInt st = 0;
479: if (fmt == PETSC_VIEWER_ASCII_INDEX) st = is->map->rstart;
480: if (is->isperm) {
481: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Index set is permutation\n",rank);
482: }
483: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Number of indices in set %D\n",rank,n);
484: for (i=0; i<n; i++) {
485: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %D %D\n",rank,i + st,idx[i]);
486: }
487: }
488: } else {
489: if (fmt == PETSC_VIEWER_ASCII_MATLAB) {
490: const char* name;
492: PetscObjectGetName((PetscObject)is,&name);
493: PetscViewerASCIISynchronizedPrintf(viewer,"%s = [...\n",name);
494: for (i=0; i<n; i++) {
495: PetscViewerASCIISynchronizedPrintf(viewer,"%D\n",idx[i]+1);
496: }
497: PetscViewerASCIISynchronizedPrintf(viewer,"];\n");
498: } else {
499: PetscInt st = 0;
501: if (fmt == PETSC_VIEWER_ASCII_INDEX) st = is->map->rstart;
502: if (is->isperm) {
503: PetscViewerASCIISynchronizedPrintf(viewer,"Index set is permutation\n");
504: }
505: PetscViewerASCIISynchronizedPrintf(viewer,"Number of indices in set %D\n",n);
506: for (i=0; i<n; i++) {
507: PetscViewerASCIISynchronizedPrintf(viewer,"%D %D\n",i + st,idx[i]);
508: }
509: }
510: }
511: PetscViewerFlush(viewer);
512: PetscViewerASCIIPopSynchronized(viewer);
513: } else if (isbinary) {
514: ISView_General_Binary(is,viewer);
515: } else if (ishdf5) {
516: #if defined(PETSC_HAVE_HDF5)
517: ISView_General_HDF5(is,viewer);
518: #endif
519: }
520: return(0);
521: }
523: static PetscErrorCode ISSort_General(IS is)
524: {
525: IS_General *sub = (IS_General*)is->data;
526: PetscInt n;
530: if (sub->sorted) return(0);
531: PetscLayoutGetLocalSize(is->map, &n);
532: PetscSortInt(n,sub->idx);
533: sub->sorted = PETSC_TRUE;
534: return(0);
535: }
537: static PetscErrorCode ISSortRemoveDups_General(IS is)
538: {
539: IS_General *sub = (IS_General*)is->data;
540: PetscInt n;
544: PetscLayoutGetLocalSize(is->map, &n);
545: if (sub->sorted) {
546: PetscSortedRemoveDupsInt(&n,sub->idx);
547: } else {
548: PetscSortRemoveDupsInt(&n,sub->idx);
549: }
550: PetscLayoutSetLocalSize(is->map, n);
551: PetscLayoutSetSize(is->map, PETSC_DECIDE);
552: PetscLayoutSetUp(is->map);
553: sub->sorted = PETSC_TRUE;
554: return(0);
555: }
557: static PetscErrorCode ISSorted_General(IS is,PetscBool *flg)
558: {
559: IS_General *sub = (IS_General*)is->data;
562: *flg = sub->sorted;
563: return(0);
564: }
566: PetscErrorCode ISToGeneral_General(IS is)
567: {
569: return(0);
570: }
572: static struct _ISOps myops = { ISGetSize_General,
573: ISGetLocalSize_General,
574: ISGetIndices_General,
575: ISRestoreIndices_General,
576: ISInvertPermutation_General,
577: ISSort_General,
578: ISSortRemoveDups_General,
579: ISSorted_General,
580: ISDuplicate_General,
581: ISDestroy_General,
582: ISView_General,
583: ISLoad_Default,
584: ISIdentity_General,
585: ISCopy_General,
586: ISToGeneral_General,
587: ISOnComm_General,
588: ISSetBlockSize_General,
589: ISContiguousLocal_General,
590: ISLocate_General};
592: PETSC_INTERN PetscErrorCode ISSetUp_General(IS);
594: PetscErrorCode ISSetUp_General(IS is)
595: {
597: IS_General *sub = (IS_General*)is->data;
598: const PetscInt *idx = sub->idx;
599: PetscInt n,i,min,max;
602: PetscLayoutGetLocalSize(is->map, &n);
604: sub->sorted = PETSC_TRUE;
605: for (i=1; i<n; i++) {
606: if (idx[i] < idx[i-1]) {sub->sorted = PETSC_FALSE; break;}
607: }
608: if (n) {
609: min = max = idx[0];
610: for (i=1; i<n; i++) {
611: if (idx[i] < min) min = idx[i];
612: if (idx[i] > max) max = idx[i];
613: }
614: is->min = min;
615: is->max = max;
616: } else {
617: is->min = PETSC_MAX_INT;
618: is->max = PETSC_MIN_INT;
619: }
620: is->isperm = PETSC_FALSE;
621: is->isidentity = PETSC_FALSE;
622: return(0);
623: }
625: /*@
626: ISCreateGeneral - Creates a data structure for an index set
627: containing a list of integers.
629: Collective on MPI_Comm
631: Input Parameters:
632: + comm - the MPI communicator
633: . n - the length of the index set
634: . idx - the list of integers
635: - mode - PETSC_COPY_VALUES, PETSC_OWN_POINTER, or PETSC_USE_POINTER; see PetscCopyMode for meaning of this flag.
637: Output Parameter:
638: . is - the new index set
640: Notes:
641: When the communicator is not MPI_COMM_SELF, the operations on IS are NOT
642: conceptually the same as MPI_Group operations. The IS are then
643: distributed sets of indices and thus certain operations on them are
644: collective.
647: Level: beginner
649: Concepts: index sets^creating
650: Concepts: IS^creating
652: .seealso: ISCreateStride(), ISCreateBlock(), ISAllGather(), PETSC_COPY_VALUES, PETSC_OWN_POINTER, PETSC_USE_POINTER, PetscCopyMode
653: @*/
654: PetscErrorCode ISCreateGeneral(MPI_Comm comm,PetscInt n,const PetscInt idx[],PetscCopyMode mode,IS *is)
655: {
659: ISCreate(comm,is);
660: ISSetType(*is,ISGENERAL);
661: ISGeneralSetIndices(*is,n,idx,mode);
662: return(0);
663: }
665: /*@
666: ISGeneralSetIndices - Sets the indices for an ISGENERAL index set
668: Collective on IS
670: Input Parameters:
671: + is - the index set
672: . n - the length of the index set
673: . idx - the list of integers
674: - mode - see PetscCopyMode for meaning of this flag.
676: Level: beginner
678: Concepts: index sets^creating
679: Concepts: IS^creating
681: .seealso: ISCreateGeneral(), ISCreateStride(), ISCreateBlock(), ISAllGather()
682: @*/
683: PetscErrorCode ISGeneralSetIndices(IS is,PetscInt n,const PetscInt idx[],PetscCopyMode mode)
684: {
688: PetscUseMethod(is,"ISGeneralSetIndices_C",(IS,PetscInt,const PetscInt[],PetscCopyMode),(is,n,idx,mode));
689: return(0);
690: }
692: PetscErrorCode ISGeneralSetIndices_General(IS is,PetscInt n,const PetscInt idx[],PetscCopyMode mode)
693: {
695: IS_General *sub = (IS_General*)is->data;
698: if (n < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"length < 0");
701: PetscLayoutSetLocalSize(is->map,n);
702: PetscLayoutSetUp(is->map);
704: if (sub->allocated) {PetscFree(sub->idx);}
705: if (mode == PETSC_COPY_VALUES) {
706: PetscMalloc1(n,&sub->idx);
707: PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));
708: PetscMemcpy(sub->idx,idx,n*sizeof(PetscInt));
709: sub->allocated = PETSC_TRUE;
710: } else if (mode == PETSC_OWN_POINTER) {
711: sub->idx = (PetscInt*)idx;
712: PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));
713: sub->allocated = PETSC_TRUE;
714: } else {
715: sub->idx = (PetscInt*)idx;
716: sub->allocated = PETSC_FALSE;
717: }
719: ISSetUp_General(is);
720: ISViewFromOptions(is,NULL,"-is_view");
721: return(0);
722: }
724: PETSC_EXTERN PetscErrorCode ISCreate_General(IS is)
725: {
727: IS_General *sub;
730: PetscNewLog(is,&sub);
731: is->data = (void *) sub;
732: PetscMemcpy(is->ops,&myops,sizeof(myops));
733: PetscObjectComposeFunction((PetscObject)is,"ISGeneralSetIndices_C",ISGeneralSetIndices_General);
734: return(0);
735: }