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