Actual source code: vecreg.c


  2: #include <petsc/private/vecimpl.h>

  4: PetscFunctionList VecList              = NULL;
  5: PetscBool         VecRegisterAllCalled = PETSC_FALSE;

  7: /*@C
  8:   VecSetType - Builds a vector, for a particular vector implementation.

 10:   Collective

 12:   Input Parameters:
 13: + vec    - The vector object
 14: - method - The name of the vector type

 16:   Options Database Key:
 17: . -vec_type <type> - Sets the vector type; use -help for a list
 18:                      of available types

 20:   Level: intermediate

 22:   Notes:
 23:   See `VecType` for available vector types (for instance, `VECSEQ` or `VECMPI`)

 25:   Use `VecDuplicate()` or `VecDuplicateVecs()` to form additional vectors of the same type as an existing vector.

 27: .seealso: [](ch_vectors), `Vec`, `VecType`, `VecGetType()`, `VecCreate()`, `VecDuplicate()`, `VecDuplicateVecs()`
 28: @*/
 29: PetscErrorCode VecSetType(Vec vec, VecType method)
 30: {
 31:   PetscErrorCode (*r)(Vec);
 32:   PetscBool   match;
 33:   PetscMPIInt size;

 35:   PetscFunctionBegin;
 37:   PetscCall(PetscObjectTypeCompare((PetscObject)vec, method, &match));
 38:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

 40:   /* Return if asked for VECSTANDARD and Vec is already VECSEQ on 1 process or VECMPI on more.
 41:      Otherwise, we free the Vec array in the call to destroy below and never reallocate it,
 42:      since the VecType will be the same and VecSetType(v,VECSEQ) will return when called from VecCreate_Standard */
 43:   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
 44:   PetscCall(PetscStrcmp(method, VECSTANDARD, &match));
 45:   if (match) {
 46:     PetscCall(PetscObjectTypeCompare((PetscObject)vec, size > 1 ? VECMPI : VECSEQ, &match));
 47:     if (match) PetscFunctionReturn(PETSC_SUCCESS);
 48:   }
 49:   /* same reasons for VECCUDA and VECVIENNACL */
 50: #if defined(PETSC_HAVE_CUDA)
 51:   PetscCall(PetscStrcmp(method, VECCUDA, &match));
 52:   if (match) {
 53:     PetscCall(PetscObjectTypeCompare((PetscObject)vec, size > 1 ? VECMPICUDA : VECSEQCUDA, &match));
 54:     if (match) PetscFunctionReturn(PETSC_SUCCESS);
 55:   }
 56: #endif
 57: #if defined(PETSC_HAVE_HIP)
 58:   PetscCall(PetscStrcmp(method, VECHIP, &match));
 59:   if (match) {
 60:     PetscCall(PetscObjectTypeCompare((PetscObject)vec, size > 1 ? VECMPIHIP : VECSEQHIP, &match));
 61:     if (match) PetscFunctionReturn(PETSC_SUCCESS);
 62:   }
 63: #endif
 64: #if defined(PETSC_HAVE_VIENNACL)
 65:   PetscCall(PetscStrcmp(method, VECVIENNACL, &match));
 66:   if (match) {
 67:     PetscCall(PetscObjectTypeCompare((PetscObject)vec, size > 1 ? VECMPIVIENNACL : VECSEQVIENNACL, &match));
 68:     if (match) PetscFunctionReturn(PETSC_SUCCESS);
 69:   }
 70: #endif
 71: #if defined(PETSC_HAVE_KOKKOS_KERNELS)
 72:   PetscCall(PetscStrcmp(method, VECKOKKOS, &match));
 73:   if (match) {
 74:     PetscCall(PetscObjectTypeCompare((PetscObject)vec, size > 1 ? VECMPIKOKKOS : VECSEQKOKKOS, &match));
 75:     if (match) PetscFunctionReturn(PETSC_SUCCESS);
 76:   }
 77: #endif
 78:   PetscCall(PetscFunctionListFind(VecList, method, &r));
 79:   PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown vector type: %s", method);
 80:   PetscTryTypeMethod(vec, destroy);
 81:   vec->ops->destroy = NULL;
 82:   PetscCall(PetscMemzero(vec->ops, sizeof(struct _VecOps)));
 83:   PetscCall(PetscFree(vec->defaultrandtype));
 84:   PetscCall(PetscStrallocpy(PETSCRANDER48, &vec->defaultrandtype));
 85:   if (vec->map->n < 0 && vec->map->N < 0) {
 86:     vec->ops->create = r;
 87:     vec->ops->load   = VecLoad_Default;
 88:   } else {
 89:     PetscCall((*r)(vec));
 90:   }
 91:   PetscFunctionReturn(PETSC_SUCCESS);
 92: }

 94: /*@C
 95:   VecGetType - Gets the vector type name (as a string) from a `Vec`.

 97:   Not Collective

 99:   Input Parameter:
100: . vec  - The vector

102:   Output Parameter:
103: . type - The `VecType` of the vector

105:   Level: intermediate

107: .seealso: [](ch_vectors), `Vec`, `VecType`, `VecGetType()`, `VecCreate()`, `VecDuplicate()`, `VecDuplicateVecs()`
108: @*/
109: PetscErrorCode VecGetType(Vec vec, VecType *type)
110: {
111:   PetscFunctionBegin;
114:   PetscCall(VecRegisterAll());
115:   *type = ((PetscObject)vec)->type_name;
116:   PetscFunctionReturn(PETSC_SUCCESS);
117: }

119: PetscErrorCode VecGetRootType_Private(Vec vec, VecType *vtype)
120: {
121:   PetscBool iscuda, iship, iskokkos, isvcl;

123:   PetscFunctionBegin;
126:   PetscCall(PetscObjectTypeCompareAny((PetscObject)vec, &iscuda, VECCUDA, VECMPICUDA, VECSEQCUDA, ""));
127:   PetscCall(PetscObjectTypeCompareAny((PetscObject)vec, &iship, VECHIP, VECMPIHIP, VECSEQHIP, ""));
128:   PetscCall(PetscObjectTypeCompareAny((PetscObject)vec, &iskokkos, VECKOKKOS, VECMPIKOKKOS, VECSEQKOKKOS, ""));
129:   PetscCall(PetscObjectTypeCompareAny((PetscObject)vec, &isvcl, VECVIENNACL, VECMPIVIENNACL, VECSEQVIENNACL, ""));
130:   if (iscuda) {
131:     *vtype = VECCUDA;
132:   } else if (iship) {
133:     *vtype = VECHIP;
134:   } else if (iskokkos) {
135:     *vtype = VECKOKKOS;
136:   } else if (isvcl) {
137:     *vtype = VECVIENNACL;
138:   } else {
139:     *vtype = VECSTANDARD;
140:   }
141:   PetscFunctionReturn(PETSC_SUCCESS);
142: }

144: /*--------------------------------------------------------------------------------------------------------------------*/

146: /*@C
147:   VecRegister -  Adds a new vector component implementation

149:   Not Collective

151:   Input Parameters:
152: + sname        - The name of a new user-defined creation routine
153: - function - The creation routine

155:   Notes:
156:   `VecRegister()` may be called multiple times to add several user-defined vectors

158:   Sample usage:
159: .vb
160:     VecRegister("my_vec",MyVectorCreate);
161: .ve

163:   Then, your vector type can be chosen with the procedural interface via
164: .vb
165:     VecCreate(MPI_Comm, Vec *);
166:     VecSetType(Vec,"my_vector_name");
167: .ve
168:    or at runtime via the option
169: .vb
170:     -vec_type my_vector_name
171: .ve

173:   Level: advanced

175: .seealso: `VecRegisterAll()`, `VecRegisterDestroy()`
176: @*/
177: PetscErrorCode VecRegister(const char sname[], PetscErrorCode (*function)(Vec))
178: {
179:   PetscFunctionBegin;
180:   PetscCall(VecInitializePackage());
181:   PetscCall(PetscFunctionListAdd(&VecList, sname, function));
182:   PetscFunctionReturn(PETSC_SUCCESS);
183: }