
//#include "cuda_runtime.h"/* CUDA error macro */cudaError_t err = call; \if(cudaSuccess != err) { \fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", \__FILE__, __LINE__, cudaGetErrorString( err) ); \exit(EXIT_FAILURE); \} } while (0)/* standard or dynamically load library *//* print error message and exit */void errAndExit(const char *err){printf("%s\n", err);fflush(stdout);exit(1);}/* print callback (could be customized) */void print_callback(const char *msg, int length){printf("%s", msg);}/* print usage and exit */void printUsageAndExit(){printf("%s", " -mode: select the solver mode\n");printf("%s", " -m file: read matrix stored in the file\n");printf("%s", " -c: set the amg solver options from the config file\n");printf("%s", " -amg: set the amg solver options from the command line\n");exit(0);}/* parse parameters */int findParamIndex(const char **argv, int argc, const char *parm){int count = 0;int index = -1;for (int i = 0; i < argc; i++){if (strncmp(argv[i], parm, 100) == 0){index = i;count++;}}if (count == 0 || count == 1){return index;}else{printf("Error, parameter %s has been specified more than once, exiting\n", parm);exit(1);}return -1;}int main(int argc, const char **argv){//parameter parsingint pidx = 0;int pidy = 0;//versionsint major, minor;char *ver, *date, *time;//input geometrydouble *gx = NULL;double *gy = NULL;double *gz = NULL;//input coloringint dim = 0;int numrows = 0;int num_colors = 0;int colored_rows = 0;int *row_coloring = NULL;//input matrix and rhs/solutionint n = 0;int bsize_x = 0;int bsize_y = 0;int sol_size = 0;int sol_bsize = 0;//library handlesAMGX_Mode mode;AMGX_config_handle cfg;AMGX_resources_handle rsrc;AMGX_matrix_handle A;AMGX_vector_handle b, x;AMGX_solver_handle solver;//status handlingAMGX_SOLVE_STATUS status;/* check arguments */if (argc == 1){printUsageAndExit();}/* load the library (if it was dynamically loaded) */void *lib_handle = NULL;//open the librarylib_handle = amgx_libopen("amgxsh.dll");lib_handle = amgx_libopen("libamgxsh.so");if (lib_handle == NULL){errAndExit("ERROR: can not load the library");}//load all the routinesif (amgx_liblink_all(lib_handle) == 0){amgx_libclose(lib_handle);errAndExit("ERROR: corrupted library loaded\n");}/* init */AMGX_SAFE_CALL(AMGX_initialize());/* system */AMGX_SAFE_CALL(AMGX_register_print_callback(&print_callback));AMGX_SAFE_CALL(AMGX_install_signal_handler());/* get api and build info */if ((pidx = findParamIndex(argv, argc, "--version")) != -1){AMGX_get_api_version(&major, &minor);printf("amgx api version: %d.%d\n", major, minor);AMGX_get_build_info_strings(&ver, &date, &time);printf("amgx build version: %s\nBuild date and time: %s %s\n",ver, date, time);AMGX_SAFE_CALL(AMGX_finalize());/* close the library (if it was dynamically loaded) */amgx_libclose(lib_handle);exit(0);}/* get mode */if ((pidx = findParamIndex(argv, argc, "-mode")) != -1){if (strncmp(argv[pidx + 1], "hDDI", 100) == 0){mode = AMGX_mode_hDDI;}else if (strncmp(argv[pidx + 1], "hDFI", 100) == 0){mode = AMGX_mode_hDFI;}else if (strncmp(argv[pidx + 1], "hFFI", 100) == 0){mode = AMGX_mode_hFFI;}else if (strncmp(argv[pidx + 1], "dDDI", 100) == 0){mode = AMGX_mode_dDDI;}else if (strncmp(argv[pidx + 1], "dDFI", 100) == 0){mode = AMGX_mode_dDFI;}else if (strncmp(argv[pidx + 1], "dFFI", 100) == 0){mode = AMGX_mode_dFFI;}else if (strncmp(argv[pidx + 1], "hCCI", 100) == 0){mode = AMGX_mode_hZZI;}else if (strncmp(argv[pidx + 1], "hZCI", 100) == 0){mode = AMGX_mode_hZCI;}else if (strncmp(argv[pidx + 1], "hZZI", 100) == 0){mode = AMGX_mode_hZZI;}else if (strncmp(argv[pidx + 1], "dCCI", 100) == 0){mode = AMGX_mode_dCCI;}else if (strncmp(argv[pidx + 1], "dZCI", 100) == 0){mode = AMGX_mode_dZCI;}else if (strncmp(argv[pidx + 1], "dZZI", 100) == 0){mode = AMGX_mode_dZZI;}else{errAndExit("ERROR: invalid mode");}}else{printf("Warning: No mode specified, using dDDI by default.\n");mode = AMGX_mode_dDDI;}/* create config */pidx = findParamIndex(argv, argc, "-amg");pidy = findParamIndex(argv, argc, "-c");if ((pidx != -1) && (pidy != -1)){printf("%s\n", argv[pidx + 1]);AMGX_SAFE_CALL(AMGX_config_create_from_file_and_string(&cfg, argv[pidy + 1], argv[pidx + 1]));}else if (pidy != -1){AMGX_SAFE_CALL(AMGX_config_create_from_file(&cfg, argv[pidy + 1]));}else if (pidx != -1){printf("%s\n", argv[pidx + 1]);AMGX_SAFE_CALL(AMGX_config_create(&cfg, argv[pidx + 1]));}else{errAndExit("ERROR: no config was specified");}AMGX_resources_create_simple(&rsrc, cfg);AMGX_matrix_create(&A, rsrc, mode);AMGX_vector_create(&x, rsrc, mode);AMGX_vector_create(&b, rsrc, mode);AMGX_solver_create(&solver, rsrc, mode, cfg);int ia[]{ 0,3,5,7 };int ja[]{ 0,1,2,1,2,0,2 };double value[]{ 3.0,5.0,2.0,2.0,3.0,1.0,3.0 };int nrow = 3;AMGX_matrix_upload_all(A, 3, 7, 1, 1, ia, ja, value,NULL);AMGX_matrix_get_size(A, &nrow, &bsize_x, &bsize_y);double xvalue1[]{ 0,0,0 };AMGX_vector_upload(x, nrow, 1, xvalue1);double rhs[3]{ 1.0,1.0,1.0 };AMGX_vector_upload(b, nrow, 1, rhs);/* solver setup */AMGX_solver_setup(solver, A);/* solver solve */AMGX_solver_solve(solver, b, x);AMGX_solver_get_status(solver, &status);double xvalue[3];AMGX_vector_download(x,xvalue);for (int i = 0; i < 3; i++){printf("x:% le\n ", xvalue[i]);}AMGX_solver_destroy(solver);AMGX_vector_destroy(x);AMGX_vector_destroy(b);AMGX_matrix_destroy(A);AMGX_resources_destroy(rsrc);/* destroy config (need to use AMGX_SAFE_CALL after this point) */AMGX_SAFE_CALL(AMGX_config_destroy(cfg));/* shutdown and exit */AMGX_SAFE_CALL(AMGX_finalize());/* close the library (if it was dynamically loaded) */amgx_libclose(lib_handle);return status;}
以上,即是Amgx的基础示例,代码的具体内容,主要包括提供一个CSR格式的稀疏矩阵,定义好对应的右端项和对应的Amgx库中的各种参数如config创建,求解模式选择等。通过该示例,实际上可以快速地移植到任意待求解的稀疏矩阵线性方程组中,要做的,仅仅是将矩阵输入数据和右端项进行替换。
