xref: /petsc/src/mat/interface/matreg.c (revision 1a83f524638a4da8317a6bd80eb6d9a2936d8384)
1 
2 /*
3      Mechanism for register PETSc matrix types
4 */
5 #include <petsc-private/matimpl.h>      /*I "petscmat.h" I*/
6 #include <stdarg.h> /* Variable-length arg lists. */
7 
8 PetscBool  MatRegisterAllCalled = PETSC_FALSE;
9 
10 /*
11    Contains the list of registered Mat routines
12 */
13 PetscFList MatList = 0;
14 
15 #undef __FUNCT__
16 #define __FUNCT__ "MatSetType"
17 /*@C
18    MatSetType - Builds matrix object for a particular matrix type
19 
20    Collective on Mat
21 
22    Input Parameters:
23 +  mat      - the matrix object
24 -  matype   - matrix type
25 
26    Options Database Key:
27 .  -mat_type  <method> - Sets the type; use -help for a list
28     of available methods (for instance, seqaij)
29 
30    Notes:
31    See "${PETSC_DIR}/include/petscmat.h" for available methods
32 
33   Level: intermediate
34 
35 .keywords: Mat, MatType, set, method
36 
37 .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
38 @*/
39 PetscErrorCode  MatSetType(Mat mat, MatType matype)
40 {
41   PetscErrorCode ierr,(*r)(Mat);
42   PetscBool      sametype,found;
43   MatBaseName    names = MatBaseNameList;
44 
45   PetscFunctionBegin;
46   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
47 
48   while (names) {
49     ierr = PetscStrcmp(matype,names->bname,&found);CHKERRQ(ierr);
50     if (found) {
51       PetscMPIInt size;
52       ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
53       if (size == 1) matype = names->sname;
54       else matype = names->mname;
55       break;
56     }
57     names = names->next;
58   }
59 
60   ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr);
61   if (sametype) PetscFunctionReturn(0);
62 
63   ierr =  PetscFListFind(MatList,((PetscObject)mat)->comm,matype,PETSC_TRUE,(void(**)(void))&r);CHKERRQ(ierr);
64   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);
65 
66   /* free the old data structure if it existed */
67   if (mat->ops->destroy) {
68     ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr);
69     mat->ops->destroy = PETSC_NULL;
70   }
71   mat->preallocated = PETSC_FALSE;
72 
73   /* create the new data structure */
74   ierr = (*r)(mat);CHKERRQ(ierr);
75 #if defined(PETSC_HAVE_AMS)
76   if (PetscAMSPublishAll) {
77     /*    ierr = PetscObjectAMSPublish((PetscObject)mat);CHKERRQ(ierr); */
78   }
79 #endif
80   PetscFunctionReturn(0);
81 }
82 
83 
84 #undef __FUNCT__
85 #define __FUNCT__ "MatRegisterDestroy"
86 /*@C
87    MatRegisterDestroy - Frees the list of matrix types that were
88    registered by MatRegister()/MatRegisterDynamic().
89 
90    Not Collective
91 
92    Level: advanced
93 
94 .keywords: Mat, register, destroy
95 
96 .seealso: MatRegister(), MatRegisterAll(), MatRegisterDynamic()
97 @*/
98 PetscErrorCode  MatRegisterDestroy(void)
99 {
100   PetscErrorCode ierr;
101 
102   PetscFunctionBegin;
103   ierr = PetscFListDestroy(&MatList);CHKERRQ(ierr);
104   MatRegisterAllCalled = PETSC_FALSE;
105   PetscFunctionReturn(0);
106 }
107 
108 #undef __FUNCT__
109 #define __FUNCT__ "MatGetType"
110 /*@C
111    MatGetType - Gets the matrix type as a string from the matrix object.
112 
113    Not Collective
114 
115    Input Parameter:
116 .  mat - the matrix
117 
118    Output Parameter:
119 .  name - name of matrix type
120 
121    Level: intermediate
122 
123 .keywords: Mat, MatType, get, method, name
124 
125 .seealso: MatSetType()
126 @*/
127 PetscErrorCode  MatGetType(Mat mat,MatType *type)
128 {
129   PetscFunctionBegin;
130   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
131   PetscValidPointer(type,2);
132   *type = ((PetscObject)mat)->type_name;
133   PetscFunctionReturn(0);
134 }
135 
136 
137 #undef __FUNCT__
138 #define __FUNCT__ "MatRegister"
139 /*@C
140   MatRegister - See MatRegisterDynamic()
141 
142   Level: advanced
143 @*/
144 PetscErrorCode  MatRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mat))
145 {
146   PetscErrorCode ierr;
147   char           fullname[PETSC_MAX_PATH_LEN];
148 
149   PetscFunctionBegin;
150   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
151   ierr = PetscFListAdd(&MatList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
152   PetscFunctionReturn(0);
153 }
154 
155 MatBaseName MatBaseNameList = 0;
156 
157 #undef __FUNCT__
158 #define __FUNCT__ "MatRegisterBaseName"
159 /*@C
160       MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type.
161 
162   Input Parameters:
163 +     bname - the basename, for example, MATAIJ
164 .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
165 -     mname - the name of the parallel matrix type, for example, MATMPIAIJ
166 
167 
168   Level: advanced
169 @*/
170 PetscErrorCode  MatRegisterBaseName(const char bname[],const char sname[],const char mname[])
171 {
172   PetscErrorCode ierr;
173   MatBaseName    names;
174 
175   PetscFunctionBegin;
176   ierr = PetscNew(struct _p_MatBaseName,&names);CHKERRQ(ierr);
177   ierr = PetscStrallocpy(bname,&names->bname);CHKERRQ(ierr);
178   ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr);
179   ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr);
180   if (!MatBaseNameList) {
181     MatBaseNameList = names;
182   } else {
183     MatBaseName next = MatBaseNameList;
184     while (next->next) next = next->next;
185     next->next = names;
186   }
187   PetscFunctionReturn(0);
188 }
189 
190 
191 /*
192    Contains the list of Mat-related operations.
193 */
194 PetscOpFList MatOpList = 0;
195 
196 #undef __FUNCT__
197 #define __FUNCT__ "MatRegisterOp"
198 /*@C
199       MatRegisterOp - Registers a function via a pointer or a dynamic library url,
200                       that implements a polymorphic operation that is dispatched
201                       based on the op name and the declared arguments' type names.
202 
203   Formally collective on comm.
204 
205   Input Parameters:
206 +  comm     - processors adding the op
207 .  url      - routine locator  (optional, if not using dynamic libraries and a nonempty fnc)
208 .  function - function pointer (optional, if using dynamic libraries and a nonempty url)
209 .  op       - operation name
210 .  numArgs  - number of op arguments
211 -  ...      - list of argument type names (const char*)
212 
213   Level: advanced
214 @*/
215 PetscErrorCode  MatRegisterOp(MPI_Comm comm, const char url[], PetscVoidFunction function, const char op[], PetscInt numArgs, ...) {
216   PetscErrorCode ierr;
217   va_list ap;
218   PetscInt i;
219   const char *argType;
220   char **argTypes = PETSC_NULL;
221   PetscFunctionBegin;
222   va_start(ap,numArgs);
223   if (numArgs) {
224     ierr = PetscMalloc(sizeof(char*)*numArgs, &argTypes); CHKERRQ(ierr);
225   }
226   for (i = 0; i < numArgs; ++i) {
227     argType = va_arg(ap,const char*);
228     ierr = PetscStrallocpy(argType, argTypes+i); CHKERRQ(ierr);
229   }
230   va_end(ap);
231   ierr = PetscOpFListAdd(comm, &MatOpList, url, function, op, numArgs, argTypes); CHKERRQ(ierr);
232   for (i = 0; i < numArgs; ++i) {
233     ierr = PetscFree(argTypes[i]); CHKERRQ(ierr);
234   }
235   ierr = PetscFree(argTypes); CHKERRQ(ierr);
236   PetscFunctionReturn(0);
237 }
238 
239 #undef __FUNCT__
240 #define __FUNCT__ "MatQueryOp"
241 /*@C
242       MatQueryOp - Finds the function that implements a polymorphic operation that is dispatched
243                    based on the op name and the declared arguments' type names.
244 
245   Formally collective on comm.
246 
247   Input Parameters:
248 +  comm     - processors adding the op
249 .  op       - operation name
250 .  numArgs  - number of op arguments
251 -  ...      - list of argument type names (const char*)
252 
253   Output Parameters:
254 .  function -- function pointer
255 
256   Level: advanced
257 @*/
258 PetscErrorCode  MatQueryOp(MPI_Comm comm, PetscVoidFunction* function, const char op[], PetscInt numArgs, ...) {
259   PetscErrorCode ierr;
260   va_list ap;
261   PetscInt i;
262   const char *argType;
263   char **argTypes = PETSC_NULL;
264   PetscFunctionBegin;
265   va_start(ap,numArgs);
266   if (numArgs) {
267     ierr = PetscMalloc(sizeof(char*)*numArgs, &argTypes); CHKERRQ(ierr);
268   }
269   for (i = 0; i < numArgs; ++i) {
270     argType = va_arg(ap,const char*);
271     ierr = PetscStrallocpy(argType, argTypes+i); CHKERRQ(ierr);
272   }
273   va_end(ap);
274   ierr = PetscOpFListFind(comm, MatOpList, function, op, numArgs, argTypes); CHKERRQ(ierr);
275   for (i = 0; i < numArgs; ++i) {
276     ierr = PetscFree(argTypes[i]); CHKERRQ(ierr);
277   }
278   ierr = PetscFree(argTypes); CHKERRQ(ierr);
279   PetscFunctionReturn(0);
280 }
281 
282 
283 
284 
285 
286 
287 
288 
289 
290