Actual source code: amd.c
1: #define PETSCMAT_DLL
3: #include petscmat.h
4: #include ../src/mat/order/order.h
5: #define UF_long long long
6: #define UF_long_max LONG_LONG_MAX
7: #define UF_long_id "%lld"
8: #include <amd.h>
10: #if defined(PETSC_USE_64BIT_INDICES)
11: # define amd_AMD_defaults amd_l_defaults
12: # define amd_AMD_order amd_l_order
13: #else
14: # define amd_AMD_defaults amd_defaults
15: # define amd_AMD_order amd_order
16: #endif
19: /*
20: MatOrdering_AMD - Find the Approximate Minimum Degree ordering
22: This provides an interface to Tim Davis' AMD package (used by UMFPACK, CHOLMOD, Matlab, etc).
23: */
26: PetscErrorCode MatOrdering_AMD(Mat mat,const MatOrderingType type,IS *row,IS *col)
27: {
29: PetscInt nrow,*ia,*ja,*perm;
30: int status;
31: PetscReal val;
32: double Control[AMD_CONTROL],Info[AMD_INFO];
33: PetscTruth tval,done;
36: /*
37: AMD does not require that the matrix be symmetric (it does so internally,
38: at least in so far as computing orderings for A+A^T.
39: */
40: MatGetRowIJ(mat,0,PETSC_FALSE,PETSC_TRUE,&nrow,&ia,&ja,&done);
41: if (!done) SETERRQ1(PETSC_ERR_SUP,"Cannot get rows for matrix type %s",((PetscObject)mat)->type_name);
43: amd_AMD_defaults(Control);
44: PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"AMD Options","Mat");
45: /*
46: We have to use temporary values here because AMD always uses double, even though PetscReal may be single
47: */
48: val = (PetscReal)Control[AMD_DENSE];
49: PetscOptionsReal("-mat_ordering_amd_dense","threshold for \"dense\" rows/columns","None",val,&val,PETSC_NULL);
50: Control[AMD_DENSE] = (double)val;
52: tval = (PetscTruth)Control[AMD_AGGRESSIVE];
53: PetscOptionsTruth("-mat_ordering_amd_aggressive","use aggressive absorption","None",tval,&tval,PETSC_NULL);
54: Control[AMD_AGGRESSIVE] = (double)tval;
55: PetscOptionsEnd();
57: PetscMalloc(nrow*sizeof(PetscInt),&perm);
58: status = amd_AMD_order(nrow,ia,ja,perm,Control,Info);
59: switch (status) {
60: case AMD_OK: break;
61: case AMD_OK_BUT_JUMBLED:
62: /* The result is fine, but PETSc matrices are supposed to satisfy stricter preconditions, so PETSc considers a
63: * matrix that triggers this error condition to be invalid.
64: */
65: SETERRQ(PETSC_ERR_PLIB,"According to AMD, the matrix has unsorted and/or duplicate row indices");
66: case AMD_INVALID:
67: amd_info(Info);
68: SETERRQ(PETSC_ERR_PLIB,"According to AMD, the matrix is invalid");
69: case AMD_OUT_OF_MEMORY:
70: SETERRQ(PETSC_ERR_MEM,"AMD could not compute ordering");
71: default:
72: SETERRQ(PETSC_ERR_LIB,"Unexpected return value");
73: }
74: MatRestoreRowIJ(mat,0,PETSC_FALSE,PETSC_TRUE,&nrow,&ia,&ja,&done);
76: ISCreateGeneral(PETSC_COMM_SELF,nrow,perm,row);
77: ISCreateGeneral(PETSC_COMM_SELF,nrow,perm,col);
78: PetscFree(perm);
79: return(0);
80: }