Commit 09697f6f authored by Daniel Brown's avatar Daniel Brown
Browse files

Merge branch 'develop' of git.ligo.org:finesse/finesse into develop

parents 86c0c3c4 4c9bce39
......@@ -69,19 +69,14 @@ failure()
echo "------------------------------------"
#tail -n 14 $LOGFILE | head -n 20
fi
echo "************************************"
exit 1
}
clean()
{
cd $ROOT || failure
echo "Cleaning Finesse files..." | tee -a $LOGFILE
make realclean
rm kat || failure
}
......@@ -95,17 +90,13 @@ check_GSL_architecture()
lib4=$gsl_libpath/libgslcblas.a
lib3=$gsl_libpath/libgslcblas.dylib
if [ -f $lib2 ]
then
if [ -f $lib2 ]; then
echo "Found libgsl.a, use static linking"
export GSL_LIBS="$lib2 $lib4"
echo $CPUARCH
if [[ $platform == "mac" && -z $CPUARCH ]]
then
#echo $CPUARCH
if [[ $platform == "mac" && -z $CPUARCH ]]; then
libinfo=`file $lib2`
if [[ "$libinfo" != *i386* && "$libinfo" != *i686* ]]
then
if [[ "$libinfo" != *i386* && "$libinfo" != *i686* ]]; then
echo "Trying ar -x ..."
testfile=version.o
ar -x $lib2 $testfile
......@@ -113,45 +104,37 @@ check_GSL_architecture()
echo $libinfo
rm $testfile
fi
if [[ "$libinfo" == *x86_64* ]]
then
if [[ "$libinfo" == *x86_64* ]]; then
CPUARCH="x86_64"
elif [[ "$libinfo" == *i386* || "$libinfo" == *i686* ]]
then
elif [[ "$libinfo" == *i386* || "$libinfo" == *i686* ]]; then
CPUARCH="i686"
else
echo " ** Could not determne architecture from GSL libraries"
exit 1
fi
echo " - setting architecture based on GSL to $CPUARCH " | tee -a $LOGFILE
fi
elif [ -f $lib1 ]
then
elif [ -f $lib1 ]; then
echo "Found libgsl.dylib, use dynamic linking"
export GSL_LIBS="$lib1 $lib3"
if [[ $platform == "mac" && -z $CPUARCH ]]
then
if [[ $platform == "mac" && -z $CPUARCH ]]; then
libinfo=`file -L $lib1`
if [[ "$libinfo" == *x86_64* ]]
then
if [[ "$libinfo" == *x86_64* ]]; then
CPUARCH="x86_64"
elif [[ "$libinfo" == *i386* || "$libinfo" == *i686* ]]
then
elif [[ "$libinfo" == *i386* || "$libinfo" == *i686* ]]; then
CPUARCH="i686"
fi
echo " - setting architecture based on GSL to $CPUARCH " | tee -a $LOGFILE
fi
else
echo" - Could not determine architecture (x86_64 or i686) of GSL library" | tee -a $LOGFILE
echo " - Could not determine architecture (x86_64 or i686) of GSL library" | tee -a $LOGFILE
return 1
fi
}
check_prerequisites()
{
# setting default compiler
export CC
# check if the src and lib directories are here
......@@ -201,8 +184,7 @@ check_prerequisites()
echo " - Missing GSL which is a required library" | tee -a $LOGFILE
return 1
else
if [[ "$platform" == 'win' ]];
then
if [[ "$platform" == 'win' ]]; then
echo " - GSL found!" | tee -a $LOGFILE
else
gsl_libpath=`gsl-config --libs | cut -d " " -f1`
......@@ -212,26 +194,20 @@ check_prerequisites()
check_GSL_architecture
fi
fi
echo " - Required toolchain found!" | tee -a $LOGFILE
return 0
}
build()
{
pwdbefore=`pwd`
if [[ $platform != "win32" && $platform != "win64" ]] ; then
if [[ $platform != "win32" && $platform != "win64" ]]; then
echo "Configuring CUBA" | tee -a $LOGFILE
# configure cuba if needed
if [ ! -f "./lib/Cuba-3.2/config.h" ] && [ ! -f "./lib/Cuba-3.2/makefile" ] ; then
if [ ! -f "./lib/Cuba-3.2/config.h" ] && [ ! -f "./lib/Cuba-3.2/makefile" ]; then
cd ./lib/Cuba-3.2
chmod 700 ./configure
if [[ $platform == "mac" ]]
then
if [[ $platform == "mac" ]]; then
echo "Configuring Cuba with extra flags (CPUARCH=$CPUARCH)"
./configure -q CFLAGS="-O3 -fomit-frame-pointer -ffast-math -Wall -Wextra -arch $CPUARCH"
else
......@@ -242,25 +218,16 @@ build()
# We set them here explicitly in order to overwrite the previously exported
# CFLAGS for the rest of the build (because they cause Cuba to crash with a
# segmentation fault).
cd $pwdbefore
else
echo " - Cuba is already configured"
fi
fi
#------------ don't know why this is here ---------------------
#gsl_libpath=`gsl-config --libs | cut -d " " -f1`
#gsl_libpath=${gsl_libpath#-L}
#gsl_libpath=${gsl_libpath#-l}
# Setting GSL_LIBS flags to allow static linking
#export GSL_LIBS="$gsl_libpath/libgslcblas.a $gsl_libpath/libgsl.a"
echo "Calling make file, see make.log for more details..."
echo ""
if [ $verbose == 1 ]
then
if [ $verbose == 1 ]; then
make ARCH=$target_arch BUILD=$platform config 2>&1 | tee make.log || failure
make ARCH=$target_arch BUILD=$platform kat 2>&1 | tee make.log || failure
else
......@@ -268,8 +235,7 @@ build()
make ARCH=$target_arch BUILD=$platform kat 2>&1 1>make.log || failure
fi
if grep " Error " make.log 1>/dev/null 2>&1
then
if grep " Error " make.log 1>/dev/null 2>&1; then
#cat make.err > $LOGFILE
failure
else
......@@ -280,13 +246,11 @@ build()
make-win-package()
{
python getWinDLLs.py
sys=`eval uname --machine`
ver=`eval git describe --abbrev=0`
echo "Making Windows $sys package..." | tee -a $LOGFILE
rm -rf .windlls
python getWinDLLs.py
dir=FINESSE_"$ver"_WIN_"$sys"
rm -rf $dir
......@@ -309,7 +273,6 @@ make-win-package()
cp $a .
echo "Created Windows distribution $dir" | tee -a $LOGFILE
cd ..
}
......@@ -430,7 +393,7 @@ case "$1" in
"--build-linux")
NATIVE=""
TARGET=$TARGET_LINUX
="-m64"
CPUARCH="-m64"
target_arch="linux"
echo "Building Linux version :" | tee -a $LOGFILE
;;
......@@ -492,8 +455,6 @@ esac
# here we go...
#export OPTIM_CFLAGS="-mfpmath=sse -O3 -ffast-math -Wall -fexpensive-optimizations -fomit-frame-pointer -funroll-loops -DNDEBUG "
if ( cc 2>&1 | grep clang >/dev/null ); then
echo "Setting optimisation flags for clang compiler"
export OPTIM_CFLAGS="-mfpmath=sse -O3 -fno-math-errno -ffinite-math-only -fno-trapping-math -fno-signed-zeros -Wall -Wextra -Wno-missing-field-initializers -fomit-frame-pointer -funroll-loops -DNDEBUG "
......@@ -510,8 +471,6 @@ case $TARGET in
;;
$TARGET_MAC)
check_prerequisites || failure
# This sets the minimum required build compatiability, this should
# be kept low to provide a broad support
OSXminor=7
#`sw_vers -productVersion | cut -d'.' -f2`
......@@ -524,11 +483,10 @@ case $TARGET in
# probably should allow custom minor version for build-mac
export MACOSX_DEPLOYMENT_TARGET="10.$OSXminor"
if [ -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/ ]; then
echo "Preparing Mac OS X SDK build environment..." | tee -a $LOGFILE
export OSX_SDK="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/"
export OSX_CFLAGS="$NATIVE $OPTIM_CFLAGS -isysroot $OSX_SDK -arch $CPUARCH -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -DOSX_BUILD_VER=$MACOSX_DEPLOYMENT_TARGET -DMACOSX_SDK=13"
if [ -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/ ]; then
echo "Preparing Mac OS X 10.15 SDK build environment..." | tee -a $LOGFILE
export OSX_SDK="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/"
export OSX_CFLAGS="$NATIVE $OPTIM_CFLAGS -isysroot $OSX_SDK -arch $CPUARCH -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -DOSX_BUILD_VER=$MACOSX_DEPLOYMENT_TARGET -DMACOSX_SDK=15"
export OSX_LDFLAGS="-isysroot $OSX_SDK -Wl,-syslibroot,$OSX_SDK -arch $CPUARCH -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET"
export CFLAGS=$OSX_CFLAGS
export CXXFLAGS=$OSX_CFLAGS
......@@ -597,14 +555,6 @@ case $TARGET in
export CFLAGS=$OSX_CFLAGS
export CXXFLAGS=$OSX_CFLAGS
export LDFLAGS=$OSX_LDFLAGS
elif [ -d /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/ ]; then
echo "Preparing Command Line Tools Mac OS X SDK build environment..." | tee -a $LOGFILE
export OSX_SDK="/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/"
export OSX_CFLAGS="$NATIVE $OPTIM_CFLAGS -isysroot $OSX_SDK -arch $CPUARCH -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -DOSX_BUILD_VER=$MACOSX_DEPLOYMENT_TARGET -DMACOSX_SDK=13"
export OSX_LDFLAGS="-isysroot $OSX_SDK -Wl,-syslibroot,$OSX_SDK -arch $CPUARCH -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET"
export CFLAGS=$OSX_CFLAGS
export CXXFLAGS=$OSX_CFLAGS
export LDFLAGS=$OSX_LDFLAGS
elif [ -d /Developer/SDKs/MacOSX10.6.sdk ]; then
echo "Preparing Mac OS X 10.6 x86_64 SDK build environment..." | tee -a $LOGFILE
export LDFLAGS="-isysroot /Developer/SDKs/MacOSX10.6.sdk -Wl,-syslibroot,/Developer/SDKs/MacOSX10.6.sdk -arch $CPUARCH $LDFLAGS"
......@@ -637,19 +587,16 @@ case $TARGET in
check_prerequisites || failure
export CFLAGS="$CFLAGS -m32 $OPTIM_CFLAGS $NATIVE"
build || failure
;;
$TARGET_WIN64)
check_prerequisites || failure
export CFLAGS="$CFLAGS -m64 $OPTIM_CFLAGS $NATIVE"
build || failure
;;
$TARGET_CLEAN)
echo "Cleaning up build files, see clean.err and clean.log for more details..."
make ARCH=$target_arch BUILD=$platform realclean 2>&1 1>make.log
if grep " Error " make.log 1>/dev/null 2>&1
then
if grep " Error " make.log 1>/dev/null 2>&1; then
#cat make.err > $LOGFILE
failure
fi
......
/*
* -- SuperLU MT routine (version 2.0) --
* Lawrence Berkeley National Lab, Univ. of California Berkeley,
* and Xerox Palo Alto Research Center.
* September 10, 2007
*
*/
#include "pdsp_defs.h"
main(int argc, char *argv[])
{
SuperMatrix A, L, U;
SuperMatrix B, X;
NCformat *Astore;
SCPformat *Lstore;
NCPformat *Ustore;
int nprocs;
fact_t fact;
trans_t trans;
yes_no_t refact, usepr;
equed_t equed;
double *a;
int *asub, *xa;
int *perm_c; /* column permutation vector */
int *perm_r; /* row permutations from partial pivoting */
void *work;
superlumt_options_t superlumt_options;
int info, lwork, nrhs, ldx, panel_size, relax;
int m, n, nnz, permc_spec;
int i, firstfact;
double *rhsb, *rhsx, *xact;
double *R, *C;
double *ferr, *berr;
double u, drop_tol, rpg, rcond;
superlu_memusage_t superlu_memusage;
void parse_command_line();
/* Default parameters to control factorization. */
nprocs = 1;
fact = EQUILIBRATE;
trans = NOTRANS;
equed = NOEQUIL;
refact= NO;
panel_size = sp_ienv(1);
relax = sp_ienv(2);
u = 1.0;
usepr = NO;
drop_tol = 0.0;
lwork = 0;
nrhs = 1;
/* Command line options to modify default behavior. */
parse_command_line(argc, argv, &nprocs, &lwork, &panel_size, &relax,
&u, &fact, &trans, &refact, &equed);
if ( lwork > 0 ) {
work = SUPERLU_MALLOC(lwork);
printf("Use work space of size LWORK = %d bytes\n", lwork);
if ( !work ) {
SUPERLU_ABORT("DLINSOLX: cannot allocate work[]");
}
}
#if ( PRNTlevel==1 )
cpp_defs();
#endif
#define HB
#if defined( DEN )
m = n;
nnz = n * n;
dband(n, n, nnz, &a, &asub, &xa);
#elif defined( BAND )
m = n;
nnz = (2*b+1) * n;
dband(n, b, nnz, &a, &asub, &xa);
#elif defined( BD )
nb = 5;
bs = 200;
m = n = bs * nb;
nnz = bs * bs * nb;
dblockdiag(nb, bs, nnz, &a, &asub, &xa);
#elif defined( HB )
dreadhb(&m, &n, &nnz, &a, &asub, &xa);
#else
dreadmt(&m, &n, &nnz, &a, &asub, &xa);
#endif
firstfact = (fact == FACTORED || refact == YES);
dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_D, SLU_GE);
Astore = A.Store;
printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz);
if (!(rhsb = doubleMalloc(m * nrhs))) SUPERLU_ABORT("Malloc fails for rhsb[].");
if (!(rhsx = doubleMalloc(m * nrhs))) SUPERLU_ABORT("Malloc fails for rhsx[].");
dCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_D, SLU_GE);
dCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_D, SLU_GE);
xact = doubleMalloc(n * nrhs);
ldx = n;
dGenXtrue(n, nrhs, xact, ldx);
dFillRHS(trans, nrhs, xact, ldx, &A, &B);
if (!(perm_r = intMalloc(m))) SUPERLU_ABORT("Malloc fails for perm_r[].");
if (!(perm_c = intMalloc(n))) SUPERLU_ABORT("Malloc fails for perm_c[].");
if (!(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))))
SUPERLU_ABORT("SUPERLU_MALLOC fails for R[].");
if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) )
SUPERLU_ABORT("SUPERLU_MALLOC fails for C[].");
if ( !(ferr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) )
SUPERLU_ABORT("SUPERLU_MALLOC fails for ferr[].");
if ( !(berr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) )
SUPERLU_ABORT("SUPERLU_MALLOC fails for berr[].");
/*
* Get column permutation vector perm_c[], according to permc_spec:
* permc_spec = 0: natural ordering
* permc_spec = 1: minimum degree ordering on structure of A'*A
* permc_spec = 2: minimum degree ordering on structure of A'+A
* permc_spec = 3: approximate minimum degree for unsymmetric matrices
*/
permc_spec = 1;
get_perm_c(permc_spec, &A, perm_c);
superlumt_options.nprocs = nprocs;
superlumt_options.fact = fact;
superlumt_options.trans = trans;
superlumt_options.refact = refact;
superlumt_options.panel_size = panel_size;
superlumt_options.relax = relax;
superlumt_options.diag_pivot_thresh = u;
superlumt_options.usepr = usepr;
superlumt_options.drop_tol = drop_tol;
superlumt_options.SymmetricMode = NO;
superlumt_options.PrintStat = NO;
superlumt_options.perm_c = perm_c;
superlumt_options.perm_r = perm_r;
superlumt_options.work = work;
superlumt_options.lwork = lwork;
/*
* Solve the system and compute the condition number
* and error bounds using pdgssvx.
*/
pdgssvx(nprocs, &superlumt_options, &A, perm_c, perm_r,
&equed, R, C, &L, &U, &B, &X, &rpg, &rcond,
ferr, berr, &superlu_memusage, &info);
printf("pdgssvx(): info %d\n", info);
if ( info == 0 || info == n+1 ) {
printf("Recip. pivot growth = %e\n", rpg);
printf("Recip. condition number = %e\n", rcond);
printf("%8s%16s%16s\n", "rhs", "FERR", "BERR");
for (i = 0; i < nrhs; ++i) {
printf("%8d%16e%16e\n", i+1, ferr[i], berr[i]);
}
Lstore = (SCPformat *) L.Store;
Ustore = (NCPformat *) U.Store;
printf("No of nonzeros in factor L = %d\n", Lstore->nnz);
printf("No of nonzeros in factor U = %d\n", Ustore->nnz);
printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n);
printf("L\\U MB %.3f\ttotal MB needed %.3f\texpansions %d\n",
superlu_memusage.for_lu/1e6, superlu_memusage.total_needed/1e6,
superlu_memusage.expansions);
fflush(stdout);
} else if ( info > 0 && lwork == -1 ) {
printf("** Estimated memory: %d bytes\n", info - n);
}
SUPERLU_FREE (rhsb);
SUPERLU_FREE (rhsx);
SUPERLU_FREE (xact);
SUPERLU_FREE (perm_r);
SUPERLU_FREE (perm_c);
SUPERLU_FREE (R);
SUPERLU_FREE (C);
SUPERLU_FREE (ferr);
SUPERLU_FREE (berr);
Destroy_CompCol_Matrix(&A);
Destroy_SuperMatrix_Store(&B);
Destroy_SuperMatrix_Store(&X);
if ( lwork >= 0 ) {
Destroy_SuperNode_SCP(&L);
Destroy_CompCol_NCP(&U);
}
}
/*
* Parse command line options.
*/
void
parse_command_line(int argc, char *argv[], int *nprocs, int *lwork,
int *w, int *relax, double *u, fact_t *fact,
trans_t *trans, yes_no_t *refact, equed_t *equed)
{
int c;
extern char *optarg;
while ( (c = getopt(argc, argv, "hp:l:w:x:u:f:t:r:e:")) != EOF ) {
switch (c) {
case 'h':
printf("Options:\n");
printf("\t-p <int> - number of processes\n");
printf("\t-l <int> - length of work[*] array\n");
printf("\t-w <int> - panel size\n");
printf("\t-x <int> - maximum size of relaxed supernodes\n");
printf("\t-u <int> - pivoting threshold\n");
printf("\t-f <FACTORED/DOFACT/EQUILIBRATE> - factor control\n");
printf("\t-t <NOTRANS/TRANS/CONJ> - transpose or not\n");
printf("\t-r <NO/YES> - refactor or not\n");
printf("\t-e <NOEQUIL/ROW/COL/BOTH> - equilibrate or not\n");
exit(1);
break;
case 'p': *nprocs = atoi(optarg);
break;
case 'l': *lwork = atoi(optarg);
break;
case 'w': *w = atoi(optarg);
break;
case 'x': *relax = atoi(optarg);
break;
case 'u': *u = atof(optarg);
break;
case 'f': *fact = (fact_t) atoi(optarg);
break;
case 't': *trans = (trans_t) atoi(optarg);
break;
case 'r': *refact = (yes_no_t) atoi(optarg);
break;
case 'e': *equed = (equed_t) atoi(optarg);
break;
default: fprintf(stderr, "Invalid command line option.\n");
break;
}
}
}
/*
* -- SuperLU MT routine (version 2.0) --
* Lawrence Berkeley National Lab, Univ. of California Berkeley,
* and Xerox Palo Alto Research Center.
* September 10, 2007
*
* Purpose
* =======
*
* This program illustrates how to integrate the SPMD mode
* of the factor routine pdgstrf_thread() into a larger SPMD
* application code, and manage the threads yourself.
* In this example, the threads creation happens only once.
*
*/
#include <stdlib.h> /* for getenv and atoi */
#include "pdsp_defs.h"
/* Arguments passed to each dot product thread. */
typedef struct {
int i;
int len;
int nprocs;
double *global_dot;
double *x;
} pddot_threadarg_t;
#if ( MACH==SUN )
mutex_t pddot_lock;
#elif ( MACH==DEC || MACH==PTHREAD )
pthread_mutex_t pddot_lock;
#elif ( MACH==SGI || MACH==ORIGIN || MACH==CRAY_PVP )
int pddot_lock = 1;
#endif
/* Arguments passed to each SPMD program. */
typedef struct {
pdgstrf_threadarg_t *pdgstrf_threadarg; /* for sparse LU. */
pddot_threadarg_t *pddot_threadarg; /* for dot product. */
} dspmd_arg_t;
void *dspmd(void *);
void *pddot_thread(void *);
main(int argc, char *argv[])
{
SuperMatrix A, AC, L, U, B;
NCformat *Astore;
SCPformat *Lstore;
NCPformat *Ustore;
superlumt_options_t superlumt_options;
pxgstrf_shared_t pxgstrf_shared;
pdgstrf_threadarg_t *pdgstrf_threadarg;
pddot_threadarg_t *pddot_threadarg;
dspmd_arg_t *dspmd_arg;
int nprocs;
fact_t fact;
trans_t trans;
yes_no_t refact, usepr;
double u, drop_tol;
double *a;
int *asub, *xa;
int *perm_c; /* column permutation vector */
int *perm_r; /* row permutations from partial pivoting */
void *work;
int info, lwork, nrhs, ldx;
int m, n, nnz, permc_spec, panel_size, relax;
int i, firstfact;
double *rhsb, *xact;
Gstat_t Gstat;
int vlength;
double *xvector, xdot, temp;
double zero = 0.0;
#if ( MACH==SUN )
thread_t *thread_id;
#elif ( MACH==DEC || MACH==PTHREAD )
pthread_t *thread_id;
void *status;
#endif
void parse_command_line();
/* Default parameters to control factorization. */
nprocs = 1;
fact = EQUILIBRATE;
trans = NOTRANS;
refact= NO;
panel_size = sp_ienv(1);
relax = sp_ienv(2);
u = 1.0;
usepr = NO;
drop_tol = 0.0;
work = NULL;
lwork = 0;
nrhs = 1;
/* Get the number of processes from command line. */
parse_command_line(argc, argv, &nprocs);
/* Read the input matrix stored in Harwell-Boeing format. */
dreadhb(&m, &n, &nnz, &a, &asub, &xa);
/* Set up the sparse matrix data structure for A. */
dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_D, SLU_GE);
if (!(rhsb = doubleMalloc(m * nrhs))) SUPERLU_ABORT("Malloc fails for rhsb[].");
dCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_D, SLU_GE);
xact = doubleMalloc(n * nrhs);
ldx = n;
dGenXtrue(n, nrhs, xact, ldx);
dFillRHS(trans, nrhs, xact, ldx, &A, &B);
if (!(perm_r = intMalloc(m))) SUPERLU_ABORT("Malloc fails for perm_r[].");
if (!(perm_c = intMalloc(n))) SUPERLU_ABORT("Malloc fails for perm_c[].");
/* ------------------------------------------------------------
Get column permutation vector perm_c[], according to permc_spec:
permc_spec = 0: natural ordering
permc_spec = 1: minimum degree ordering on structure of A'*A
permc_spec = 2: minimum degree ordering on structure of A'+A
permc_spec = 3: approximate minimum degree for unsymmetric matrices
------------------------------------------------------------*/
permc_spec = 1;
get_perm_c(permc_spec, &A, perm_c);