鲲鹏社区首页
中文
注册
开发者
我要评分
获取效率
正确性
完整性
易理解
在线提单
论坛求助

示例

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;
}