Actual source code: vscreate.c
petsc-3.11.4 2019-09-28
1: /*
2: The VECSCATTER (vec scatter) interface routines, callable by users.
3: */
5: #include <petsc/private/vecscatterimpl.h>
7: /* Logging support */
8: PetscClassId VEC_SCATTER_CLASSID;
10: PetscFunctionList VecScatterList = NULL;
11: PetscBool VecScatterRegisterAllCalled = PETSC_FALSE;
13: /*@C
14: VecScatterSetType - Builds a vector scatter, for a particular vector scatter implementation.
16: Collective on VecScatter
18: Input Parameters:
19: + vscat - The vector scatter object
20: - type - The name of the vector scatter type
22: Options Database Key:
23: . -vecscatter_type <type> - Sets the vector scatter type; use -help for a list
24: of available types
26: Notes:
27: See "petsc/include/petscvec.h" for available vector scatter types (for instance, VECSCATTERMPI1, or VECSCATTERMPI3NODE).
29: Use VecScatterDuplicate() to form additional vectors scatter of the same type as an existing vector scatter.
31: Level: intermediate
33: .keywords: vector scatter, set, type
34: .seealso: VecScatterGetType(), VecScatterCreate()
35: @*/
36: PetscErrorCode VecScatterSetType(VecScatter vscat, VecScatterType type)
37: {
38: PetscBool match;
40: PetscErrorCode (*r)(VecScatter);
44: PetscObjectTypeCompare((PetscObject)vscat, type, &match);
45: if (match) return(0);
47: PetscFunctionListFind(VecScatterList,type,&r);
48: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown vector scatter type: %s",type);
50: if (vscat->ops->destroy) {
51: (*vscat->ops->destroy)(vscat);
52: vscat->ops->destroy = NULL;
53: }
55: (*r)(vscat);
56: return(0);
57: }
59: /*@C
60: VecScatterGetType - Gets the vector scatter type name (as a string) from the VecScatter.
62: Not Collective
64: Input Parameter:
65: . vscat - The vector scatter
67: Output Parameter:
68: . type - The vector scatter type name
70: Level: intermediate
72: .keywords: vector scatter, get, type, name
73: .seealso: VecScatterSetType(), VecScatterCreate()
74: @*/
75: PetscErrorCode VecScatterGetType(VecScatter vscat, VecScatterType *type)
76: {
82: VecScatterRegisterAll();
83: *type = ((PetscObject)vscat)->type_name;
84: return(0);
85: }
87: /*@
88: VecScatterSetFromOptions - Configures the vector scatter from the options database.
90: Collective on VecScatter
92: Input Parameter:
93: . vscat - The vector scatter
95: Notes:
96: To see all options, run your program with the -help option, or consult the users manual.
97: Must be called before VecScatterSetUp() but before the vector scatter is used.
99: Level: beginner
101: Concepts: vectorscatter^setting options
102: Concepts: vectorscatter^setting type
104: .keywords: VecScatter, set, options, database
105: .seealso: VecScatterCreate(), VecScatterDestroy(), VecScatterSetUp()
106: @*/
107: PetscErrorCode VecScatterSetFromOptions(VecScatter vscat)
108: {
110: PetscBool opt;
111: VecScatterType defaultType;
112: char typeName[256];
113: PetscMPIInt size;
118: PetscObjectOptionsBegin((PetscObject)vscat);
119: MPI_Comm_size(PetscObjectComm((PetscObject)vscat), &size);
121: /* Handle vector type options */
122: if (((PetscObject)vscat)->type_name) {
123: defaultType = ((PetscObject)vscat)->type_name;
124: } else {
125: if (size > 1) defaultType = VECSCATTERMPI1;
126: else defaultType = VECSCATTERSEQ;
127: }
129: VecScatterRegisterAll();
130: PetscOptionsFList("-vecscatter_type","Vector Scatter type","VecScatterSetType",VecScatterList,defaultType,typeName,256,&opt);
131: if (size > 1 && opt) {
132: VecScatterSetType(vscat,typeName);
133: } else {
134: VecScatterSetType(vscat,defaultType);
135: }
137: vscat->beginandendtogether = PETSC_FALSE;
138: PetscOptionsBool("-vecscatter_merge","Use combined (merged) vector scatter begin and end","VecScatterCreate",vscat->beginandendtogether,&vscat->beginandendtogether,NULL);
139: if (vscat->beginandendtogether) {
140: PetscInfo(vscat,"Using combined (merged) vector scatter begin and end\n");
141: }
143: PetscOptionsEnd();
144: return(0);
145: }
147: /*@C
148: VecScatterRegister - Adds a new vector scatter component implementation
150: Not Collective
152: Input Parameters:
153: + name - The name of a new user-defined creation routine
154: - create_func - The creation routine itself
156: Notes:
157: VecScatterRegister() may be called multiple times to add several user-defined vectors
159: Sample usage:
160: .vb
161: VecScatterRegister("my_vecscatter",MyVecScatterCreate);
162: .ve
164: Then, your vector scatter type can be chosen with the procedural interface via
165: .vb
166: VecScatterCreate(MPI_Comm, VecScatter *);
167: VecScatterSetType(VecScatter,"my_vectorscatter_name");
168: .ve
169: or at runtime via the option
170: .vb
171: -vecscatter_type my_vectorscatter_name
172: .ve
174: Level: advanced
176: .keywords: VecScatter, Register
178: .seealso: VecScatterRegisterAll(), VecScatterRegisterDestroy()
179: @*/
180: PetscErrorCode VecScatterRegister(const char sname[], PetscErrorCode (*function)(VecScatter))
181: {
185: VecInitializePackage();
186: PetscFunctionListAdd(&VecScatterList,sname,function);
187: return(0);
188: }
190: /* ---------------------------------------------------------------- */
191: /*@
192: VecScatterCreate - Creates a vector scatter context.
194: Collective on Vec
196: Input Parameters:
197: + xin - a vector that defines the shape (parallel data layout of the vector)
198: of vectors from which we scatter
199: . yin - a vector that defines the shape (parallel data layout of the vector)
200: of vectors to which we scatter
201: . ix - the indices of xin to scatter (if NULL scatters all values)
202: - iy - the indices of yin to hold results (if NULL fills entire vector yin)
204: Output Parameter:
205: . newctx - location to store the new scatter context
207: Options Database Keys: (uses regular MPI_Sends by default)
208: . -vecscatter_view - Prints detail of communications
209: . -vecscatter_view ::ascii_info - Print less details about communication
210: . -vecscatter_merge - VecScatterBegin() handles all of the communication, VecScatterEnd() is a nop
211: eliminates the chance for overlap of computation and communication
212: . -vecscatter_packtogether - Pack all messages before sending, receive all messages before unpacking
213: will make the results of scatters deterministic when otherwise they are not (it may be slower also).
215: Level: intermediate
217: Notes:
218: If both xin and yin are parallel, their communicator must be on the same
219: set of processes, but their process order can be different.
220: In calls to VecScatter() you can use different vectors than the xin and
221: yin you used above; BUT they must have the same parallel data layout, for example,
222: they could be obtained from VecDuplicate().
223: A VecScatter context CANNOT be used in two or more simultaneous scatters;
224: that is you cannot call a second VecScatterBegin() with the same scatter
225: context until the VecScatterEnd() has been called on the first VecScatterBegin().
226: In this case a separate VecScatter is needed for each concurrent scatter.
228: Currently the MPI_Send() use PERSISTENT versions.
229: (this unfortunately requires that the same in and out arrays be used for each use, this
230: is why we always need to pack the input into the work array before sending
231: and unpack upon receiving instead of using MPI datatypes to avoid the packing/unpacking).
233: Both ix and iy cannot be NULL at the same time.
235: Concepts: scatter^between vectors
236: Concepts: gather^between vectors
238: .seealso: VecScatterDestroy(), VecScatterCreateToAll(), VecScatterCreateToZero()
239: @*/
240: PetscErrorCode VecScatterCreate(Vec xin,IS ix,Vec yin,IS iy,VecScatter *newctx)
241: {
242: VecScatter ctx;
243: PetscErrorCode ierr;
244: PetscMPIInt size,xsize,ysize,result;
245: MPI_Comm comm,xcomm,ycomm;
249: *newctx = NULL;
251: if (!ix && !iy) SETERRQ(PetscObjectComm((PetscObject)xin),PETSC_ERR_SUP,"Cannot pass default in for both input and output indices");
253: /* Get comm from xin and yin */
254: PetscObjectGetComm((PetscObject)xin,&xcomm);
255: MPI_Comm_size(xcomm,&xsize);
256: PetscObjectGetComm((PetscObject)yin,&ycomm);
257: MPI_Comm_size(ycomm,&ysize);
259: if (xsize > 1 && ysize > 1) {
260: MPI_Comm_compare(xcomm,ycomm,&result);
261: if (result == MPI_UNEQUAL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"VecScatterCreate: parallel vectors xin and yin must have identical/congruent/similar communicators");
262: }
264: comm = xsize > ysize ? xcomm : ycomm; /* If xsize==ysize, we use ycomm as comm of ctx, which does affect correctness */
265: size = xsize > ysize ? xsize : ysize;
267: VecScatterInitializePackage();
268: PetscHeaderCreate(ctx,VEC_SCATTER_CLASSID,"VecScatter","Vector Scatter","Vec",comm,VecScatterDestroy,VecScatterView);
270: ctx->from_v = xin;
271: ctx->to_v = yin;
272: ctx->from_is = ix;
273: ctx->to_is = iy;
274: VecGetLocalSize(xin,&ctx->from_n);
275: VecGetLocalSize(yin,&ctx->to_n);
277: /* Set default scatter type */
278: if (size == 1) {VecScatterSetType(ctx,VECSCATTERSEQ);}
279: else {VecScatterSetType(ctx,VECSCATTERMPI1);}
281: VecScatterSetFromOptions(ctx);
282: VecScatterSetUp(ctx);
284: *newctx = ctx;
285: return(0);
286: }