xref: /petsc/src/sys/objects/state.c (revision 10450e9e44b354a0a3da7bbd573407bdf051df10)
17d0a6c19SBarry Smith 
2e5c89e4eSSatish Balay /*
3e5c89e4eSSatish Balay      Provides utility routines for manulating any type of PETSc object.
4e5c89e4eSSatish Balay */
5af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I   "petscsys.h"    I*/
6e5c89e4eSSatish Balay 
7e5c89e4eSSatish Balay /*@C
8811af0c4SBarry Smith   PetscObjectStateGet - Gets the state of any `PetscObject`,
9e5c89e4eSSatish Balay   regardless of the type.
10e5c89e4eSSatish Balay 
11e5c89e4eSSatish Balay   Not Collective
12e5c89e4eSSatish Balay 
13e5c89e4eSSatish Balay   Input Parameter:
14811af0c4SBarry Smith . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
15811af0c4SBarry Smith          cast with a (`PetscObject`), for example,
16811af0c4SBarry Smith          `PetscObjectStateGet`((`PetscObject`)mat,&state);
17e5c89e4eSSatish Balay 
18e5c89e4eSSatish Balay   Output Parameter:
19e5c89e4eSSatish Balay . state - the object state
20e5c89e4eSSatish Balay 
2121532e8aSBarry Smith   Level: advanced
2221532e8aSBarry Smith 
23811af0c4SBarry Smith   Note:
24811af0c4SBarry Smith   Object state is an integer which gets increased every time
25e5c89e4eSSatish Balay   the object is changed. By saving and later querying the object state
26e5c89e4eSSatish Balay   one can determine whether information about the object is still current.
27811af0c4SBarry Smith   Currently, state is maintained for `Vec` and `Mat` objects.
28e5c89e4eSSatish Balay 
2987497f52SBarry Smith .seealso: `PetscObjectStateIncrease()`, `PetscObjectStateSet()`
30e5c89e4eSSatish Balay @*/
31d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectStateGet(PetscObject obj, PetscObjectState *state)
32d71ae5a4SJacob Faibussowitsch {
33e5c89e4eSSatish Balay   PetscFunctionBegin;
343cfa8680SLisandro Dalcin   PetscValidHeader(obj, 1);
3517a82feaSJacob Faibussowitsch   PetscValidInt64Pointer(state, 2);
36e5c89e4eSSatish Balay   *state = obj->state;
373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38e5c89e4eSSatish Balay }
39e5c89e4eSSatish Balay 
40e5c89e4eSSatish Balay /*@C
41811af0c4SBarry Smith   PetscObjectStateSet - Sets the state of any `PetscObject`,
42e5c89e4eSSatish Balay   regardless of the type.
43e5c89e4eSSatish Balay 
44704cc5ceSJed Brown   Logically Collective
45e5c89e4eSSatish Balay 
46d8d19677SJose E. Roman   Input Parameters:
47811af0c4SBarry Smith + obj   - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
48811af0c4SBarry Smith          cast with a (`PetscObject`), for example,
49811af0c4SBarry Smith          `PetscObjectStateSet`((`PetscObject`)mat,state);
50e5c89e4eSSatish Balay - state - the object state
51e5c89e4eSSatish Balay 
522fe279fdSBarry Smith   Level: advanced
532fe279fdSBarry Smith 
54811af0c4SBarry Smith   Note:
5595452b02SPatrick Sanan   This function should be used with extreme caution. There is
5621532e8aSBarry Smith   essentially only one use for it: if the user calls `Mat`(`Vec`)GetRow(Array),
57e5c89e4eSSatish Balay   which increases the state, but does not alter the data, then this
58704cc5ceSJed Brown   routine can be used to reset the state.  Such a reset must be collective.
59e5c89e4eSSatish Balay 
6087497f52SBarry Smith .seealso: `PetscObjectStateGet()`, `PetscObjectStateIncrease()`
61e5c89e4eSSatish Balay @*/
62d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectStateSet(PetscObject obj, PetscObjectState state)
63d71ae5a4SJacob Faibussowitsch {
64e5c89e4eSSatish Balay   PetscFunctionBegin;
653cfa8680SLisandro Dalcin   PetscValidHeader(obj, 1);
66e5c89e4eSSatish Balay   obj->state = state;
673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
68e5c89e4eSSatish Balay }
69e5c89e4eSSatish Balay 
708b5db460SBarry Smith PetscInt PetscObjectComposedDataMax = 10;
7153c77d0aSJed Brown 
7262755792SVictor Eijkhout /*@C
73811af0c4SBarry Smith   PetscObjectComposedDataRegister - Get an available id for composing data with a `PetscObject`
7462755792SVictor Eijkhout 
7562755792SVictor Eijkhout   Not Collective
7662755792SVictor Eijkhout 
77aec76313SJacob Faibussowitsch   Output Parameter:
7862755792SVictor Eijkhout . id - an identifier under which data can be stored
7962755792SVictor Eijkhout 
8062755792SVictor Eijkhout   Level: developer
8162755792SVictor Eijkhout 
8295452b02SPatrick Sanan   Notes:
8387497f52SBarry Smith   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.
841957e957SBarry Smith 
8587497f52SBarry Smith   `PetscObjectCompose()` and  `PetscObjectQuery()` provide a way to attach any data to an object
8662755792SVictor Eijkhout 
8787497f52SBarry Smith .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
88aec76313SJacob Faibussowitsch           `PetscObjectComposedDataGetInt()`, `PetscObject`,
8987497f52SBarry Smith           `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`,
90aec76313SJacob Faibussowitsch           `PetscObjectComposedDataSetScalarstar()`
9162755792SVictor Eijkhout @*/
92d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataRegister(PetscInt *id)
93d71ae5a4SJacob Faibussowitsch {
94d44a1e48SBarry Smith   static PetscInt globalcurrentstate = 0;
95d44a1e48SBarry Smith 
96e5c89e4eSSatish Balay   PetscFunctionBegin;
9717a82feaSJacob Faibussowitsch   PetscValidIntPointer(id, 1);
98e5c89e4eSSatish Balay   *id = globalcurrentstate++;
998b5db460SBarry Smith   if (globalcurrentstate > PetscObjectComposedDataMax) PetscObjectComposedDataMax += 10;
1003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
101e5c89e4eSSatish Balay }
102e5c89e4eSSatish Balay 
10317a82feaSJacob Faibussowitsch static PetscErrorCode PetscObjectComposedDataIncrease_(PetscInt *id_max, char **composed, PetscObjectState **composed_state, size_t obj_size)
104d71ae5a4SJacob Faibussowitsch {
10517a82feaSJacob Faibussowitsch   // must use char here since PetscCalloc2() and PetscMemcpy() use sizeof(**ptr), so if
10617a82feaSJacob Faibussowitsch   // composed is void ** (to match PetscObjectComposedDataStarIncrease_()) that would expand to
10717a82feaSJacob Faibussowitsch   // sizeof(void) which is illegal.
10817a82feaSJacob Faibussowitsch   const char             *ar = *composed;
10917a82feaSJacob Faibussowitsch   const PetscObjectState *ir = *composed_state;
11017a82feaSJacob Faibussowitsch   const PetscInt          n = *id_max, new_n = PetscObjectComposedDataMax;
11117a82feaSJacob Faibussowitsch   char                   *new_ar;
11217a82feaSJacob Faibussowitsch   PetscObjectState       *new_ir;
113e5c89e4eSSatish Balay 
114e5c89e4eSSatish Balay   PetscFunctionBegin;
11517a82feaSJacob Faibussowitsch   PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of composed data ids: %" PetscInt_FMT " < 0", n);
11617a82feaSJacob Faibussowitsch   PetscCall(PetscCalloc2(new_n * obj_size, &new_ar, new_n, &new_ir));
11717a82feaSJacob Faibussowitsch   PetscCall(PetscMemcpy(new_ar, ar, n * obj_size));
11817a82feaSJacob Faibussowitsch   PetscCall(PetscArraycpy(new_ir, ir, n));
1199566063dSJacob Faibussowitsch   PetscCall(PetscFree2(ar, ir));
12017a82feaSJacob Faibussowitsch   *id_max         = new_n;
12117a82feaSJacob Faibussowitsch   *composed       = new_ar;
12217a82feaSJacob Faibussowitsch   *composed_state = new_ir;
12317a82feaSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12417a82feaSJacob Faibussowitsch }
12517a82feaSJacob Faibussowitsch 
12617a82feaSJacob Faibussowitsch #define PetscObjectComposedDataIncrease(id_max, composed, composed_state) PetscObjectComposedDataIncrease_(id_max, (char **)(composed), composed_state, sizeof(**(composed)))
12717a82feaSJacob Faibussowitsch 
12817a82feaSJacob Faibussowitsch static PetscErrorCode PetscObjectComposedDataStarIncrease_(PetscInt *id_max, void ***composed, PetscObjectState **composed_state, size_t obj_size)
12917a82feaSJacob Faibussowitsch {
13017a82feaSJacob Faibussowitsch   void                  **ar = *composed;
13117a82feaSJacob Faibussowitsch   const PetscObjectState *ir = *composed_state;
13217a82feaSJacob Faibussowitsch   const PetscInt          n = *id_max, new_n = PetscObjectComposedDataMax;
13317a82feaSJacob Faibussowitsch   void                  **new_ar;
13417a82feaSJacob Faibussowitsch   PetscObjectState       *new_ir;
13517a82feaSJacob Faibussowitsch 
13617a82feaSJacob Faibussowitsch   PetscFunctionBegin;
13717a82feaSJacob Faibussowitsch   PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of composed star data ids: %" PetscInt_FMT " < 0", n);
13817a82feaSJacob Faibussowitsch   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
13917a82feaSJacob Faibussowitsch   PetscCall(PetscMemcpy(new_ar, ar, n * obj_size));
14017a82feaSJacob Faibussowitsch   PetscCall(PetscArraycpy(new_ir, ir, n));
14117a82feaSJacob Faibussowitsch   PetscCall(PetscFree2(ar, ir));
14217a82feaSJacob Faibussowitsch   *id_max         = new_n;
14317a82feaSJacob Faibussowitsch   *composed       = new_ar;
14417a82feaSJacob Faibussowitsch   *composed_state = new_ir;
14517a82feaSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14617a82feaSJacob Faibussowitsch }
14717a82feaSJacob Faibussowitsch 
14817a82feaSJacob Faibussowitsch #define PetscObjectComposedDataStarIncrease(id_max, composed, composed_state) PetscObjectComposedDataStarIncrease_(id_max, (void ***)(composed), composed_state, sizeof(**(composed)))
14917a82feaSJacob Faibussowitsch 
15017a82feaSJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject obj)
15117a82feaSJacob Faibussowitsch {
15217a82feaSJacob Faibussowitsch   PetscFunctionBegin;
15317a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataIncrease(&obj->int_idmax, &obj->intcomposeddata, &obj->intcomposedstate));
1543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
155e5c89e4eSSatish Balay }
15653c77d0aSJed Brown 
157d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject obj)
158d71ae5a4SJacob Faibussowitsch {
159e5c89e4eSSatish Balay   PetscFunctionBegin;
16017a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataStarIncrease(&obj->intstar_idmax, &obj->intstarcomposeddata, &obj->intstarcomposedstate));
1613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
162e5c89e4eSSatish Balay }
163e5c89e4eSSatish Balay 
164d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject obj)
165d71ae5a4SJacob Faibussowitsch {
166e5c89e4eSSatish Balay   PetscFunctionBegin;
16717a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataIncrease(&obj->real_idmax, &obj->realcomposeddata, &obj->realcomposedstate));
1683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
169e5c89e4eSSatish Balay }
170e5c89e4eSSatish Balay 
171d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject obj)
172d71ae5a4SJacob Faibussowitsch {
173e5c89e4eSSatish Balay   PetscFunctionBegin;
17417a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataStarIncrease(&obj->realstar_idmax, &obj->realstarcomposeddata, &obj->realstarcomposedstate));
1753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
176e5c89e4eSSatish Balay }
177e5c89e4eSSatish Balay 
178d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject obj)
179d71ae5a4SJacob Faibussowitsch {
180e5c89e4eSSatish Balay   PetscFunctionBegin;
18117a82feaSJacob Faibussowitsch #if PetscDefined(USE_COMPLEX)
18217a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataIncrease(&obj->scalar_idmax, &obj->scalarcomposeddata, &obj->scalarcomposedstate));
1839cd7b5a2SJacob Faibussowitsch #else
18417a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataIncreaseReal(obj));
1859cd7b5a2SJacob Faibussowitsch #endif
18617a82feaSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
187e5c89e4eSSatish Balay }
188e5c89e4eSSatish Balay 
189d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject obj)
190d71ae5a4SJacob Faibussowitsch {
191e5c89e4eSSatish Balay   PetscFunctionBegin;
19217a82feaSJacob Faibussowitsch #if PetscDefined(USE_COMPLEX)
19317a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataStarIncrease(&obj->scalarstar_idmax, &obj->scalarstarcomposeddata, &obj->scalarstarcomposedstate));
1949cd7b5a2SJacob Faibussowitsch #else
19517a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataIncreaseRealstar(obj));
1969cd7b5a2SJacob Faibussowitsch #endif
19717a82feaSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
198e5c89e4eSSatish Balay }
199e5c89e4eSSatish Balay 
200127c8a3bSJed Brown /*@
201811af0c4SBarry Smith   PetscObjectGetId - get a unique object ID for the `PetscObject`
202127c8a3bSJed Brown 
203127c8a3bSJed Brown   Not Collective
204127c8a3bSJed Brown 
2054165533cSJose E. Roman   Input Parameter:
206127c8a3bSJed Brown . obj - object
207127c8a3bSJed Brown 
2084165533cSJose E. Roman   Output Parameter:
209127c8a3bSJed Brown . id - integer ID
210127c8a3bSJed Brown 
211127c8a3bSJed Brown   Level: developer
212127c8a3bSJed Brown 
213811af0c4SBarry Smith   Note:
214127c8a3bSJed Brown   The object ID may be different on different processes, but object IDs are never reused so local equality implies global equality.
215127c8a3bSJed Brown 
216db781477SPatrick Sanan .seealso: `PetscObjectStateGet()`, `PetscObjectCompareId()`
217127c8a3bSJed Brown @*/
218d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectGetId(PetscObject obj, PetscObjectId *id)
219d71ae5a4SJacob Faibussowitsch {
220127c8a3bSJed Brown   PetscFunctionBegin;
2210e6b6b59SJacob Faibussowitsch   PetscValidHeader(obj, 1);
22217a82feaSJacob Faibussowitsch   PetscValidInt64Pointer(id, 2);
223127c8a3bSJed Brown   *id = obj->id;
2243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
225127c8a3bSJed Brown }
226bdaf1daeSBarry Smith 
227bdaf1daeSBarry Smith /*@
228c94eee08SBarry Smith   PetscObjectCompareId - compares the objects ID with a given id
229bdaf1daeSBarry Smith 
230bdaf1daeSBarry Smith   Not Collective
231bdaf1daeSBarry Smith 
2324165533cSJose E. Roman   Input Parameters:
233bdaf1daeSBarry Smith + obj - object
234bdaf1daeSBarry Smith - id  - integer ID
235bdaf1daeSBarry Smith 
236*10450e9eSJacob Faibussowitsch   Output Parameter:
237bdaf1daeSBarry Smith . eq - the ids are equal
238bdaf1daeSBarry Smith 
239bdaf1daeSBarry Smith   Level: developer
240bdaf1daeSBarry Smith 
241811af0c4SBarry Smith   Note:
242*10450e9eSJacob Faibussowitsch   The object ID may be different on different processes, but object IDs are never reused so
243*10450e9eSJacob Faibussowitsch   local equality implies global equality.
244bdaf1daeSBarry Smith 
245db781477SPatrick Sanan .seealso: `PetscObjectStateGet()`, `PetscObjectGetId()`
246bdaf1daeSBarry Smith @*/
247d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectCompareId(PetscObject obj, PetscObjectId id, PetscBool *eq)
248d71ae5a4SJacob Faibussowitsch {
2490e6b6b59SJacob Faibussowitsch   PetscObjectId oid;
2500e6b6b59SJacob Faibussowitsch 
251bdaf1daeSBarry Smith   PetscFunctionBegin;
2520e6b6b59SJacob Faibussowitsch   PetscValidHeader(obj, 1);
2530e6b6b59SJacob Faibussowitsch   PetscValidBoolPointer(eq, 3);
2540e6b6b59SJacob Faibussowitsch   PetscCall(PetscObjectGetId(obj, &oid));
2550e6b6b59SJacob Faibussowitsch   *eq = (id == oid) ? PETSC_TRUE : PETSC_FALSE;
2563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
257bdaf1daeSBarry Smith }
258