1 2 /* 3 Mechanism for register PETSc matrix types 4 */ 5 #include <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, const 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 = PetscTypeCompare((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,const 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