示例
C Interface:
#include "mg.h" #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include "mpi.h" int main(int argc, char **argv) { MPI_Init(&argc, &argv); MPI_Comm comm = MPI_COMM_WORLD; int rankSize; MPI_Comm_size(comm, &rankSize); int pId; MPI_Comm_rank(comm, &pId); // Init proc size int px = 1; int py = 1; int pz = 1; // Init matrix size int gx = 400; int gy = 200; int gz = 50; int lx = gx / px; int ly = gy / py; int lz = gz; int xbeg = (pId % px) * lx; int xend = xbeg + lx; int ybeg = (pId / px) * ly; int yend = ybeg + ly; int zbeg = 0; int zend = lz; int totLen = (lx + 2) * (ly + 2) * (lz + 2); // Init matrix A KmlMgMatrixH A = NULL; float *aValue = (float *)malloc(19 * totLen * sizeof(float)); { KmlMgMatrixStore store; store.comm = comm; store.globalx = gx; store.globaly = gy; store.globalz = gz; store.procx = px; store.procy = py; store.procz = pz; store.xbeg = xbeg; store.xend = xend; store.ybeg = ybeg; store.yend = yend; store.zbeg = zbeg; store.zend = zend; store.xhalo = 1; store.yhalo = 1; store.zhalo = 1; store.crossPolar = 1; store.type = KML_MG_MATRIX_STORE_SPARSE_HALO; store.sparse.values = NULL; store.sparse.type = KML_MG_SPARSE_AOS; store.sparse.stencil = KML_MG_STENCIL_3D19; KmlMgMatrixOptions options; options.fieldMask = KML_MG_MATRIX_OPTIONS_INDEX_TYPE | KML_MG_MATRIX_OPTIONS_VALUE_TYPE; options.indexType = KML_MG_INDEX_INT32; options.valueType = KML_MG_VALUE_FP32; if (A != NULL) { KmlMgMatrixDestroy(A); } if (KmlMgMatrixCreate(&A, &store, &options) != KML_MG_OK) { printf("Create A error!\n"); }; // Set A values, order is Y-X-Z for (int i = 1; i < lx + 1; i++) { for (int j = 1; j < ly + 1; j++) { for (int k = 1; k < lz + 1; k++) { for (int l = 0; l < 19; l++) { aValue[j * (lx + 2) * (lz + 2) * 19 + i * (lz + 2) * 19 + k * 19 + l] = 0.5; } aValue[j * (lx + 2) * (lz + 2) * 19 + i * (lz + 2) * 19 + k * 19 + 9] *= 100; } } } if (KmlMgMatrixSetValues(A, (void *)aValue) != KML_MG_OK) { printf("SetValues of A error!\n"); }; } // Init B & X KmlMgMatrixH B = NULL; float *bValue = (float *)malloc(totLen * sizeof(float)); KmlMgMatrixH X = NULL; float *xValue = (float *)malloc(totLen * sizeof(float)); { KmlMgMatrixStore store; store.comm = comm; store.globalx = gx; store.globaly = gy; store.globalz = gz; store.procx = px; store.procy = py; store.procz = pz; store.xbeg = xbeg; store.xend = xend; store.ybeg = ybeg; store.yend = yend; store.zbeg = zbeg; store.zend = zend; store.xhalo = 1; store.yhalo = 1; store.zhalo = 1; store.crossPolar = 1; store.type = KML_MG_MATRIX_STORE_DENSE_COL_MAJOR_HALO; store.dense.values = NULL; store.dense.numDim = 1; store.dense.is2D = 0; store.dense.needCorner = 1; KmlMgMatrixOptions options; options.fieldMask = KML_MG_MATRIX_OPTIONS_INDEX_TYPE | KML_MG_MATRIX_OPTIONS_VALUE_TYPE; options.indexType = KML_MG_INDEX_INT32; options.valueType = KML_MG_VALUE_FP32; // Create B if (KmlMgMatrixCreate(&B, &store, &options) != KML_MG_OK) { printf("Create B error!\n"); }; // Set B values for (int i = 0; i < totLen; i++) { bValue[i] = 1.1; } if (KmlMgMatrixSetValues(B, (void *)bValue) != KML_MG_OK) { printf("SetValues of B error!\n"); }; // Create X if (KmlMgMatrixCreate(&X, &store, &options) != KML_MG_OK) { printf("Create X error!\n"); }; // Set X values for (int i = 0; i < totLen; i++) { xValue[i] = 0.0; } if (KmlMgMatrixSetValues(X, (void *)xValue) != KML_MG_OK) { printf("SetValues of X error!\n"); }; } // Init solver KmlMgSolverH solver = NULL; KmlMgPreconditionerOptions preOpt; // need malloc and free { KmlMgSolverOptions solOpt; solOpt.fieldMask = KML_MG_SOLVER_OPTIONS_INDEX_TYPE | KML_MG_SOLVER_OPTIONS_KSP_VALUE_TYPE | KML_MG_SOLVER_OPTIONS_PC_VALUE_TYPE | KML_MG_SOLVER_OPTIONS_PC_CALC_TYPE | KML_MG_SOLVER_OPTIONS_KSP; solOpt.indexType = KML_MG_INDEX_INT32; solOpt.kspValueType = KML_MG_VALUE_FP32; solOpt.pcValueType = KML_MG_VALUE_FP32; solOpt.pcCalcType = KML_MG_VALUE_FP32; solOpt.ksp = KML_MG_SOLVER_GCR; if (solver != NULL) { KmlMgSolverDestroy(solver); } if (KmlMgSolverCreate(&solver, comm, &solOpt) != KML_MG_OK) { printf("solver Create error!\n"); }; preOpt.fieldMask = KML_MG_PRECONDITIONER_OPTIONS_INDEX_TYPE | KML_MG_PRECONDITIONER_OPTIONS_KSP_VALUE_TYPE | KML_MG_PRECONDITIONER_OPTIONS_VALUE_TYPE | KML_MG_PRECONDITIONER_OPTIONS_CALC_TYPE | KML_MG_PRECONDITIONER_OPTIONS_NUM_LEVEL | KML_MG_PRECONDITIONER_OPTIONS_SHIFT_LEVEL | KML_MG_PRECONDITIONER_OPTIONS_CYCLE_TYPE | KML_MG_PRECONDITIONER_OPTIONS_SWEEP | KML_MG_PRECONDITIONER_OPTIONS_XPSS | KML_MG_PRECONDITIONER_OPTIONS_SMOOTHER | KML_MG_PRECONDITIONER_OPTIONS_WEIGHT | KML_MG_PRECONDITIONER_OPTIONS_COARSEN | KML_MG_PRECONDITIONER_OPTIONS_RESTRICT | KML_MG_PRECONDITIONER_OPTIONS_PROLONG | KML_MG_PRECONDITIONER_OPTIONS_ALPHA | KML_MG_PRECONDITIONER_OPTIONS_CONTROL; preOpt.indexType = KML_MG_INDEX_INT32; preOpt.kspValueType = KML_MG_VALUE_FP32; preOpt.valueType = KML_MG_VALUE_FP32; preOpt.calcType = KML_MG_VALUE_FP32; preOpt.numLevels = 4; preOpt.shiftLevelId = 1; preOpt.cycle = KML_MG_CYCLE_V; int *gridSweep = (int *)malloc(2 * sizeof(int)); gridSweep[0] = 1; gridSweep[1] = 0; preOpt.gridSweep = gridSweep; int *xpss = (int *)malloc(4 * sizeof(int)); xpss[0] = 1; xpss[1] = 1; xpss[2] = 1; xpss[3] = 1; preOpt.xpss = xpss; KmlMgSmootherType *smoother = (KmlMgSmootherType *)malloc(4 * sizeof(KmlMgSmootherType)); smoother[0] = KML_MG_SMOOTHER_PLANE_ILU; smoother[1] = KML_MG_SMOOTHER_LINE_GS; smoother[2] = KML_MG_SMOOTHER_LINE_GS; smoother[3] = KML_MG_SMOOTHER_LINE_GS; preOpt.smoother = smoother; float *weight = (float *)malloc(4 * sizeof(float)); weight[0] = 1.0; weight[1] = 1.0; weight[2] = 1.0; weight[3] = 1.0; preOpt.weight = weight; KmlMgCoarsenType *coarsen = (KmlMgCoarsenType *)malloc(4 * sizeof(KmlMgCoarsenType)); coarsen[0] = KML_MG_COARSEN_SEMI_XY; coarsen[1] = KML_MG_COARSEN_SEMI_XY; coarsen[2] = KML_MG_COARSEN_SEMI_XY; coarsen[3] = KML_MG_COARSEN_SEMI_XY; preOpt.coarsen = coarsen; KmlMgRestInteType *rest = (KmlMgRestInteType *)malloc(4 * sizeof(KmlMgRestInteType)); rest[0] = KML_MG_REST_INTE_CELL_2D16; rest[1] = KML_MG_REST_INTE_CELL_2D4; rest[2] = KML_MG_REST_INTE_CELL_2D4; rest[3] = KML_MG_REST_INTE_CELL_2D4; preOpt.rest = rest; KmlMgRestInteType *interp = (KmlMgRestInteType *)malloc(4 * sizeof(KmlMgRestInteType)); interp[0] = KML_MG_REST_INTE_CELL_2D16; interp[1] = KML_MG_REST_INTE_CELL_2D16; interp[2] = KML_MG_REST_INTE_CELL_2D16; interp[3] = KML_MG_REST_INTE_CELL_2D16; preOpt.interp = interp; float *alpha = (float *)malloc(4 * sizeof(float)); alpha[0] = 1.0; alpha[1] = 1.0; alpha[2] = 1.0; alpha[3] = 1.0; preOpt.alpha = alpha; int *control = (int *)malloc(4 * sizeof(int)); control[0] = 0; control[1] = 1; control[2] = 1; control[3] = 1; preOpt.control = control; if (KmlMgSolverSetPreconditioner(solver, &preOpt) != KML_MG_OK) { printf("solver SetPreconditioner error!\n"); } printf("SetPreconditioner done!\n"); if (KmlMgSolverSetPreconditionerMatrix(solver, A) != KML_MG_OK) { printf("solver SetPreconditionerMatrix error!\n"); } printf("SetPreconditionerMatrix done!\n"); if (KmlMgSolverPrepare(solver, A) != KML_MG_OK) { printf("solver Prepare error!\n"); } printf("Prepare done!\n"); } // Apply { KmlMgApplyOptions opt; opt.fieldMask = KML_MG_APPLY_OPTIONS_USE_ZERO_GUESS | KML_MG_APPLY_OPTIONS_TOLERANCE_TYPE | KML_MG_APPLY_OPTIONS_TOLERANCE | KML_MG_APPLY_OPTIONS_MAX_ITERATION | KML_MG_APPLY_OPTIONS_RESTART_STEP; opt.useZeroGuess = 1; opt.toleranceType = KML_MG_TOLERANCE_ABS; opt.tolerance = 1e-6; opt.maxIteration = 200; opt.restartStep = 10; KmlMgStatus sta = KmlMgSolverApply(solver, B, X, &opt); if (sta != KML_MG_OK) { printf("solver Apply error!\n"); } const char * str = KmlMgStatusStr(sta); printf("%s\n", str); printf("Apply done\n"); } KmlMgMatrixInfo info; info.fieldMask = KML_MG_MATRIX_INFO_STORE; KmlMgMatrixQuery(X, &info); // Clear { if (A != NULL) { KmlMgMatrixDestroy(A); } if (aValue != NULL) { free((void *)aValue); } if (B != NULL) { KmlMgMatrixDestroy(B); } if (bValue != NULL) { free((void *)bValue); } if (X != NULL) { KmlMgMatrixDestroy(X); } if (xValue != NULL) { free((void *)xValue); } if (preOpt.gridSweep != NULL) { free((void *)preOpt.gridSweep); } if (preOpt.xpss != NULL) { free((void *)preOpt.xpss); } if (preOpt.smoother != NULL) { free((void *)preOpt.smoother); } if (preOpt.weight != NULL) { free((void *)preOpt.weight); } if (preOpt.coarsen != NULL) { free((void *)preOpt.coarsen); } if (preOpt.rest != NULL) { free((void *)preOpt.rest); } if (preOpt.interp != NULL) { free((void *)preOpt.interp); } if (preOpt.alpha != NULL) { free((void *)preOpt.alpha); } if (preOpt.control != NULL) { free((void *)preOpt.control); } } MPI_Finalize(); return 0; }
父主题: HMG