xref: /petsc/src/mat/interface/matreg.c (revision b45d2f2cb7e031d9c0de5873eca80614ca7b863b)
1be1d678aSKris Buschelman 
27e14e8a7SBarry Smith /*
399cd5145SBarry Smith      Mechanism for register PETSc matrix types
47e14e8a7SBarry Smith */
5*b45d2f2cSJed Brown #include <petsc-private/matimpl.h>      /*I "petscmat.h" I*/
6c0c8ee5eSDmitry 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 
191c0c8ee5eSDmitry Karpeev /*
192c0c8ee5eSDmitry Karpeev    Contains the list of Mat-related operations.
193c0c8ee5eSDmitry Karpeev */
194c0c8ee5eSDmitry Karpeev PetscOpFList MatOpList = 0;
195c0c8ee5eSDmitry Karpeev 
196c0c8ee5eSDmitry Karpeev #undef __FUNCT__
197c0c8ee5eSDmitry Karpeev #define __FUNCT__ "MatRegisterOp"
198c0c8ee5eSDmitry Karpeev /*@C
199c0c8ee5eSDmitry Karpeev       MatRegisterOp - Registers a function via a pointer or a dynamic library url,
200c0c8ee5eSDmitry Karpeev                       that implements a polymorphic operation that is dispatched
201c0c8ee5eSDmitry Karpeev                       based on the op name and the declared arguments' type names.
202c0c8ee5eSDmitry Karpeev 
203c0c8ee5eSDmitry Karpeev   Formally collective on comm.
204c0c8ee5eSDmitry Karpeev 
205c0c8ee5eSDmitry Karpeev   Input Parameters:
206c0c8ee5eSDmitry Karpeev +  comm     - processors adding the op
207c0c8ee5eSDmitry Karpeev .  url      - routine locator  (optional, if not using dynamic libraries and a nonempty fnc)
208c0c8ee5eSDmitry Karpeev .  function - function pointer (optional, if using dynamic libraries and a nonempty url)
209c0c8ee5eSDmitry Karpeev .  op       - operation name
210c0c8ee5eSDmitry Karpeev .  numArgs  - number of op arguments
211c0c8ee5eSDmitry Karpeev -  ...      - list of argument type names (const char*)
212c0c8ee5eSDmitry Karpeev 
213c0c8ee5eSDmitry Karpeev   Level: advanced
214c0c8ee5eSDmitry Karpeev @*/
2152356f84bSDmitry Karpeev PetscErrorCode  MatRegisterOp(MPI_Comm comm, const char url[], PetscVoidFunction function, const char op[], PetscInt numArgs, ...) {
216c0c8ee5eSDmitry Karpeev   PetscErrorCode ierr;
217c0c8ee5eSDmitry Karpeev   va_list ap;
218c0c8ee5eSDmitry Karpeev   PetscInt i;
219c0c8ee5eSDmitry Karpeev   const char *argType;
220c0c8ee5eSDmitry Karpeev   char **argTypes = PETSC_NULL;
221c0c8ee5eSDmitry Karpeev   PetscFunctionBegin;
222c0c8ee5eSDmitry Karpeev   va_start(ap,numArgs);
223c0c8ee5eSDmitry Karpeev   if(numArgs) {
224c0c8ee5eSDmitry Karpeev     ierr = PetscMalloc(sizeof(char*)*numArgs, &argTypes); CHKERRQ(ierr);
225c0c8ee5eSDmitry Karpeev   }
226c0c8ee5eSDmitry Karpeev   for(i = 0; i < numArgs; ++i) {
227c0c8ee5eSDmitry Karpeev     argType = va_arg(ap,const char*);
228c0c8ee5eSDmitry Karpeev     ierr = PetscStrallocpy(argType, argTypes+i); CHKERRQ(ierr);
229c0c8ee5eSDmitry Karpeev   }
230c0c8ee5eSDmitry Karpeev   va_end(ap);
231c0c8ee5eSDmitry Karpeev   ierr = PetscOpFListAdd(comm, &MatOpList, url, function, op, numArgs, argTypes); CHKERRQ(ierr);
232c0c8ee5eSDmitry Karpeev   for(i = 0; i < numArgs; ++i) {
233c0c8ee5eSDmitry Karpeev     ierr = PetscFree(argTypes[i]); CHKERRQ(ierr);
234c0c8ee5eSDmitry Karpeev   }
235c0c8ee5eSDmitry Karpeev   ierr = PetscFree(argTypes); CHKERRQ(ierr);
236c0c8ee5eSDmitry Karpeev   PetscFunctionReturn(0);
237c0c8ee5eSDmitry Karpeev }
238c0c8ee5eSDmitry Karpeev 
239c0c8ee5eSDmitry Karpeev #undef __FUNCT__
240c0c8ee5eSDmitry Karpeev #define __FUNCT__ "MatQueryOp"
241c0c8ee5eSDmitry Karpeev /*@C
242c0c8ee5eSDmitry Karpeev       MatQueryOp - Finds the function that implements a polymorphic operation that is dispatched
243c0c8ee5eSDmitry Karpeev                    based on the op name and the declared arguments' type names.
244c0c8ee5eSDmitry Karpeev 
245c0c8ee5eSDmitry Karpeev   Formally collective on comm.
246c0c8ee5eSDmitry Karpeev 
247c0c8ee5eSDmitry Karpeev   Input Parameters:
248c0c8ee5eSDmitry Karpeev +  comm     - processors adding the op
249c0c8ee5eSDmitry Karpeev .  op       - operation name
250c0c8ee5eSDmitry Karpeev .  numArgs  - number of op arguments
251c0c8ee5eSDmitry Karpeev -  ...      - list of argument type names (const char*)
252c0c8ee5eSDmitry Karpeev 
253c0c8ee5eSDmitry Karpeev   Output Parameters:
254c0c8ee5eSDmitry Karpeev .  function -- function pointer
255c0c8ee5eSDmitry Karpeev 
256c0c8ee5eSDmitry Karpeev   Level: advanced
257c0c8ee5eSDmitry Karpeev @*/
2582356f84bSDmitry Karpeev PetscErrorCode  MatQueryOp(MPI_Comm comm, PetscVoidFunction* function, const char op[], PetscInt numArgs, ...) {
259c0c8ee5eSDmitry Karpeev   PetscErrorCode ierr;
260c0c8ee5eSDmitry Karpeev   va_list ap;
261c0c8ee5eSDmitry Karpeev   PetscInt i;
262c0c8ee5eSDmitry Karpeev   const char *argType;
263c0c8ee5eSDmitry Karpeev   char **argTypes = PETSC_NULL;
264c0c8ee5eSDmitry Karpeev   PetscFunctionBegin;
265c0c8ee5eSDmitry Karpeev   va_start(ap,numArgs);
266c0c8ee5eSDmitry Karpeev   if(numArgs) {
267c0c8ee5eSDmitry Karpeev     ierr = PetscMalloc(sizeof(char*)*numArgs, &argTypes); CHKERRQ(ierr);
268c0c8ee5eSDmitry Karpeev   }
269c0c8ee5eSDmitry Karpeev   for(i = 0; i < numArgs; ++i) {
270c0c8ee5eSDmitry Karpeev     argType = va_arg(ap,const char*);
271c0c8ee5eSDmitry Karpeev     ierr = PetscStrallocpy(argType, argTypes+i); CHKERRQ(ierr);
272c0c8ee5eSDmitry Karpeev   }
273c0c8ee5eSDmitry Karpeev   va_end(ap);
274c0c8ee5eSDmitry Karpeev   ierr = PetscOpFListFind(comm, MatOpList, function, op, numArgs, argTypes); CHKERRQ(ierr);
275c0c8ee5eSDmitry Karpeev   for(i = 0; i < numArgs; ++i) {
276c0c8ee5eSDmitry Karpeev     ierr = PetscFree(argTypes[i]); CHKERRQ(ierr);
277c0c8ee5eSDmitry Karpeev   }
278c0c8ee5eSDmitry Karpeev   ierr = PetscFree(argTypes); CHKERRQ(ierr);
279c0c8ee5eSDmitry Karpeev   PetscFunctionReturn(0);
280c0c8ee5eSDmitry Karpeev }
281c0c8ee5eSDmitry Karpeev 
28299cd5145SBarry Smith 
28399cd5145SBarry Smith 
284273d9f13SBarry Smith 
285273d9f13SBarry Smith 
286273d9f13SBarry Smith 
287273d9f13SBarry Smith 
288273d9f13SBarry Smith 
289273d9f13SBarry Smith 
290