xref: /petsc/src/sys/objects/state.c (revision 0619917b5a674bb687c64e7daba2ab22be99af31)
1 
2 /*
3      Provides utility routines for manulating any type of PETSc object.
4 */
5 #include <petsc/private/petscimpl.h> /*I   "petscsys.h"    I*/
6 
7 /*@C
8   PetscObjectStateGet - Gets the state of any `PetscObject`,
9   regardless of the type.
10 
11   Not Collective
12 
13   Input Parameter:
14 . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
15          cast with a (`PetscObject`), for example,
16          `PetscObjectStateGet`((`PetscObject`)mat,&state);
17 
18   Output Parameter:
19 . state - the object state
20 
21   Level: advanced
22 
23   Note:
24   Object state is an integer which gets increased every time
25   the object is changed. By saving and later querying the object state
26   one can determine whether information about the object is still current.
27   Currently, state is maintained for `Vec` and `Mat` objects.
28 
29 .seealso: `PetscObjectStateIncrease()`, `PetscObjectStateSet()`
30 @*/
31 PetscErrorCode PetscObjectStateGet(PetscObject obj, PetscObjectState *state)
32 {
33   PetscFunctionBegin;
34   PetscValidHeader(obj, 1);
35   PetscAssertPointer(state, 2);
36   *state = obj->state;
37   PetscFunctionReturn(PETSC_SUCCESS);
38 }
39 
40 /*@C
41   PetscObjectStateSet - Sets the state of any `PetscObject`,
42   regardless of the type.
43 
44   Logically Collective
45 
46   Input Parameters:
47 + obj   - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
48          cast with a (`PetscObject`), for example,
49          `PetscObjectStateSet`((`PetscObject`)mat,state);
50 - state - the object state
51 
52   Level: advanced
53 
54   Note:
55   This function should be used with extreme caution. There is
56   essentially only one use for it: if the user calls `Mat`(`Vec`)GetRow(Array),
57   which increases the state, but does not alter the data, then this
58   routine can be used to reset the state.  Such a reset must be collective.
59 
60 .seealso: `PetscObjectStateGet()`, `PetscObjectStateIncrease()`
61 @*/
62 PetscErrorCode PetscObjectStateSet(PetscObject obj, PetscObjectState state)
63 {
64   PetscFunctionBegin;
65   PetscValidHeader(obj, 1);
66   obj->state = state;
67   PetscFunctionReturn(PETSC_SUCCESS);
68 }
69 
70 PetscInt PetscObjectComposedDataMax = 10;
71 
72 /*@C
73   PetscObjectComposedDataRegister - Get an available id for composing data with a `PetscObject`
74 
75   Not Collective
76 
77   Output Parameter:
78 . id - an identifier under which data can be stored
79 
80   Level: developer
81 
82   Notes:
83   You must keep this value (for example in a global variable) in order to attach the data to an object or access in an object.
84 
85   `PetscObjectCompose()` and  `PetscObjectQuery()` provide a way to attach any data to an object
86 
87 .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
88           `PetscObjectComposedDataGetInt()`, `PetscObject`,
89           `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`,
90           `PetscObjectComposedDataSetScalarstar()`
91 @*/
92 PetscErrorCode PetscObjectComposedDataRegister(PetscInt *id)
93 {
94   static PetscInt globalcurrentstate = 0;
95 
96   PetscFunctionBegin;
97   PetscAssertPointer(id, 1);
98   *id = globalcurrentstate++;
99   if (globalcurrentstate > PetscObjectComposedDataMax) PetscObjectComposedDataMax += 10;
100   PetscFunctionReturn(PETSC_SUCCESS);
101 }
102 
103 static PetscErrorCode PetscObjectComposedDataIncrease_(PetscInt *id_max, char **composed, PetscObjectState **composed_state, size_t obj_size)
104 {
105   // must use char here since PetscCalloc2() and PetscMemcpy() use sizeof(**ptr), so if
106   // composed is void ** (to match PetscObjectComposedDataStarIncrease_()) that would expand to
107   // sizeof(void) which is illegal.
108   const char             *ar = *composed;
109   const PetscObjectState *ir = *composed_state;
110   const PetscInt          n = *id_max, new_n = PetscObjectComposedDataMax;
111   char                   *new_ar;
112   PetscObjectState       *new_ir;
113 
114   PetscFunctionBegin;
115   PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of composed data ids: %" PetscInt_FMT " < 0", n);
116   PetscCall(PetscCalloc2(new_n * obj_size, &new_ar, new_n, &new_ir));
117   PetscCall(PetscMemcpy(new_ar, ar, n * obj_size));
118   PetscCall(PetscArraycpy(new_ir, ir, n));
119   PetscCall(PetscFree2(ar, ir));
120   *id_max         = new_n;
121   *composed       = new_ar;
122   *composed_state = new_ir;
123   PetscFunctionReturn(PETSC_SUCCESS);
124 }
125 
126 #define PetscObjectComposedDataIncrease(id_max, composed, composed_state) PetscObjectComposedDataIncrease_(id_max, (char **)(composed), composed_state, sizeof(**(composed)))
127 
128 static PetscErrorCode PetscObjectComposedDataStarIncrease_(PetscInt *id_max, void ***composed, PetscObjectState **composed_state, size_t obj_size)
129 {
130   void                  **ar = *composed;
131   const PetscObjectState *ir = *composed_state;
132   const PetscInt          n = *id_max, new_n = PetscObjectComposedDataMax;
133   void                  **new_ar;
134   PetscObjectState       *new_ir;
135 
136   PetscFunctionBegin;
137   PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of composed star data ids: %" PetscInt_FMT " < 0", n);
138   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
139   PetscCall(PetscMemcpy(new_ar, ar, n * obj_size));
140   PetscCall(PetscArraycpy(new_ir, ir, n));
141   PetscCall(PetscFree2(ar, ir));
142   *id_max         = new_n;
143   *composed       = new_ar;
144   *composed_state = new_ir;
145   PetscFunctionReturn(PETSC_SUCCESS);
146 }
147 
148 #define PetscObjectComposedDataStarIncrease(id_max, composed, composed_state) PetscObjectComposedDataStarIncrease_(id_max, (void ***)(composed), composed_state, sizeof(**(composed)))
149 
150 PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject obj)
151 {
152   PetscFunctionBegin;
153   PetscCall(PetscObjectComposedDataIncrease(&obj->int_idmax, &obj->intcomposeddata, &obj->intcomposedstate));
154   PetscFunctionReturn(PETSC_SUCCESS);
155 }
156 
157 PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject obj)
158 {
159   PetscFunctionBegin;
160   PetscCall(PetscObjectComposedDataStarIncrease(&obj->intstar_idmax, &obj->intstarcomposeddata, &obj->intstarcomposedstate));
161   PetscFunctionReturn(PETSC_SUCCESS);
162 }
163 
164 PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject obj)
165 {
166   PetscFunctionBegin;
167   PetscCall(PetscObjectComposedDataIncrease(&obj->real_idmax, &obj->realcomposeddata, &obj->realcomposedstate));
168   PetscFunctionReturn(PETSC_SUCCESS);
169 }
170 
171 PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject obj)
172 {
173   PetscFunctionBegin;
174   PetscCall(PetscObjectComposedDataStarIncrease(&obj->realstar_idmax, &obj->realstarcomposeddata, &obj->realstarcomposedstate));
175   PetscFunctionReturn(PETSC_SUCCESS);
176 }
177 
178 PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject obj)
179 {
180   PetscFunctionBegin;
181 #if PetscDefined(USE_COMPLEX)
182   PetscCall(PetscObjectComposedDataIncrease(&obj->scalar_idmax, &obj->scalarcomposeddata, &obj->scalarcomposedstate));
183 #else
184   PetscCall(PetscObjectComposedDataIncreaseReal(obj));
185 #endif
186   PetscFunctionReturn(PETSC_SUCCESS);
187 }
188 
189 PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject obj)
190 {
191   PetscFunctionBegin;
192 #if PetscDefined(USE_COMPLEX)
193   PetscCall(PetscObjectComposedDataStarIncrease(&obj->scalarstar_idmax, &obj->scalarstarcomposeddata, &obj->scalarstarcomposedstate));
194 #else
195   PetscCall(PetscObjectComposedDataIncreaseRealstar(obj));
196 #endif
197   PetscFunctionReturn(PETSC_SUCCESS);
198 }
199 
200 /*@
201   PetscObjectGetId - get a unique object ID for the `PetscObject`
202 
203   Not Collective
204 
205   Input Parameter:
206 . obj - object
207 
208   Output Parameter:
209 . id - integer ID
210 
211   Level: developer
212 
213   Note:
214   The object ID may be different on different processes, but object IDs are never reused so local equality implies global equality.
215 
216 .seealso: `PetscObjectStateGet()`, `PetscObjectCompareId()`
217 @*/
218 PetscErrorCode PetscObjectGetId(PetscObject obj, PetscObjectId *id)
219 {
220   PetscFunctionBegin;
221   PetscValidHeader(obj, 1);
222   PetscAssertPointer(id, 2);
223   *id = obj->id;
224   PetscFunctionReturn(PETSC_SUCCESS);
225 }
226 
227 /*@
228   PetscObjectCompareId - compares the objects ID with a given id
229 
230   Not Collective
231 
232   Input Parameters:
233 + obj - object
234 - id  - integer ID
235 
236   Output Parameter:
237 . eq - the ids are equal
238 
239   Level: developer
240 
241   Note:
242   The object ID may be different on different processes, but object IDs are never reused so
243   local equality implies global equality.
244 
245 .seealso: `PetscObjectStateGet()`, `PetscObjectGetId()`
246 @*/
247 PetscErrorCode PetscObjectCompareId(PetscObject obj, PetscObjectId id, PetscBool *eq)
248 {
249   PetscObjectId oid;
250 
251   PetscFunctionBegin;
252   PetscValidHeader(obj, 1);
253   PetscAssertPointer(eq, 3);
254   PetscCall(PetscObjectGetId(obj, &oid));
255   *eq = (id == oid) ? PETSC_TRUE : PETSC_FALSE;
256   PetscFunctionReturn(PETSC_SUCCESS);
257 }
258