xref: /petsc/src/mat/interface/matreg.c (revision c0c8ee5e0ae1bee780a6017f61276792be745fee)
1be1d678aSKris Buschelman 
27e14e8a7SBarry Smith /*
399cd5145SBarry Smith      Mechanism for register PETSc matrix types
47e14e8a7SBarry Smith */
5c6db04a5SJed Brown #include <private/matimpl.h>      /*I "petscmat.h" I*/
6*c0c8ee5eSDmitry Karpeev #include <stdarg.h> /* Variable-length arg lists. */
77e14e8a7SBarry Smith 
8ace3abfcSBarry Smith PetscBool  MatRegisterAllCalled = PETSC_FALSE;
97e14e8a7SBarry Smith 
107e14e8a7SBarry Smith /*
1199cd5145SBarry Smith    Contains the list of registered Mat routines
127e14e8a7SBarry Smith */
13b0a32e0cSBarry Smith PetscFList MatList = 0;
147e14e8a7SBarry Smith 
154a2ae208SSatish Balay #undef __FUNCT__
164a2ae208SSatish Balay #define __FUNCT__ "MatSetType"
177e14e8a7SBarry Smith /*@C
1899cd5145SBarry Smith    MatSetType - Builds matrix object for a particular matrix type
197e14e8a7SBarry Smith 
2099cd5145SBarry Smith    Collective on Mat
217e14e8a7SBarry Smith 
227e14e8a7SBarry Smith    Input Parameters:
2399cd5145SBarry Smith +  mat      - the matrix object
2499cd5145SBarry Smith -  matype   - matrix type
257e14e8a7SBarry Smith 
267e14e8a7SBarry Smith    Options Database Key:
2799cd5145SBarry Smith .  -mat_type  <method> - Sets the type; use -help for a list
2899cd5145SBarry Smith     of available methods (for instance, seqaij)
297e14e8a7SBarry Smith 
307e14e8a7SBarry Smith    Notes:
3199cd5145SBarry Smith    See "${PETSC_DIR}/include/petscmat.h" for available methods
327e14e8a7SBarry Smith 
337e14e8a7SBarry Smith   Level: intermediate
347e14e8a7SBarry Smith 
35c2bf8781Svictorle .keywords: Mat, MatType, set, method
367e14e8a7SBarry Smith 
376e0d5acbSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
387e14e8a7SBarry Smith @*/
397087cfbeSBarry Smith PetscErrorCode  MatSetType(Mat mat, const MatType matype)
407e14e8a7SBarry Smith {
41dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(Mat);
4201bebe75SBarry Smith   PetscBool      sametype,found;
4301bebe75SBarry Smith   MatBaseName    names = MatBaseNameList;
447e14e8a7SBarry Smith 
457e14e8a7SBarry Smith   PetscFunctionBegin;
460700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
47117016b1SBarry Smith 
4801bebe75SBarry Smith   while (names) {
4901bebe75SBarry Smith     ierr = PetscStrcmp(matype,names->bname,&found);CHKERRQ(ierr);
5001bebe75SBarry Smith     if (found) {
5101bebe75SBarry Smith       PetscMPIInt size;
5201bebe75SBarry Smith       ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5301bebe75SBarry Smith       if (size == 1) matype = names->sname;
5401bebe75SBarry Smith       else matype = names->mname;
5501bebe75SBarry Smith       break;
5601bebe75SBarry Smith     }
5701bebe75SBarry Smith     names = names->next;
5801bebe75SBarry Smith   }
5901bebe75SBarry Smith 
6099cd5145SBarry Smith   ierr = PetscTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr);
6192ff6ae8SBarry Smith   if (sametype) PetscFunctionReturn(0);
6292ff6ae8SBarry Smith 
634b91b6eaSBarry Smith   ierr =  PetscFListFind(MatList,((PetscObject)mat)->comm,matype,PETSC_TRUE,(void(**)(void))&r);CHKERRQ(ierr);
64e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);
657e14e8a7SBarry Smith 
6635d8aa7fSBarry Smith   /* free the old data structure if it existed */
6735d8aa7fSBarry Smith   if (mat->ops->destroy) {
6835d8aa7fSBarry Smith     ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr);
690dd8e64fSKris Buschelman     mat->ops->destroy = PETSC_NULL;
7035d8aa7fSBarry Smith   }
7167d6de01SJed Brown   mat->preallocated = PETSC_FALSE;
72a2ec6df8SKris Buschelman 
7335d8aa7fSBarry Smith   /* create the new data structure */
7499cd5145SBarry Smith   ierr = (*r)(mat);CHKERRQ(ierr);
759fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
769fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
7742eaa7f3SBarry Smith     /*    ierr = PetscObjectAMSPublish((PetscObject)mat);CHKERRQ(ierr); */
789fb22e1aSBarry Smith   }
799fb22e1aSBarry Smith #endif
807e14e8a7SBarry Smith   PetscFunctionReturn(0);
817e14e8a7SBarry Smith }
827e14e8a7SBarry Smith 
8335d8aa7fSBarry Smith 
844a2ae208SSatish Balay #undef __FUNCT__
854a2ae208SSatish Balay #define __FUNCT__ "MatRegisterDestroy"
867e14e8a7SBarry Smith /*@C
8799cd5145SBarry Smith    MatRegisterDestroy - Frees the list of matrix types that were
883cea93caSBarry Smith    registered by MatRegister()/MatRegisterDynamic().
897e14e8a7SBarry Smith 
907e14e8a7SBarry Smith    Not Collective
917e14e8a7SBarry Smith 
927e14e8a7SBarry Smith    Level: advanced
937e14e8a7SBarry Smith 
9499cd5145SBarry Smith .keywords: Mat, register, destroy
957e14e8a7SBarry Smith 
963cea93caSBarry Smith .seealso: MatRegister(), MatRegisterAll(), MatRegisterDynamic()
977e14e8a7SBarry Smith @*/
987087cfbeSBarry Smith PetscErrorCode  MatRegisterDestroy(void)
997e14e8a7SBarry Smith {
100dfbe8321SBarry Smith   PetscErrorCode ierr;
1017e14e8a7SBarry Smith 
1027e14e8a7SBarry Smith   PetscFunctionBegin;
1031441b1d3SBarry Smith   ierr = PetscFListDestroy(&MatList);CHKERRQ(ierr);
1040e9836bfSBarry Smith   MatRegisterAllCalled = PETSC_FALSE;
1057e14e8a7SBarry Smith   PetscFunctionReturn(0);
1067e14e8a7SBarry Smith }
1077e14e8a7SBarry Smith 
1084a2ae208SSatish Balay #undef __FUNCT__
1094a2ae208SSatish Balay #define __FUNCT__ "MatGetType"
1107e14e8a7SBarry Smith /*@C
111f87b78b8SBarry Smith    MatGetType - Gets the matrix type as a string from the matrix object.
1127e14e8a7SBarry Smith 
1137e14e8a7SBarry Smith    Not Collective
1147e14e8a7SBarry Smith 
1157e14e8a7SBarry Smith    Input Parameter:
11699cd5145SBarry Smith .  mat - the matrix
1177e14e8a7SBarry Smith 
1187e14e8a7SBarry Smith    Output Parameter:
11999cd5145SBarry Smith .  name - name of matrix type
1207e14e8a7SBarry Smith 
1217e14e8a7SBarry Smith    Level: intermediate
1227e14e8a7SBarry Smith 
123c2bf8781Svictorle .keywords: Mat, MatType, get, method, name
1247e14e8a7SBarry Smith 
12599cd5145SBarry Smith .seealso: MatSetType()
1267e14e8a7SBarry Smith @*/
1277087cfbeSBarry Smith PetscErrorCode  MatGetType(Mat mat,const MatType *type)
1287e14e8a7SBarry Smith {
1297e14e8a7SBarry Smith   PetscFunctionBegin;
1300700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
131c4e43342SLisandro Dalcin   PetscValidPointer(type,2);
1327adad957SLisandro Dalcin   *type = ((PetscObject)mat)->type_name;
1337e14e8a7SBarry Smith   PetscFunctionReturn(0);
1347e14e8a7SBarry Smith }
1357e14e8a7SBarry Smith 
1367e14e8a7SBarry Smith 
1374a2ae208SSatish Balay #undef __FUNCT__
1384a2ae208SSatish Balay #define __FUNCT__ "MatRegister"
1393cea93caSBarry Smith /*@C
1403cea93caSBarry Smith   MatRegister - See MatRegisterDynamic()
1413cea93caSBarry Smith 
1427f6c08e0SMatthew Knepley   Level: advanced
1433cea93caSBarry Smith @*/
1447087cfbeSBarry Smith PetscErrorCode  MatRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mat))
1457e14e8a7SBarry Smith {
146dfbe8321SBarry Smith   PetscErrorCode ierr;
147e10c49a3SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
1487e14e8a7SBarry Smith 
1497e14e8a7SBarry Smith   PetscFunctionBegin;
150b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
151c134de8dSSatish Balay   ierr = PetscFListAdd(&MatList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
15299cd5145SBarry Smith   PetscFunctionReturn(0);
15399cd5145SBarry Smith }
15499cd5145SBarry Smith 
15501bebe75SBarry Smith MatBaseName MatBaseNameList = 0;
15601bebe75SBarry Smith 
15701bebe75SBarry Smith #undef __FUNCT__
15801bebe75SBarry Smith #define __FUNCT__ "MatRegisterBaseName"
15901bebe75SBarry Smith /*@C
16001bebe75SBarry Smith       MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type.
16101bebe75SBarry Smith 
16201bebe75SBarry Smith   Input Parameters:
16301bebe75SBarry Smith +     bname - the basename, for example, MATAIJ
16401bebe75SBarry Smith .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
16501bebe75SBarry Smith -     mname - the name of the parallel matrix type, for example, MATMPIAIJ
16601bebe75SBarry Smith 
16701bebe75SBarry Smith 
16801bebe75SBarry Smith   Level: advanced
16901bebe75SBarry Smith @*/
17001bebe75SBarry Smith PetscErrorCode  MatRegisterBaseName(const char bname[],const char sname[],const char mname[])
17101bebe75SBarry Smith {
17201bebe75SBarry Smith   PetscErrorCode ierr;
17301bebe75SBarry Smith   MatBaseName    names;
17401bebe75SBarry Smith 
17501bebe75SBarry Smith   PetscFunctionBegin;
17601bebe75SBarry Smith   ierr = PetscNew(struct _p_MatBaseName,&names);CHKERRQ(ierr);
17701bebe75SBarry Smith   ierr = PetscStrallocpy(bname,&names->bname);CHKERRQ(ierr);
17801bebe75SBarry Smith   ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr);
17901bebe75SBarry Smith   ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr);
18001bebe75SBarry Smith   if (!MatBaseNameList) {
18101bebe75SBarry Smith     MatBaseNameList = names;
18201bebe75SBarry Smith   } else {
18301bebe75SBarry Smith     MatBaseName next = MatBaseNameList;
18401bebe75SBarry Smith     while (next->next) next = next->next;
18501bebe75SBarry Smith     next->next = names;
18601bebe75SBarry Smith   }
18701bebe75SBarry Smith   PetscFunctionReturn(0);
18801bebe75SBarry Smith }
18901bebe75SBarry Smith 
19099cd5145SBarry Smith 
191*c0c8ee5eSDmitry Karpeev /*
192*c0c8ee5eSDmitry Karpeev    Contains the list of Mat-related operations.
193*c0c8ee5eSDmitry Karpeev */
194*c0c8ee5eSDmitry Karpeev PetscOpFList MatOpList = 0;
195*c0c8ee5eSDmitry Karpeev 
196*c0c8ee5eSDmitry Karpeev #undef __FUNCT__
197*c0c8ee5eSDmitry Karpeev #define __FUNCT__ "MatRegisterOp"
198*c0c8ee5eSDmitry Karpeev /*@C
199*c0c8ee5eSDmitry Karpeev       MatRegisterOp - Registers a function via a pointer or a dynamic library url,
200*c0c8ee5eSDmitry Karpeev                       that implements a polymorphic operation that is dispatched
201*c0c8ee5eSDmitry Karpeev                       based on the op name and the declared arguments' type names.
202*c0c8ee5eSDmitry Karpeev 
203*c0c8ee5eSDmitry Karpeev   Formally collective on comm.
204*c0c8ee5eSDmitry Karpeev 
205*c0c8ee5eSDmitry Karpeev   Input Parameters:
206*c0c8ee5eSDmitry Karpeev +  comm     - processors adding the op
207*c0c8ee5eSDmitry Karpeev .  url      - routine locator  (optional, if not using dynamic libraries and a nonempty fnc)
208*c0c8ee5eSDmitry Karpeev .  function - function pointer (optional, if using dynamic libraries and a nonempty url)
209*c0c8ee5eSDmitry Karpeev .  op       - operation name
210*c0c8ee5eSDmitry Karpeev .  numArgs  - number of op arguments
211*c0c8ee5eSDmitry Karpeev -  ...      - list of argument type names (const char*)
212*c0c8ee5eSDmitry Karpeev 
213*c0c8ee5eSDmitry Karpeev   Level: advanced
214*c0c8ee5eSDmitry Karpeev @*/
215*c0c8ee5eSDmitry Karpeev PetscErrorCode  MatRegisterOp(MPI_Comm comm, const char url[], PetscOpF function, const char op[], PetscInt numArgs, ...) {
216*c0c8ee5eSDmitry Karpeev   PetscErrorCode ierr;
217*c0c8ee5eSDmitry Karpeev   va_list ap;
218*c0c8ee5eSDmitry Karpeev   PetscInt i;
219*c0c8ee5eSDmitry Karpeev   const char *argType;
220*c0c8ee5eSDmitry Karpeev   char **argTypes = PETSC_NULL;
221*c0c8ee5eSDmitry Karpeev   PetscFunctionBegin;
222*c0c8ee5eSDmitry Karpeev   va_start(ap,numArgs);
223*c0c8ee5eSDmitry Karpeev   if(numArgs) {
224*c0c8ee5eSDmitry Karpeev     ierr = PetscMalloc(sizeof(char*)*numArgs, &argTypes); CHKERRQ(ierr);
225*c0c8ee5eSDmitry Karpeev   }
226*c0c8ee5eSDmitry Karpeev   for(i = 0; i < numArgs; ++i) {
227*c0c8ee5eSDmitry Karpeev     argType = va_arg(ap,const char*);
228*c0c8ee5eSDmitry Karpeev     ierr = PetscStrallocpy(argType, argTypes+i); CHKERRQ(ierr);
229*c0c8ee5eSDmitry Karpeev   }
230*c0c8ee5eSDmitry Karpeev   va_end(ap);
231*c0c8ee5eSDmitry Karpeev   ierr = PetscOpFListAdd(comm, &MatOpList, url, function, op, numArgs, argTypes); CHKERRQ(ierr);
232*c0c8ee5eSDmitry Karpeev   for(i = 0; i < numArgs; ++i) {
233*c0c8ee5eSDmitry Karpeev     ierr = PetscFree(argTypes[i]); CHKERRQ(ierr);
234*c0c8ee5eSDmitry Karpeev   }
235*c0c8ee5eSDmitry Karpeev   ierr = PetscFree(argTypes); CHKERRQ(ierr);
236*c0c8ee5eSDmitry Karpeev   PetscFunctionReturn(0);
237*c0c8ee5eSDmitry Karpeev }
238*c0c8ee5eSDmitry Karpeev 
239*c0c8ee5eSDmitry Karpeev #undef __FUNCT__
240*c0c8ee5eSDmitry Karpeev #define __FUNCT__ "MatQueryOp"
241*c0c8ee5eSDmitry Karpeev /*@C
242*c0c8ee5eSDmitry Karpeev       MatQueryOp - Finds the function that implements a polymorphic operation that is dispatched
243*c0c8ee5eSDmitry Karpeev                    based on the op name and the declared arguments' type names.
244*c0c8ee5eSDmitry Karpeev 
245*c0c8ee5eSDmitry Karpeev   Formally collective on comm.
246*c0c8ee5eSDmitry Karpeev 
247*c0c8ee5eSDmitry Karpeev   Input Parameters:
248*c0c8ee5eSDmitry Karpeev +  comm     - processors adding the op
249*c0c8ee5eSDmitry Karpeev .  op       - operation name
250*c0c8ee5eSDmitry Karpeev .  numArgs  - number of op arguments
251*c0c8ee5eSDmitry Karpeev -  ...      - list of argument type names (const char*)
252*c0c8ee5eSDmitry Karpeev 
253*c0c8ee5eSDmitry Karpeev   Output Parameters:
254*c0c8ee5eSDmitry Karpeev .  function -- function pointer
255*c0c8ee5eSDmitry Karpeev 
256*c0c8ee5eSDmitry Karpeev   Level: advanced
257*c0c8ee5eSDmitry Karpeev @*/
258*c0c8ee5eSDmitry Karpeev PetscErrorCode  MatQueryOp(MPI_Comm comm, PetscOpF* function, const char op[], PetscInt numArgs, ...) {
259*c0c8ee5eSDmitry Karpeev   PetscErrorCode ierr;
260*c0c8ee5eSDmitry Karpeev   va_list ap;
261*c0c8ee5eSDmitry Karpeev   PetscInt i;
262*c0c8ee5eSDmitry Karpeev   const char *argType;
263*c0c8ee5eSDmitry Karpeev   char **argTypes = PETSC_NULL;
264*c0c8ee5eSDmitry Karpeev   PetscFunctionBegin;
265*c0c8ee5eSDmitry Karpeev   va_start(ap,numArgs);
266*c0c8ee5eSDmitry Karpeev   if(numArgs) {
267*c0c8ee5eSDmitry Karpeev     ierr = PetscMalloc(sizeof(char*)*numArgs, &argTypes); CHKERRQ(ierr);
268*c0c8ee5eSDmitry Karpeev   }
269*c0c8ee5eSDmitry Karpeev   for(i = 0; i < numArgs; ++i) {
270*c0c8ee5eSDmitry Karpeev     argType = va_arg(ap,const char*);
271*c0c8ee5eSDmitry Karpeev     ierr = PetscStrallocpy(argType, argTypes+i); CHKERRQ(ierr);
272*c0c8ee5eSDmitry Karpeev   }
273*c0c8ee5eSDmitry Karpeev   va_end(ap);
274*c0c8ee5eSDmitry Karpeev   ierr = PetscOpFListFind(comm, MatOpList, function, op, numArgs, argTypes); CHKERRQ(ierr);
275*c0c8ee5eSDmitry Karpeev   for(i = 0; i < numArgs; ++i) {
276*c0c8ee5eSDmitry Karpeev     ierr = PetscFree(argTypes[i]); CHKERRQ(ierr);
277*c0c8ee5eSDmitry Karpeev   }
278*c0c8ee5eSDmitry Karpeev   ierr = PetscFree(argTypes); CHKERRQ(ierr);
279*c0c8ee5eSDmitry Karpeev   PetscFunctionReturn(0);
280*c0c8ee5eSDmitry Karpeev }
281*c0c8ee5eSDmitry Karpeev 
28299cd5145SBarry Smith 
28399cd5145SBarry Smith 
284273d9f13SBarry Smith 
285273d9f13SBarry Smith 
286273d9f13SBarry Smith 
287273d9f13SBarry Smith 
288273d9f13SBarry Smith 
289273d9f13SBarry Smith 
290