xref: /petsc/src/sys/objects/state.c (revision 6d8694c4fbab79f9439f1ad13c0386ba7ee1ca4b)
1e5c89e4eSSatish Balay /*
2e5c89e4eSSatish Balay      Provides utility routines for manulating any type of PETSc object.
3e5c89e4eSSatish Balay */
4af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I   "petscsys.h"    I*/
5e5c89e4eSSatish Balay 
6ffeef943SBarry Smith /*@
7811af0c4SBarry Smith   PetscObjectStateGet - Gets the state of any `PetscObject`,
8e5c89e4eSSatish Balay   regardless of the type.
9e5c89e4eSSatish Balay 
10e5c89e4eSSatish Balay   Not Collective
11e5c89e4eSSatish Balay 
12e5c89e4eSSatish Balay   Input Parameter:
13811af0c4SBarry Smith . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
14811af0c4SBarry Smith          cast with a (`PetscObject`), for example,
15811af0c4SBarry Smith          `PetscObjectStateGet`((`PetscObject`)mat,&state);
16e5c89e4eSSatish Balay 
17e5c89e4eSSatish Balay   Output Parameter:
18e5c89e4eSSatish Balay . state - the object state
19e5c89e4eSSatish Balay 
2021532e8aSBarry Smith   Level: advanced
2121532e8aSBarry Smith 
22811af0c4SBarry Smith   Note:
23811af0c4SBarry Smith   Object state is an integer which gets increased every time
24e5c89e4eSSatish Balay   the object is changed. By saving and later querying the object state
25e5c89e4eSSatish Balay   one can determine whether information about the object is still current.
26811af0c4SBarry Smith   Currently, state is maintained for `Vec` and `Mat` objects.
27e5c89e4eSSatish Balay 
2887497f52SBarry Smith .seealso: `PetscObjectStateIncrease()`, `PetscObjectStateSet()`
29e5c89e4eSSatish Balay @*/
PetscObjectStateGet(PetscObject obj,PetscObjectState * state)30d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectStateGet(PetscObject obj, PetscObjectState *state)
31d71ae5a4SJacob Faibussowitsch {
32e5c89e4eSSatish Balay   PetscFunctionBegin;
333cfa8680SLisandro Dalcin   PetscValidHeader(obj, 1);
344f572ea9SToby Isaac   PetscAssertPointer(state, 2);
35e5c89e4eSSatish Balay   *state = obj->state;
363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37e5c89e4eSSatish Balay }
38e5c89e4eSSatish Balay 
39ffeef943SBarry Smith /*@
40811af0c4SBarry Smith   PetscObjectStateSet - Sets the state of any `PetscObject`,
41e5c89e4eSSatish Balay   regardless of the type.
42e5c89e4eSSatish Balay 
43704cc5ceSJed Brown   Logically Collective
44e5c89e4eSSatish Balay 
45d8d19677SJose E. Roman   Input Parameters:
46811af0c4SBarry Smith + obj   - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
47811af0c4SBarry Smith          cast with a (`PetscObject`), for example,
48811af0c4SBarry Smith          `PetscObjectStateSet`((`PetscObject`)mat,state);
49e5c89e4eSSatish Balay - state - the object state
50e5c89e4eSSatish Balay 
512fe279fdSBarry Smith   Level: advanced
522fe279fdSBarry Smith 
53811af0c4SBarry Smith   Note:
5495452b02SPatrick Sanan   This function should be used with extreme caution. There is
5521532e8aSBarry Smith   essentially only one use for it: if the user calls `Mat`(`Vec`)GetRow(Array),
56e5c89e4eSSatish Balay   which increases the state, but does not alter the data, then this
57704cc5ceSJed Brown   routine can be used to reset the state.  Such a reset must be collective.
58e5c89e4eSSatish Balay 
5987497f52SBarry Smith .seealso: `PetscObjectStateGet()`, `PetscObjectStateIncrease()`
60e5c89e4eSSatish Balay @*/
PetscObjectStateSet(PetscObject obj,PetscObjectState state)61d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectStateSet(PetscObject obj, PetscObjectState state)
62d71ae5a4SJacob Faibussowitsch {
63e5c89e4eSSatish Balay   PetscFunctionBegin;
643cfa8680SLisandro Dalcin   PetscValidHeader(obj, 1);
65e5c89e4eSSatish Balay   obj->state = state;
663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
67e5c89e4eSSatish Balay }
68e5c89e4eSSatish Balay 
698b5db460SBarry Smith PetscInt PetscObjectComposedDataMax = 10;
7053c77d0aSJed Brown 
7162755792SVictor Eijkhout /*@C
72811af0c4SBarry Smith   PetscObjectComposedDataRegister - Get an available id for composing data with a `PetscObject`
7362755792SVictor Eijkhout 
7462755792SVictor Eijkhout   Not Collective
7562755792SVictor Eijkhout 
76aec76313SJacob Faibussowitsch   Output Parameter:
7762755792SVictor Eijkhout . id - an identifier under which data can be stored
7862755792SVictor Eijkhout 
7962755792SVictor Eijkhout   Level: developer
8062755792SVictor Eijkhout 
8195452b02SPatrick Sanan   Notes:
8287497f52SBarry 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.
831957e957SBarry Smith 
8487497f52SBarry Smith   `PetscObjectCompose()` and  `PetscObjectQuery()` provide a way to attach any data to an object
8562755792SVictor Eijkhout 
8687497f52SBarry Smith .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
87aec76313SJacob Faibussowitsch           `PetscObjectComposedDataGetInt()`, `PetscObject`,
8887497f52SBarry Smith           `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`,
89aec76313SJacob Faibussowitsch           `PetscObjectComposedDataSetScalarstar()`
9062755792SVictor Eijkhout @*/
PetscObjectComposedDataRegister(PetscInt * id)91d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataRegister(PetscInt *id)
92d71ae5a4SJacob Faibussowitsch {
93d44a1e48SBarry Smith   static PetscInt globalcurrentstate = 0;
94d44a1e48SBarry Smith 
95e5c89e4eSSatish Balay   PetscFunctionBegin;
964f572ea9SToby Isaac   PetscAssertPointer(id, 1);
97e5c89e4eSSatish Balay   *id = globalcurrentstate++;
988b5db460SBarry Smith   if (globalcurrentstate > PetscObjectComposedDataMax) PetscObjectComposedDataMax += 10;
993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
100e5c89e4eSSatish Balay }
101e5c89e4eSSatish Balay 
PetscObjectComposedDataIncrease_(PetscInt * id_max,char ** composed,PetscObjectState ** composed_state,size_t obj_size)10217a82feaSJacob Faibussowitsch static PetscErrorCode PetscObjectComposedDataIncrease_(PetscInt *id_max, char **composed, PetscObjectState **composed_state, size_t obj_size)
103d71ae5a4SJacob Faibussowitsch {
10417a82feaSJacob Faibussowitsch   // must use char here since PetscCalloc2() and PetscMemcpy() use sizeof(**ptr), so if
10517a82feaSJacob Faibussowitsch   // composed is void ** (to match PetscObjectComposedDataStarIncrease_()) that would expand to
10617a82feaSJacob Faibussowitsch   // sizeof(void) which is illegal.
107*ce78bad3SBarry Smith   char             *ar = *composed;
108*ce78bad3SBarry Smith   PetscObjectState *ir = *composed_state;
10917a82feaSJacob Faibussowitsch   const PetscInt    n = *id_max, new_n = PetscObjectComposedDataMax;
11017a82feaSJacob Faibussowitsch   char             *new_ar;
11117a82feaSJacob Faibussowitsch   PetscObjectState *new_ir;
112e5c89e4eSSatish Balay 
113e5c89e4eSSatish Balay   PetscFunctionBegin;
11417a82feaSJacob Faibussowitsch   PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of composed data ids: %" PetscInt_FMT " < 0", n);
11517a82feaSJacob Faibussowitsch   PetscCall(PetscCalloc2(new_n * obj_size, &new_ar, new_n, &new_ir));
11617a82feaSJacob Faibussowitsch   PetscCall(PetscMemcpy(new_ar, ar, n * obj_size));
11717a82feaSJacob Faibussowitsch   PetscCall(PetscArraycpy(new_ir, ir, n));
1189566063dSJacob Faibussowitsch   PetscCall(PetscFree2(ar, ir));
11917a82feaSJacob Faibussowitsch   *id_max         = new_n;
12017a82feaSJacob Faibussowitsch   *composed       = new_ar;
12117a82feaSJacob Faibussowitsch   *composed_state = new_ir;
12217a82feaSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12317a82feaSJacob Faibussowitsch }
12417a82feaSJacob Faibussowitsch 
12517a82feaSJacob Faibussowitsch #define PetscObjectComposedDataIncrease(id_max, composed, composed_state) PetscObjectComposedDataIncrease_(id_max, (char **)(composed), composed_state, sizeof(**(composed)))
12617a82feaSJacob Faibussowitsch 
PetscObjectComposedDataStarIncrease_(PetscInt * id_max,void *** composed,PetscObjectState ** composed_state,size_t obj_size)12717a82feaSJacob Faibussowitsch static PetscErrorCode PetscObjectComposedDataStarIncrease_(PetscInt *id_max, void ***composed, PetscObjectState **composed_state, size_t obj_size)
12817a82feaSJacob Faibussowitsch {
12917a82feaSJacob Faibussowitsch   void                  **ar = *composed;
13017a82feaSJacob Faibussowitsch   const PetscObjectState *ir = *composed_state;
13117a82feaSJacob Faibussowitsch   const PetscInt          n = *id_max, new_n = PetscObjectComposedDataMax;
13217a82feaSJacob Faibussowitsch   void                  **new_ar;
13317a82feaSJacob Faibussowitsch   PetscObjectState       *new_ir;
13417a82feaSJacob Faibussowitsch 
13517a82feaSJacob Faibussowitsch   PetscFunctionBegin;
13617a82feaSJacob Faibussowitsch   PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of composed star data ids: %" PetscInt_FMT " < 0", n);
13717a82feaSJacob Faibussowitsch   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
13817a82feaSJacob Faibussowitsch   PetscCall(PetscMemcpy(new_ar, ar, n * obj_size));
13917a82feaSJacob Faibussowitsch   PetscCall(PetscArraycpy(new_ir, ir, n));
14017a82feaSJacob Faibussowitsch   PetscCall(PetscFree2(ar, ir));
14117a82feaSJacob Faibussowitsch   *id_max         = new_n;
14217a82feaSJacob Faibussowitsch   *composed       = new_ar;
14317a82feaSJacob Faibussowitsch   *composed_state = new_ir;
14417a82feaSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14517a82feaSJacob Faibussowitsch }
14617a82feaSJacob Faibussowitsch 
14717a82feaSJacob Faibussowitsch #define PetscObjectComposedDataStarIncrease(id_max, composed, composed_state) PetscObjectComposedDataStarIncrease_(id_max, (void ***)(composed), composed_state, sizeof(**(composed)))
14817a82feaSJacob Faibussowitsch 
PetscObjectComposedDataIncreaseInt(PetscObject obj)14917a82feaSJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject obj)
15017a82feaSJacob Faibussowitsch {
15117a82feaSJacob Faibussowitsch   PetscFunctionBegin;
15217a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataIncrease(&obj->int_idmax, &obj->intcomposeddata, &obj->intcomposedstate));
1533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
154e5c89e4eSSatish Balay }
15553c77d0aSJed Brown 
PetscObjectComposedDataIncreaseIntstar(PetscObject obj)156d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject obj)
157d71ae5a4SJacob Faibussowitsch {
158e5c89e4eSSatish Balay   PetscFunctionBegin;
15917a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataStarIncrease(&obj->intstar_idmax, &obj->intstarcomposeddata, &obj->intstarcomposedstate));
1603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
161e5c89e4eSSatish Balay }
162e5c89e4eSSatish Balay 
PetscObjectComposedDataIncreaseReal(PetscObject obj)163d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject obj)
164d71ae5a4SJacob Faibussowitsch {
165e5c89e4eSSatish Balay   PetscFunctionBegin;
16617a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataIncrease(&obj->real_idmax, &obj->realcomposeddata, &obj->realcomposedstate));
1673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
168e5c89e4eSSatish Balay }
169e5c89e4eSSatish Balay 
PetscObjectComposedDataIncreaseRealstar(PetscObject obj)170d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject obj)
171d71ae5a4SJacob Faibussowitsch {
172e5c89e4eSSatish Balay   PetscFunctionBegin;
17317a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataStarIncrease(&obj->realstar_idmax, &obj->realstarcomposeddata, &obj->realstarcomposedstate));
1743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
175e5c89e4eSSatish Balay }
176e5c89e4eSSatish Balay 
PetscObjectComposedDataIncreaseScalar(PetscObject obj)177d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject obj)
178d71ae5a4SJacob Faibussowitsch {
179e5c89e4eSSatish Balay   PetscFunctionBegin;
18017a82feaSJacob Faibussowitsch #if PetscDefined(USE_COMPLEX)
18117a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataIncrease(&obj->scalar_idmax, &obj->scalarcomposeddata, &obj->scalarcomposedstate));
1829cd7b5a2SJacob Faibussowitsch #else
18317a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataIncreaseReal(obj));
1849cd7b5a2SJacob Faibussowitsch #endif
18517a82feaSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
186e5c89e4eSSatish Balay }
187e5c89e4eSSatish Balay 
PetscObjectComposedDataIncreaseScalarstar(PetscObject obj)188d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject obj)
189d71ae5a4SJacob Faibussowitsch {
190e5c89e4eSSatish Balay   PetscFunctionBegin;
19117a82feaSJacob Faibussowitsch #if PetscDefined(USE_COMPLEX)
19217a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataStarIncrease(&obj->scalarstar_idmax, &obj->scalarstarcomposeddata, &obj->scalarstarcomposedstate));
1939cd7b5a2SJacob Faibussowitsch #else
19417a82feaSJacob Faibussowitsch   PetscCall(PetscObjectComposedDataIncreaseRealstar(obj));
1959cd7b5a2SJacob Faibussowitsch #endif
19617a82feaSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
197e5c89e4eSSatish Balay }
198e5c89e4eSSatish Balay 
199127c8a3bSJed Brown /*@
200811af0c4SBarry Smith   PetscObjectGetId - get a unique object ID for the `PetscObject`
201127c8a3bSJed Brown 
202127c8a3bSJed Brown   Not Collective
203127c8a3bSJed Brown 
2044165533cSJose E. Roman   Input Parameter:
205127c8a3bSJed Brown . obj - object
206127c8a3bSJed Brown 
2074165533cSJose E. Roman   Output Parameter:
208127c8a3bSJed Brown . id - integer ID
209127c8a3bSJed Brown 
210127c8a3bSJed Brown   Level: developer
211127c8a3bSJed Brown 
212811af0c4SBarry Smith   Note:
213127c8a3bSJed Brown   The object ID may be different on different processes, but object IDs are never reused so local equality implies global equality.
214127c8a3bSJed Brown 
215db781477SPatrick Sanan .seealso: `PetscObjectStateGet()`, `PetscObjectCompareId()`
216127c8a3bSJed Brown @*/
PetscObjectGetId(PetscObject obj,PetscObjectId * id)217d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectGetId(PetscObject obj, PetscObjectId *id)
218d71ae5a4SJacob Faibussowitsch {
219127c8a3bSJed Brown   PetscFunctionBegin;
2200e6b6b59SJacob Faibussowitsch   PetscValidHeader(obj, 1);
2214f572ea9SToby Isaac   PetscAssertPointer(id, 2);
222127c8a3bSJed Brown   *id = obj->id;
2233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
224127c8a3bSJed Brown }
225bdaf1daeSBarry Smith 
226bdaf1daeSBarry Smith /*@
227c94eee08SBarry Smith   PetscObjectCompareId - compares the objects ID with a given id
228bdaf1daeSBarry Smith 
229bdaf1daeSBarry Smith   Not Collective
230bdaf1daeSBarry Smith 
2314165533cSJose E. Roman   Input Parameters:
232bdaf1daeSBarry Smith + obj - object
233bdaf1daeSBarry Smith - id  - integer ID
234bdaf1daeSBarry Smith 
23510450e9eSJacob Faibussowitsch   Output Parameter:
236bdaf1daeSBarry Smith . eq - the ids are equal
237bdaf1daeSBarry Smith 
238bdaf1daeSBarry Smith   Level: developer
239bdaf1daeSBarry Smith 
240811af0c4SBarry Smith   Note:
24110450e9eSJacob Faibussowitsch   The object ID may be different on different processes, but object IDs are never reused so
24210450e9eSJacob Faibussowitsch   local equality implies global equality.
243bdaf1daeSBarry Smith 
244db781477SPatrick Sanan .seealso: `PetscObjectStateGet()`, `PetscObjectGetId()`
245bdaf1daeSBarry Smith @*/
PetscObjectCompareId(PetscObject obj,PetscObjectId id,PetscBool * eq)246d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectCompareId(PetscObject obj, PetscObjectId id, PetscBool *eq)
247d71ae5a4SJacob Faibussowitsch {
2480e6b6b59SJacob Faibussowitsch   PetscObjectId oid;
2490e6b6b59SJacob Faibussowitsch 
250bdaf1daeSBarry Smith   PetscFunctionBegin;
2510e6b6b59SJacob Faibussowitsch   PetscValidHeader(obj, 1);
2524f572ea9SToby Isaac   PetscAssertPointer(eq, 3);
2530e6b6b59SJacob Faibussowitsch   PetscCall(PetscObjectGetId(obj, &oid));
2540e6b6b59SJacob Faibussowitsch   *eq = (id == oid) ? PETSC_TRUE : PETSC_FALSE;
2553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
256bdaf1daeSBarry Smith }
257