From c08d64017905c363fb58cc99eb6bea77ace0fc68 Mon Sep 17 00:00:00 2001 From: HPDell Date: Sun, 10 Dec 2023 16:05:34 +0000 Subject: [PATCH 01/20] add: configuration for MPI --- configure | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 21 ++++++++++++++ src/Makevars.in | 10 +++++++ 3 files changed, 106 insertions(+) diff --git a/configure b/configure index 614a79f..27a887e 100755 --- a/configure +++ b/configure @@ -615,12 +615,16 @@ PACKAGE_URL='' ac_subst_vars='LTLIBOBJS LIBOBJS OPENMP_CXXFLAGS +MPI_LIBS +MPI_CFLAGS +ENABLE_MPI ENABLE_CUDA CUDA_INCL PKG_LIBS NVCC CU_INCL GWmodel_CUDA_LIB_PATH +MPICC CUDA_LIBS TARGET_CUDA_LIB CUDA_DEFS @@ -679,6 +683,7 @@ ac_subst_files='' ac_user_opts=' enable_option_checking enable_cuda +enable_mpi enable_openmp ' ac_precious_vars='build_alias @@ -1310,6 +1315,7 @@ Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-cuda install cuda (default no) + --enable-mpi install mpi (default no) --disable-openmp do not use OpenMP Some influential environment variables: @@ -3038,6 +3044,72 @@ NVCC="${CUDA_HOME}/bin/nvcc" printf "%s\n" "building the cuda include path" >&6; } CUDA_INCL="${CUDA_HOME}/include" +ENABLE_MPI=1 +# Check whether --enable-mpi was given. +if test ${enable_mpi+y} +then : + enableval=$enable_mpi; case "${enableval}" in + yes) ENABLE_MPI=1 ;; + no) ENABLE_MPI=0 ;; + *) as_fn_error $? "bad value ${enableval} for --enable-mpi" "$LINENO" 5 ;; +esac +fi + + +if test ${ENABLE_MPI} -eq 1; then + # Extract the first word of "mpicc", so it can be a program name with args. +set dummy mpicc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_MPICC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $MPICC in + [\\/]* | ?:[\\/]*) + ac_cv_path_MPICC="$MPICC" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_MPICC="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MPICC=$ac_cv_path_MPICC +if test -n "$MPICC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MPICC" >&5 +printf "%s\n" "$MPICC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + + if test "${MPICC}" != ""; then + MPI_CFLAGS=`${MPICC} -showme:compile` + MPI_LIBS=`${MPICC} -showme:link` + else + as_fn_error $? "mpicc not found, is MPI installed?" "$LINENO" 5 + fi +fi GWmodel_CUDA_LIB_PATH="~/.cache/GWmodel" @@ -3051,6 +3123,9 @@ printf "%s\n" "$as_me: Building Makevars" >&6;} + + + ac_config_files="$ac_config_files src/Makevars" if test -e penmp || test -e mp; then diff --git a/configure.ac b/configure.ac index 911bdb6..edc35ca 100644 --- a/configure.ac +++ b/configure.ac @@ -84,6 +84,24 @@ NVCC="${CUDA_HOME}/bin/nvcc" AC_MSG_RESULT(building the cuda include path) CUDA_INCL="${CUDA_HOME}/include" +ENABLE_MPI=1 +AC_ARG_ENABLE([mpi], [AS_HELP_STRING([--enable-mpi],[install mpi (default no)])], +[ case "${enableval}" in + yes) ENABLE_MPI=1 ;; + no) ENABLE_MPI=0 ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-mpi) ;; +esac]) + +if test ${ENABLE_MPI} -eq 1; then + AC_PATH_PROG([MPICC], [mpicc]) + + if test "${MPICC}" != ""; then + MPI_CFLAGS=`${MPICC} -showme:compile` + MPI_LIBS=`${MPICC} -showme:link` + else + AC_MSG_ERROR([mpicc not found, is MPI installed?]) + fi +fi AC_SUBST(GWmodel_CUDA_LIB_PATH,["~/.cache/GWmodel"]) @@ -94,6 +112,9 @@ AC_SUBST(NVCC) AC_SUBST(PKG_LIBS) AC_SUBST(CUDA_INCL) AC_SUBST(ENABLE_CUDA) +AC_SUBST(ENABLE_MPI) +AC_SUBST(MPI_CFLAGS) +AC_SUBST(MPI_LIBS) AC_CONFIG_FILES([src/Makevars]) AC_OPENMP diff --git a/src/Makevars.in b/src/Makevars.in index 17eacae..0f06a04 100644 --- a/src/Makevars.in +++ b/src/Makevars.in @@ -102,6 +102,16 @@ OBJECTS_CUDA_CXX = endif ### [End] +### [Begin] Configure MPI +ENABLE_MPI = @ENABLE_MPI@ +ifeq ($(ENABLE_MPI),1) +MPI_CFLAGS = @MPI_CFLAGS@ +MPI_LIBS = @MPI_LIBS@ +PKG_CXXFLAGS += ${MPI_CFLAGS} -DENABLE_MPI +PKG_LIBS += ${MPI_LIBS} +endif +### [End] + OBJECTS = ${OBJECTS_CUDA_CU} ${OBJECTS_CUDA_CXX} ${OBJECTS_CXX} .PHONY: all clean From 4cb963143c95075d4afaec62a59f8d279bbf6304 Mon Sep 17 00:00:00 2001 From: HPDell Date: Sun, 10 Dec 2023 18:23:19 +0000 Subject: [PATCH 02/20] add: MPI for basic GWR --- R/gwr_basic.R | 14 +++++++++++ R/utils.R | 6 +++-- src/gwr_basic.cpp | 51 ++++++++++++++++++++++++++++++++++---- src/libgwmodel | 2 +- src/utils.h | 17 +++++++++++++ tests/mpi/test-gwr_basic.R | 8 ++++++ 6 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 tests/mpi/test-gwr_basic.R diff --git a/R/gwr_basic.R b/R/gwr_basic.R index b5a48c2..05f4efb 100644 --- a/R/gwr_basic.R +++ b/R/gwr_basic.R @@ -67,6 +67,15 @@ gwr_basic <- function( kernel = match.arg(kernel) parallel_method = match.arg(parallel_method) attr(data, "na.action") <- getOption("na.action") + is_mpi_workers <- F + if (is.loaded("mpi_initialize")) { + if (requireNamespace("Rmpi", quietly = TRUE)) { + if (Rmpi::mpi.comm.size(0) > 1) { + parallel_method <- paste0("mpi.", parallel_method) + is_mpi_workers <- Rmpi::mpi.comm.rank(0) > 0 + } + } + } ### Extract coords data <- do.call(na.action(data), args = list(data)) @@ -116,6 +125,11 @@ gwr_basic <- function( ), error = function (e) { stop("Error:", conditionMessage(e)) }) + + if (is_mpi_workers) { + return(NULL) + } + if (optim_bw) bw <- c_result$bandwidth betas <- c_result$betas diff --git a/R/utils.R b/R/utils.R index 7aa335f..8570665 100644 --- a/R/utils.R +++ b/R/utils.R @@ -172,10 +172,12 @@ enum_list <- function(x, labels, default = labels[[1]]) { } parallel_types <- list( - "none" = 1, + "no" = 1, "omp" = 2, "cuda" = 4, - "cluster" = 8 + "mpi.no" = 9, + "mpi.omp" = 10, + "mpi.cuda" = 12 ) kernel_enums <- c("gaussian", "exp", "bisquare", "tricube", "boxcar") diff --git a/src/gwr_basic.cpp b/src/gwr_basic.cpp index ca61203..892e50a 100644 --- a/src/gwr_basic.cpp +++ b/src/gwr_basic.cpp @@ -8,6 +8,8 @@ #include "gwmodelcuda/IGWRBasicGpuTask.h" #endif // ENABLE_CUDA_SHARED +#include "mpi.h" + using namespace std; using namespace Rcpp; using namespace arma; @@ -80,6 +82,19 @@ int verbose } #endif // ENABLE_CUDA_SHARED + MYMPI_COMM_INFO_DECL +#ifdef ENABLE_MPI + if (parallel_type & ParallelType::MPI) + { + MYMPI_COMM_INFO_GET + } +#endif // ENABLE_MPI + + // Convert data types + mat mx = myas(x); + vec my = myas(y); + mat mcoords = myas(coords); + // Make Spatial Weight BandwidthWeight bandwidth(bw, adaptive, BandwidthWeight::KernelFunctionType((size_t)kernel)); Distance* distance = nullptr; @@ -110,21 +125,30 @@ int verbose algorithm.setGoldenLowerBounds(optim_bw_lower); if (optim_bw_upper < R_PosInf) algorithm.setGoldenUpperBounds(optim_bw_upper); - switch (ParallelType(size_t(parallel_type))) + algorithm.setParallelType(ParallelType(parallel_type)); + switch (algorithm.parallelType()) { case ParallelType::SerialOnly: - algorithm.setParallelType(ParallelType::SerialOnly); +#ifdef ENABLE_MPI + case ParallelType::MPI_Serial: +#endif // ENABLE_MPI break; -#ifdef _OPENMP case ParallelType::OpenMP: - algorithm.setParallelType(ParallelType::OpenMP); +#ifdef ENABLE_MPI + case ParallelType::MPI_MP: +#endif // ENABLE_MPI +#ifdef _OPENMP algorithm.setOmpThreadNum(vpar_args[0]); break; +#else + throw std::logic_error("OpenMP method not implemented."); #endif case ParallelType::CUDA: +#ifdef ENABLE_MPI + case ParallelType::MPI_CUDA: +#endif // ENABLE_MPI #ifdef ENABLE_CUDA if (vpar_args.size() < 2) throw std::length_error("CUDA parallelisation needs two parallel args."); - algorithm.setParallelType(ParallelType::CUDA); algorithm.setGPUId(vpar_args[0]); algorithm.setGroupSize(vpar_args[1]); #else // ENABLE_CUDA @@ -134,8 +158,18 @@ int verbose algorithm.setParallelType(ParallelType::SerialOnly); break; } +#ifdef ENABLE_MPI + if (algorithm.parallelType() & ParallelType::MPI) + { + Rcout << "MPI mode\n"; + algorithm.setWorkerId(iProcess); + algorithm.setWorkerNum(nProcess); + } +#endif // ENABLE_MPI + MYMPI_MASTER_BEGIN if (verbose) algorithm.setTelegram(make_unique(algorithm, as>(variable_names), verbose)); + MYMPI_MASTER_END try { algorithm.fit(); @@ -146,6 +180,9 @@ int verbose } // Return Results + List result_list; + + MYMPI_MASTER_BEGIN mat betas = algorithm.betas(); List result_list = List::create( Named("betas") = betas, @@ -171,6 +208,10 @@ int verbose { result_list["fitted"] = GWRBasic::Fitted(x, betas); } + MYMPI_MASTER_END + + if (parallel_type & ParallelType::MPI) + result_list["mpi_rank"] = iProcess; return result_list; } diff --git a/src/libgwmodel b/src/libgwmodel index 56b31b2..946247f 160000 --- a/src/libgwmodel +++ b/src/libgwmodel @@ -1 +1 @@ -Subproject commit 56b31b280ff044f7ad4d6a1e0604e6477e754607 +Subproject commit 946247f0973ab964ba181cbc144cd31f63231911 diff --git a/src/utils.h b/src/utils.h index e668844..37274da 100644 --- a/src/utils.h +++ b/src/utils.h @@ -5,3 +5,20 @@ Rcpp::List mywrap(const gwm::RegressionDiagnostic& diagnostic); Rcpp::List mywrap(const gwm::VariablesCriterionList& criterion_list); + +#define MYMPI_COMM_INFO_DECL \ + int iProcess = 0, nProcess = 1; + +#define MYMPI_COMM_INFO_GET \ + MPI_Comm_rank(MPI_COMM_WORLD, &iProcess); \ + MPI_Comm_size(MPI_COMM_WORLD, &nProcess); + +#define MYMPI_MASTER_BEGIN \ + if (iProcess == 0) { + +#define MYMPI_MASTER_END } + +#define MYMPI_WORKER_BEGIN \ + if (nProcess == 0) { + +#define MYMPI_WORKER_END } diff --git a/tests/mpi/test-gwr_basic.R b/tests/mpi/test-gwr_basic.R new file mode 100644 index 0000000..572f206 --- /dev/null +++ b/tests/mpi/test-gwr_basic.R @@ -0,0 +1,8 @@ +library(sf) +library(GWmodel3, lib.loc = "../../../Rlibrary.tmp") +library(Rmpi) +# data(LondonHP) +# gwr_basic(PURCHASE~FLOORSZ+UNEMPLOY, LondonHP, 64, TRUE, verbose = 2) +data(wuhan.hp, package = "hgwrr") +gwr_basic(Price ~ d.PrimarySchool + BuildingArea + Fee, wuhan.hp, bw = 512, adaptive = T, verbose = 2) +invisible(mpi.finalize()) \ No newline at end of file From 76d7be90ec6f8c14ce09a22425a09e63deb35f28 Mon Sep 17 00:00:00 2001 From: HPDell Date: Fri, 15 Dec 2023 12:40:35 +0000 Subject: [PATCH 03/20] add: MGWR mpi mode --- R/gwr_multiscale.R | 13 ++++++++++++ src/Makevars.in | 1 + src/gwr_basic.cpp | 3 ++- src/gwr_multiscale.cpp | 35 ++++++++++++++++++++++++++++----- tests/mpi/test-gwr_multiscale.R | 8 ++++++++ 5 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 tests/mpi/test-gwr_multiscale.R diff --git a/R/gwr_multiscale.R b/R/gwr_multiscale.R index 9b6b5e5..3fbbda5 100644 --- a/R/gwr_multiscale.R +++ b/R/gwr_multiscale.R @@ -115,6 +115,15 @@ gwr_multiscale <- function( parallel_method <- match.arg(parallel_method) criterion <- match.arg(criterion) attr(data, "na.action") <- getOption("na.action") + is_mpi_workers <- F + if (is.loaded("mpi_initialize")) { + if (requireNamespace("Rmpi", quietly = TRUE)) { + if (Rmpi::mpi.comm.size(0) > 1) { + parallel_method <- paste0("mpi.", parallel_method) + is_mpi_workers <- Rmpi::mpi.comm.rank(0) > 0 + } + } + } ### Extract coords data <- do.call(na.action(data), args = list(data)) @@ -216,6 +225,10 @@ gwr_multiscale <- function( ), error = function (e) { stop("Error:", conditionMessage(e)) }) + if (is_mpi_workers) { + return(NULL) + } + bw_value <- c_result$bw_value betas <- c_result$betas fitted <- c_result$fitted diff --git a/src/Makevars.in b/src/Makevars.in index 0f06a04..3f32023 100644 --- a/src/Makevars.in +++ b/src/Makevars.in @@ -109,6 +109,7 @@ MPI_CFLAGS = @MPI_CFLAGS@ MPI_LIBS = @MPI_LIBS@ PKG_CXXFLAGS += ${MPI_CFLAGS} -DENABLE_MPI PKG_LIBS += ${MPI_LIBS} +OBJECTS_CXX += libgwmodel/src/gwmodelpp/utils/armampi.o endif ### [End] diff --git a/src/gwr_basic.cpp b/src/gwr_basic.cpp index 892e50a..6dba404 100644 --- a/src/gwr_basic.cpp +++ b/src/gwr_basic.cpp @@ -8,7 +8,9 @@ #include "gwmodelcuda/IGWRBasicGpuTask.h" #endif // ENABLE_CUDA_SHARED +#ifdef ENABLE_MPI #include "mpi.h" +#endif // ENABLE_MPI using namespace std; using namespace Rcpp; @@ -155,7 +157,6 @@ int verbose throw std::logic_error("Method not implemented."); #endif // ENABLE_CUDA default: - algorithm.setParallelType(ParallelType::SerialOnly); break; } #ifdef ENABLE_MPI diff --git a/src/gwr_multiscale.cpp b/src/gwr_multiscale.cpp index 0354b9c..45ce92c 100644 --- a/src/gwr_multiscale.cpp +++ b/src/gwr_multiscale.cpp @@ -4,6 +4,10 @@ #include "gwmodel.h" #include "telegrams/GWRMultiscaleTelegram.h" +#ifdef ENABLE_MPI +#include +#endif // ENABLE_MPI + using namespace std; using namespace Rcpp; using namespace arma; @@ -91,25 +95,39 @@ List gwr_multiscale_fit ( algorithm.setHasHatMatrix(hatmatrix); algorithm.setBandwidthSelectRetryTimes(retry_times); algorithm.setMaxIteration(max_iterations); + algorithm.setParallelType(ParallelType(parallel_type)); switch (ParallelType(size_t(parallel_type))) { - case ParallelType::SerialOnly: - algorithm.setParallelType(ParallelType::SerialOnly); - break; -#ifdef _OPENMP case ParallelType::OpenMP: +#ifdef ENABLE_MPI + case ParallelType::MPI_MP: +#endif // ENABLE_MPI +#ifdef _OPENMP algorithm.setParallelType(ParallelType::OpenMP); algorithm.setOmpThreadNum(vpar_args[0]); break; +#else + throw std::logic_error("OpenMP method not implemented."); #endif default: - algorithm.setParallelType(ParallelType::SerialOnly); break; } +#ifdef ENABLE_MPI + if (algorithm.parallelType() & ParallelType::MPI) + { + Rcout << "MPI mode\n"; + algorithm.setWorkerId(iProcess); + algorithm.setWorkerNum(nProcess); + } +#endif // ENABLE_MPI + + MYMPI_MASTER_BEGIN if (verbose > 0) { algorithm.setTelegram(make_unique(algorithm, as>(variable_names), verbose)); } + MYMPI_MASTER_END + try { algorithm.fit(); @@ -118,7 +136,10 @@ List gwr_multiscale_fit ( { stop(e.what()); } + + List result_list; + MYMPI_MASTER_BEGIN // Get bandwidth vector bw_value; const vector& spatialWeights = algorithm.spatialWeights(); @@ -136,6 +157,10 @@ List gwr_multiscale_fit ( Named("bw_value") = wrap(bw_value), Named("fitted") = fitted ); + MYMPI_MASTER_END + + if (parallel_type & ParallelType::MPI) + result_list["mpi_rank"] = iProcess; return result_list; } diff --git a/tests/mpi/test-gwr_multiscale.R b/tests/mpi/test-gwr_multiscale.R new file mode 100644 index 0000000..d11f4e9 --- /dev/null +++ b/tests/mpi/test-gwr_multiscale.R @@ -0,0 +1,8 @@ +library(sf) +library(GWmodel3, lib.loc = "../../../Rlibrary.tmp") +library(Rmpi) +# data(LondonHP) +# gwr_basic(PURCHASE~FLOORSZ+UNEMPLOY, LondonHP, 64, TRUE, verbose = 2) +data(wuhan.hp, package = "hgwrr") +gwr_multiscale(Price ~ d.PrimarySchool + BuildingArea + Fee, wuhan.hp) +invisible(mpi.finalize()) \ No newline at end of file From 8202e301050695cd2964eda6ffe686c333655b26 Mon Sep 17 00:00:00 2001 From: HPDell Date: Mon, 18 Dec 2023 15:37:15 +0000 Subject: [PATCH 04/20] edit: git ignore .log and .out for testing --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index f7fcd1b..96e8e71 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,5 @@ docs /doc/ /Meta/ *.lib +*.log +*.out From 5de585611fdc5f46563cf401fff60020b5b2f611 Mon Sep 17 00:00:00 2001 From: HPDell Date: Mon, 18 Dec 2023 15:45:09 +0000 Subject: [PATCH 05/20] edit: golden bounds --- tests/mpi/test-gwr_basic.R | 2 +- tests/mpi/test-gwr_multiscale.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/mpi/test-gwr_basic.R b/tests/mpi/test-gwr_basic.R index 572f206..7dabe5c 100644 --- a/tests/mpi/test-gwr_basic.R +++ b/tests/mpi/test-gwr_basic.R @@ -4,5 +4,5 @@ library(Rmpi) # data(LondonHP) # gwr_basic(PURCHASE~FLOORSZ+UNEMPLOY, LondonHP, 64, TRUE, verbose = 2) data(wuhan.hp, package = "hgwrr") -gwr_basic(Price ~ d.PrimarySchool + BuildingArea + Fee, wuhan.hp, bw = 512, adaptive = T, verbose = 2) +gwr_basic(Price ~ d.PrimarySchool + BuildingArea + Fee, wuhan.hp, bw = 512, adaptive = T, verbose = 2, optim_bw_range = c(256, Inf)) invisible(mpi.finalize()) \ No newline at end of file diff --git a/tests/mpi/test-gwr_multiscale.R b/tests/mpi/test-gwr_multiscale.R index d11f4e9..40597f7 100644 --- a/tests/mpi/test-gwr_multiscale.R +++ b/tests/mpi/test-gwr_multiscale.R @@ -4,5 +4,5 @@ library(Rmpi) # data(LondonHP) # gwr_basic(PURCHASE~FLOORSZ+UNEMPLOY, LondonHP, 64, TRUE, verbose = 2) data(wuhan.hp, package = "hgwrr") -gwr_multiscale(Price ~ d.PrimarySchool + BuildingArea + Fee, wuhan.hp) +gwr_multiscale(Price ~ d.PrimarySchool + BuildingArea + Fee, wuhan.hp, config = list(mgwr_config(adaptive = T)), optim_bw_range = c(256, Inf)) invisible(mpi.finalize()) \ No newline at end of file From 0a59c5f1234a69a32e3ecd80edd7f36239865fcb Mon Sep 17 00:00:00 2001 From: HPDell Date: Fri, 12 Jul 2024 15:08:53 +0100 Subject: [PATCH 06/20] add: MPI config in Markvars.win --- src/Makevars.win | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Makevars.win b/src/Makevars.win index 32f2be8..fcaf941 100644 --- a/src/Makevars.win +++ b/src/Makevars.win @@ -78,5 +78,11 @@ endif endif ### [End] +### [Begin] Configure MPI +PKG_CXXFLAGS += -DENABLE_MPI +PKG_LIBS += -lmsmpi +OBJECTS_LIBGWMODEL += libgwmodel/src/gwmodelpp/utils/armampi.o +### [End] + OBJECTS = $(OBJECTS_LIBGWMODEL) $(OBJECTS_TELEGRAM) $(OBJECTS_GWMODEL) From 7b9238c3ce28c9d5a610706c08a74a193ccf842f Mon Sep 17 00:00:00 2001 From: HPDell Date: Sat, 13 Jul 2024 12:49:06 +0100 Subject: [PATCH 07/20] fix: merge errors --- src/gwr_basic.cpp | 7 +------ src/gwr_multiscale.cpp | 6 +++++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/gwr_basic.cpp b/src/gwr_basic.cpp index 6dba404..0a67bac 100644 --- a/src/gwr_basic.cpp +++ b/src/gwr_basic.cpp @@ -92,11 +92,6 @@ int verbose } #endif // ENABLE_MPI - // Convert data types - mat mx = myas(x); - vec my = myas(y); - mat mcoords = myas(coords); - // Make Spatial Weight BandwidthWeight bandwidth(bw, adaptive, BandwidthWeight::KernelFunctionType((size_t)kernel)); Distance* distance = nullptr; @@ -185,7 +180,7 @@ int verbose MYMPI_MASTER_BEGIN mat betas = algorithm.betas(); - List result_list = List::create( + result_list = List::create( Named("betas") = betas, Named("betasSE") = algorithm.betasSE(), Named("sTrace") = algorithm.sHat(), diff --git a/src/gwr_multiscale.cpp b/src/gwr_multiscale.cpp index 45ce92c..fb6f125 100644 --- a/src/gwr_multiscale.cpp +++ b/src/gwr_multiscale.cpp @@ -112,6 +112,8 @@ List gwr_multiscale_fit ( default: break; } + + MYMPI_COMM_INFO_DECL #ifdef ENABLE_MPI if (algorithm.parallelType() & ParallelType::MPI) { @@ -151,7 +153,7 @@ List gwr_multiscale_fit ( // Return Results mat betas = algorithm.betas(); vec fitted = sum(x % betas, 1); - List result_list = List::create( + result_list = List::create( Named("betas") = betas, Named("diagnostic") = mywrap(algorithm.diagnostic()), Named("bw_value") = wrap(bw_value), @@ -159,8 +161,10 @@ List gwr_multiscale_fit ( ); MYMPI_MASTER_END +#ifdef ENABLE_MPI if (parallel_type & ParallelType::MPI) result_list["mpi_rank"] = iProcess; +#endif // ENABLE_MPI return result_list; } From 81be6a12ca29300a91e62d6b53ce6621c5c41de8 Mon Sep 17 00:00:00 2001 From: HPDell Date: Sun, 14 Jul 2024 11:53:35 +0100 Subject: [PATCH 08/20] fix: set MPI communication info --- src/gwr_multiscale.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gwr_multiscale.cpp b/src/gwr_multiscale.cpp index fb6f125..0c3c800 100644 --- a/src/gwr_multiscale.cpp +++ b/src/gwr_multiscale.cpp @@ -117,7 +117,8 @@ List gwr_multiscale_fit ( #ifdef ENABLE_MPI if (algorithm.parallelType() & ParallelType::MPI) { - Rcout << "MPI mode\n"; + if (verbose > 0) Rcout << "* MPI mode\n"; + MYMPI_COMM_INFO_GET algorithm.setWorkerId(iProcess); algorithm.setWorkerNum(nProcess); } From 0d2df9dc51974b72011a17ce14cb2632b3cf023b Mon Sep 17 00:00:00 2001 From: HPDell Date: Sun, 14 Jul 2024 11:57:05 +0100 Subject: [PATCH 09/20] fix: type mismatch --- src/libgwmodel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libgwmodel b/src/libgwmodel index 946247f..627f44b 160000 --- a/src/libgwmodel +++ b/src/libgwmodel @@ -1 +1 @@ -Subproject commit 946247f0973ab964ba181cbc144cd31f63231911 +Subproject commit 627f44b867e9639d29fe78189035da5965c70fee From c40dd29107a1c2e8030a98241ae17c13e3074056 Mon Sep 17 00:00:00 2001 From: HPDell Date: Sun, 14 Jul 2024 12:06:27 +0100 Subject: [PATCH 10/20] edit: only print MPI mode in the root process --- src/gwr_multiscale.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gwr_multiscale.cpp b/src/gwr_multiscale.cpp index 0c3c800..63485a2 100644 --- a/src/gwr_multiscale.cpp +++ b/src/gwr_multiscale.cpp @@ -117,10 +117,12 @@ List gwr_multiscale_fit ( #ifdef ENABLE_MPI if (algorithm.parallelType() & ParallelType::MPI) { - if (verbose > 0) Rcout << "* MPI mode\n"; MYMPI_COMM_INFO_GET algorithm.setWorkerId(iProcess); algorithm.setWorkerNum(nProcess); + MYMPI_MASTER_BEGIN + Rcout << "* MPI mode\n"; + MYMPI_MASTER_END } #endif // ENABLE_MPI From 81e1e3d9e8612b0771387de7ae01ab23fbfc7762 Mon Sep 17 00:00:00 2001 From: HPDell Date: Sun, 14 Jul 2024 15:17:53 +0100 Subject: [PATCH 11/20] fix: MPI type error - Use GWM_MPI_UWORD to represent uword in difference conditions - Use int to swap status between processes --- src/libgwmodel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libgwmodel b/src/libgwmodel index 627f44b..45e0037 160000 --- a/src/libgwmodel +++ b/src/libgwmodel @@ -1 +1 @@ -Subproject commit 627f44b867e9639d29fe78189035da5965c70fee +Subproject commit 45e00377f4a56e1c21907a6ddd84be5cd4cfe257 From 7f6549d77ce42d30a3813b1cd2316b64c7c36a8d Mon Sep 17 00:00:00 2001 From: HPDell Date: Mon, 22 Jul 2024 15:14:56 +0100 Subject: [PATCH 12/20] edit(submod): switch to version v0.10.0 --- src/libgwmodel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libgwmodel b/src/libgwmodel index 45e0037..00110f7 160000 --- a/src/libgwmodel +++ b/src/libgwmodel @@ -1 +1 @@ -Subproject commit 45e00377f4a56e1c21907a6ddd84be5cd4cfe257 +Subproject commit 00110f7733765749c825c709cca4fed31f8397ec From ebf93a17034f05418116c878419fe42df47b74b8 Mon Sep 17 00:00:00 2001 From: HPDell Date: Mon, 22 Jul 2024 15:29:31 +0100 Subject: [PATCH 13/20] edit(DESCRIPTION): include Rmpi in Suggests --- DESCRIPTION | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index ae8fe41..0bbdf90 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -47,6 +47,7 @@ RoxygenNote: 7.2.3 Suggests: testthat (>= 3.0.0), knitr, - rmarkdown + rmarkdown, + Rmpi Config/testthat/edition: 3 VignetteBuilder: knitr From 7ac5eb390d6f0d749c11ca87dd5ac52e4ff4b324 Mon Sep 17 00:00:00 2001 From: HPDell Date: Mon, 22 Jul 2024 15:37:01 +0100 Subject: [PATCH 14/20] edit(tests): rearrange test folder --- .Rbuildignore | 1 + tests/others/cuda-gwr_basic.R | 5 +++++ tests/{mpi/test-gwr_basic.R => others/mpi-gwr_basic.R} | 0 .../test-gwr_multiscale.R => others/mpi-gwr_multiscale.R} | 0 tests/testthat/test-gwr_basic.R | 7 +------ 5 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 tests/others/cuda-gwr_basic.R rename tests/{mpi/test-gwr_basic.R => others/mpi-gwr_basic.R} (100%) rename tests/{mpi/test-gwr_multiscale.R => others/mpi-gwr_multiscale.R} (100%) diff --git a/.Rbuildignore b/.Rbuildignore index 3983c2b..d910125 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -9,6 +9,7 @@ src/libgwmodel/Doxygen\.zh-Hans src/libgwmodel/\.readthedocs\.yaml src/libgwmodel/test src/libgwmodel/docs +tests/others ^_pkgdown\.yml$ ^docs$ ^pkgdown$ diff --git a/tests/others/cuda-gwr_basic.R b/tests/others/cuda-gwr_basic.R new file mode 100644 index 0000000..d325da6 --- /dev/null +++ b/tests/others/cuda-gwr_basic.R @@ -0,0 +1,5 @@ +library(sf) +library(GWmodel3, lib.loc = "../../../Rlibrary.tmp") +data(wuhan.hp, package = "hgwrr") +whhp <- with(wuhan.hp, sf::st_as_sf(data, coords = c("lon", "lat"))) +gwr_basic(Price ~ d.PrimarySchool + BuildingArea + Fee, whhp, bw = 64, parallel_method = "cuda", parallel_arg = c(0, 64)) \ No newline at end of file diff --git a/tests/mpi/test-gwr_basic.R b/tests/others/mpi-gwr_basic.R similarity index 100% rename from tests/mpi/test-gwr_basic.R rename to tests/others/mpi-gwr_basic.R diff --git a/tests/mpi/test-gwr_multiscale.R b/tests/others/mpi-gwr_multiscale.R similarity index 100% rename from tests/mpi/test-gwr_multiscale.R rename to tests/others/mpi-gwr_multiscale.R diff --git a/tests/testthat/test-gwr_basic.R b/tests/testthat/test-gwr_basic.R index 1e9439d..d5213e9 100644 --- a/tests/testthat/test-gwr_basic.R +++ b/tests/testthat/test-gwr_basic.R @@ -67,15 +67,10 @@ test_that("Basic GWR: CUDA", { test_that("Basic GWR: CUDA for Windows development", { skip("This test case is only used for development on Windows") - library(GWmodel3, lib.loc = "../Rlibrary.tmp") + library(GWmodel3, lib.loc = "../../../Rlibrary.tmp") data(LondonHP) expect_no_error({ m_cuda <- gwr_basic(PURCHASE~FLOORSZ+UNEMPLOY, LondonHP, 64, TRUE, parallel_method = "cuda", parallel_arg = c(0, 64), verbose = 1) predict(m_cuda, LondonHP, verbose = 1) }) - expect_no_error({ - data(wuhan.hp, package = "hgwrr") - whhp <- with(wuhan.hp, sf::st_as_sf(data, coords = c("lon", "lat"))) - gwr_basic(Price ~ d.PrimarySchool + BuildingArea + Fee, whhp, bw = 64, parallel_method = "cuda", parallel_arg = c(0, 64)) - }) }) From 10a1bec2bbb63a99b4c76844085a2dd4f0b092d2 Mon Sep 17 00:00:00 2001 From: HPDell Date: Mon, 22 Jul 2024 16:28:24 +0100 Subject: [PATCH 15/20] edit: hide MPI by default --- configure | 517 +++++++++++++++++++++++++---------------------- configure.ac | 2 +- src/Makevars.win | 3 + 3 files changed, 277 insertions(+), 245 deletions(-) diff --git a/configure b/configure index 27a887e..b3062d9 100755 --- a/configure +++ b/configure @@ -1,9 +1,9 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for GWmodel3 0.2-2. +# Generated by GNU Autoconf 2.72 for GWmodel3 0.2-2. # # -# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, +# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation, # Inc. # # @@ -15,7 +15,6 @@ # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh @@ -24,12 +23,13 @@ then : # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else $as_nop - case `(set -o) 2>/dev/null` in #( +else case e in #( + e) case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; +esac ;; esac fi @@ -101,7 +101,7 @@ IFS=$as_save_IFS ;; esac -# We did not find ourselves, most probably we were run as `sh COMMAND' +# We did not find ourselves, most probably we were run as 'sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 @@ -131,15 +131,14 @@ case $- in # (((( esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. +# out after a failed 'exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="as_nop=: -if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 + as_bourne_compatible="if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: @@ -147,12 +146,13 @@ then : # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST -else \$as_nop - case \`(set -o) 2>/dev/null\` in #( +else case e in #( + e) case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; +esac ;; esac fi " @@ -170,8 +170,9 @@ as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : -else \$as_nop - exitcode=1; echo positional parameters were not saved. +else case e in #( + e) exitcode=1; echo positional parameters were not saved. ;; +esac fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) @@ -184,14 +185,15 @@ test -x / || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes -else $as_nop - as_have_required=no +else case e in #( + e) as_have_required=no ;; +esac fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : -else $as_nop - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do @@ -224,12 +226,13 @@ IFS=$as_save_IFS if $as_found then : -else $as_nop - if { test -f "$SHELL" || test -f "$SHELL.exe"; } && +else case e in #( + e) if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes -fi +fi ;; +esac fi @@ -251,7 +254,7 @@ case $- in # (((( esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. +# out after a failed 'exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi @@ -270,7 +273,8 @@ $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 -fi +fi ;; +esac fi fi SHELL=${CONFIG_SHELL-/bin/sh} @@ -309,14 +313,6 @@ as_fn_exit () as_fn_set_status $1 exit $1 } # as_fn_exit -# as_fn_nop -# --------- -# Do nothing but, unlike ":", preserve the value of $?. -as_fn_nop () -{ - return $? -} -as_nop=as_fn_nop # as_fn_mkdir_p # ------------- @@ -385,11 +381,12 @@ then : { eval $1+=\$2 }' -else $as_nop - as_fn_append () +else case e in #( + e) as_fn_append () { eval $1=\$$1\$2 - } + } ;; +esac fi # as_fn_append # as_fn_arith ARG... @@ -403,21 +400,14 @@ then : { as_val=$(( $* )) }' -else $as_nop - as_fn_arith () +else case e in #( + e) as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` - } + } ;; +esac fi # as_fn_arith -# as_fn_nop -# --------- -# Do nothing but, unlike ":", preserve the value of $?. -as_fn_nop () -{ - return $? -} -as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- @@ -491,6 +481,8 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits /[$]LINENO/= ' <$as_myself | sed ' + t clear + :clear s/[$]LINENO.*/&-/ t lineno b @@ -539,7 +531,6 @@ esac as_echo='printf %s\n' as_echo_n='printf %s' - rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file @@ -551,9 +542,9 @@ if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. + # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. + # In both cases, we have to default to 'cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then @@ -578,10 +569,12 @@ as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated # Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated test -n "$DJDIR" || exec 7<&0 /dev/null && - as_fn_error $? "invalid feature name: \`$ac_useropt'" + as_fn_error $? "invalid feature name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -830,7 +823,7 @@ do ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: \`$ac_useropt'" + as_fn_error $? "invalid feature name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1043,7 +1036,7 @@ do ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: \`$ac_useropt'" + as_fn_error $? "invalid package name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1059,7 +1052,7 @@ do ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: \`$ac_useropt'" + as_fn_error $? "invalid package name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1089,8 +1082,8 @@ do | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" + -*) as_fn_error $? "unrecognized option: '$ac_option' +Try '$0 --help' for more information" ;; *=*) @@ -1098,7 +1091,7 @@ Try \`$0 --help' for more information" # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + as_fn_error $? "invalid variable name: '$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; @@ -1148,7 +1141,7 @@ do as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done -# There might be people who depend on the old broken behavior: `$host' +# There might be people who depend on the old broken behavior: '$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias @@ -1216,7 +1209,7 @@ if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_msg="sources are in $srcdir, but 'cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` @@ -1244,7 +1237,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures GWmodel3 0.2-2 to adapt to many kinds of systems. +'configure' configures GWmodel3 0.2-2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1258,11 +1251,11 @@ Configuration: --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages + -q, --quiet, --silent do not print 'checking ...' messages --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' + -C, --config-cache alias for '--cache-file=config.cache' -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] + --srcdir=DIR find the sources in DIR [configure dir or '..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX @@ -1270,10 +1263,10 @@ Installation directories: --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. +By default, 'make install' will install all the files in +'$ac_default_prefix/bin', '$ac_default_prefix/lib' etc. You can specify +an installation prefix other than '$ac_default_prefix' using '--prefix', +for instance '--prefix=\$HOME'. For better control, use the options below. @@ -1328,7 +1321,7 @@ Some influential environment variables: you have headers in a nonstandard directory CXXCPP C++ preprocessor -Use these variables to override the choices made by `configure' or to help +Use these variables to override the choices made by 'configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. @@ -1396,9 +1389,9 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF GWmodel3 configure 0.2-2 -generated by GNU Autoconf 2.71 +generated by GNU Autoconf 2.72 -Copyright (C) 2021 Free Software Foundation, Inc. +Copyright (C) 2023 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1437,11 +1430,12 @@ printf "%s\n" "$ac_try_echo"; } >&5 } && test -s conftest.$ac_objext then : ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_retval=1 + ac_retval=1 ;; +esac fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval @@ -1475,11 +1469,12 @@ printf "%s\n" "$ac_try_echo"; } >&5 } then : ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_retval=1 + ac_retval=1 ;; +esac fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval @@ -1517,11 +1512,12 @@ printf "%s\n" "$ac_try_echo"; } >&5 } then : ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_retval=1 + ac_retval=1 ;; +esac fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would @@ -1557,7 +1553,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by GWmodel3 $as_me 0.2-2, which was -generated by GNU Autoconf 2.71. Invocation command line was +generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -1803,10 +1799,10 @@ esac printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ - || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } fi done @@ -2053,12 +2049,12 @@ for ac_var in $ac_precious_vars; do eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: '$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) @@ -2067,18 +2063,18 @@ printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: '$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: '$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: '$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: '$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: '$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. @@ -2094,11 +2090,11 @@ printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi done if $ac_cache_corrupted; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' + as_fn_error $? "run '${MAKE-make} distclean' and/or 'rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## @@ -2144,8 +2140,8 @@ printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CXX+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CXX"; then +else case e in #( + e) if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2167,7 +2163,8 @@ done done IFS=$as_save_IFS -fi +fi ;; +esac fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then @@ -2193,8 +2190,8 @@ printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CXX+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CXX"; then +else case e in #( + e) if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2216,7 +2213,8 @@ done done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then @@ -2316,8 +2314,8 @@ printf "%s\n" "$ac_try_echo"; } >&5 printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' + # Autoconf-2.13 could set the ac_cv_exeext variable to 'no'. +# So ignore a value of 'no', otherwise this would lead to 'EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. @@ -2337,7 +2335,7 @@ do ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' + # safe: cross compilers may not add the suffix if given an '-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. @@ -2348,8 +2346,9 @@ do done test "$ac_cv_exeext" = no && ac_cv_exeext= -else $as_nop - ac_file='' +else case e in #( + e) ac_file='' ;; +esac fi if test -z "$ac_file" then : @@ -2358,13 +2357,14 @@ printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error 77 "C++ compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } +See 'config.log' for more details" "$LINENO" 5; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 printf %s "checking for C++ compiler default output file name... " >&6; } @@ -2388,10 +2388,10 @@ printf "%s\n" "$ac_try_echo"; } >&5 printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. + # If both 'conftest.exe' and 'conftest' are 'present' (well, observable) +# catch 'conftest.exe'. For instance with Cygwin, 'ls conftest' will +# work properly (i.e., refer to 'conftest.exe'), while it won't with +# 'rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in @@ -2401,11 +2401,12 @@ for ac_file in conftest.exe conftest conftest.*; do * ) break;; esac done -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -2421,6 +2422,8 @@ int main (void) { FILE *f = fopen ("conftest.out", "w"); + if (!f) + return 1; return ferror (f) || fclose (f) != 0; ; @@ -2460,26 +2463,27 @@ printf "%s\n" "$ac_try_echo"; } >&5 if test "$cross_compiling" = maybe; then cross_compiling=yes else - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error 77 "cannot run C++ compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } +If you meant to cross compile, use '--host'. +See 'config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +rm -f conftest.$ac_ext conftest$ac_cv_exeext \ + conftest.o conftest.obj conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -2511,16 +2515,18 @@ then : break;; esac done -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext +rm -f conftest.$ac_cv_objext conftest.$ac_ext ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } @@ -2531,8 +2537,8 @@ printf %s "checking whether the compiler supports GNU C++... " >&6; } if test ${ac_cv_cxx_compiler_gnu+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -2549,12 +2555,14 @@ _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_compiler_gnu=yes -else $as_nop - ac_compiler_gnu=no +else case e in #( + e) ac_compiler_gnu=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } @@ -2572,8 +2580,8 @@ printf %s "checking whether $CXX accepts -g... " >&6; } if test ${ac_cv_prog_cxx_g+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_save_cxx_werror_flag=$ac_cxx_werror_flag +else case e in #( + e) ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" @@ -2591,8 +2599,8 @@ _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes -else $as_nop - CXXFLAGS="" +else case e in #( + e) CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -2607,8 +2615,8 @@ _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : -else $as_nop - ac_cxx_werror_flag=$ac_save_cxx_werror_flag +else case e in #( + e) ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -2625,12 +2633,15 @@ if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - ac_cxx_werror_flag=$ac_save_cxx_werror_flag + ac_cxx_werror_flag=$ac_save_cxx_werror_flag ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } @@ -2654,11 +2665,11 @@ if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 printf %s "checking for $CXX option to enable C++11 features... " >&6; } -if test ${ac_cv_prog_cxx_11+y} +if test ${ac_cv_prog_cxx_cxx11+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cxx_11=no +else case e in #( + e) ac_cv_prog_cxx_cxx11=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -2675,36 +2686,39 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx11" != "xno" && break done rm -f conftest.$ac_ext -CXX=$ac_save_CXX +CXX=$ac_save_CXX ;; +esac fi if test "x$ac_cv_prog_cxx_cxx11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cxx_cxx11" = x +else case e in #( + e) if test "x$ac_cv_prog_cxx_cxx11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } - CXX="$CXX $ac_cv_prog_cxx_cxx11" + CXX="$CXX $ac_cv_prog_cxx_cxx11" ;; +esac fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 - ac_prog_cxx_stdcxx=cxx11 + ac_prog_cxx_stdcxx=cxx11 ;; +esac fi fi if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 printf %s "checking for $CXX option to enable C++98 features... " >&6; } -if test ${ac_cv_prog_cxx_98+y} +if test ${ac_cv_prog_cxx_cxx98+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cxx_98=no +else case e in #( + e) ac_cv_prog_cxx_cxx98=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -2721,25 +2735,28 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx98" != "xno" && break done rm -f conftest.$ac_ext -CXX=$ac_save_CXX +CXX=$ac_save_CXX ;; +esac fi if test "x$ac_cv_prog_cxx_cxx98" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cxx_cxx98" = x +else case e in #( + e) if test "x$ac_cv_prog_cxx_cxx98" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } - CXX="$CXX $ac_cv_prog_cxx_cxx98" + CXX="$CXX $ac_cv_prog_cxx_cxx98" ;; +esac fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 - ac_prog_cxx_stdcxx=cxx98 + ac_prog_cxx_stdcxx=cxx98 ;; +esac fi fi @@ -2761,8 +2778,8 @@ if test -z "$CXXCPP"; then if test ${ac_cv_prog_CXXCPP+y} then : printf %s "(cached) " >&6 -else $as_nop - # Double quotes because $CXX needs to be expanded +else case e in #( + e) # Double quotes because $CXX needs to be expanded for CXXCPP in "$CXX -E" cpp /lib/cpp do ac_preproc_ok=false @@ -2780,9 +2797,10 @@ _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : -else $as_nop - # Broken: fails on valid input. -continue +else case e in #( + e) # Broken: fails on valid input. +continue ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext @@ -2796,15 +2814,16 @@ if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue -else $as_nop - # Passes both tests. +else case e in #( + e) # Passes both tests. ac_preproc_ok=: -break +break ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : @@ -2813,7 +2832,8 @@ fi done ac_cv_prog_CXXCPP=$CXXCPP - + ;; +esac fi CXXCPP=$ac_cv_prog_CXXCPP else @@ -2836,9 +2856,10 @@ _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : -else $as_nop - # Broken: fails on valid input. -continue +else case e in #( + e) # Broken: fails on valid input. +continue ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext @@ -2852,24 +2873,26 @@ if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue -else $as_nop - # Passes both tests. +else case e in #( + e) # Passes both tests. ac_preproc_ok=: -break +break ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi ac_ext=cpp @@ -2888,8 +2911,8 @@ printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_GSL_CONFIG+y} then : printf %s "(cached) " >&6 -else $as_nop - case $GSL_CONFIG in +else case e in #( + e) case $GSL_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_GSL_CONFIG="$GSL_CONFIG" # Let the user override the test with a path. ;; @@ -2914,6 +2937,7 @@ done IFS=$as_save_IFS ;; +esac ;; esac fi GSL_CONFIG=$ac_cv_path_GSL_CONFIG @@ -2972,20 +2996,21 @@ printf "%s\n" "\"using CUDA_HOME=${CUDA_HOME}\"" >&6; } if test ${ENABLE_CUDA} -eq 1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking \"whether this is the 64 bit linux version of CUDA\"" >&5 printf %s "checking \"whether this is the 64 bit linux version of CUDA\"... " >&6; } - as_ac_File=`printf "%s\n" "ac_cv_file_${CUDA_HOME}/lib64/libcudart.so" | $as_tr_sh` + as_ac_File=`printf "%s\n" "ac_cv_file_${CUDA_HOME}/lib64/libcudart.so" | sed "$as_sed_sh"` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${CUDA_HOME}/lib64/libcudart.so" >&5 printf %s "checking for ${CUDA_HOME}/lib64/libcudart.so... " >&6; } if eval test \${$as_ac_File+y} then : printf %s "(cached) " >&6 -else $as_nop - test "$cross_compiling" = yes && +else case e in #( + e) test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "${CUDA_HOME}/lib64/libcudart.so"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" -fi +fi ;; +esac fi eval ac_res=\$$as_ac_File { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 @@ -3044,7 +3069,7 @@ NVCC="${CUDA_HOME}/bin/nvcc" printf "%s\n" "building the cuda include path" >&6; } CUDA_INCL="${CUDA_HOME}/include" -ENABLE_MPI=1 +ENABLE_MPI=0 # Check whether --enable-mpi was given. if test ${enable_mpi+y} then : @@ -3064,8 +3089,8 @@ printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_MPICC+y} then : printf %s "(cached) " >&6 -else $as_nop - case $MPICC in +else case e in #( + e) case $MPICC in [\\/]* | ?:[\\/]*) ac_cv_path_MPICC="$MPICC" # Let the user override the test with a path. ;; @@ -3090,6 +3115,7 @@ done IFS=$as_save_IFS ;; +esac ;; esac fi MPICC=$ac_cv_path_MPICC @@ -3144,8 +3170,8 @@ printf %s "checking for $CXX option to support OpenMP... " >&6; } if test ${ac_cv_prog_cxx_openmp+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cxx_openmp='not found' +else case e in #( + e) ac_cv_prog_cxx_openmp='not found' for ac_option in '' -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp -homp \ -Popenmp --openmp; do @@ -3176,8 +3202,9 @@ _ACEOF if ac_fn_cxx_try_link "$LINENO" then : ac_cv_prog_cxx_openmp=$ac_option -else $as_nop - ac_cv_prog_cxx_openmp='unsupported' +else case e in #( + e) ac_cv_prog_cxx_openmp='unsupported' ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext @@ -3194,7 +3221,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext elif test "$ac_cv_prog_cxx_openmp" = ''; then ac_cv_prog_cxx_openmp='none needed' fi - rm -f penmp mp + rm -f penmp mp ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_openmp" >&5 printf "%s\n" "$ac_cv_prog_cxx_openmp" >&6; } @@ -3215,8 +3243,8 @@ cat >confcache <<\_ACEOF # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the +# 'ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* 'ac_cv_foo' will be assigned the # following values. _ACEOF @@ -3246,14 +3274,14 @@ printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote + # 'set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) - # `set' quotes correctly as required by POSIX, so do not add quotes. + # 'set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | @@ -3317,9 +3345,7 @@ s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote -s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g -s/\[/\\&/g -s/\]/\\&/g +s/[][ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\$/$$/g H :any @@ -3379,7 +3405,6 @@ cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh @@ -3388,12 +3413,13 @@ then : # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else $as_nop - case `(set -o) 2>/dev/null` in #( +else case e in #( + e) case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; +esac ;; esac fi @@ -3465,7 +3491,7 @@ IFS=$as_save_IFS ;; esac -# We did not find ourselves, most probably we were run as `sh COMMAND' +# We did not find ourselves, most probably we were run as 'sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 @@ -3494,7 +3520,6 @@ as_fn_error () } # as_fn_error - # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. @@ -3534,11 +3559,12 @@ then : { eval $1+=\$2 }' -else $as_nop - as_fn_append () +else case e in #( + e) as_fn_append () { eval $1=\$$1\$2 - } + } ;; +esac fi # as_fn_append # as_fn_arith ARG... @@ -3552,11 +3578,12 @@ then : { as_val=$(( $* )) }' -else $as_nop - as_fn_arith () +else case e in #( + e) as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` - } + } ;; +esac fi # as_fn_arith @@ -3639,9 +3666,9 @@ if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. + # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. + # In both cases, we have to default to 'cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then @@ -3722,10 +3749,12 @@ as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated # Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated exec 6>&1 @@ -3741,7 +3770,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by GWmodel3 $as_me 0.2-2, which was -generated by GNU Autoconf 2.71. Invocation command line was +generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -3768,7 +3797,7 @@ _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions +'$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. @@ -3796,10 +3825,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ GWmodel3 config.status 0.2-2 -configured by $0, generated by GNU Autoconf 2.71, +configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" -Copyright (C) 2021 Free Software Foundation, Inc. +Copyright (C) 2023 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -3856,8 +3885,8 @@ do ac_cs_silent=: ;; # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; + -*) as_fn_error $? "unrecognized option: '$1' +Try '$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; @@ -3907,7 +3936,7 @@ do case $ac_config_target in "src/Makevars") CONFIG_FILES="$CONFIG_FILES src/Makevars" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + *) as_fn_error $? "invalid argument: '$ac_config_target'" "$LINENO" 5;; esac done @@ -3925,7 +3954,7 @@ fi # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. +# after its creation but before its name has been assigned to '$tmp'. $debug || { tmp= ac_tmp= @@ -3949,7 +3978,7 @@ ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. +# This happens for instance with './config.status config.h'. if test -n "$CONFIG_FILES"; then @@ -4115,7 +4144,7 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :L* | :C*:*) as_fn_error $? "invalid tag '$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -4137,19 +4166,19 @@ do -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. + # because $ac_f cannot contain ':'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + as_fn_error 1 "cannot find input file: '$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done - # Let's still pretend it is `configure' which instantiates (i.e., don't + # Let's still pretend it is 'configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` @@ -4273,7 +4302,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 esac _ACEOF -# Neutralize VPATH when `$srcdir' = `.'. +# Neutralize VPATH when '$srcdir' = '.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 @@ -4302,9 +4331,9 @@ test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable 'datarootdir' which seems to be undefined. Please make sure it is defined" >&5 -printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable 'datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" diff --git a/configure.ac b/configure.ac index edc35ca..7555bff 100644 --- a/configure.ac +++ b/configure.ac @@ -84,7 +84,7 @@ NVCC="${CUDA_HOME}/bin/nvcc" AC_MSG_RESULT(building the cuda include path) CUDA_INCL="${CUDA_HOME}/include" -ENABLE_MPI=1 +ENABLE_MPI=0 AC_ARG_ENABLE([mpi], [AS_HELP_STRING([--enable-mpi],[install mpi (default no)])], [ case "${enableval}" in yes) ENABLE_MPI=1 ;; diff --git a/src/Makevars.win b/src/Makevars.win index fcaf941..8d0a6d0 100644 --- a/src/Makevars.win +++ b/src/Makevars.win @@ -79,9 +79,12 @@ endif ### [End] ### [Begin] Configure MPI +MPI_ENABLED = ${ENABLE_MPI} +ifeq ($(MPI_ENABLED),1) PKG_CXXFLAGS += -DENABLE_MPI PKG_LIBS += -lmsmpi OBJECTS_LIBGWMODEL += libgwmodel/src/gwmodelpp/utils/armampi.o +endif ### [End] OBJECTS = $(OBJECTS_LIBGWMODEL) $(OBJECTS_TELEGRAM) $(OBJECTS_GWMODEL) From 1d80d2ea0c27f157430c39211b6cc2095698c463 Mon Sep 17 00:00:00 2001 From: HPDell Date: Mon, 22 Jul 2024 17:48:40 +0100 Subject: [PATCH 16/20] edit(workflow): install openmpi --- .github/workflows/cran-check.yml | 2 +- .github/workflows/pages.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cran-check.yml b/.github/workflows/cran-check.yml index f6423b3..db138fc 100644 --- a/.github/workflows/cran-check.yml +++ b/.github/workflows/cran-check.yml @@ -49,7 +49,7 @@ jobs: with: r-version: 'release' - name: Install Dependencies - run: brew install gsl pandoc + run: brew install gsl pandoc open-mpi - name: Install R Dependencies uses: r-lib/actions/setup-r-dependencies@v2 with: diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 5242fe4..77c3671 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -34,7 +34,7 @@ jobs: - name: Install C++ dependencies run: | sudo apt-get update -qq - sudo apt-get install -qq libgsl-dev + sudo apt-get install -qq libgsl-dev libopenmpi-dev - name: Set up R uses: r-lib/actions/setup-r@v2 From 62272a2526f92f060477cbaae2bc97d5cb06ff34 Mon Sep 17 00:00:00 2001 From: HPDell Date: Mon, 22 Jul 2024 19:08:54 +0100 Subject: [PATCH 17/20] edit(workflow): check on macos 14 --- .github/workflows/cran-check.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cran-check.yml b/.github/workflows/cran-check.yml index db138fc..f8d2e55 100644 --- a/.github/workflows/cran-check.yml +++ b/.github/workflows/cran-check.yml @@ -38,7 +38,7 @@ jobs: check-dir: '"check"' check_macos: - runs-on: macos-12 + runs-on: macos-14 steps: - name: Checkout uses: actions/checkout@v3 @@ -50,6 +50,8 @@ jobs: r-version: 'release' - name: Install Dependencies run: brew install gsl pandoc open-mpi + - name: Install Rmpi + run: Rscript -e 'install.packages("Rmpi")' - name: Install R Dependencies uses: r-lib/actions/setup-r-dependencies@v2 with: From 4931a1f8febd95c344086739363b12c5d372100f Mon Sep 17 00:00:00 2001 From: HPDell Date: Mon, 22 Jul 2024 19:50:13 +0100 Subject: [PATCH 18/20] edit(workflow): Rmpi set configure args --- .github/workflows/cran-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cran-check.yml b/.github/workflows/cran-check.yml index f8d2e55..f042a2d 100644 --- a/.github/workflows/cran-check.yml +++ b/.github/workflows/cran-check.yml @@ -51,7 +51,7 @@ jobs: - name: Install Dependencies run: brew install gsl pandoc open-mpi - name: Install Rmpi - run: Rscript -e 'install.packages("Rmpi")' + run: Rscript -e 'install.packages("Rmpi", configure.args = c("--with-Rmpi-include=/opt/homebrew/include/", "--with-Rmpi-libpath=/opt/homebrew/lib/", "--with-Rmpi-type=OPENMPI"))' - name: Install R Dependencies uses: r-lib/actions/setup-r-dependencies@v2 with: From b371f9b4749f6ef092b51708914bccbacb24e9a5 Mon Sep 17 00:00:00 2001 From: HPDell Date: Wed, 24 Jul 2024 18:19:28 +0100 Subject: [PATCH 19/20] edit(vignette): add contents about MPI --- vignettes/other-01-hpc.Rmd | 66 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/vignettes/other-01-hpc.Rmd b/vignettes/other-01-hpc.Rmd index cd3e09c..066bcb6 100644 --- a/vignettes/other-01-hpc.Rmd +++ b/vignettes/other-01-hpc.Rmd @@ -136,3 +136,69 @@ remotes::install_github("GWmodel-Lab/GWmodel3", build_opts = c("--configure-args ``` Before installing the package, make sure that the environment variable `CUDA_HOME` is defined as the path to the CUDA toolkit. + +# Multiprocessing + +The multiprocessing parallel is implemented by the Message Passing Interface (MPI). +To use enable the paralleling, we need to install an implementation of MPI and [**Rmpi**](https://cran.r-project.org/web/packages/Rmpi/). +Please follow the instructions on the [official site](https://fisher.stats.uwo.ca/faculty/yu/Rmpi/) to install the package. + +## Install + +### Linux + +Available implementations of MPI are: + +- [OpenMPI](https://www.open-mpi.org/) +- [MPICH](https://www.mpich.org/) + +After cloning the source package, install this package with the following script. + +```bash +R CMD INSTALL GWmodel3 --configure-args=--enable-mpi=yes +``` + +### Windows + +Available implementations of MPI are: + +- [Microsoft MPI](https://learn.microsoft.com/en-us/message-passing-interface/microsoft-mpi) + +Then set a environment `ENABLE_MPI=1`, and use the following script to install the package. + +```powershell +R.exe CMD INSTALL GWmodel3 +``` + +## Usage + +Note that programs running with MPI parallel processing execute the same script in each process, unlike the multi-session parallelism provided by the **parallel** package. +When we are writing an R script to be paralleled by MPI, it is targeted to configure one process of the cluster. +For example, the following script let every process use the serial algorithm to fit the GWR model and set the bandwidth to 64 nearest neighbours. + +```r +# test.R +library(sf) +library(Rmpi) +library(GWmodel3) +data(LondonHP) +gwr_basic( + formula = PURCHASE ~ FLOORSZ + UNEMPLOY + PROF, + data = LondonHP, + bw = 64, + adaptive = TRUE +) +invisible(mpi.finalize()) +``` + +If we save the script to file `test.R`, we can run it by 4 processes with the following script. + +```bash +mpiexec -np 4 Rscript test.R +``` + +The number `4` can be changed to other numbers of processes. +In this case, all the processes run on the same machine. + +To run scripts on a high-performance cluster using MPI, a scheduler that supports MPI, such as Slurm, is required. +The specific method for execution should be referenced from the scheduler's documentation. From 123813883c4acf0b4b1b16c571415a589076304e Mon Sep 17 00:00:00 2001 From: HPDell Date: Thu, 25 Jul 2024 10:42:30 +0100 Subject: [PATCH 20/20] edit(vignette): HPC add other information [skip ci] --- vignettes/other-01-hpc.Rmd | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/vignettes/other-01-hpc.Rmd b/vignettes/other-01-hpc.Rmd index 066bcb6..6be5490 100644 --- a/vignettes/other-01-hpc.Rmd +++ b/vignettes/other-01-hpc.Rmd @@ -19,30 +19,32 @@ To solve this problem, this package provided some techniques to speed up the com - Multithreading based on OpenMP - GPU comoputing based on NVIDIA CUDA computing toolkit +- Multiprocessing based on MPI Currently, almost all algorithms have a serial implementation and one or two high-performance implementation. -| Algorithm | Multithreading | GPU computing | -| -------------- | -------------- | ------------- | -| Basic GWR | o | o | -| Multiscale GWR | o | | -| GWDR | o | | +| Algorithm | Multithreading | GPU computing | Multiprocessing | +| -------------- | -------------- | ------------- | --------------- | +| Basic GWR | o | o | o | +| Multiscale GWR | o | | o | +| GWDR | o | | | -All the parallelizable algorithms take two parameters to control parallelization: `parallel_method` and `parallel_arg`. +The multithreading- and GPU- parallelization algorithms take two parameters to control parallelization: `parallel_method` and `parallel_arg`. The `parallel_method` is used to pick a high-performance implementation. The valid options are `"omp"` and `"cuda"`, representing multithreading and GPU computing respectively. The `parallel_arg` is used to pass arguments. Different parallel methods needs different arguments. +For the multiprocessing parallelization, please see below for further details. -However, not all platform support both techniques, and some platform may have limited performance. +However, not all platform support all the techniques, and some platform may have limited performance. When users choosed unsupported method, it will fall back to the serial implementation. Please refer to the table below for additional information regarding platform support. -| Platform | Multithreading | GPU computing | -| ---------------------- | -------------- | ------------- | -| Windows | o | o\* | -| macOS (Apple Sillicon) | | | -| Linux | o | o | +| Platform | Multithreading | GPU computing | Multiprocessing | +| ---------------------- | -------------- | ------------- | --------------- | +| Windows | o | o\* | o | +| macOS (Apple Sillicon) | | | o | +| Linux | o | o | o | \*On Windows, GPU computing is supported through an additional library called "GWmodelCUDA", which is built with MSVC. This is because CUDA does not support the MinGW compiler, which is used to compile R packages.