From 21b038fc8df54beb55ddf9aabc27b88fc10bf191 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Sun, 17 Jan 2021 22:15:20 -0600 Subject: [PATCH 1/4] [R-package] Add GPU install options (fixes #3765) --- R-package/README.md | 22 +++++++++++ R-package/src/install.libs.R | 5 +++ build_r.R | 71 +++++++++++++++++++++++++++++++++--- 3 files changed, 93 insertions(+), 5 deletions(-) diff --git a/R-package/README.md b/R-package/README.md index a1664ec1c951..756a6cc1d15e 100644 --- a/R-package/README.md +++ b/R-package/README.md @@ -169,6 +169,28 @@ After installing these other libraries, follow the steps in ["Installing from So Rscript build_r.R --use-gpu ``` +You may also need or want to provide additional configuration, depending on your setup. For example, you may need to provide locations for Boost and OpenCL. + +```shell +Rscript build_r.R \ + --use-gpu \ + --opencl-library=/usr/lib/x86_64-linux-gnu/libOpenCL.so \ + --boost-librarydir=/usr/lib/x86_64-linux-gnu +``` + +The following options correspond to the [CMake FindBoost options](https://cmake.org/cmake/help/latest/module/FindBoost.html) by the same names. + +* `--boost-root` +* `--boost-dir` +* `--boost-include-dir` +* `--boost-librarydir` + +The following options correspond to the [CMake FindOpenCL options](https://cmake.org/cmake/help/latest/module/FindOpenCL.html) by the same names. + +* `--opencl-include-dir` +* `--opencl-library` + + ### Installing Precompiled Binaries Precompiled binaries for Mac and Windows are prepared by CRAN a few days after each release to CRAN. They can be installed with the following R code. diff --git a/R-package/src/install.libs.R b/R-package/src/install.libs.R index 593b934ecad9..aac0de80a63a 100644 --- a/R-package/src/install.libs.R +++ b/R-package/src/install.libs.R @@ -135,6 +135,11 @@ build_cmd <- "make" build_args <- "_lightgbm" lib_folder <- file.path(source_dir, fsep = "/") +# add in arguments passed in by command-line arguments +# build_r.R replaces the line below +command_line_args <- NULL +cmake_args <- c(cmake_args, command_line_args) + WINDOWS_BUILD_TOOLS <- list( "MinGW" = c( build_tool = "mingw32-make.exe" diff --git a/build_r.R b/build_r.R index fbafadfcc319..52057a4e9766 100644 --- a/build_r.R +++ b/build_r.R @@ -4,23 +4,63 @@ #export CXX=/usr/local/bin/g++-8 CC=/usr/local/bin/gcc-8 # Sys.setenv("CXX" = "/usr/local/bin/g++-8") # Sys.setenv("CC" = "/usr/local/bin/gcc-8") - args <- commandArgs(trailingOnly = TRUE) INSTALL_AFTER_BUILD <- !("--skip-install" %in% args) TEMP_R_DIR <- file.path(getwd(), "lightgbm_r") TEMP_SOURCE_DIR <- file.path(TEMP_R_DIR, "src") -USING_GPU <- "--use-gpu" %in% args -USING_MINGW <- "--use-mingw" %in% args -USING_MSYS2 <- "--use-msys2" %in% args +# [description] +# Parse the content of commandArgs() into a structured +# list. This returns a list with two sections. +# * "flags" = a character of vector of flags like "--use-gpu" +# * "keyword_args" = a named character vector, where names +# refer to options and values are the option values. For +# example, c("--boost-librarydir" = "/usr/lib/x86_64-linux-gnu") +.parse_args <- function(args) { + out_list <- list( + "flags" = character(0) + , "keyword_args" = character(0) + ) + for (arg in args) { + if (any(grepl("=", arg))){ + split_arg <- strsplit(arg, "=")[[1L]] + arg_name <- split_arg[[1L]] + arg_value <- split_arg[[2L]] + out_list[["keyword_args"]][[arg_name]] <- arg_value + } else { + out_list[["flags"]] <- c(out_list[["flags"]], arg) + } + } + return(out_list) +} +parsed_args <- .parse_args(args) + +USING_GPU <- "--use-gpu" %in% parsed_args[["flags"]] +USING_MINGW <- "--use-mingw" %in% parsed_args[["flags"]] +USING_MSYS2 <- "--use-msys2" %in% parsed_args[["flags"]] + +# this maps command-line arguments to defines passed into CMake, +ARGS_TO_DEFINES <- c( + "--boost-root" = "-DBOOST_ROOT" + , "--boost-dir" = "-Dboost_DIR" + , "--boost-include-dir" = "-DBoost_INCLUDE_DIR" + , "--boost-librarydir" = "-DBOOST_LIBRARYDIR" + , "--opencl-include-dir" = "-DOpenCL_INCLUDE_DIR" + , "--opencl-library" = "-DOpenCL_LIBRARY" +) recognized_args <- c( "--skip-install" , "--use-gpu" , "--use-mingw" , "--use-msys2" + , names(ARGS_TO_DEFINES) ) -unrecognized_args <- setdiff(args, recognized_args) +given_args <- c( + parsed_args[["flags"]] + , names(parsed_args[["keyword_args"]]) +) +unrecognized_args <- setdiff(given_args, recognized_args) if (length(unrecognized_args) > 0L) { msg <- paste0( "Unrecognized arguments: " @@ -47,6 +87,27 @@ install_libs_content <- .replace_flag("use_gpu", USING_GPU, install_libs_content install_libs_content <- .replace_flag("use_mingw", USING_MINGW, install_libs_content) install_libs_content <- .replace_flag("use_msys2", USING_MSYS2, install_libs_content) +# set up extra flags based on keyword arguments +keyword_args <- parsed_args[["keyword_args"]] +if (length(keyword_args) > 0L){ + cmake_args_to_add <- NULL + for (i in seq_len(length(keyword_args))){ + arg_name <- names(keyword_args)[[i]] + define_name <- ARGS_TO_DEFINES[[arg_name]] + arg_value <- shQuote(keyword_args[[arg_name]]) + cmake_args_to_add <- c(cmake_args_to_add, paste0(define_name, "=", arg_value)) + } + install_libs_content <- gsub( + pattern = paste0("command_line_args <- NULL") + , replacement = paste0( + "command_line_args <- c(\"" + , paste(cmake_args_to_add, collapse = "\", \"") + , "\")" + ) + , x = install_libs_content + ) +} + # R returns FALSE (not a non-zero exit code) if a file copy operation # breaks. Let's fix that .handle_result <- function(res) { From 6b74b07ec9157ed812d63f9b1a19694af156e12f Mon Sep 17 00:00:00 2001 From: James Lamb Date: Sun, 17 Jan 2021 22:56:30 -0600 Subject: [PATCH 2/4] whitespace --- R-package/README.md | 1 - R-package/src/install.libs.R | 4 ++-- build_r.R | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/R-package/README.md b/R-package/README.md index 756a6cc1d15e..2dfb0ce89bf6 100644 --- a/R-package/README.md +++ b/R-package/README.md @@ -190,7 +190,6 @@ The following options correspond to the [CMake FindOpenCL options](https://cmake * `--opencl-include-dir` * `--opencl-library` - ### Installing Precompiled Binaries Precompiled binaries for Mac and Windows are prepared by CRAN a few days after each release to CRAN. They can be installed with the following R code. diff --git a/R-package/src/install.libs.R b/R-package/src/install.libs.R index aac0de80a63a..9f839e2c1d73 100644 --- a/R-package/src/install.libs.R +++ b/R-package/src/install.libs.R @@ -135,8 +135,8 @@ build_cmd <- "make" build_args <- "_lightgbm" lib_folder <- file.path(source_dir, fsep = "/") -# add in arguments passed in by command-line arguments -# build_r.R replaces the line below +# add in command-line arguments +# NOTE: build_r.R replaces the line below command_line_args <- NULL cmake_args <- c(cmake_args, command_line_args) diff --git a/build_r.R b/build_r.R index 52057a4e9766..b9a1821939c9 100644 --- a/build_r.R +++ b/build_r.R @@ -4,6 +4,7 @@ #export CXX=/usr/local/bin/g++-8 CC=/usr/local/bin/gcc-8 # Sys.setenv("CXX" = "/usr/local/bin/g++-8") # Sys.setenv("CC" = "/usr/local/bin/gcc-8") + args <- commandArgs(trailingOnly = TRUE) INSTALL_AFTER_BUILD <- !("--skip-install" %in% args) TEMP_R_DIR <- file.path(getwd(), "lightgbm_r") From 7b58db728928606283858c4642b8476ac7622d17 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Sun, 17 Jan 2021 23:14:33 -0600 Subject: [PATCH 3/4] linting --- build_r.R | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build_r.R b/build_r.R index b9a1821939c9..3e966ac6d664 100644 --- a/build_r.R +++ b/build_r.R @@ -19,11 +19,11 @@ TEMP_SOURCE_DIR <- file.path(TEMP_R_DIR, "src") # example, c("--boost-librarydir" = "/usr/lib/x86_64-linux-gnu") .parse_args <- function(args) { out_list <- list( - "flags" = character(0) - , "keyword_args" = character(0) + "flags" = character(0L) + , "keyword_args" = character(0L) ) for (arg in args) { - if (any(grepl("=", arg))){ + if (any(grepl("=", arg))) { split_arg <- strsplit(arg, "=")[[1L]] arg_name <- split_arg[[1L]] arg_value <- split_arg[[2L]] @@ -90,9 +90,9 @@ install_libs_content <- .replace_flag("use_msys2", USING_MSYS2, install_libs_con # set up extra flags based on keyword arguments keyword_args <- parsed_args[["keyword_args"]] -if (length(keyword_args) > 0L){ +if (length(keyword_args) > 0L) { cmake_args_to_add <- NULL - for (i in seq_len(length(keyword_args))){ + for (i in seq_len(length(keyword_args))) { arg_name <- names(keyword_args)[[i]] define_name <- ARGS_TO_DEFINES[[arg_name]] arg_value <- shQuote(keyword_args[[arg_name]]) From e519e935de495bcbaaa4409f55e30a2acb0f2c22 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Mon, 18 Jan 2021 18:05:01 -0600 Subject: [PATCH 4/4] Update build_r.R Co-authored-by: Nikita Titov --- build_r.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_r.R b/build_r.R index 42c8ac8cd19f..0bbe42fc8637 100644 --- a/build_r.R +++ b/build_r.R @@ -43,7 +43,7 @@ USING_MSYS2 <- "--use-msys2" %in% parsed_args[["flags"]] # this maps command-line arguments to defines passed into CMake, ARGS_TO_DEFINES <- c( "--boost-root" = "-DBOOST_ROOT" - , "--boost-dir" = "-Dboost_DIR" + , "--boost-dir" = "-DBoost_DIR" , "--boost-include-dir" = "-DBoost_INCLUDE_DIR" , "--boost-librarydir" = "-DBOOST_LIBRARYDIR" , "--opencl-include-dir" = "-DOpenCL_INCLUDE_DIR"