示例
C Interface:
#include <stdio.h>
#include <math.h>
#include <mpi.h>
#include <omp.h>
#include <assert.h>
#include "amg4c.h"
int test(int isonlyAMG)
{
int nthreads = 1;
int rtn = 0;
int gid;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Comm_rank(comm, &gid);
int globalN = 8;
int localOffset = 0;
int localLength = globalN;
int offsets[9] = {0, 2, 4, 6, 7, 8, 10, 12, 14};
int indices[14] = {0, 7, 1, 6, 2, 5, 3, 4, 2, 5, 1, 6, 0, 7};
double values[14] = {1.0, 2.0, -2.0, 3.0, 3.0, 4.0, -4.0, 5.0, 4.0, -6.0, 3.0, 7.0, 2.0, 8.0};
double b_[8] = {3.0, 1.0, 7.0, -4.0, 5.0, -2.0, 10.0, 10.0};
double x_[8] = {0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5};
int isAvg = 0;
int64_t localNnz = offsets[localLength];
int *indices_ = NULL;
double *values_ = NULL;
indices_ = indices;
values_ = values;
KmlAmgMatrixH matrixA = NULL;
KmlAmgMatrixOptions MatrixAoptions;
KmlAmgMatrixStore MatrixAstore;
{
MatrixAoptions.fieldMask = KMLAMG_MATRIX_OPTIONS_VALUE_TYPE | KMLAMG_MATRIX_OPTIONS_INDEX_TYPE |
KMLAMG_MATRIX_OPTIONS_COMM | KMLAMG_MATRIX_OPTIONS_NUM_THREADS;
MatrixAoptions.comm = comm;
MatrixAoptions.indexType = KMLAMG_INDEX_INT32;
MatrixAoptions.valueType = KMLAMG_VALUE_FP64;
MatrixAoptions.numThreads = nthreads;
MatrixAstore.globalNRows = globalN;
MatrixAstore.globalNCols = globalN;
MatrixAstore.isAvgPart = isAvg;
MatrixAstore.localBegin = localOffset;
MatrixAstore.localNRows = localLength;
MatrixAstore.localNCols = localLength;
MatrixAstore.type = KMLAMG_MATRIX_STORE_CSR;
MatrixAstore.csr.offsets = offsets;
MatrixAstore.csr.indices = indices_;
MatrixAstore.csr.values = NULL;
if (KmlAmgMatrixCreate(&matrixA, &MatrixAstore, &MatrixAoptions) != KMLAMG_SUCCESS) {
printf("Create A error!\n");
};
}
if (KmlAmgMatrixSetValues(matrixA, values_) != KMLAMG_SUCCESS) {
printf("matrixA SetValues error!\n");
}
KmlAmgMatrixH VectorB = NULL;
KmlAmgMatrixOptions VectorBoptions;
KmlAmgMatrixStore VectorBstore;
{
VectorBoptions.fieldMask = KMLAMG_MATRIX_OPTIONS_VALUE_TYPE | KMLAMG_MATRIX_OPTIONS_INDEX_TYPE |
KMLAMG_MATRIX_OPTIONS_COMM | KMLAMG_MATRIX_OPTIONS_NUM_THREADS;
VectorBoptions.comm = comm;
VectorBoptions.indexType = KMLAMG_INDEX_INT32;
VectorBoptions.valueType = KMLAMG_VALUE_FP64;
VectorBoptions.numThreads = nthreads;
VectorBstore.globalNRows = globalN;
VectorBstore.globalNCols = 1;
VectorBstore.isAvgPart = isAvg;
VectorBstore.localBegin = localOffset;
VectorBstore.localNRows = localLength;
VectorBstore.localNCols = 1;
VectorBstore.type = KMLAMG_MATRIX_STORE_DENSE_ROW_MAJOR;
VectorBstore.dense.values = NULL;
if (KmlAmgMatrixCreate(&VectorB, &VectorBstore, &VectorBoptions) != KMLAMG_SUCCESS) {
printf("Create B error!\n");
};
}
if (KmlAmgMatrixSetValues(VectorB, b_) != KMLAMG_SUCCESS) {
printf("VectorB SetValues error!\n");
}
KmlAmgMatrixH VectorX = NULL;
KmlAmgMatrixOptions VectorXoptions;
KmlAmgMatrixStore VectorXstore;
{
VectorXoptions.fieldMask = KMLAMG_MATRIX_OPTIONS_VALUE_TYPE | KMLAMG_MATRIX_OPTIONS_INDEX_TYPE |
KMLAMG_MATRIX_OPTIONS_COMM | KMLAMG_MATRIX_OPTIONS_NUM_THREADS;
VectorXoptions.comm = comm;
VectorXoptions.indexType = KMLAMG_INDEX_INT32;
VectorXoptions.valueType = KMLAMG_VALUE_FP64;
VectorXoptions.numThreads = nthreads;
VectorXstore.globalNRows = globalN;
VectorXstore.globalNCols = 1;
VectorXstore.isAvgPart = isAvg;
VectorXstore.localBegin = localOffset;
VectorXstore.localNRows = localLength;
VectorXstore.localNCols = 1;
VectorXstore.type = KMLAMG_MATRIX_STORE_DENSE_ROW_MAJOR;
VectorXstore.dense.values = x_;
if (KmlAmgMatrixCreate(&VectorX, &VectorXstore, &VectorXoptions) != KMLAMG_SUCCESS) {
printf("Create X error!\n");
};
}
if (KmlAmgMatrixSetValues(VectorX, x_) != KMLAMG_SUCCESS) {
printf("VectorX SetValues error!\n");
}
KmlAmgPrecondH precond = NULL;
KmlAmgPrecondOptions PreOptions;
KmlAmgPrecondSetupOptions PreSetOptions;
{
PreOptions.fieldMask = KMLAMG_PRECOND_OPTIONS_VALUE_TYPE | KMLAMG_PRECOND_OPTIONS_INDEX_TYPE |
KMLAMG_PRECOND_OPTIONS_TYPE | KMLAMG_PRECOND_OPTIONS_NUM_THREADS;
PreOptions.valueType = KMLAMG_VALUE_FP64;
PreOptions.indexType = KMLAMG_INDEX_INT32;
PreOptions.precondType = KMLAMG_PRECOND_AMG;
PreOptions.numThreads = nthreads;
if (KmlAmgPrecondCreate(&precond, &PreOptions) != KMLAMG_SUCCESS) {
printf("Create Precond error!\n");
};
PreSetOptions.fieldMask =
KMLAMG_PRECOND_SETUP_OPTIONS_PARTITION | KMLAMG_PRECOND_SETUP_OPTIONS_STRONG_THRESHOLD |
KMLAMG_PRECOND_SETUP_OPTIONS_MAX_LEVELS | KMLAMG_PRECOND_SETUP_OPTIONS_COARSEN_TYPE |
KMLAMG_PRECOND_SETUP_OPTIONS_INTERP_TYPE | KMLAMG_PRECOND_SETUP_OPTIONS_DOWN_SMOOTH_TYPE |
KMLAMG_PRECOND_SETUP_OPTIONS_UP_SMOOTH_TYPE | KMLAMG_PRECOND_SETUP_OPTIONS_COARSEST_SMOOTH_TYPE;
PreSetOptions.strongThreshold = 0.25;
PreSetOptions.maxLevels = 1;
PreSetOptions.coarsenType = KMLAMG_PRECOND_AMG_COARSEN_PMIS;
PreSetOptions.interpType = KMLAMG_PRECOND_AMG_INTERP_DIRECT;
PreSetOptions.downSmoothType = KMLAMG_PRECOND_AMG_SMOOTH_L1_SOR_FORWARD;
PreSetOptions.upSmoothType = KMLAMG_PRECOND_AMG_SMOOTH_L1_SOR_BACKWARD;
PreSetOptions.coarsestSmoothType = KMLAMG_PRECOND_AMG_SMOOTH_L1_SOR_SYMMETRIC;
PreSetOptions.partitionAlgo = KMLAMG_PARTITION_KRDR;
if (KmlAmgPrecondSetSetupOptions(precond, &PreSetOptions) != KMLAMG_SUCCESS) {
printf("Set Precond setup options error!\n");
};
if (KmlAmgPrecondSetup(precond, matrixA) != KMLAMG_SUCCESS) {
printf("Setup Precond error!\n");
};
}
KmlAmgSolverH Ksp = NULL;
KmlAmgSolverOptions KspOptions;
KmlAmgSolverSetupOptions KspSetupOptions;
{
KspOptions.fieldMask = KMLAMG_SOLVER_OPTIONS_VALUE_TYPE | KMLAMG_SOLVER_OPTIONS_INDEX_TYPE |
KMLAMG_SOLVER_OPTIONS_TYPE | KMLAMG_SOLVER_OPTIONS_NUM_THREADS;
KspOptions.valueType = KMLAMG_VALUE_FP64;
KspOptions.indexType = KMLAMG_INDEX_INT32;
KspOptions.solverType = KMLAMG_SOLVER_CG;
KspOptions.numThreads = nthreads;
if (KmlAmgSolverCreate(&Ksp, &KspOptions) != KMLAMG_SUCCESS) {
printf("KmlAmgSolverCreate error!\n");
};
KspSetupOptions.fieldMask = KMLAMG_SOLVER_SETUP_OPTIONS_PARTITION;
KspSetupOptions.partitionAlgo = KMLAMG_PARTITION_KRDR;
}
if (isonlyAMG) {
KmlAmgPrecondApplyOptions preApplyOptions;
preApplyOptions.fieldMask = 0;
KmlAmgPrecondSetApplyOptions(precond, &preApplyOptions);
KmlAmgPrecondApply(precond, VectorB, VectorX);
KmlAmgPrecondInfo Precondinfo;
Precondinfo.fieldMask = 0;
KmlAmgPrecondQuery(precond, &Precondinfo);
double *xvalue = (double *)VectorXstore.dense.values;
printf("x is ");
for (int i = 0; i < globalN; i++) {
printf("%f ", xvalue[i]);
}
printf("\n");
return 0;
}
KmlAmgSolverSetPrec(Ksp, precond);
KmlAmgSolverApplyOptions KspApplyOptions;
{
KspApplyOptions.fieldMask = KMLAMG_SOLVER_APPLY_OPTIONS_MAX_ITERS | KMLAMG_SOLVER_APPLY_OPTIONS_TOLERANCE;
KspApplyOptions.maxIters = 1000;
KspApplyOptions.tolerance = 1e-9;
MPI_Barrier(comm);
for (int s = 0; s < 1; s++) {
KmlAmgMatrixSetValues(matrixA, values_);
KmlAmgMatrixSetValues(VectorB, b_);
MPI_Barrier(comm);
KmlAmgSolverSetSetupOptions(Ksp, &KspSetupOptions);
KmlAmgSolverSetup(Ksp, matrixA);
for (int ss = 0; ss < 1; ss++) {
MPI_Barrier(comm);
KmlAmgMatrixSetValues(VectorX, x_);
KmlAmgSolverSetApplyOptions(Ksp, &KspApplyOptions);
KmlAmgSolverApply(Ksp, VectorB, VectorX);
}
}
}
KmlAmgSolverInfo SolverInfo;
SolverInfo.fieldMask = 0;
KmlAmgSolverQuery(Ksp, &SolverInfo);
double *xvalue = (double *)VectorXstore.dense.values;
printf("x is ");
for (int i = 0; i < globalN; i++) {
printf("%f ", xvalue[i]);
}
printf("\n");
int *perm = (int *)malloc(sizeof(int)*globalN);
KmlAmgPrecondInfo precondInfo;
precondInfo.fieldMask = KMLAMG_PRECOND_INFO_LOCAL_BEGIN | KMLAMG_PRECOND_INFO_PERM;
precondInfo.perm = (void *)perm;
KmlAmgPrecondQuery(precond, &precondInfo);
int64_t permSum = 0;
for (int64_t i = 0; i < globalN; i++) {
permSum += perm[i];
}
assert(permSum == (globalN * (globalN - 1)) / 2);
KmlAmgSolverInfo solverInfo;
solverInfo.fieldMask = KMLAMG_SOLVER_INFO_LOCAL_BEGIN | KMLAMG_SOLVER_INFO_PERM | KMLAMG_SOLVER_INFO_NUM_ITERS;
solverInfo.perm = (void *)perm;
KmlAmgSolverQuery(Ksp, &solverInfo);
permSum = 0;
for (int64_t i = 0; i < globalN; i++) {
permSum += perm[i];
}
assert(permSum == (globalN * (globalN - 1)) / 2);
printf("nIterations = %ld\n", solverInfo.nIters);
KmlAmgMatrixDestroy(matrixA);
KmlAmgMatrixDestroy(VectorB);
KmlAmgMatrixDestroy(VectorX);
KmlAmgPrecondDestroy(precond);
KmlAmgSolverDestroy(Ksp);
return rtn;
}
int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);
test(0);
MPI_Finalize();
return 0;
}
父主题: TYAMG