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: }