From d23e086eb5c110ab6e9bd39c157f8c7c197f27c1 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Sat, 29 Feb 2020 10:01:55 -0600 Subject: [PATCH 01/41] [R-package] started cutting over from custom R-to-C interface to R.h --- CMakeLists.txt | 2 + src/lightgbm_R.cpp | 373 +++++++++++++++++++++++---------------------- 2 files changed, 189 insertions(+), 186 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 335b000ca159..ba9e9b631b11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,8 @@ if(USE_DEBUG) ADD_DEFINITIONS(-DDEBUG) endif(USE_DEBUG) +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/Library/Frameworks/R.framework/Versions/3.6/Resources/include") + if(USE_MPI) find_package(MPI REQUIRED) ADD_DEFINITIONS(-DUSE_MPI) diff --git a/src/lightgbm_R.cpp b/src/lightgbm_R.cpp index 4ba70a5f1c22..cbbafa445a7e 100644 --- a/src/lightgbm_R.cpp +++ b/src/lightgbm_R.cpp @@ -20,6 +20,7 @@ #define R_API_BEGIN() \ try { + #define R_API_END() } \ catch(std::exception& ex) { R_INT_PTR(call_state)[0] = -1; LGBM_SetLastError(ex.what()); return call_state;} \ catch(std::string& ex) { R_INT_PTR(call_state)[0] = -1; LGBM_SetLastError(ex.c_str()); return call_state; } \ @@ -34,7 +35,7 @@ using namespace LightGBM; -LGBM_SE EncodeChar(LGBM_SE dest, const char* src, LGBM_SE buf_len, LGBM_SE actual_len, size_t str_len) { +SEXP EncodeChar(SEXP dest, const char* src, SEXP buf_len, SEXP actual_len, size_t str_len) { if (str_len > INT32_MAX) { Log::Fatal("Don't support large string in R-package"); } @@ -47,15 +48,15 @@ LGBM_SE EncodeChar(LGBM_SE dest, const char* src, LGBM_SE buf_len, LGBM_SE actua return dest; } -LGBM_SE LGBM_GetLastError_R(LGBM_SE buf_len, LGBM_SE actual_len, LGBM_SE err_msg) { +SEXP LGBM_GetLastError_R(SEXP buf_len, SEXP actual_len, SEXP err_msg) { return EncodeChar(err_msg, LGBM_GetLastError(), buf_len, actual_len, std::strlen(LGBM_GetLastError()) + 1); } -LGBM_SE LGBM_DatasetCreateFromFile_R(LGBM_SE filename, - LGBM_SE parameters, - LGBM_SE reference, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_DatasetCreateFromFile_R(EXP filename, + SEXP parameters, + SEXP reference, + SEXP out, + SEXP call_state) { R_API_BEGIN(); DatasetHandle handle = nullptr; CHECK_CALL(LGBM_DatasetCreateFromFile(R_CHAR_PTR(filename), R_CHAR_PTR(parameters), @@ -64,16 +65,16 @@ LGBM_SE LGBM_DatasetCreateFromFile_R(LGBM_SE filename, R_API_END(); } -LGBM_SE LGBM_DatasetCreateFromCSC_R(LGBM_SE indptr, - LGBM_SE indices, - LGBM_SE data, - LGBM_SE num_indptr, - LGBM_SE nelem, - LGBM_SE num_row, - LGBM_SE parameters, - LGBM_SE reference, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_DatasetCreateFromCSC_R(SEXP indptr, + SEXP indices, + SEXP data, + SEXP num_indptr, + SEXP nelem, + SEXP num_row, + SEXP parameters, + SEXP reference, + SEXP out, + SEXP call_state) { R_API_BEGIN(); const int* p_indptr = R_INT_PTR(indptr); const int* p_indices = R_INT_PTR(indices); @@ -90,13 +91,13 @@ LGBM_SE LGBM_DatasetCreateFromCSC_R(LGBM_SE indptr, R_API_END(); } -LGBM_SE LGBM_DatasetCreateFromMat_R(LGBM_SE data, - LGBM_SE num_row, - LGBM_SE num_col, - LGBM_SE parameters, - LGBM_SE reference, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_DatasetCreateFromMat_R(SEXP data, + SEXP num_row, + SEXP num_col, + SEXP parameters, + SEXP reference, + SEXP out, + SEXP call_state) { R_API_BEGIN(); int32_t nrow = static_cast(R_AS_INT(num_row)); int32_t ncol = static_cast(R_AS_INT(num_col)); @@ -108,12 +109,12 @@ LGBM_SE LGBM_DatasetCreateFromMat_R(LGBM_SE data, R_API_END(); } -LGBM_SE LGBM_DatasetGetSubset_R(LGBM_SE handle, - LGBM_SE used_row_indices, - LGBM_SE len_used_row_indices, - LGBM_SE parameters, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_DatasetGetSubset_R(SEXP handle, + SEXP used_row_indices, + SEXP len_used_row_indices, + SEXP parameters, + SEXP out, + SEXP call_state) { R_API_BEGIN(); int len = R_AS_INT(len_used_row_indices); std::vector idxvec(len); @@ -130,9 +131,9 @@ LGBM_SE LGBM_DatasetGetSubset_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_DatasetSetFeatureNames_R(LGBM_SE handle, - LGBM_SE feature_names, - LGBM_SE call_state) { +SEXP LGBM_DatasetSetFeatureNames_R(SEXP handle, + SEXP feature_names, + SEXP call_state) { R_API_BEGIN(); auto vec_names = Common::Split(R_CHAR_PTR(feature_names), '\t'); std::vector vec_sptr; @@ -145,11 +146,11 @@ LGBM_SE LGBM_DatasetSetFeatureNames_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_DatasetGetFeatureNames_R(LGBM_SE handle, - LGBM_SE buf_len, - LGBM_SE actual_len, - LGBM_SE feature_names, - LGBM_SE call_state) { +SEXP LGBM_DatasetGetFeatureNames_R(SEXP handle, + SEXP buf_len, + SEXP actual_len, + SEXP feature_names, + SEXP call_state) { R_API_BEGIN(); int len = 0; CHECK_CALL(LGBM_DatasetGetNumFeature(R_GET_PTR(handle), &len)); @@ -168,17 +169,17 @@ LGBM_SE LGBM_DatasetGetFeatureNames_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_DatasetSaveBinary_R(LGBM_SE handle, - LGBM_SE filename, - LGBM_SE call_state) { +SEXP LGBM_DatasetSaveBinary_R(SEXP handle, + SEXP filename, + SEXP call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_DatasetSaveBinary(R_GET_PTR(handle), R_CHAR_PTR(filename))); R_API_END(); } -LGBM_SE LGBM_DatasetFree_R(LGBM_SE handle, - LGBM_SE call_state) { +SEXP LGBM_DatasetFree_R(SEXP handle, + SEXP call_state) { R_API_BEGIN(); if (R_GET_PTR(handle) != nullptr) { CHECK_CALL(LGBM_DatasetFree(R_GET_PTR(handle))); @@ -187,11 +188,11 @@ LGBM_SE LGBM_DatasetFree_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_DatasetSetField_R(LGBM_SE handle, - LGBM_SE field_name, - LGBM_SE field_data, - LGBM_SE num_element, - LGBM_SE call_state) { +SEXP LGBM_DatasetSetField_R(SEXP handle, + SEXP field_name, + SEXP field_data, + SEXP num_element, + SEXP call_state) { R_API_BEGIN(); int len = static_cast(R_AS_INT(num_element)); const char* name = R_CHAR_PTR(field_name); @@ -215,10 +216,10 @@ LGBM_SE LGBM_DatasetSetField_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_DatasetGetField_R(LGBM_SE handle, - LGBM_SE field_name, - LGBM_SE field_data, - LGBM_SE call_state) { +SEXP LGBM_DatasetGetField_R(SEXP handle, + SEXP field_name, + SEXP field_data, + SEXP call_state) { R_API_BEGIN(); const char* name = R_CHAR_PTR(field_name); int out_len = 0; @@ -249,10 +250,10 @@ LGBM_SE LGBM_DatasetGetField_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_DatasetGetFieldSize_R(LGBM_SE handle, - LGBM_SE field_name, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_DatasetGetFieldSize_R(SEXP handle, + SEXP field_name, + SEXP out, + SEXP call_state) { R_API_BEGIN(); const char* name = R_CHAR_PTR(field_name); int out_len = 0; @@ -266,16 +267,16 @@ LGBM_SE LGBM_DatasetGetFieldSize_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_DatasetUpdateParamChecking_R(LGBM_SE old_params, - LGBM_SE new_params, - LGBM_SE call_state) { +SEXP LGBM_DatasetUpdateParamChecking_R(SEXP old_params, + SEXP new_params, + SEXP call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_DatasetUpdateParamChecking(R_CHAR_PTR(old_params), R_CHAR_PTR(new_params))); R_API_END(); } -LGBM_SE LGBM_DatasetGetNumData_R(LGBM_SE handle, LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_DatasetGetNumData_R(SEXP handle, SEXP out, + SEXP call_state) { int nrow; R_API_BEGIN(); CHECK_CALL(LGBM_DatasetGetNumData(R_GET_PTR(handle), &nrow)); @@ -283,9 +284,9 @@ LGBM_SE LGBM_DatasetGetNumData_R(LGBM_SE handle, LGBM_SE out, R_API_END(); } -LGBM_SE LGBM_DatasetGetNumFeature_R(LGBM_SE handle, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_DatasetGetNumFeature_R(SEXP handle, + SEXP out, + SEXP call_state) { int nfeature; R_API_BEGIN(); CHECK_CALL(LGBM_DatasetGetNumFeature(R_GET_PTR(handle), &nfeature)); @@ -295,8 +296,8 @@ LGBM_SE LGBM_DatasetGetNumFeature_R(LGBM_SE handle, // --- start Booster interfaces -LGBM_SE LGBM_BoosterFree_R(LGBM_SE handle, - LGBM_SE call_state) { +SEXP LGBM_BoosterFree_R(SEXP handle, + SEXP call_state) { R_API_BEGIN(); if (R_GET_PTR(handle) != nullptr) { CHECK_CALL(LGBM_BoosterFree(R_GET_PTR(handle))); @@ -305,10 +306,10 @@ LGBM_SE LGBM_BoosterFree_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterCreate_R(LGBM_SE train_data, - LGBM_SE parameters, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_BoosterCreate_R(SEXP train_data, + SEXP parameters, + SEXP out, + SEXP call_state) { R_API_BEGIN(); BoosterHandle handle = nullptr; CHECK_CALL(LGBM_BoosterCreate(R_GET_PTR(train_data), R_CHAR_PTR(parameters), &handle)); @@ -316,9 +317,9 @@ LGBM_SE LGBM_BoosterCreate_R(LGBM_SE train_data, R_API_END(); } -LGBM_SE LGBM_BoosterCreateFromModelfile_R(LGBM_SE filename, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_BoosterCreateFromModelfile_R(SEXP filename, + SEXP out, + SEXP call_state) { R_API_BEGIN(); int out_num_iterations = 0; BoosterHandle handle = nullptr; @@ -327,9 +328,9 @@ LGBM_SE LGBM_BoosterCreateFromModelfile_R(LGBM_SE filename, R_API_END(); } -LGBM_SE LGBM_BoosterLoadModelFromString_R(LGBM_SE model_str, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_BoosterLoadModelFromString_R(SEXP model_str, + SEXP out, + SEXP call_state) { R_API_BEGIN(); int out_num_iterations = 0; BoosterHandle handle = nullptr; @@ -338,41 +339,41 @@ LGBM_SE LGBM_BoosterLoadModelFromString_R(LGBM_SE model_str, R_API_END(); } -LGBM_SE LGBM_BoosterMerge_R(LGBM_SE handle, - LGBM_SE other_handle, - LGBM_SE call_state) { +SEXP LGBM_BoosterMerge_R(SEXP handle, + SEXP other_handle, + SEXP call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterMerge(R_GET_PTR(handle), R_GET_PTR(other_handle))); R_API_END(); } -LGBM_SE LGBM_BoosterAddValidData_R(LGBM_SE handle, - LGBM_SE valid_data, - LGBM_SE call_state) { +SEXP LGBM_BoosterAddValidData_R(SEXP handle, + SEXP valid_data, + SEXP call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterAddValidData(R_GET_PTR(handle), R_GET_PTR(valid_data))); R_API_END(); } -LGBM_SE LGBM_BoosterResetTrainingData_R(LGBM_SE handle, - LGBM_SE train_data, - LGBM_SE call_state) { +SEXP LGBM_BoosterResetTrainingData_R(SEXP handle, + SEXP train_data, + SEXP call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterResetTrainingData(R_GET_PTR(handle), R_GET_PTR(train_data))); R_API_END(); } -LGBM_SE LGBM_BoosterResetParameter_R(LGBM_SE handle, - LGBM_SE parameters, - LGBM_SE call_state) { +SEXP LGBM_BoosterResetParameter_R(SEXP handle, + SEXP parameters, + SEXP call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterResetParameter(R_GET_PTR(handle), R_CHAR_PTR(parameters))); R_API_END(); } -LGBM_SE LGBM_BoosterGetNumClasses_R(LGBM_SE handle, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_BoosterGetNumClasses_R(SEXP handle, + SEXP out, + SEXP call_state) { int num_class; R_API_BEGIN(); CHECK_CALL(LGBM_BoosterGetNumClasses(R_GET_PTR(handle), &num_class)); @@ -380,19 +381,19 @@ LGBM_SE LGBM_BoosterGetNumClasses_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterUpdateOneIter_R(LGBM_SE handle, - LGBM_SE call_state) { +SEXP LGBM_BoosterUpdateOneIter_R(SEXP handle, + SEXP call_state) { int is_finished = 0; R_API_BEGIN(); CHECK_CALL(LGBM_BoosterUpdateOneIter(R_GET_PTR(handle), &is_finished)); R_API_END(); } -LGBM_SE LGBM_BoosterUpdateOneIterCustom_R(LGBM_SE handle, - LGBM_SE grad, - LGBM_SE hess, - LGBM_SE len, - LGBM_SE call_state) { +SEXP LGBM_BoosterUpdateOneIterCustom_R(SEXP handle, + SEXP grad, + SEXP hess, + SEXP len, + SEXP call_state) { int is_finished = 0; R_API_BEGIN(); int int_len = R_AS_INT(len); @@ -406,16 +407,16 @@ LGBM_SE LGBM_BoosterUpdateOneIterCustom_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterRollbackOneIter_R(LGBM_SE handle, - LGBM_SE call_state) { +SEXP LGBM_BoosterRollbackOneIter_R(SEXP handle, + SEXP call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterRollbackOneIter(R_GET_PTR(handle))); R_API_END(); } -LGBM_SE LGBM_BoosterGetCurrentIteration_R(LGBM_SE handle, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_BoosterGetCurrentIteration_R(SEXP handle, + SEXP out, + SEXP call_state) { int out_iteration; R_API_BEGIN(); CHECK_CALL(LGBM_BoosterGetCurrentIteration(R_GET_PTR(handle), &out_iteration)); @@ -423,29 +424,29 @@ LGBM_SE LGBM_BoosterGetCurrentIteration_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterGetUpperBoundValue_R(LGBM_SE handle, - LGBM_SE out_result, - LGBM_SE call_state) { +SEXP LGBM_BoosterGetUpperBoundValue_R(SEXP handle, + SEXP out_result, + SEXP call_state) { R_API_BEGIN(); double* ptr_ret = R_REAL_PTR(out_result); CHECK_CALL(LGBM_BoosterGetUpperBoundValue(R_GET_PTR(handle), ptr_ret)); R_API_END(); } -LGBM_SE LGBM_BoosterGetLowerBoundValue_R(LGBM_SE handle, - LGBM_SE out_result, - LGBM_SE call_state) { +SEXP LGBM_BoosterGetLowerBoundValue_R(SEXP handle, + SEXP out_result, + SEXP call_state) { R_API_BEGIN(); double* ptr_ret = R_REAL_PTR(out_result); CHECK_CALL(LGBM_BoosterGetLowerBoundValue(R_GET_PTR(handle), ptr_ret)); R_API_END(); } -LGBM_SE LGBM_BoosterGetEvalNames_R(LGBM_SE handle, - LGBM_SE buf_len, - LGBM_SE actual_len, - LGBM_SE eval_names, - LGBM_SE call_state) { +SEXP LGBM_BoosterGetEvalNames_R(SEXP handle, + SEXP buf_len, + SEXP actual_len, + SEXP eval_names, + SEXP call_state) { R_API_BEGIN(); int len; CHECK_CALL(LGBM_BoosterGetEvalCounts(R_GET_PTR(handle), &len)); @@ -463,10 +464,10 @@ LGBM_SE LGBM_BoosterGetEvalNames_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterGetEval_R(LGBM_SE handle, - LGBM_SE data_idx, - LGBM_SE out_result, - LGBM_SE call_state) { +SEXP LGBM_BoosterGetEval_R(SEXP handle, + SEXP data_idx, + SEXP out_result, + SEXP call_state) { R_API_BEGIN(); int len; CHECK_CALL(LGBM_BoosterGetEvalCounts(R_GET_PTR(handle), &len)); @@ -477,10 +478,10 @@ LGBM_SE LGBM_BoosterGetEval_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterGetNumPredict_R(LGBM_SE handle, - LGBM_SE data_idx, - LGBM_SE out, - LGBM_SE call_state) { +SEXP LGBM_BoosterGetNumPredict_R(SEXP handle, + SEXP data_idx, + SEXP out, + SEXP call_state) { R_API_BEGIN(); int64_t len; CHECK_CALL(LGBM_BoosterGetNumPredict(R_GET_PTR(handle), R_AS_INT(data_idx), &len)); @@ -488,10 +489,10 @@ LGBM_SE LGBM_BoosterGetNumPredict_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterGetPredict_R(LGBM_SE handle, - LGBM_SE data_idx, - LGBM_SE out_result, - LGBM_SE call_state) { +SEXP LGBM_BoosterGetPredict_R(SEXP handle, + SEXP data_idx, + SEXP out_result, + SEXP call_state) { R_API_BEGIN(); double* ptr_ret = R_REAL_PTR(out_result); int64_t out_len; @@ -499,7 +500,7 @@ LGBM_SE LGBM_BoosterGetPredict_R(LGBM_SE handle, R_API_END(); } -int GetPredictType(LGBM_SE is_rawscore, LGBM_SE is_leafidx, LGBM_SE is_predcontrib) { +int GetPredictType(SEXP is_rawscore, SEXP is_leafidx, SEXP is_predcontrib) { int pred_type = C_API_PREDICT_NORMAL; if (R_AS_INT(is_rawscore)) { pred_type = C_API_PREDICT_RAW_SCORE; @@ -513,16 +514,16 @@ int GetPredictType(LGBM_SE is_rawscore, LGBM_SE is_leafidx, LGBM_SE is_predcontr return pred_type; } -LGBM_SE LGBM_BoosterPredictForFile_R(LGBM_SE handle, - LGBM_SE data_filename, - LGBM_SE data_has_header, - LGBM_SE is_rawscore, - LGBM_SE is_leafidx, - LGBM_SE is_predcontrib, - LGBM_SE num_iteration, - LGBM_SE parameter, - LGBM_SE result_filename, - LGBM_SE call_state) { +SEXP LGBM_BoosterPredictForFile_R(SEXP handle, + SEXP data_filename, + SEXP data_has_header, + SEXP is_rawscore, + SEXP is_leafidx, + SEXP is_predcontrib, + SEXP num_iteration, + SEXP parameter, + SEXP result_filename, + SEXP call_state) { R_API_BEGIN(); int pred_type = GetPredictType(is_rawscore, is_leafidx, is_predcontrib); CHECK_CALL(LGBM_BoosterPredictForFile(R_GET_PTR(handle), R_CHAR_PTR(data_filename), @@ -531,14 +532,14 @@ LGBM_SE LGBM_BoosterPredictForFile_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterCalcNumPredict_R(LGBM_SE handle, - LGBM_SE num_row, - LGBM_SE is_rawscore, - LGBM_SE is_leafidx, - LGBM_SE is_predcontrib, - LGBM_SE num_iteration, - LGBM_SE out_len, - LGBM_SE call_state) { +SEXP LGBM_BoosterCalcNumPredict_R(SEXP handle, + SEXP num_row, + SEXP is_rawscore, + SEXP is_leafidx, + SEXP is_predcontrib, + SEXP num_iteration, + SEXP out_len, + SEXP call_state) { R_API_BEGIN(); int pred_type = GetPredictType(is_rawscore, is_leafidx, is_predcontrib); int64_t len = 0; @@ -548,20 +549,20 @@ LGBM_SE LGBM_BoosterCalcNumPredict_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterPredictForCSC_R(LGBM_SE handle, - LGBM_SE indptr, - LGBM_SE indices, - LGBM_SE data, - LGBM_SE num_indptr, - LGBM_SE nelem, - LGBM_SE num_row, - LGBM_SE is_rawscore, - LGBM_SE is_leafidx, - LGBM_SE is_predcontrib, - LGBM_SE num_iteration, - LGBM_SE parameter, - LGBM_SE out_result, - LGBM_SE call_state) { +SEXP LGBM_BoosterPredictForCSC_R(SEXP handle, + SEXP indptr, + SEXP indices, + SEXP data, + SEXP num_indptr, + SEXP nelem, + SEXP num_row, + SEXP is_rawscore, + SEXP is_leafidx, + SEXP is_predcontrib, + SEXP num_iteration, + SEXP parameter, + SEXP out_result, + SEXP call_state) { R_API_BEGIN(); int pred_type = GetPredictType(is_rawscore, is_leafidx, is_predcontrib); @@ -581,17 +582,17 @@ LGBM_SE LGBM_BoosterPredictForCSC_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterPredictForMat_R(LGBM_SE handle, - LGBM_SE data, - LGBM_SE num_row, - LGBM_SE num_col, - LGBM_SE is_rawscore, - LGBM_SE is_leafidx, - LGBM_SE is_predcontrib, - LGBM_SE num_iteration, - LGBM_SE parameter, - LGBM_SE out_result, - LGBM_SE call_state) { +SEXP LGBM_BoosterPredictForMat_R(SEXP handle, + SEXP data, + SEXP num_row, + SEXP num_col, + SEXP is_rawscore, + SEXP is_leafidx, + SEXP is_predcontrib, + SEXP num_iteration, + SEXP parameter, + SEXP out_result, + SEXP call_state) { R_API_BEGIN(); int pred_type = GetPredictType(is_rawscore, is_leafidx, is_predcontrib); @@ -608,21 +609,21 @@ LGBM_SE LGBM_BoosterPredictForMat_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterSaveModel_R(LGBM_SE handle, - LGBM_SE num_iteration, - LGBM_SE filename, - LGBM_SE call_state) { +SEXP LGBM_BoosterSaveModel_R(SEXP handle, + SEXP num_iteration, + SEXP filename, + SEXP call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterSaveModel(R_GET_PTR(handle), 0, R_AS_INT(num_iteration), R_CHAR_PTR(filename))); R_API_END(); } -LGBM_SE LGBM_BoosterSaveModelToString_R(LGBM_SE handle, - LGBM_SE num_iteration, - LGBM_SE buffer_len, - LGBM_SE actual_len, - LGBM_SE out_str, - LGBM_SE call_state) { +SEXP LGBM_BoosterSaveModelToString_R(SEXP handle, + SEXP num_iteration, + SEXP buffer_len, + SEXP actual_len, + SEXP out_str, + SEXP call_state) { R_API_BEGIN(); int64_t out_len = 0; std::vector inner_char_buf(R_AS_INT(buffer_len)); @@ -631,12 +632,12 @@ LGBM_SE LGBM_BoosterSaveModelToString_R(LGBM_SE handle, R_API_END(); } -LGBM_SE LGBM_BoosterDumpModel_R(LGBM_SE handle, - LGBM_SE num_iteration, - LGBM_SE buffer_len, - LGBM_SE actual_len, - LGBM_SE out_str, - LGBM_SE call_state) { +SEXP LGBM_BoosterDumpModel_R(SEXP handle, + SEXP num_iteration, + SEXP buffer_len, + SEXP actual_len, + SEXP out_str, + SEXP call_state) { R_API_BEGIN(); int64_t out_len = 0; std::vector inner_char_buf(R_AS_INT(buffer_len)); From 7e03224fc6c549ef48c2e4ec17c26db690933407 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 10 Mar 2020 20:13:51 -0500 Subject: [PATCH 02/41] replaced LGBM_SE with SEXP --- include/LightGBM/R_object_helper.h | 8 +- include/LightGBM/lightgbm_R.h | 456 ++++++++++++++--------------- 2 files changed, 232 insertions(+), 232 deletions(-) diff --git a/include/LightGBM/R_object_helper.h b/include/LightGBM/R_object_helper.h index 8321011260cc..14ad7b5e383a 100644 --- a/include/LightGBM/R_object_helper.h +++ b/include/LightGBM/R_object_helper.h @@ -144,7 +144,7 @@ typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN; #define R_ADDR(x) (reinterpret_cast DATAPTR(x)) - inline void R_SET_PTR(LGBM_SE x, void* ptr) { + inline void R_SET_PTR(SEXP x, void* ptr) { if (ptr == nullptr) { R_ADDR(x)[0] = (int64_t)(NULL); } else { @@ -152,7 +152,7 @@ typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN; } } - inline void* R_GET_PTR(LGBM_SE x) { + inline void* R_GET_PTR(SEXP x) { if (R_IS_NULL(x)) { return nullptr; } else { @@ -168,7 +168,7 @@ typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN; #define R_ADDR(x) (reinterpret_cast DATAPTR(x)) - inline void R_SET_PTR(LGBM_SE x, void* ptr) { + inline void R_SET_PTR(SEXP x, void* ptr) { if (ptr == nullptr) { R_ADDR(x)[0] = (int32_t)(NULL); } else { @@ -176,7 +176,7 @@ typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN; } } - inline void* R_GET_PTR(LGBM_SE x) { + inline void* R_GET_PTR(SEXP x) { if (R_IS_NULL(x)) { return nullptr; } else { diff --git a/include/LightGBM/lightgbm_R.h b/include/LightGBM/lightgbm_R.h index 076ea2946384..6d898be38ef4 100644 --- a/include/LightGBM/lightgbm_R.h +++ b/include/LightGBM/lightgbm_R.h @@ -15,10 +15,10 @@ * \return err_msg error information * \return error information */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_GetLastError_R( - LGBM_SE buf_len, - LGBM_SE actual_len, - LGBM_SE err_msg +LIGHTGBM_C_EXPORT SEXP LGBM_GetLastError_R( + SEXP buf_len, + SEXP actual_len, + SEXP err_msg ); // --- start Dataset interface @@ -31,12 +31,12 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_GetLastError_R( * \param out created dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetCreateFromFile_R( - LGBM_SE filename, - LGBM_SE parameters, - LGBM_SE reference, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetCreateFromFile_R( + SEXP filename, + SEXP parameters, + SEXP reference, + SEXP out, + SEXP call_state ); /*! @@ -52,17 +52,17 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetCreateFromFile_R( * \param out created dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetCreateFromCSC_R( - LGBM_SE indptr, - LGBM_SE indices, - LGBM_SE data, - LGBM_SE nindptr, - LGBM_SE nelem, - LGBM_SE num_row, - LGBM_SE parameters, - LGBM_SE reference, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetCreateFromCSC_R( + SEXP indptr, + SEXP indices, + SEXP data, + SEXP nindptr, + SEXP nelem, + SEXP num_row, + SEXP parameters, + SEXP reference, + SEXP out, + SEXP call_state ); /*! @@ -75,14 +75,14 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetCreateFromCSC_R( * \param out created dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetCreateFromMat_R( - LGBM_SE data, - LGBM_SE nrow, - LGBM_SE ncol, - LGBM_SE parameters, - LGBM_SE reference, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetCreateFromMat_R( + SEXP data, + SEXP nrow, + SEXP ncol, + SEXP parameters, + SEXP reference, + SEXP out, + SEXP call_state ); /*! @@ -94,13 +94,13 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetCreateFromMat_R( * \param out created dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetSubset_R( - LGBM_SE handle, - LGBM_SE used_row_indices, - LGBM_SE len_used_row_indices, - LGBM_SE parameters, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetSubset_R( + SEXP handle, + SEXP used_row_indices, + SEXP len_used_row_indices, + SEXP parameters, + SEXP out, + SEXP call_state ); /*! @@ -109,10 +109,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetSubset_R( * \param feature_names feature names * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetSetFeatureNames_R( - LGBM_SE handle, - LGBM_SE feature_names, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetSetFeatureNames_R( + SEXP handle, + SEXP feature_names, + SEXP call_state ); /*! @@ -121,12 +121,12 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetSetFeatureNames_R( * \param feature_names feature names * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetFeatureNames_R( - LGBM_SE handle, - LGBM_SE buf_len, - LGBM_SE actual_len, - LGBM_SE feature_names, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetFeatureNames_R( + SEXP handle, + SEXP buf_len, + SEXP actual_len, + SEXP feature_names, + SEXP call_state ); /*! @@ -135,10 +135,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetFeatureNames_R( * \param filename file name * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetSaveBinary_R( - LGBM_SE handle, - LGBM_SE filename, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetSaveBinary_R( + SEXP handle, + SEXP filename, + SEXP call_state ); /*! @@ -146,9 +146,9 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetSaveBinary_R( * \param handle an instance of dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetFree_R( - LGBM_SE handle, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetFree_R( + SEXP handle, + SEXP call_state ); /*! @@ -161,12 +161,12 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetFree_R( * \param num_element number of element in field_data * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetSetField_R( - LGBM_SE handle, - LGBM_SE field_name, - LGBM_SE field_data, - LGBM_SE num_element, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetSetField_R( + SEXP handle, + SEXP field_name, + SEXP field_data, + SEXP num_element, + SEXP call_state ); /*! @@ -176,11 +176,11 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetSetField_R( * \param out size of info vector from dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetFieldSize_R( - LGBM_SE handle, - LGBM_SE field_name, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetFieldSize_R( + SEXP handle, + SEXP field_name, + SEXP out, + SEXP call_state ); /*! @@ -190,11 +190,11 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetFieldSize_R( * \param field_data pointer to vector * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetField_R( - LGBM_SE handle, - LGBM_SE field_name, - LGBM_SE field_data, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetField_R( + SEXP handle, + SEXP field_name, + SEXP field_data, + SEXP call_state ); /*! @@ -203,10 +203,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetField_R( * \param new_params New dataset parameters * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetUpdateParamChecking_R( - LGBM_SE old_params, - LGBM_SE new_params, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetUpdateParamChecking_R( + SEXP old_params, + SEXP new_params, + SEXP call_state ); /*! @@ -215,10 +215,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetUpdateParamChecking_R( * \param out The address to hold number of data * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetNumData_R( - LGBM_SE handle, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetNumData_R( + SEXP handle, + SEXP out, + SEXP call_state ); /*! @@ -227,10 +227,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetNumData_R( * \param out The output of number of features * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetNumFeature_R( - LGBM_SE handle, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetNumFeature_R( + SEXP handle, + SEXP out, + SEXP call_state ); // --- start Booster interfaces @@ -242,11 +242,11 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetNumFeature_R( * \param out handle of created Booster * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterCreate_R( - LGBM_SE train_data, - LGBM_SE parameters, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterCreate_R( + SEXP train_data, + SEXP parameters, + SEXP out, + SEXP call_state ); /*! @@ -254,9 +254,9 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterCreate_R( * \param handle handle to be freed * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterFree_R( - LGBM_SE handle, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterFree_R( + SEXP handle, + SEXP call_state ); /*! @@ -265,10 +265,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterFree_R( * \param out handle of created Booster * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterCreateFromModelfile_R( - LGBM_SE filename, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterCreateFromModelfile_R( + SEXP filename, + SEXP out, + SEXP call_state ); /*! @@ -277,10 +277,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterCreateFromModelfile_R( * \param out handle of created Booster * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterLoadModelFromString_R( - LGBM_SE model_str, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterLoadModelFromString_R( + SEXP model_str, + SEXP out, + SEXP call_state ); /*! @@ -289,10 +289,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterLoadModelFromString_R( * \param other_handle * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterMerge_R( - LGBM_SE handle, - LGBM_SE other_handle, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterMerge_R( + SEXP handle, + SEXP other_handle, + SEXP call_state ); /*! @@ -301,10 +301,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterMerge_R( * \param valid_data validation data set * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterAddValidData_R( - LGBM_SE handle, - LGBM_SE valid_data, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterAddValidData_R( + SEXP handle, + SEXP valid_data, + SEXP call_state ); /*! @@ -313,10 +313,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterAddValidData_R( * \param train_data training data set * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterResetTrainingData_R( - LGBM_SE handle, - LGBM_SE train_data, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterResetTrainingData_R( + SEXP handle, + SEXP train_data, + SEXP call_state ); /*! @@ -325,10 +325,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterResetTrainingData_R( * \param parameters format: 'key1=value1 key2=value2' * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterResetParameter_R( - LGBM_SE handle, - LGBM_SE parameters, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterResetParameter_R( + SEXP handle, + SEXP parameters, + SEXP call_state ); /*! @@ -337,10 +337,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterResetParameter_R( * \param out number of classes * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetNumClasses_R( - LGBM_SE handle, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetNumClasses_R( + SEXP handle, + SEXP out, + SEXP call_state ); /*! @@ -348,9 +348,9 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetNumClasses_R( * \param handle handle * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterUpdateOneIter_R( - LGBM_SE handle, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterUpdateOneIter_R( + SEXP handle, + SEXP call_state ); /*! @@ -362,12 +362,12 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterUpdateOneIter_R( * \param len length of grad/hess * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterUpdateOneIterCustom_R( - LGBM_SE handle, - LGBM_SE grad, - LGBM_SE hess, - LGBM_SE len, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterUpdateOneIterCustom_R( + SEXP handle, + SEXP grad, + SEXP hess, + SEXP len, + SEXP call_state ); /*! @@ -375,9 +375,9 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterUpdateOneIterCustom_R( * \param handle handle * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterRollbackOneIter_R( - LGBM_SE handle, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterRollbackOneIter_R( + SEXP handle, + SEXP call_state ); /*! @@ -385,10 +385,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterRollbackOneIter_R( * \param out iteration of boosting rounds * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetCurrentIteration_R( - LGBM_SE handle, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetCurrentIteration_R( + SEXP handle, + SEXP out, + SEXP call_state ); /*! @@ -397,10 +397,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetCurrentIteration_R( * \param[out] out_results Result pointing to max value * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetUpperBoundValue_R( - LGBM_SE handle, - LGBM_SE out_result, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetUpperBoundValue_R( + SEXP handle, + SEXP out_result, + SEXP call_state ); /*! @@ -409,10 +409,10 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetUpperBoundValue_R( * \param[out] out_results Result pointing to min value * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetLowerBoundValue_R( - LGBM_SE handle, - LGBM_SE out_result, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetLowerBoundValue_R( + SEXP handle, + SEXP out_result, + SEXP call_state ); /*! @@ -420,12 +420,12 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetLowerBoundValue_R( * \param eval_names eval names * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetEvalNames_R( - LGBM_SE handle, - LGBM_SE buf_len, - LGBM_SE actual_len, - LGBM_SE eval_names, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetEvalNames_R( + SEXP handle, + SEXP buf_len, + SEXP actual_len, + SEXP eval_names, + SEXP call_state ); /*! @@ -435,11 +435,11 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetEvalNames_R( * \param out_result float array contains result * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetEval_R( - LGBM_SE handle, - LGBM_SE data_idx, - LGBM_SE out_result, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetEval_R( + SEXP handle, + SEXP data_idx, + SEXP out_result, + SEXP call_state ); /*! @@ -449,11 +449,11 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetEval_R( * \param out size of predict * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetNumPredict_R( - LGBM_SE handle, - LGBM_SE data_idx, - LGBM_SE out, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetNumPredict_R( + SEXP handle, + SEXP data_idx, + SEXP out, + SEXP call_state ); /*! @@ -464,11 +464,11 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetNumPredict_R( * \param out_result, used to store predict result, should pre-allocate memory * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetPredict_R( - LGBM_SE handle, - LGBM_SE data_idx, - LGBM_SE out_result, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetPredict_R( + SEXP handle, + SEXP data_idx, + SEXP out_result, + SEXP call_state ); /*! @@ -482,17 +482,17 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetPredict_R( * \return 0 when succeed, -1 when failure happens * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterPredictForFile_R( - LGBM_SE handle, - LGBM_SE data_filename, - LGBM_SE data_has_header, - LGBM_SE is_rawscore, - LGBM_SE is_leafidx, - LGBM_SE is_predcontrib, - LGBM_SE num_iteration, - LGBM_SE parameter, - LGBM_SE result_filename, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterPredictForFile_R( + SEXP handle, + SEXP data_filename, + SEXP data_has_header, + SEXP is_rawscore, + SEXP is_leafidx, + SEXP is_predcontrib, + SEXP num_iteration, + SEXP parameter, + SEXP result_filename, + SEXP call_state ); /*! @@ -505,15 +505,15 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterPredictForFile_R( * \param out_len length of prediction * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterCalcNumPredict_R( - LGBM_SE handle, - LGBM_SE num_row, - LGBM_SE is_rawscore, - LGBM_SE is_leafidx, - LGBM_SE is_predcontrib, - LGBM_SE num_iteration, - LGBM_SE out_len, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterCalcNumPredict_R( + SEXP handle, + SEXP num_row, + SEXP is_rawscore, + SEXP is_leafidx, + SEXP is_predcontrib, + SEXP num_iteration, + SEXP out_len, + SEXP call_state ); /*! @@ -534,21 +534,21 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterCalcNumPredict_R( * \param out prediction result * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterPredictForCSC_R( - LGBM_SE handle, - LGBM_SE indptr, - LGBM_SE indices, - LGBM_SE data, - LGBM_SE nindptr, - LGBM_SE nelem, - LGBM_SE num_row, - LGBM_SE is_rawscore, - LGBM_SE is_leafidx, - LGBM_SE is_predcontrib, - LGBM_SE num_iteration, - LGBM_SE parameter, - LGBM_SE out_result, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterPredictForCSC_R( + SEXP handle, + SEXP indptr, + SEXP indices, + SEXP data, + SEXP nindptr, + SEXP nelem, + SEXP num_row, + SEXP is_rawscore, + SEXP is_leafidx, + SEXP is_predcontrib, + SEXP num_iteration, + SEXP parameter, + SEXP out_result, + SEXP call_state ); /*! @@ -566,18 +566,18 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterPredictForCSC_R( * \param out prediction result * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterPredictForMat_R( - LGBM_SE handle, - LGBM_SE data, - LGBM_SE nrow, - LGBM_SE ncol, - LGBM_SE is_rawscore, - LGBM_SE is_leafidx, - LGBM_SE is_predcontrib, - LGBM_SE num_iteration, - LGBM_SE parameter, - LGBM_SE out_result, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterPredictForMat_R( + SEXP handle, + SEXP data, + SEXP nrow, + SEXP ncol, + SEXP is_rawscore, + SEXP is_leafidx, + SEXP is_predcontrib, + SEXP num_iteration, + SEXP parameter, + SEXP out_result, + SEXP call_state ); /*! @@ -587,11 +587,11 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterPredictForMat_R( * \param filename file name * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterSaveModel_R( - LGBM_SE handle, - LGBM_SE num_iteration, - LGBM_SE filename, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterSaveModel_R( + SEXP handle, + SEXP num_iteration, + SEXP filename, + SEXP call_state ); /*! @@ -601,13 +601,13 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterSaveModel_R( * \param out_str string of model * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterSaveModelToString_R( - LGBM_SE handle, - LGBM_SE num_iteration, - LGBM_SE buffer_len, - LGBM_SE actual_len, - LGBM_SE out_str, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterSaveModelToString_R( + SEXP handle, + SEXP num_iteration, + SEXP buffer_len, + SEXP actual_len, + SEXP out_str, + SEXP call_state ); /*! @@ -617,13 +617,13 @@ LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterSaveModelToString_R( * \param out_str json format string of model * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterDumpModel_R( - LGBM_SE handle, - LGBM_SE num_iteration, - LGBM_SE buffer_len, - LGBM_SE actual_len, - LGBM_SE out_str, - LGBM_SE call_state +LIGHTGBM_C_EXPORT SEXP LGBM_BoosterDumpModel_R( + SEXP handle, + SEXP num_iteration, + SEXP buffer_len, + SEXP actual_len, + SEXP out_str, + SEXP call_state ); #endif // LIGHTGBM_R_H_ From 88b495027d4a19397518dd8c3e97aa05dd410f46 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 10 Mar 2020 20:28:15 -0500 Subject: [PATCH 03/41] fixed error about ocnflicting definitions of length --- include/LightGBM/R_object_helper.h | 4 ++++ src/lightgbm_R.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/LightGBM/R_object_helper.h b/include/LightGBM/R_object_helper.h index 14ad7b5e383a..ed0197a802f0 100644 --- a/include/LightGBM/R_object_helper.h +++ b/include/LightGBM/R_object_helper.h @@ -13,6 +13,10 @@ #ifndef R_OBJECT_HELPER_H_ #define R_OBJECT_HELPER_H_ +// https://github.com/nimble-dev/nimble/issues/307#issue-224932135 +#define R_NO_REMAP +#include + #include #define TYPE_BITS 5 diff --git a/src/lightgbm_R.cpp b/src/lightgbm_R.cpp index cbbafa445a7e..ec17c10d0853 100644 --- a/src/lightgbm_R.cpp +++ b/src/lightgbm_R.cpp @@ -52,7 +52,7 @@ SEXP LGBM_GetLastError_R(SEXP buf_len, SEXP actual_len, SEXP err_msg) { return EncodeChar(err_msg, LGBM_GetLastError(), buf_len, actual_len, std::strlen(LGBM_GetLastError()) + 1); } -SEXP LGBM_DatasetCreateFromFile_R(EXP filename, +SEXP LGBM_DatasetCreateFromFile_R(SEXP filename, SEXP parameters, SEXP reference, SEXP out, From f12eaa29965d20dba6a2a85db00ab00d0fe57c29 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Wed, 11 Mar 2020 00:47:20 -0500 Subject: [PATCH 04/41] got linking working --- CMakeLists.txt | 8 + R-package/src/cmake/modules/FindLibR.cmake | 173 +++++++++++++++++++++ include/LightGBM/R_object_helper.h | 22 +-- 3 files changed, 189 insertions(+), 14 deletions(-) create mode 100644 R-package/src/cmake/modules/FindLibR.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ba9e9b631b11..3c70b2cb3707 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,10 @@ OPTION(USE_TIMETAG "Set to ON to output time costs" OFF) OPTION(USE_DEBUG "Set to ON for Debug mode" OFF) OPTION(BUILD_FOR_R "Set to ON if building lib_lightgbm for use with the R package" OFF) +list(APPEND CMAKE_MODULE_PATH "${lightgbm_SOURCE_DIR}/cmake/modules") +find_package(LibR REQUIRED) +message(STATUS "LIBR_CORE_LIBRARY " ${LIBR_CORE_LIBRARY}) + if(APPLE) OPTION(APPLE_OUTPUT_DYLIB "Output dylib shared library" OFF) endif(APPLE) @@ -303,6 +307,10 @@ if(WIN32 AND (MINGW OR CYGWIN)) TARGET_LINK_LIBRARIES(_lightgbm IPHLPAPI) endif() +# link to R +TARGET_LINK_LIBRARIES(lightgbm ${LIBR_CORE_LIBRARY}) +TARGET_LINK_LIBRARIES(_lightgbm ${LIBR_CORE_LIBRARY}) + install(TARGETS lightgbm _lightgbm RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake new file mode 100644 index 000000000000..c0252e0e3705 --- /dev/null +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -0,0 +1,173 @@ +# CMake module for R to find the location of R +# +# Borrows heavily from xgboost's R package +# +# Defines the following: +# LIBR_FOUND +# LIBR_HOME +# LIBR_EXECUTABLE +# LIBR_INCLUDE_DIRS +# LIBR_LIB_DIR +# LIBR_CORE_LIBRARY +# and a cmake function to create R.lib for MSVC + + +# Windows users might want to change this to their R version: +if(NOT R_VERSION) + set(R_VERSION "3.4.1") +endif() +if(NOT R_ARCH) + if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") + set(R_ARCH "i386") + else() + set(R_ARCH "x64") + endif() +endif() + +# Creates R.lib and R.def in the build directory for linking with MSVC +function(create_rlib_for_msvc) + # various checks and warnings + if(NOT WIN32 OR NOT MSVC) + message(FATAL_ERROR "create_rlib_for_msvc() can only be used with MSVC") + endif() + if(NOT EXISTS "${LIBR_LIB_DIR}") + message(FATAL_ERROR "LIBR_LIB_DIR was not set!") + endif() + find_program(GENDEF_EXE gendef) + find_program(DLLTOOL_EXE dlltool) + if(NOT GENDEF_EXE OR NOT DLLTOOL_EXE) + message(FATAL_ERROR "\nEither gendef.exe or dlltool.exe not found!\ + \nDo you have Rtools installed with its MinGW's bin/ in PATH?") + endif() + # extract symbols from R.dll into R.def and R.lib import library + execute_process(COMMAND gendef + "-" "${LIBR_LIB_DIR}/R.dll" + OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/R.def") + execute_process(COMMAND dlltool + "--input-def" "${CMAKE_CURRENT_BINARY_DIR}/R.def" + "--output-lib" "${CMAKE_CURRENT_BINARY_DIR}/R.lib") +endfunction(create_rlib_for_msvc) + + +# detection for OSX +if(APPLE) + + find_library(LIBR_LIBRARIES R) + + if(LIBR_LIBRARIES MATCHES ".*\\.framework") + set(LIBR_HOME "${LIBR_LIBRARIES}/Resources" CACHE PATH "R home directory") + set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include" CACHE PATH "R include directory") + set(LIBR_EXECUTABLE "${LIBR_HOME}/R" CACHE PATH "R executable") + set(LIBR_LIB_DIR "${LIBR_HOME}/lib" CACHE PATH "R lib directory") + else() + get_filename_component(_LIBR_LIBRARIES "${LIBR_LIBRARIES}" REALPATH) + get_filename_component(_LIBR_LIBRARIES_DIR "${_LIBR_LIBRARIES}" DIRECTORY) + set(LIBR_EXECUTABLE "${_LIBR_LIBRARIES_DIR}/../bin/R") + execute_process( + COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home())" + OUTPUT_VARIABLE LIBR_HOME) + set(LIBR_HOME ${LIBR_HOME} CACHE PATH "R home directory") + set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include" CACHE PATH "R include directory") + set(LIBR_LIB_DIR "${LIBR_HOME}/lib" CACHE PATH "R lib directory") + endif() + +# detection for UNIX & Win32 +else() + + # attempt to find R executable + if(NOT LIBR_EXECUTABLE) + find_program(LIBR_EXECUTABLE NAMES R R.exe) + endif() + + if(UNIX) + + if(NOT LIBR_EXECUTABLE) + message(FATAL_ERROR "Unable to locate R executable.\ + \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE cmake variable") + endif() + + # ask R for the home path + execute_process( + COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home())" + OUTPUT_VARIABLE LIBR_HOME + ) + # ask R for the include dir + execute_process( + COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('include'))" + OUTPUT_VARIABLE LIBR_INCLUDE_DIRS + ) + # ask R for the lib dir + execute_process( + COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('lib'))" + OUTPUT_VARIABLE LIBR_LIB_DIR + ) + + # Windows + else() + # ask R for R_HOME + if(LIBR_EXECUTABLE) + execute_process( + COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(normalizePath(R.home(),winslash='/'))" + OUTPUT_VARIABLE LIBR_HOME) + endif() + # if R executable not available, query R_HOME path from registry + if(NOT LIBR_HOME) + get_filename_component(LIBR_HOME + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\R-core\\R\\${R_VERSION};InstallPath]" + ABSOLUTE) + if(NOT LIBR_HOME) + message(FATAL_ERROR "\nUnable to locate R executable.\ + \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE cmake variable") + endif() + endif() + # set exe location based on R_ARCH + if(NOT LIBR_EXECUTABLE) + set(LIBR_EXECUTABLE "${LIBR_HOME}/bin/${R_ARCH}/R.exe") + endif() + # set other R paths based on home path + set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include") + set(LIBR_LIB_DIR "${LIBR_HOME}/bin/${R_ARCH}") + +message(STATUS "LIBR_HOME [${LIBR_HOME}]") +message(STATUS "LIBR_EXECUTABLE [${LIBR_EXECUTABLE}]") +message(STATUS "LIBR_INCLUDE_DIRS [${LIBR_INCLUDE_DIRS}]") +message(STATUS "LIBR_LIB_DIR [${LIBR_LIB_DIR}]") +message(STATUS "LIBR_CORE_LIBRARY [${LIBR_CORE_LIBRARY}]") + + endif() + +endif() + +if(WIN32 AND MSVC) + # create a local R.lib import library for R.dll if it doesn't exist + if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/R.lib") + create_rlib_for_msvc() + endif() +endif() + +# look for the core R library +find_library(LIBR_CORE_LIBRARY NAMES R + HINTS "${CMAKE_CURRENT_BINARY_DIR}" "${LIBR_LIB_DIR}" "${LIBR_HOME}/bin" "${LIBR_LIBRARIES}") +if(LIBR_CORE_LIBRARY-NOTFOUND) + message(STATUS "Could not find R core shared library.") +endif() + +set(LIBR_HOME ${LIBR_HOME} CACHE PATH "R home directory") +set(LIBR_EXECUTABLE ${LIBR_EXECUTABLE} CACHE PATH "R executable") +set(LIBR_INCLUDE_DIRS ${LIBR_INCLUDE_DIRS} CACHE PATH "R include directory") +set(LIBR_LIB_DIR ${LIBR_LIB_DIR} CACHE PATH "R shared libraries directory") +set(LIBR_CORE_LIBRARY ${LIBR_CORE_LIBRARY} CACHE PATH "R core shared library") + +# define find requirements +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LibR DEFAULT_MSG + LIBR_HOME + LIBR_EXECUTABLE + LIBR_INCLUDE_DIRS + LIBR_LIB_DIR + LIBR_CORE_LIBRARY +) + +if(LIBR_FOUND) + message(STATUS "Found R: ${LIBR_EXECUTABLE}") +endif() diff --git a/include/LightGBM/R_object_helper.h b/include/LightGBM/R_object_helper.h index ed0197a802f0..51d3fa53022e 100644 --- a/include/LightGBM/R_object_helper.h +++ b/include/LightGBM/R_object_helper.h @@ -13,11 +13,13 @@ #ifndef R_OBJECT_HELPER_H_ #define R_OBJECT_HELPER_H_ +#include +#include + // https://github.com/nimble-dev/nimble/issues/307#issue-224932135 #define R_NO_REMAP #include - -#include +//#include #define TYPE_BITS 5 // use .Internal(internalsID()) to uuid @@ -41,13 +43,6 @@ unsigned int extra : 32 - NAMED_BITS; }; - // 64bit pointer - #if INTPTR_MAX == INT64_MAX - typedef int64_t R_xlen_t; - #else - typedef int R_xlen_t; - #endif - #else struct lgbm_sxpinfo { unsigned int type : 5; @@ -62,7 +57,6 @@ unsigned int gccls : 3; }; - typedef int R_xlen_t; #endif // R_VER_ABOVE_35 struct lgbm_primsxp { @@ -111,7 +105,7 @@ typedef struct LGBM_SER { struct lgbm_closxp closxp; struct lgbm_promsxp promsxp; } u; -} LGBM_SER, *LGBM_SE; +} LGBM_SER; struct lgbm_vecsxp { R_xlen_t length; @@ -141,7 +135,7 @@ typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN; #define R_AS_INT64(x) (*(reinterpret_cast DATAPTR(x))) -#define R_IS_NULL(x) ((*reinterpret_cast(x)).sxpinfo.type == 0) +// #define R_IS_NULL(x) ((*reinterpret_cast(x)).sxpinfo.type == 0) // 64bit pointer #if INTPTR_MAX == INT64_MAX @@ -157,7 +151,7 @@ typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN; } inline void* R_GET_PTR(SEXP x) { - if (R_IS_NULL(x)) { + if (R_ExternalPtrAddr(x) == NULL) { return nullptr; } else { auto ret = reinterpret_cast(R_ADDR(x)[0]); @@ -181,7 +175,7 @@ typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN; } inline void* R_GET_PTR(SEXP x) { - if (R_IS_NULL(x)) { + if (R_ExternalPtrAddr(x) == NULL) { return nullptr; } else { auto ret = reinterpret_cast(R_ADDR(x)[0]); From 35e1b42e909d9300274b33d7ce9965022853789c Mon Sep 17 00:00:00 2001 From: James Lamb Date: Wed, 11 Mar 2020 01:01:43 -0500 Subject: [PATCH 05/41] more stuff --- CMakeLists.txt | 14 +++++++------- include/LightGBM/R_object_helper.h | 9 +++++++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c70b2cb3707..7ba9e9bc55a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,10 +16,6 @@ OPTION(USE_TIMETAG "Set to ON to output time costs" OFF) OPTION(USE_DEBUG "Set to ON for Debug mode" OFF) OPTION(BUILD_FOR_R "Set to ON if building lib_lightgbm for use with the R package" OFF) -list(APPEND CMAKE_MODULE_PATH "${lightgbm_SOURCE_DIR}/cmake/modules") -find_package(LibR REQUIRED) -message(STATUS "LIBR_CORE_LIBRARY " ${LIBR_CORE_LIBRARY}) - if(APPLE) OPTION(APPLE_OUTPUT_DYLIB "Output dylib shared library" OFF) endif(APPLE) @@ -76,6 +72,9 @@ if(USE_R35) endif(USE_R35) if(BUILD_FOR_R) + list(APPEND CMAKE_MODULE_PATH "${lightgbm_SOURCE_DIR}/cmake/modules") + find_package(LibR REQUIRED) + message(STATUS "LIBR_CORE_LIBRARY " ${LIBR_CORE_LIBRARY}) ADD_DEFINITIONS(-DLGB_R_BUILD) endif(BUILD_FOR_R) @@ -307,9 +306,10 @@ if(WIN32 AND (MINGW OR CYGWIN)) TARGET_LINK_LIBRARIES(_lightgbm IPHLPAPI) endif() -# link to R -TARGET_LINK_LIBRARIES(lightgbm ${LIBR_CORE_LIBRARY}) -TARGET_LINK_LIBRARIES(_lightgbm ${LIBR_CORE_LIBRARY}) +if(BUILD_FOR_R) + TARGET_LINK_LIBRARIES(lightgbm ${LIBR_CORE_LIBRARY}) + TARGET_LINK_LIBRARIES(_lightgbm ${LIBR_CORE_LIBRARY}) +endif(BUILD_FOR_R) install(TARGETS lightgbm _lightgbm RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin diff --git a/include/LightGBM/R_object_helper.h b/include/LightGBM/R_object_helper.h index 51d3fa53022e..bf1f282fae20 100644 --- a/include/LightGBM/R_object_helper.h +++ b/include/LightGBM/R_object_helper.h @@ -137,6 +137,11 @@ typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN; // #define R_IS_NULL(x) ((*reinterpret_cast(x)).sxpinfo.type == 0) +// https://stackoverflow.com/questions/26666614/how-do-i-check-if-an-externalptr-is-null-from-within-r +SEXP R_IS_NULL(SEXP pointer) { + return ScalarLogical(!R_ExternalPtrAddr(pointer)); +} + // 64bit pointer #if INTPTR_MAX == INT64_MAX @@ -151,7 +156,7 @@ typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN; } inline void* R_GET_PTR(SEXP x) { - if (R_ExternalPtrAddr(x) == NULL) { + if (R_IS_NULL(x)) { return nullptr; } else { auto ret = reinterpret_cast(R_ADDR(x)[0]); @@ -175,7 +180,7 @@ typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN; } inline void* R_GET_PTR(SEXP x) { - if (R_ExternalPtrAddr(x) == NULL) { + if (R_IS_NULL(x)) { return nullptr; } else { auto ret = reinterpret_cast(R_ADDR(x)[0]); From 608f5a858c4e1021ece6adb32307acb774084876 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Wed, 11 Mar 2020 21:29:12 -0500 Subject: [PATCH 06/41] eliminated R CMD CHECK note about printing --- include/LightGBM/R_object_helper.h | 35 +-- include/LightGBM/lightgbm_R.h | 456 ++++++++++++++--------------- include/LightGBM/utils/log.h | 37 ++- src/lightgbm_R.cpp | 373 ++++++++++++----------- 4 files changed, 457 insertions(+), 444 deletions(-) diff --git a/include/LightGBM/R_object_helper.h b/include/LightGBM/R_object_helper.h index bf1f282fae20..1464c0a7083f 100644 --- a/include/LightGBM/R_object_helper.h +++ b/include/LightGBM/R_object_helper.h @@ -13,14 +13,8 @@ #ifndef R_OBJECT_HELPER_H_ #define R_OBJECT_HELPER_H_ -#include #include -// https://github.com/nimble-dev/nimble/issues/307#issue-224932135 -#define R_NO_REMAP -#include -//#include - #define TYPE_BITS 5 // use .Internal(internalsID()) to uuid #define R_INTERNALS_UUID "2fdf6c18-697a-4ba7-b8ef-11c0d92f1327" @@ -43,6 +37,13 @@ unsigned int extra : 32 - NAMED_BITS; }; + // 64bit pointer + #if INTPTR_MAX == INT64_MAX + typedef int64_t xlen_t; + #else + typedef int xlen_t; + #endif + #else struct lgbm_sxpinfo { unsigned int type : 5; @@ -57,6 +58,7 @@ unsigned int gccls : 3; }; + typedef int xlen_t; #endif // R_VER_ABOVE_35 struct lgbm_primsxp { @@ -105,11 +107,11 @@ typedef struct LGBM_SER { struct lgbm_closxp closxp; struct lgbm_promsxp promsxp; } u; -} LGBM_SER; +} LGBM_SER, *LGBM_SE; struct lgbm_vecsxp { - R_xlen_t length; - R_xlen_t truelength; + xlen_t length; + xlen_t truelength; }; typedef struct VECTOR_SER { @@ -135,19 +137,14 @@ typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN; #define R_AS_INT64(x) (*(reinterpret_cast DATAPTR(x))) -// #define R_IS_NULL(x) ((*reinterpret_cast(x)).sxpinfo.type == 0) - -// https://stackoverflow.com/questions/26666614/how-do-i-check-if-an-externalptr-is-null-from-within-r -SEXP R_IS_NULL(SEXP pointer) { - return ScalarLogical(!R_ExternalPtrAddr(pointer)); -} +#define R_IS_NULL(x) ((*reinterpret_cast(x)).sxpinfo.type == 0) // 64bit pointer #if INTPTR_MAX == INT64_MAX #define R_ADDR(x) (reinterpret_cast DATAPTR(x)) - inline void R_SET_PTR(SEXP x, void* ptr) { + inline void R_SET_PTR(LGBM_SE x, void* ptr) { if (ptr == nullptr) { R_ADDR(x)[0] = (int64_t)(NULL); } else { @@ -155,7 +152,7 @@ SEXP R_IS_NULL(SEXP pointer) { } } - inline void* R_GET_PTR(SEXP x) { + inline void* R_GET_PTR(LGBM_SE x) { if (R_IS_NULL(x)) { return nullptr; } else { @@ -171,7 +168,7 @@ SEXP R_IS_NULL(SEXP pointer) { #define R_ADDR(x) (reinterpret_cast DATAPTR(x)) - inline void R_SET_PTR(SEXP x, void* ptr) { + inline void R_SET_PTR(LGBM_SE x, void* ptr) { if (ptr == nullptr) { R_ADDR(x)[0] = (int32_t)(NULL); } else { @@ -179,7 +176,7 @@ SEXP R_IS_NULL(SEXP pointer) { } } - inline void* R_GET_PTR(SEXP x) { + inline void* R_GET_PTR(LGBM_SE x) { if (R_IS_NULL(x)) { return nullptr; } else { diff --git a/include/LightGBM/lightgbm_R.h b/include/LightGBM/lightgbm_R.h index 6d898be38ef4..076ea2946384 100644 --- a/include/LightGBM/lightgbm_R.h +++ b/include/LightGBM/lightgbm_R.h @@ -15,10 +15,10 @@ * \return err_msg error information * \return error information */ -LIGHTGBM_C_EXPORT SEXP LGBM_GetLastError_R( - SEXP buf_len, - SEXP actual_len, - SEXP err_msg +LIGHTGBM_C_EXPORT LGBM_SE LGBM_GetLastError_R( + LGBM_SE buf_len, + LGBM_SE actual_len, + LGBM_SE err_msg ); // --- start Dataset interface @@ -31,12 +31,12 @@ LIGHTGBM_C_EXPORT SEXP LGBM_GetLastError_R( * \param out created dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetCreateFromFile_R( - SEXP filename, - SEXP parameters, - SEXP reference, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetCreateFromFile_R( + LGBM_SE filename, + LGBM_SE parameters, + LGBM_SE reference, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -52,17 +52,17 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetCreateFromFile_R( * \param out created dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetCreateFromCSC_R( - SEXP indptr, - SEXP indices, - SEXP data, - SEXP nindptr, - SEXP nelem, - SEXP num_row, - SEXP parameters, - SEXP reference, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetCreateFromCSC_R( + LGBM_SE indptr, + LGBM_SE indices, + LGBM_SE data, + LGBM_SE nindptr, + LGBM_SE nelem, + LGBM_SE num_row, + LGBM_SE parameters, + LGBM_SE reference, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -75,14 +75,14 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetCreateFromCSC_R( * \param out created dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetCreateFromMat_R( - SEXP data, - SEXP nrow, - SEXP ncol, - SEXP parameters, - SEXP reference, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetCreateFromMat_R( + LGBM_SE data, + LGBM_SE nrow, + LGBM_SE ncol, + LGBM_SE parameters, + LGBM_SE reference, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -94,13 +94,13 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetCreateFromMat_R( * \param out created dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetSubset_R( - SEXP handle, - SEXP used_row_indices, - SEXP len_used_row_indices, - SEXP parameters, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetSubset_R( + LGBM_SE handle, + LGBM_SE used_row_indices, + LGBM_SE len_used_row_indices, + LGBM_SE parameters, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -109,10 +109,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetSubset_R( * \param feature_names feature names * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetSetFeatureNames_R( - SEXP handle, - SEXP feature_names, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetSetFeatureNames_R( + LGBM_SE handle, + LGBM_SE feature_names, + LGBM_SE call_state ); /*! @@ -121,12 +121,12 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetSetFeatureNames_R( * \param feature_names feature names * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetFeatureNames_R( - SEXP handle, - SEXP buf_len, - SEXP actual_len, - SEXP feature_names, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetFeatureNames_R( + LGBM_SE handle, + LGBM_SE buf_len, + LGBM_SE actual_len, + LGBM_SE feature_names, + LGBM_SE call_state ); /*! @@ -135,10 +135,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetFeatureNames_R( * \param filename file name * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetSaveBinary_R( - SEXP handle, - SEXP filename, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetSaveBinary_R( + LGBM_SE handle, + LGBM_SE filename, + LGBM_SE call_state ); /*! @@ -146,9 +146,9 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetSaveBinary_R( * \param handle an instance of dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetFree_R( - SEXP handle, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetFree_R( + LGBM_SE handle, + LGBM_SE call_state ); /*! @@ -161,12 +161,12 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetFree_R( * \param num_element number of element in field_data * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetSetField_R( - SEXP handle, - SEXP field_name, - SEXP field_data, - SEXP num_element, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetSetField_R( + LGBM_SE handle, + LGBM_SE field_name, + LGBM_SE field_data, + LGBM_SE num_element, + LGBM_SE call_state ); /*! @@ -176,11 +176,11 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetSetField_R( * \param out size of info vector from dataset * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetFieldSize_R( - SEXP handle, - SEXP field_name, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetFieldSize_R( + LGBM_SE handle, + LGBM_SE field_name, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -190,11 +190,11 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetFieldSize_R( * \param field_data pointer to vector * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetField_R( - SEXP handle, - SEXP field_name, - SEXP field_data, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetField_R( + LGBM_SE handle, + LGBM_SE field_name, + LGBM_SE field_data, + LGBM_SE call_state ); /*! @@ -203,10 +203,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetField_R( * \param new_params New dataset parameters * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetUpdateParamChecking_R( - SEXP old_params, - SEXP new_params, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetUpdateParamChecking_R( + LGBM_SE old_params, + LGBM_SE new_params, + LGBM_SE call_state ); /*! @@ -215,10 +215,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetUpdateParamChecking_R( * \param out The address to hold number of data * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetNumData_R( - SEXP handle, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetNumData_R( + LGBM_SE handle, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -227,10 +227,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetNumData_R( * \param out The output of number of features * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetNumFeature_R( - SEXP handle, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_DatasetGetNumFeature_R( + LGBM_SE handle, + LGBM_SE out, + LGBM_SE call_state ); // --- start Booster interfaces @@ -242,11 +242,11 @@ LIGHTGBM_C_EXPORT SEXP LGBM_DatasetGetNumFeature_R( * \param out handle of created Booster * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterCreate_R( - SEXP train_data, - SEXP parameters, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterCreate_R( + LGBM_SE train_data, + LGBM_SE parameters, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -254,9 +254,9 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterCreate_R( * \param handle handle to be freed * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterFree_R( - SEXP handle, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterFree_R( + LGBM_SE handle, + LGBM_SE call_state ); /*! @@ -265,10 +265,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterFree_R( * \param out handle of created Booster * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterCreateFromModelfile_R( - SEXP filename, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterCreateFromModelfile_R( + LGBM_SE filename, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -277,10 +277,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterCreateFromModelfile_R( * \param out handle of created Booster * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterLoadModelFromString_R( - SEXP model_str, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterLoadModelFromString_R( + LGBM_SE model_str, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -289,10 +289,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterLoadModelFromString_R( * \param other_handle * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterMerge_R( - SEXP handle, - SEXP other_handle, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterMerge_R( + LGBM_SE handle, + LGBM_SE other_handle, + LGBM_SE call_state ); /*! @@ -301,10 +301,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterMerge_R( * \param valid_data validation data set * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterAddValidData_R( - SEXP handle, - SEXP valid_data, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterAddValidData_R( + LGBM_SE handle, + LGBM_SE valid_data, + LGBM_SE call_state ); /*! @@ -313,10 +313,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterAddValidData_R( * \param train_data training data set * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterResetTrainingData_R( - SEXP handle, - SEXP train_data, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterResetTrainingData_R( + LGBM_SE handle, + LGBM_SE train_data, + LGBM_SE call_state ); /*! @@ -325,10 +325,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterResetTrainingData_R( * \param parameters format: 'key1=value1 key2=value2' * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterResetParameter_R( - SEXP handle, - SEXP parameters, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterResetParameter_R( + LGBM_SE handle, + LGBM_SE parameters, + LGBM_SE call_state ); /*! @@ -337,10 +337,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterResetParameter_R( * \param out number of classes * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetNumClasses_R( - SEXP handle, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetNumClasses_R( + LGBM_SE handle, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -348,9 +348,9 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetNumClasses_R( * \param handle handle * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterUpdateOneIter_R( - SEXP handle, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterUpdateOneIter_R( + LGBM_SE handle, + LGBM_SE call_state ); /*! @@ -362,12 +362,12 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterUpdateOneIter_R( * \param len length of grad/hess * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterUpdateOneIterCustom_R( - SEXP handle, - SEXP grad, - SEXP hess, - SEXP len, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterUpdateOneIterCustom_R( + LGBM_SE handle, + LGBM_SE grad, + LGBM_SE hess, + LGBM_SE len, + LGBM_SE call_state ); /*! @@ -375,9 +375,9 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterUpdateOneIterCustom_R( * \param handle handle * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterRollbackOneIter_R( - SEXP handle, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterRollbackOneIter_R( + LGBM_SE handle, + LGBM_SE call_state ); /*! @@ -385,10 +385,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterRollbackOneIter_R( * \param out iteration of boosting rounds * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetCurrentIteration_R( - SEXP handle, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetCurrentIteration_R( + LGBM_SE handle, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -397,10 +397,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetCurrentIteration_R( * \param[out] out_results Result pointing to max value * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetUpperBoundValue_R( - SEXP handle, - SEXP out_result, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetUpperBoundValue_R( + LGBM_SE handle, + LGBM_SE out_result, + LGBM_SE call_state ); /*! @@ -409,10 +409,10 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetUpperBoundValue_R( * \param[out] out_results Result pointing to min value * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetLowerBoundValue_R( - SEXP handle, - SEXP out_result, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetLowerBoundValue_R( + LGBM_SE handle, + LGBM_SE out_result, + LGBM_SE call_state ); /*! @@ -420,12 +420,12 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetLowerBoundValue_R( * \param eval_names eval names * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetEvalNames_R( - SEXP handle, - SEXP buf_len, - SEXP actual_len, - SEXP eval_names, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetEvalNames_R( + LGBM_SE handle, + LGBM_SE buf_len, + LGBM_SE actual_len, + LGBM_SE eval_names, + LGBM_SE call_state ); /*! @@ -435,11 +435,11 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetEvalNames_R( * \param out_result float array contains result * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetEval_R( - SEXP handle, - SEXP data_idx, - SEXP out_result, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetEval_R( + LGBM_SE handle, + LGBM_SE data_idx, + LGBM_SE out_result, + LGBM_SE call_state ); /*! @@ -449,11 +449,11 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetEval_R( * \param out size of predict * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetNumPredict_R( - SEXP handle, - SEXP data_idx, - SEXP out, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetNumPredict_R( + LGBM_SE handle, + LGBM_SE data_idx, + LGBM_SE out, + LGBM_SE call_state ); /*! @@ -464,11 +464,11 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetNumPredict_R( * \param out_result, used to store predict result, should pre-allocate memory * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetPredict_R( - SEXP handle, - SEXP data_idx, - SEXP out_result, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterGetPredict_R( + LGBM_SE handle, + LGBM_SE data_idx, + LGBM_SE out_result, + LGBM_SE call_state ); /*! @@ -482,17 +482,17 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterGetPredict_R( * \return 0 when succeed, -1 when failure happens * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterPredictForFile_R( - SEXP handle, - SEXP data_filename, - SEXP data_has_header, - SEXP is_rawscore, - SEXP is_leafidx, - SEXP is_predcontrib, - SEXP num_iteration, - SEXP parameter, - SEXP result_filename, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterPredictForFile_R( + LGBM_SE handle, + LGBM_SE data_filename, + LGBM_SE data_has_header, + LGBM_SE is_rawscore, + LGBM_SE is_leafidx, + LGBM_SE is_predcontrib, + LGBM_SE num_iteration, + LGBM_SE parameter, + LGBM_SE result_filename, + LGBM_SE call_state ); /*! @@ -505,15 +505,15 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterPredictForFile_R( * \param out_len length of prediction * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterCalcNumPredict_R( - SEXP handle, - SEXP num_row, - SEXP is_rawscore, - SEXP is_leafidx, - SEXP is_predcontrib, - SEXP num_iteration, - SEXP out_len, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterCalcNumPredict_R( + LGBM_SE handle, + LGBM_SE num_row, + LGBM_SE is_rawscore, + LGBM_SE is_leafidx, + LGBM_SE is_predcontrib, + LGBM_SE num_iteration, + LGBM_SE out_len, + LGBM_SE call_state ); /*! @@ -534,21 +534,21 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterCalcNumPredict_R( * \param out prediction result * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterPredictForCSC_R( - SEXP handle, - SEXP indptr, - SEXP indices, - SEXP data, - SEXP nindptr, - SEXP nelem, - SEXP num_row, - SEXP is_rawscore, - SEXP is_leafidx, - SEXP is_predcontrib, - SEXP num_iteration, - SEXP parameter, - SEXP out_result, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterPredictForCSC_R( + LGBM_SE handle, + LGBM_SE indptr, + LGBM_SE indices, + LGBM_SE data, + LGBM_SE nindptr, + LGBM_SE nelem, + LGBM_SE num_row, + LGBM_SE is_rawscore, + LGBM_SE is_leafidx, + LGBM_SE is_predcontrib, + LGBM_SE num_iteration, + LGBM_SE parameter, + LGBM_SE out_result, + LGBM_SE call_state ); /*! @@ -566,18 +566,18 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterPredictForCSC_R( * \param out prediction result * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterPredictForMat_R( - SEXP handle, - SEXP data, - SEXP nrow, - SEXP ncol, - SEXP is_rawscore, - SEXP is_leafidx, - SEXP is_predcontrib, - SEXP num_iteration, - SEXP parameter, - SEXP out_result, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterPredictForMat_R( + LGBM_SE handle, + LGBM_SE data, + LGBM_SE nrow, + LGBM_SE ncol, + LGBM_SE is_rawscore, + LGBM_SE is_leafidx, + LGBM_SE is_predcontrib, + LGBM_SE num_iteration, + LGBM_SE parameter, + LGBM_SE out_result, + LGBM_SE call_state ); /*! @@ -587,11 +587,11 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterPredictForMat_R( * \param filename file name * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterSaveModel_R( - SEXP handle, - SEXP num_iteration, - SEXP filename, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterSaveModel_R( + LGBM_SE handle, + LGBM_SE num_iteration, + LGBM_SE filename, + LGBM_SE call_state ); /*! @@ -601,13 +601,13 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterSaveModel_R( * \param out_str string of model * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterSaveModelToString_R( - SEXP handle, - SEXP num_iteration, - SEXP buffer_len, - SEXP actual_len, - SEXP out_str, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterSaveModelToString_R( + LGBM_SE handle, + LGBM_SE num_iteration, + LGBM_SE buffer_len, + LGBM_SE actual_len, + LGBM_SE out_str, + LGBM_SE call_state ); /*! @@ -617,13 +617,13 @@ LIGHTGBM_C_EXPORT SEXP LGBM_BoosterSaveModelToString_R( * \param out_str json format string of model * \return 0 when succeed, -1 when failure happens */ -LIGHTGBM_C_EXPORT SEXP LGBM_BoosterDumpModel_R( - SEXP handle, - SEXP num_iteration, - SEXP buffer_len, - SEXP actual_len, - SEXP out_str, - SEXP call_state +LIGHTGBM_C_EXPORT LGBM_SE LGBM_BoosterDumpModel_R( + LGBM_SE handle, + LGBM_SE num_iteration, + LGBM_SE buffer_len, + LGBM_SE actual_len, + LGBM_SE out_str, + LGBM_SE call_state ); #endif // LIGHTGBM_R_H_ diff --git a/include/LightGBM/utils/log.h b/include/LightGBM/utils/log.h index 75809c6a19cb..119495406618 100644 --- a/include/LightGBM/utils/log.h +++ b/include/LightGBM/utils/log.h @@ -14,6 +14,13 @@ #include #include +#ifdef LGB_R_BUILD + #define R_NO_REMAP + #define R_USE_C99_IN_CXX + #include + #include +#endif + namespace LightGBM { #if defined(_MSC_VER) @@ -57,7 +64,6 @@ namespace LightGBM { if ((pointer) == nullptr) LightGBM::Log::Fatal(#pointer " Can't be NULL at %s, line %d .\n", __FILE__, __LINE__); #endif - enum class LogLevel: int { Fatal = -1, Warning = 0, @@ -65,7 +71,6 @@ enum class LogLevel: int { Debug = 2, }; - /*! * \brief A static Log class */ @@ -107,19 +112,31 @@ class Log { vsprintf(str_buf, format, val); #endif va_end(val); - fprintf(stderr, "[LightGBM] [Fatal] %s\n", str_buf); - fflush(stderr); - throw std::runtime_error(std::string(str_buf)); + + #ifndef LGB_R_BUILD + fprintf(stderr, "[LightGBM] [Fatal] %s\n", str_buf); + fflush(stderr); + throw std::runtime_error(std::string(str_buf)); + #else + Rf_error("[LightGBM] [Fatal] %s\n", str_buf); + #endif } private: static void Write(LogLevel level, const char* level_str, const char *format, va_list val) { if (level <= GetLevel()) { // omit the message with low level - // write to STDOUT - printf("[LightGBM] [%s] ", level_str); - vprintf(format, val); - printf("\n"); - fflush(stdout); + #ifndef LGB_R_BUILD + // write to STDOUT + printf("[LightGBM] [%s] ", level_str); + vprintf(format, val); + printf("\n"); + fflush(stdout); + #else + // write to STDOUT + Rprintf("[LightGBM] [%s] ", level_str); + Rvprintf(format, val); + Rprintf("\n"); + #endif } } diff --git a/src/lightgbm_R.cpp b/src/lightgbm_R.cpp index ec17c10d0853..4ba70a5f1c22 100644 --- a/src/lightgbm_R.cpp +++ b/src/lightgbm_R.cpp @@ -20,7 +20,6 @@ #define R_API_BEGIN() \ try { - #define R_API_END() } \ catch(std::exception& ex) { R_INT_PTR(call_state)[0] = -1; LGBM_SetLastError(ex.what()); return call_state;} \ catch(std::string& ex) { R_INT_PTR(call_state)[0] = -1; LGBM_SetLastError(ex.c_str()); return call_state; } \ @@ -35,7 +34,7 @@ using namespace LightGBM; -SEXP EncodeChar(SEXP dest, const char* src, SEXP buf_len, SEXP actual_len, size_t str_len) { +LGBM_SE EncodeChar(LGBM_SE dest, const char* src, LGBM_SE buf_len, LGBM_SE actual_len, size_t str_len) { if (str_len > INT32_MAX) { Log::Fatal("Don't support large string in R-package"); } @@ -48,15 +47,15 @@ SEXP EncodeChar(SEXP dest, const char* src, SEXP buf_len, SEXP actual_len, size_ return dest; } -SEXP LGBM_GetLastError_R(SEXP buf_len, SEXP actual_len, SEXP err_msg) { +LGBM_SE LGBM_GetLastError_R(LGBM_SE buf_len, LGBM_SE actual_len, LGBM_SE err_msg) { return EncodeChar(err_msg, LGBM_GetLastError(), buf_len, actual_len, std::strlen(LGBM_GetLastError()) + 1); } -SEXP LGBM_DatasetCreateFromFile_R(SEXP filename, - SEXP parameters, - SEXP reference, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_DatasetCreateFromFile_R(LGBM_SE filename, + LGBM_SE parameters, + LGBM_SE reference, + LGBM_SE out, + LGBM_SE call_state) { R_API_BEGIN(); DatasetHandle handle = nullptr; CHECK_CALL(LGBM_DatasetCreateFromFile(R_CHAR_PTR(filename), R_CHAR_PTR(parameters), @@ -65,16 +64,16 @@ SEXP LGBM_DatasetCreateFromFile_R(SEXP filename, R_API_END(); } -SEXP LGBM_DatasetCreateFromCSC_R(SEXP indptr, - SEXP indices, - SEXP data, - SEXP num_indptr, - SEXP nelem, - SEXP num_row, - SEXP parameters, - SEXP reference, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_DatasetCreateFromCSC_R(LGBM_SE indptr, + LGBM_SE indices, + LGBM_SE data, + LGBM_SE num_indptr, + LGBM_SE nelem, + LGBM_SE num_row, + LGBM_SE parameters, + LGBM_SE reference, + LGBM_SE out, + LGBM_SE call_state) { R_API_BEGIN(); const int* p_indptr = R_INT_PTR(indptr); const int* p_indices = R_INT_PTR(indices); @@ -91,13 +90,13 @@ SEXP LGBM_DatasetCreateFromCSC_R(SEXP indptr, R_API_END(); } -SEXP LGBM_DatasetCreateFromMat_R(SEXP data, - SEXP num_row, - SEXP num_col, - SEXP parameters, - SEXP reference, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_DatasetCreateFromMat_R(LGBM_SE data, + LGBM_SE num_row, + LGBM_SE num_col, + LGBM_SE parameters, + LGBM_SE reference, + LGBM_SE out, + LGBM_SE call_state) { R_API_BEGIN(); int32_t nrow = static_cast(R_AS_INT(num_row)); int32_t ncol = static_cast(R_AS_INT(num_col)); @@ -109,12 +108,12 @@ SEXP LGBM_DatasetCreateFromMat_R(SEXP data, R_API_END(); } -SEXP LGBM_DatasetGetSubset_R(SEXP handle, - SEXP used_row_indices, - SEXP len_used_row_indices, - SEXP parameters, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_DatasetGetSubset_R(LGBM_SE handle, + LGBM_SE used_row_indices, + LGBM_SE len_used_row_indices, + LGBM_SE parameters, + LGBM_SE out, + LGBM_SE call_state) { R_API_BEGIN(); int len = R_AS_INT(len_used_row_indices); std::vector idxvec(len); @@ -131,9 +130,9 @@ SEXP LGBM_DatasetGetSubset_R(SEXP handle, R_API_END(); } -SEXP LGBM_DatasetSetFeatureNames_R(SEXP handle, - SEXP feature_names, - SEXP call_state) { +LGBM_SE LGBM_DatasetSetFeatureNames_R(LGBM_SE handle, + LGBM_SE feature_names, + LGBM_SE call_state) { R_API_BEGIN(); auto vec_names = Common::Split(R_CHAR_PTR(feature_names), '\t'); std::vector vec_sptr; @@ -146,11 +145,11 @@ SEXP LGBM_DatasetSetFeatureNames_R(SEXP handle, R_API_END(); } -SEXP LGBM_DatasetGetFeatureNames_R(SEXP handle, - SEXP buf_len, - SEXP actual_len, - SEXP feature_names, - SEXP call_state) { +LGBM_SE LGBM_DatasetGetFeatureNames_R(LGBM_SE handle, + LGBM_SE buf_len, + LGBM_SE actual_len, + LGBM_SE feature_names, + LGBM_SE call_state) { R_API_BEGIN(); int len = 0; CHECK_CALL(LGBM_DatasetGetNumFeature(R_GET_PTR(handle), &len)); @@ -169,17 +168,17 @@ SEXP LGBM_DatasetGetFeatureNames_R(SEXP handle, R_API_END(); } -SEXP LGBM_DatasetSaveBinary_R(SEXP handle, - SEXP filename, - SEXP call_state) { +LGBM_SE LGBM_DatasetSaveBinary_R(LGBM_SE handle, + LGBM_SE filename, + LGBM_SE call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_DatasetSaveBinary(R_GET_PTR(handle), R_CHAR_PTR(filename))); R_API_END(); } -SEXP LGBM_DatasetFree_R(SEXP handle, - SEXP call_state) { +LGBM_SE LGBM_DatasetFree_R(LGBM_SE handle, + LGBM_SE call_state) { R_API_BEGIN(); if (R_GET_PTR(handle) != nullptr) { CHECK_CALL(LGBM_DatasetFree(R_GET_PTR(handle))); @@ -188,11 +187,11 @@ SEXP LGBM_DatasetFree_R(SEXP handle, R_API_END(); } -SEXP LGBM_DatasetSetField_R(SEXP handle, - SEXP field_name, - SEXP field_data, - SEXP num_element, - SEXP call_state) { +LGBM_SE LGBM_DatasetSetField_R(LGBM_SE handle, + LGBM_SE field_name, + LGBM_SE field_data, + LGBM_SE num_element, + LGBM_SE call_state) { R_API_BEGIN(); int len = static_cast(R_AS_INT(num_element)); const char* name = R_CHAR_PTR(field_name); @@ -216,10 +215,10 @@ SEXP LGBM_DatasetSetField_R(SEXP handle, R_API_END(); } -SEXP LGBM_DatasetGetField_R(SEXP handle, - SEXP field_name, - SEXP field_data, - SEXP call_state) { +LGBM_SE LGBM_DatasetGetField_R(LGBM_SE handle, + LGBM_SE field_name, + LGBM_SE field_data, + LGBM_SE call_state) { R_API_BEGIN(); const char* name = R_CHAR_PTR(field_name); int out_len = 0; @@ -250,10 +249,10 @@ SEXP LGBM_DatasetGetField_R(SEXP handle, R_API_END(); } -SEXP LGBM_DatasetGetFieldSize_R(SEXP handle, - SEXP field_name, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_DatasetGetFieldSize_R(LGBM_SE handle, + LGBM_SE field_name, + LGBM_SE out, + LGBM_SE call_state) { R_API_BEGIN(); const char* name = R_CHAR_PTR(field_name); int out_len = 0; @@ -267,16 +266,16 @@ SEXP LGBM_DatasetGetFieldSize_R(SEXP handle, R_API_END(); } -SEXP LGBM_DatasetUpdateParamChecking_R(SEXP old_params, - SEXP new_params, - SEXP call_state) { +LGBM_SE LGBM_DatasetUpdateParamChecking_R(LGBM_SE old_params, + LGBM_SE new_params, + LGBM_SE call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_DatasetUpdateParamChecking(R_CHAR_PTR(old_params), R_CHAR_PTR(new_params))); R_API_END(); } -SEXP LGBM_DatasetGetNumData_R(SEXP handle, SEXP out, - SEXP call_state) { +LGBM_SE LGBM_DatasetGetNumData_R(LGBM_SE handle, LGBM_SE out, + LGBM_SE call_state) { int nrow; R_API_BEGIN(); CHECK_CALL(LGBM_DatasetGetNumData(R_GET_PTR(handle), &nrow)); @@ -284,9 +283,9 @@ SEXP LGBM_DatasetGetNumData_R(SEXP handle, SEXP out, R_API_END(); } -SEXP LGBM_DatasetGetNumFeature_R(SEXP handle, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_DatasetGetNumFeature_R(LGBM_SE handle, + LGBM_SE out, + LGBM_SE call_state) { int nfeature; R_API_BEGIN(); CHECK_CALL(LGBM_DatasetGetNumFeature(R_GET_PTR(handle), &nfeature)); @@ -296,8 +295,8 @@ SEXP LGBM_DatasetGetNumFeature_R(SEXP handle, // --- start Booster interfaces -SEXP LGBM_BoosterFree_R(SEXP handle, - SEXP call_state) { +LGBM_SE LGBM_BoosterFree_R(LGBM_SE handle, + LGBM_SE call_state) { R_API_BEGIN(); if (R_GET_PTR(handle) != nullptr) { CHECK_CALL(LGBM_BoosterFree(R_GET_PTR(handle))); @@ -306,10 +305,10 @@ SEXP LGBM_BoosterFree_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterCreate_R(SEXP train_data, - SEXP parameters, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_BoosterCreate_R(LGBM_SE train_data, + LGBM_SE parameters, + LGBM_SE out, + LGBM_SE call_state) { R_API_BEGIN(); BoosterHandle handle = nullptr; CHECK_CALL(LGBM_BoosterCreate(R_GET_PTR(train_data), R_CHAR_PTR(parameters), &handle)); @@ -317,9 +316,9 @@ SEXP LGBM_BoosterCreate_R(SEXP train_data, R_API_END(); } -SEXP LGBM_BoosterCreateFromModelfile_R(SEXP filename, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_BoosterCreateFromModelfile_R(LGBM_SE filename, + LGBM_SE out, + LGBM_SE call_state) { R_API_BEGIN(); int out_num_iterations = 0; BoosterHandle handle = nullptr; @@ -328,9 +327,9 @@ SEXP LGBM_BoosterCreateFromModelfile_R(SEXP filename, R_API_END(); } -SEXP LGBM_BoosterLoadModelFromString_R(SEXP model_str, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_BoosterLoadModelFromString_R(LGBM_SE model_str, + LGBM_SE out, + LGBM_SE call_state) { R_API_BEGIN(); int out_num_iterations = 0; BoosterHandle handle = nullptr; @@ -339,41 +338,41 @@ SEXP LGBM_BoosterLoadModelFromString_R(SEXP model_str, R_API_END(); } -SEXP LGBM_BoosterMerge_R(SEXP handle, - SEXP other_handle, - SEXP call_state) { +LGBM_SE LGBM_BoosterMerge_R(LGBM_SE handle, + LGBM_SE other_handle, + LGBM_SE call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterMerge(R_GET_PTR(handle), R_GET_PTR(other_handle))); R_API_END(); } -SEXP LGBM_BoosterAddValidData_R(SEXP handle, - SEXP valid_data, - SEXP call_state) { +LGBM_SE LGBM_BoosterAddValidData_R(LGBM_SE handle, + LGBM_SE valid_data, + LGBM_SE call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterAddValidData(R_GET_PTR(handle), R_GET_PTR(valid_data))); R_API_END(); } -SEXP LGBM_BoosterResetTrainingData_R(SEXP handle, - SEXP train_data, - SEXP call_state) { +LGBM_SE LGBM_BoosterResetTrainingData_R(LGBM_SE handle, + LGBM_SE train_data, + LGBM_SE call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterResetTrainingData(R_GET_PTR(handle), R_GET_PTR(train_data))); R_API_END(); } -SEXP LGBM_BoosterResetParameter_R(SEXP handle, - SEXP parameters, - SEXP call_state) { +LGBM_SE LGBM_BoosterResetParameter_R(LGBM_SE handle, + LGBM_SE parameters, + LGBM_SE call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterResetParameter(R_GET_PTR(handle), R_CHAR_PTR(parameters))); R_API_END(); } -SEXP LGBM_BoosterGetNumClasses_R(SEXP handle, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_BoosterGetNumClasses_R(LGBM_SE handle, + LGBM_SE out, + LGBM_SE call_state) { int num_class; R_API_BEGIN(); CHECK_CALL(LGBM_BoosterGetNumClasses(R_GET_PTR(handle), &num_class)); @@ -381,19 +380,19 @@ SEXP LGBM_BoosterGetNumClasses_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterUpdateOneIter_R(SEXP handle, - SEXP call_state) { +LGBM_SE LGBM_BoosterUpdateOneIter_R(LGBM_SE handle, + LGBM_SE call_state) { int is_finished = 0; R_API_BEGIN(); CHECK_CALL(LGBM_BoosterUpdateOneIter(R_GET_PTR(handle), &is_finished)); R_API_END(); } -SEXP LGBM_BoosterUpdateOneIterCustom_R(SEXP handle, - SEXP grad, - SEXP hess, - SEXP len, - SEXP call_state) { +LGBM_SE LGBM_BoosterUpdateOneIterCustom_R(LGBM_SE handle, + LGBM_SE grad, + LGBM_SE hess, + LGBM_SE len, + LGBM_SE call_state) { int is_finished = 0; R_API_BEGIN(); int int_len = R_AS_INT(len); @@ -407,16 +406,16 @@ SEXP LGBM_BoosterUpdateOneIterCustom_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterRollbackOneIter_R(SEXP handle, - SEXP call_state) { +LGBM_SE LGBM_BoosterRollbackOneIter_R(LGBM_SE handle, + LGBM_SE call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterRollbackOneIter(R_GET_PTR(handle))); R_API_END(); } -SEXP LGBM_BoosterGetCurrentIteration_R(SEXP handle, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_BoosterGetCurrentIteration_R(LGBM_SE handle, + LGBM_SE out, + LGBM_SE call_state) { int out_iteration; R_API_BEGIN(); CHECK_CALL(LGBM_BoosterGetCurrentIteration(R_GET_PTR(handle), &out_iteration)); @@ -424,29 +423,29 @@ SEXP LGBM_BoosterGetCurrentIteration_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterGetUpperBoundValue_R(SEXP handle, - SEXP out_result, - SEXP call_state) { +LGBM_SE LGBM_BoosterGetUpperBoundValue_R(LGBM_SE handle, + LGBM_SE out_result, + LGBM_SE call_state) { R_API_BEGIN(); double* ptr_ret = R_REAL_PTR(out_result); CHECK_CALL(LGBM_BoosterGetUpperBoundValue(R_GET_PTR(handle), ptr_ret)); R_API_END(); } -SEXP LGBM_BoosterGetLowerBoundValue_R(SEXP handle, - SEXP out_result, - SEXP call_state) { +LGBM_SE LGBM_BoosterGetLowerBoundValue_R(LGBM_SE handle, + LGBM_SE out_result, + LGBM_SE call_state) { R_API_BEGIN(); double* ptr_ret = R_REAL_PTR(out_result); CHECK_CALL(LGBM_BoosterGetLowerBoundValue(R_GET_PTR(handle), ptr_ret)); R_API_END(); } -SEXP LGBM_BoosterGetEvalNames_R(SEXP handle, - SEXP buf_len, - SEXP actual_len, - SEXP eval_names, - SEXP call_state) { +LGBM_SE LGBM_BoosterGetEvalNames_R(LGBM_SE handle, + LGBM_SE buf_len, + LGBM_SE actual_len, + LGBM_SE eval_names, + LGBM_SE call_state) { R_API_BEGIN(); int len; CHECK_CALL(LGBM_BoosterGetEvalCounts(R_GET_PTR(handle), &len)); @@ -464,10 +463,10 @@ SEXP LGBM_BoosterGetEvalNames_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterGetEval_R(SEXP handle, - SEXP data_idx, - SEXP out_result, - SEXP call_state) { +LGBM_SE LGBM_BoosterGetEval_R(LGBM_SE handle, + LGBM_SE data_idx, + LGBM_SE out_result, + LGBM_SE call_state) { R_API_BEGIN(); int len; CHECK_CALL(LGBM_BoosterGetEvalCounts(R_GET_PTR(handle), &len)); @@ -478,10 +477,10 @@ SEXP LGBM_BoosterGetEval_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterGetNumPredict_R(SEXP handle, - SEXP data_idx, - SEXP out, - SEXP call_state) { +LGBM_SE LGBM_BoosterGetNumPredict_R(LGBM_SE handle, + LGBM_SE data_idx, + LGBM_SE out, + LGBM_SE call_state) { R_API_BEGIN(); int64_t len; CHECK_CALL(LGBM_BoosterGetNumPredict(R_GET_PTR(handle), R_AS_INT(data_idx), &len)); @@ -489,10 +488,10 @@ SEXP LGBM_BoosterGetNumPredict_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterGetPredict_R(SEXP handle, - SEXP data_idx, - SEXP out_result, - SEXP call_state) { +LGBM_SE LGBM_BoosterGetPredict_R(LGBM_SE handle, + LGBM_SE data_idx, + LGBM_SE out_result, + LGBM_SE call_state) { R_API_BEGIN(); double* ptr_ret = R_REAL_PTR(out_result); int64_t out_len; @@ -500,7 +499,7 @@ SEXP LGBM_BoosterGetPredict_R(SEXP handle, R_API_END(); } -int GetPredictType(SEXP is_rawscore, SEXP is_leafidx, SEXP is_predcontrib) { +int GetPredictType(LGBM_SE is_rawscore, LGBM_SE is_leafidx, LGBM_SE is_predcontrib) { int pred_type = C_API_PREDICT_NORMAL; if (R_AS_INT(is_rawscore)) { pred_type = C_API_PREDICT_RAW_SCORE; @@ -514,16 +513,16 @@ int GetPredictType(SEXP is_rawscore, SEXP is_leafidx, SEXP is_predcontrib) { return pred_type; } -SEXP LGBM_BoosterPredictForFile_R(SEXP handle, - SEXP data_filename, - SEXP data_has_header, - SEXP is_rawscore, - SEXP is_leafidx, - SEXP is_predcontrib, - SEXP num_iteration, - SEXP parameter, - SEXP result_filename, - SEXP call_state) { +LGBM_SE LGBM_BoosterPredictForFile_R(LGBM_SE handle, + LGBM_SE data_filename, + LGBM_SE data_has_header, + LGBM_SE is_rawscore, + LGBM_SE is_leafidx, + LGBM_SE is_predcontrib, + LGBM_SE num_iteration, + LGBM_SE parameter, + LGBM_SE result_filename, + LGBM_SE call_state) { R_API_BEGIN(); int pred_type = GetPredictType(is_rawscore, is_leafidx, is_predcontrib); CHECK_CALL(LGBM_BoosterPredictForFile(R_GET_PTR(handle), R_CHAR_PTR(data_filename), @@ -532,14 +531,14 @@ SEXP LGBM_BoosterPredictForFile_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterCalcNumPredict_R(SEXP handle, - SEXP num_row, - SEXP is_rawscore, - SEXP is_leafidx, - SEXP is_predcontrib, - SEXP num_iteration, - SEXP out_len, - SEXP call_state) { +LGBM_SE LGBM_BoosterCalcNumPredict_R(LGBM_SE handle, + LGBM_SE num_row, + LGBM_SE is_rawscore, + LGBM_SE is_leafidx, + LGBM_SE is_predcontrib, + LGBM_SE num_iteration, + LGBM_SE out_len, + LGBM_SE call_state) { R_API_BEGIN(); int pred_type = GetPredictType(is_rawscore, is_leafidx, is_predcontrib); int64_t len = 0; @@ -549,20 +548,20 @@ SEXP LGBM_BoosterCalcNumPredict_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterPredictForCSC_R(SEXP handle, - SEXP indptr, - SEXP indices, - SEXP data, - SEXP num_indptr, - SEXP nelem, - SEXP num_row, - SEXP is_rawscore, - SEXP is_leafidx, - SEXP is_predcontrib, - SEXP num_iteration, - SEXP parameter, - SEXP out_result, - SEXP call_state) { +LGBM_SE LGBM_BoosterPredictForCSC_R(LGBM_SE handle, + LGBM_SE indptr, + LGBM_SE indices, + LGBM_SE data, + LGBM_SE num_indptr, + LGBM_SE nelem, + LGBM_SE num_row, + LGBM_SE is_rawscore, + LGBM_SE is_leafidx, + LGBM_SE is_predcontrib, + LGBM_SE num_iteration, + LGBM_SE parameter, + LGBM_SE out_result, + LGBM_SE call_state) { R_API_BEGIN(); int pred_type = GetPredictType(is_rawscore, is_leafidx, is_predcontrib); @@ -582,17 +581,17 @@ SEXP LGBM_BoosterPredictForCSC_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterPredictForMat_R(SEXP handle, - SEXP data, - SEXP num_row, - SEXP num_col, - SEXP is_rawscore, - SEXP is_leafidx, - SEXP is_predcontrib, - SEXP num_iteration, - SEXP parameter, - SEXP out_result, - SEXP call_state) { +LGBM_SE LGBM_BoosterPredictForMat_R(LGBM_SE handle, + LGBM_SE data, + LGBM_SE num_row, + LGBM_SE num_col, + LGBM_SE is_rawscore, + LGBM_SE is_leafidx, + LGBM_SE is_predcontrib, + LGBM_SE num_iteration, + LGBM_SE parameter, + LGBM_SE out_result, + LGBM_SE call_state) { R_API_BEGIN(); int pred_type = GetPredictType(is_rawscore, is_leafidx, is_predcontrib); @@ -609,21 +608,21 @@ SEXP LGBM_BoosterPredictForMat_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterSaveModel_R(SEXP handle, - SEXP num_iteration, - SEXP filename, - SEXP call_state) { +LGBM_SE LGBM_BoosterSaveModel_R(LGBM_SE handle, + LGBM_SE num_iteration, + LGBM_SE filename, + LGBM_SE call_state) { R_API_BEGIN(); CHECK_CALL(LGBM_BoosterSaveModel(R_GET_PTR(handle), 0, R_AS_INT(num_iteration), R_CHAR_PTR(filename))); R_API_END(); } -SEXP LGBM_BoosterSaveModelToString_R(SEXP handle, - SEXP num_iteration, - SEXP buffer_len, - SEXP actual_len, - SEXP out_str, - SEXP call_state) { +LGBM_SE LGBM_BoosterSaveModelToString_R(LGBM_SE handle, + LGBM_SE num_iteration, + LGBM_SE buffer_len, + LGBM_SE actual_len, + LGBM_SE out_str, + LGBM_SE call_state) { R_API_BEGIN(); int64_t out_len = 0; std::vector inner_char_buf(R_AS_INT(buffer_len)); @@ -632,12 +631,12 @@ SEXP LGBM_BoosterSaveModelToString_R(SEXP handle, R_API_END(); } -SEXP LGBM_BoosterDumpModel_R(SEXP handle, - SEXP num_iteration, - SEXP buffer_len, - SEXP actual_len, - SEXP out_str, - SEXP call_state) { +LGBM_SE LGBM_BoosterDumpModel_R(LGBM_SE handle, + LGBM_SE num_iteration, + LGBM_SE buffer_len, + LGBM_SE actual_len, + LGBM_SE out_str, + LGBM_SE call_state) { R_API_BEGIN(); int64_t out_len = 0; std::vector inner_char_buf(R_AS_INT(buffer_len)); From aa87eb6d035011bce4d3be2e48d9031eda32a940 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Wed, 11 Mar 2020 21:47:17 -0500 Subject: [PATCH 07/41] switched from hard-coded include dir to the one from FindLibR.cmake --- CMakeLists.txt | 4 ++-- R-package/src/cmake/modules/FindLibR.cmake | 1 - include/LightGBM/utils/log.h | 6 ++++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ba9e9bc55a6..f405892b6752 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,8 @@ if(BUILD_FOR_R) list(APPEND CMAKE_MODULE_PATH "${lightgbm_SOURCE_DIR}/cmake/modules") find_package(LibR REQUIRED) message(STATUS "LIBR_CORE_LIBRARY " ${LIBR_CORE_LIBRARY}) + message(STATUS "LIBR_INCLUDE_DIRS " ${LIBR_INCLUDE_DIRS}) + include_directories(${LIBR_INCLUDE_DIRS}) ADD_DEFINITIONS(-DLGB_R_BUILD) endif(BUILD_FOR_R) @@ -86,8 +88,6 @@ if(USE_DEBUG) ADD_DEFINITIONS(-DDEBUG) endif(USE_DEBUG) -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/Library/Frameworks/R.framework/Versions/3.6/Resources/include") - if(USE_MPI) find_package(MPI REQUIRED) ADD_DEFINITIONS(-DUSE_MPI) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index c0252e0e3705..241771202178 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -11,7 +11,6 @@ # LIBR_CORE_LIBRARY # and a cmake function to create R.lib for MSVC - # Windows users might want to change this to their R version: if(NOT R_VERSION) set(R_VERSION "3.4.1") diff --git a/include/LightGBM/utils/log.h b/include/LightGBM/utils/log.h index 119495406618..f5b5a0410177 100644 --- a/include/LightGBM/utils/log.h +++ b/include/LightGBM/utils/log.h @@ -113,6 +113,8 @@ class Log { #endif va_end(val); + // R code should write back to R's error stream, + // otherwise to stderr #ifndef LGB_R_BUILD fprintf(stderr, "[LightGBM] [Fatal] %s\n", str_buf); fflush(stderr); @@ -125,14 +127,14 @@ class Log { private: static void Write(LogLevel level, const char* level_str, const char *format, va_list val) { if (level <= GetLevel()) { // omit the message with low level + // R code should write back to R's error stream, + // otherwise to stdout #ifndef LGB_R_BUILD - // write to STDOUT printf("[LightGBM] [%s] ", level_str); vprintf(format, val); printf("\n"); fflush(stdout); #else - // write to STDOUT Rprintf("[LightGBM] [%s] ", level_str); Rvprintf(format, val); Rprintf("\n"); From 11ea756603cfa5ac63dad947e4013c4bc52e8aa7 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Wed, 11 Mar 2020 22:00:02 -0500 Subject: [PATCH 08/41] cleaned up formatting in FindLibR.cmake --- R-package/src/cmake/modules/FindLibR.cmake | 64 +++++++++++++++------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 241771202178..40bd7b643044 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -1,6 +1,9 @@ -# CMake module for R to find the location of R +# CMake module used to fine the location of R's +# dll and header files. # -# Borrows heavily from xgboost's R package +# Borrows heavily from xgboost's R package: +# +# * https://github.com/dmlc/xgboost/blob/master/cmake/modules/FindLibR.cmake # # Defines the following: # LIBR_FOUND @@ -11,10 +14,6 @@ # LIBR_CORE_LIBRARY # and a cmake function to create R.lib for MSVC -# Windows users might want to change this to their R version: -if(NOT R_VERSION) - set(R_VERSION "3.4.1") -endif() if(NOT R_ARCH) if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") set(R_ARCH "i386") @@ -25,19 +24,24 @@ endif() # Creates R.lib and R.def in the build directory for linking with MSVC function(create_rlib_for_msvc) + # various checks and warnings if(NOT WIN32 OR NOT MSVC) message(FATAL_ERROR "create_rlib_for_msvc() can only be used with MSVC") endif() + if(NOT EXISTS "${LIBR_LIB_DIR}") message(FATAL_ERROR "LIBR_LIB_DIR was not set!") endif() + find_program(GENDEF_EXE gendef) find_program(DLLTOOL_EXE dlltool) + if(NOT GENDEF_EXE OR NOT DLLTOOL_EXE) message(FATAL_ERROR "\nEither gendef.exe or dlltool.exe not found!\ \nDo you have Rtools installed with its MinGW's bin/ in PATH?") - endif() + endif() + # extract symbols from R.dll into R.def and R.lib import library execute_process(COMMAND gendef "-" "${LIBR_LIB_DIR}/R.dll" @@ -47,7 +51,6 @@ function(create_rlib_for_msvc) "--output-lib" "${CMAKE_CURRENT_BINARY_DIR}/R.lib") endfunction(create_rlib_for_msvc) - # detection for OSX if(APPLE) @@ -64,12 +67,13 @@ if(APPLE) set(LIBR_EXECUTABLE "${_LIBR_LIBRARIES_DIR}/../bin/R") execute_process( COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home())" - OUTPUT_VARIABLE LIBR_HOME) + OUTPUT_VARIABLE LIBR_HOME + ) set(LIBR_HOME ${LIBR_HOME} CACHE PATH "R home directory") set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include" CACHE PATH "R include directory") set(LIBR_LIB_DIR "${LIBR_HOME}/lib" CACHE PATH "R lib directory") endif() - + # detection for UNIX & Win32 else() @@ -77,7 +81,7 @@ else() if(NOT LIBR_EXECUTABLE) find_program(LIBR_EXECUTABLE NAMES R R.exe) endif() - + if(UNIX) if(NOT LIBR_EXECUTABLE) @@ -90,11 +94,13 @@ else() COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home())" OUTPUT_VARIABLE LIBR_HOME ) + # ask R for the include dir execute_process( COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('include'))" OUTPUT_VARIABLE LIBR_INCLUDE_DIRS ) + # ask R for the lib dir execute_process( COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('lib'))" @@ -103,50 +109,67 @@ else() # Windows else() - # ask R for R_HOME + + # ask R for R_HOME if(LIBR_EXECUTABLE) execute_process( COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(normalizePath(R.home(),winslash='/'))" - OUTPUT_VARIABLE LIBR_HOME) + OUTPUT_VARIABLE LIBR_HOME + ) endif() + # if R executable not available, query R_HOME path from registry if(NOT LIBR_HOME) + + # Windows users might want to change this to their R version: + if(NOT R_VERSION) + set(R_VERSION "3.4.1") + endif() + get_filename_component(LIBR_HOME "[HKEY_LOCAL_MACHINE\\SOFTWARE\\R-core\\R\\${R_VERSION};InstallPath]" - ABSOLUTE) + ABSOLUTE + ) + if(NOT LIBR_HOME) message(FATAL_ERROR "\nUnable to locate R executable.\ \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE cmake variable") endif() + endif() + # set exe location based on R_ARCH if(NOT LIBR_EXECUTABLE) set(LIBR_EXECUTABLE "${LIBR_HOME}/bin/${R_ARCH}/R.exe") endif() + # set other R paths based on home path set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include") set(LIBR_LIB_DIR "${LIBR_HOME}/bin/${R_ARCH}") - -message(STATUS "LIBR_HOME [${LIBR_HOME}]") -message(STATUS "LIBR_EXECUTABLE [${LIBR_EXECUTABLE}]") -message(STATUS "LIBR_INCLUDE_DIRS [${LIBR_INCLUDE_DIRS}]") -message(STATUS "LIBR_LIB_DIR [${LIBR_LIB_DIR}]") -message(STATUS "LIBR_CORE_LIBRARY [${LIBR_CORE_LIBRARY}]") + + message(STATUS "LIBR_HOME [${LIBR_HOME}]") + message(STATUS "LIBR_EXECUTABLE [${LIBR_EXECUTABLE}]") + message(STATUS "LIBR_INCLUDE_DIRS [${LIBR_INCLUDE_DIRS}]") + message(STATUS "LIBR_LIB_DIR [${LIBR_LIB_DIR}]") + message(STATUS "LIBR_CORE_LIBRARY [${LIBR_CORE_LIBRARY}]") endif() endif() if(WIN32 AND MSVC) + # create a local R.lib import library for R.dll if it doesn't exist if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/R.lib") create_rlib_for_msvc() endif() + endif() # look for the core R library find_library(LIBR_CORE_LIBRARY NAMES R HINTS "${CMAKE_CURRENT_BINARY_DIR}" "${LIBR_LIB_DIR}" "${LIBR_HOME}/bin" "${LIBR_LIBRARIES}") + if(LIBR_CORE_LIBRARY-NOTFOUND) message(STATUS "Could not find R core shared library.") endif() @@ -159,6 +182,7 @@ set(LIBR_CORE_LIBRARY ${LIBR_CORE_LIBRARY} CACHE PATH "R core shared library") # define find requirements include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(LibR DEFAULT_MSG LIBR_HOME LIBR_EXECUTABLE From 04b235b5d44f0fa82b1cb5189d7dc084801306b2 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Wed, 11 Mar 2020 22:47:02 -0500 Subject: [PATCH 09/41] commented-out everything in CI that does not touch R --- .travis.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index bbd72bb9b207..a998ce6cf04e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,16 +14,16 @@ env: global: # default values - PYTHON_VERSION=3.7 matrix: - - TASK=regular PYTHON_VERSION=3.6 - - TASK=sdist PYTHON_VERSION=2.7 - - TASK=bdist - - TASK=if-else - - TASK=lint - - TASK=check-docs - - TASK=mpi METHOD=source - - TASK=mpi METHOD=pip - - TASK=gpu METHOD=source PYTHON_VERSION=3.5 - - TASK=gpu METHOD=pip PYTHON_VERSION=3.6 + # - TASK=regular PYTHON_VERSION=3.6 + # - TASK=sdist PYTHON_VERSION=2.7 + # - TASK=bdist + # - TASK=if-else + # - TASK=lint + # - TASK=check-docs + # - TASK=mpi METHOD=source + # - TASK=mpi METHOD=pip + # - TASK=gpu METHOD=source PYTHON_VERSION=3.5 + # - TASK=gpu METHOD=pip PYTHON_VERSION=3.6 - TASK=r-package matrix: From f54d9ac5f1b781aeaae16428a9b093bdc7f9043a Mon Sep 17 00:00:00 2001 From: James Lamb Date: Wed, 11 Mar 2020 22:47:18 -0500 Subject: [PATCH 10/41] more changes --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a998ce6cf04e..2f3c7c0cacfd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ env: # - TASK=sdist PYTHON_VERSION=2.7 # - TASK=bdist # - TASK=if-else - # - TASK=lint + - TASK=lint # - TASK=check-docs # - TASK=mpi METHOD=source # - TASK=mpi METHOD=pip From 08756cd2fb71fe2c1a520f70bef105ad1b9a36a8 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Wed, 11 Mar 2020 23:09:38 -0500 Subject: [PATCH 11/41] trying to get better logs --- .ci/test_r_package.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.ci/test_r_package.sh b/.ci/test_r_package.sh index 134d89d155c3..316881a1959b 100755 --- a/.ci/test_r_package.sh +++ b/.ci/test_r_package.sh @@ -84,7 +84,9 @@ export _R_CHECK_FORCE_SUGGESTS_=0 # R CMD CHECK R CMD check ${PKG_TARBALL} \ --as-cran \ -|| exit -1 +|| cat /home/travis/build/jameslamb/LightGBM/lightgbm.Rcheck/00install.out + +exit -1 if grep -q -R "WARNING" "$LOG_FILE_NAME"; then echo "WARNINGS have been found by R CMD check!" From 631e2edf91daa705aa4c0d0d3bc89a6d10aaa816 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Wed, 11 Mar 2020 23:55:09 -0500 Subject: [PATCH 12/41] tried ignoring --- R-package/.Rbuildignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R-package/.Rbuildignore b/R-package/.Rbuildignore index 309a82858cbc..6f9097d231d6 100644 --- a/R-package/.Rbuildignore +++ b/R-package/.Rbuildignore @@ -12,6 +12,8 @@ # Code copied in at build time ^src/CMakeLists.txt$ +^CMakeCache.txt$ +^src/CMakeCache.txt$ # unnecessary files from submodules ^src/compute/.appveyor.yml$ From 1c2a732db565a587def60a0248e126fa7f193b20 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Thu, 12 Mar 2020 00:17:32 -0500 Subject: [PATCH 13/41] added error message to confirm a suspicion --- .travis.yml | 2 +- R-package/src/cmake/modules/FindLibR.cmake | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2f3c7c0cacfd..a998ce6cf04e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ env: # - TASK=sdist PYTHON_VERSION=2.7 # - TASK=bdist # - TASK=if-else - - TASK=lint + # - TASK=lint # - TASK=check-docs # - TASK=mpi METHOD=source # - TASK=mpi METHOD=pip diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 40bd7b643044..3e2f7f57b8c3 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -80,6 +80,13 @@ else() # attempt to find R executable if(NOT LIBR_EXECUTABLE) find_program(LIBR_EXECUTABLE NAMES R R.exe) + + # CRAN may run RD CMD CHECK instead of R CMD CHECK, + # which can lead to this infamous error: + # 'R' should not be used without a path -- see par. 1.6 of the manual + if(LIBR_EXECUTABLE MATCHES ".*lightgbm\\.Rcheck.*") + message(FATAL_ERROR "Hit this block. '${LIBR_EXECUTABLE}'") + endif() endif() if(UNIX) From c915389d589a2381207dfd87bae0b2ffeffe9a8f Mon Sep 17 00:00:00 2001 From: James Lamb Date: Thu, 12 Mar 2020 00:34:01 -0500 Subject: [PATCH 14/41] still trying to find R during R CMD CHECK --- R-package/src/cmake/modules/FindLibR.cmake | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 3e2f7f57b8c3..ac6daaff397d 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -79,11 +79,17 @@ else() # attempt to find R executable if(NOT LIBR_EXECUTABLE) - find_program(LIBR_EXECUTABLE NAMES R R.exe) - + # CRAN may run RD CMD CHECK instead of R CMD CHECK, # which can lead to this infamous error: # 'R' should not be used without a path -- see par. 1.6 of the manual + find_program( + LIBR_EXECUTABLE + NO_DEFAULT_PATH + HINTS "${CMAKE_CURRENT_BINARY_DIR}" "/usr/bin" "/usr/lib/" + NAMES R R.exe + ) + if(LIBR_EXECUTABLE MATCHES ".*lightgbm\\.Rcheck.*") message(FATAL_ERROR "Hit this block. '${LIBR_EXECUTABLE}'") endif() From eae206cbd740e3d3a9923afac144aac555c9f265 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Thu, 12 Mar 2020 09:49:01 -0500 Subject: [PATCH 15/41] restore full CI --- .ci/test_r_package.sh | 4 +--- .travis.yml | 20 ++++++++++---------- R-package/.Rbuildignore | 2 -- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.ci/test_r_package.sh b/.ci/test_r_package.sh index 316881a1959b..134d89d155c3 100755 --- a/.ci/test_r_package.sh +++ b/.ci/test_r_package.sh @@ -84,9 +84,7 @@ export _R_CHECK_FORCE_SUGGESTS_=0 # R CMD CHECK R CMD check ${PKG_TARBALL} \ --as-cran \ -|| cat /home/travis/build/jameslamb/LightGBM/lightgbm.Rcheck/00install.out - -exit -1 +|| exit -1 if grep -q -R "WARNING" "$LOG_FILE_NAME"; then echo "WARNINGS have been found by R CMD check!" diff --git a/.travis.yml b/.travis.yml index a998ce6cf04e..bbd72bb9b207 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,16 +14,16 @@ env: global: # default values - PYTHON_VERSION=3.7 matrix: - # - TASK=regular PYTHON_VERSION=3.6 - # - TASK=sdist PYTHON_VERSION=2.7 - # - TASK=bdist - # - TASK=if-else - # - TASK=lint - # - TASK=check-docs - # - TASK=mpi METHOD=source - # - TASK=mpi METHOD=pip - # - TASK=gpu METHOD=source PYTHON_VERSION=3.5 - # - TASK=gpu METHOD=pip PYTHON_VERSION=3.6 + - TASK=regular PYTHON_VERSION=3.6 + - TASK=sdist PYTHON_VERSION=2.7 + - TASK=bdist + - TASK=if-else + - TASK=lint + - TASK=check-docs + - TASK=mpi METHOD=source + - TASK=mpi METHOD=pip + - TASK=gpu METHOD=source PYTHON_VERSION=3.5 + - TASK=gpu METHOD=pip PYTHON_VERSION=3.6 - TASK=r-package matrix: diff --git a/R-package/.Rbuildignore b/R-package/.Rbuildignore index 6f9097d231d6..309a82858cbc 100644 --- a/R-package/.Rbuildignore +++ b/R-package/.Rbuildignore @@ -12,8 +12,6 @@ # Code copied in at build time ^src/CMakeLists.txt$ -^CMakeCache.txt$ -^src/CMakeCache.txt$ # unnecessary files from submodules ^src/compute/.appveyor.yml$ From 6038fb398129ed5e9431560eff4be4ac0faf00fd Mon Sep 17 00:00:00 2001 From: James Lamb Date: Thu, 12 Mar 2020 11:23:27 -0500 Subject: [PATCH 16/41] fixed comment --- include/LightGBM/utils/log.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/LightGBM/utils/log.h b/include/LightGBM/utils/log.h index f5b5a0410177..ee3ff453ace5 100644 --- a/include/LightGBM/utils/log.h +++ b/include/LightGBM/utils/log.h @@ -127,7 +127,7 @@ class Log { private: static void Write(LogLevel level, const char* level_str, const char *format, va_list val) { if (level <= GetLevel()) { // omit the message with low level - // R code should write back to R's error stream, + // R code should write back to R's output stream, // otherwise to stdout #ifndef LGB_R_BUILD printf("[LightGBM] [%s] ", level_str); From 3e318d85bb23ce96715f2f6afb0d68461dfdfef2 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Thu, 12 Mar 2020 12:46:46 -0500 Subject: [PATCH 17/41] Update R-package/src/cmake/modules/FindLibR.cmake --- R-package/src/cmake/modules/FindLibR.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index ac6daaff397d..a6243ae0d6c3 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -1,4 +1,4 @@ -# CMake module used to fine the location of R's +# CMake module used to find the location of R's # dll and header files. # # Borrows heavily from xgboost's R package: From e0c4668a2e2f42b08e9be8072073824a67c69aa7 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Thu, 12 Mar 2020 14:57:07 -0500 Subject: [PATCH 18/41] changed strategy for finding LIBR_HOME on Windows --- CMakeLists.txt | 2 ++ R-package/src/cmake/modules/FindLibR.cmake | 32 ++++++++++++++++------ R-package/src/install.libs.R | 11 ++++++++ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f405892b6752..cf1b47926e92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,8 @@ endif(USE_R35) if(BUILD_FOR_R) list(APPEND CMAKE_MODULE_PATH "${lightgbm_SOURCE_DIR}/cmake/modules") + set(CMAKE_R_VERSION ${CMAKE_R_VERSION}) + message(STATUS "passed-in R version: " ${CMAKE_R_VERSION}) find_package(LibR REQUIRED) message(STATUS "LIBR_CORE_LIBRARY " ${LIBR_CORE_LIBRARY}) message(STATUS "LIBR_INCLUDE_DIRS " ${LIBR_INCLUDE_DIRS}) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index a6243ae0d6c3..e41c0609d126 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -51,6 +51,16 @@ function(create_rlib_for_msvc) "--output-lib" "${CMAKE_CURRENT_BINARY_DIR}/R.lib") endfunction(create_rlib_for_msvc) +# R version information is used to search for R's libraries in +# the registry on Windows. Since this code is orchestrated by +# an R script (src/install.libs.R), that script uses R's built-ins to +# find the version of R and pass it through as a cmake variable +if(CMAKE_R_VERSION) + message("R version passed into FindLibR.cmake: ${CMAKE_R_VERSION}") +else() + message(FATAL_ERROR "Expected CMAKE_R_VERSION to be passed in but none was provided. Check src/install.libs.R") +endif() + # detection for OSX if(APPLE) @@ -91,7 +101,7 @@ else() ) if(LIBR_EXECUTABLE MATCHES ".*lightgbm\\.Rcheck.*") - message(FATAL_ERROR "Hit this block. '${LIBR_EXECUTABLE}'") + message(FATAL_ERROR "If you are seeing this error, it means you are running R CMD check and R is using '${LIBR_EXECUTABLE}'. Edit src/cmake/modulesFindLibR.cmake and add your R path to HINTS near this error") endif() endif() @@ -134,16 +144,22 @@ else() # if R executable not available, query R_HOME path from registry if(NOT LIBR_HOME) - # Windows users might want to change this to their R version: - if(NOT R_VERSION) - set(R_VERSION "3.4.1") - endif() - - get_filename_component(LIBR_HOME - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\R-core\\R\\${R_VERSION};InstallPath]" + # Try to find R's location in the registry + # ref: https://cran.r-project.org/bin/windows/base/rw-FAQ.html#Does-R-use-the-Registry_003f + get_filename_component( + LIBR_HOME + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\R-core\\R\\${CMAKE_R_VERSION};InstallPath]" ABSOLUTE ) + if(NOT LIBR_HOME) + get_filename_component( + LIBR_HOME + "[HKEY_CURRENT_USER\\SOFTWARE\\R-core\\R\\${CMAKE_R_VERSION};InstallPath]" + ABSOLUTE + ) + endif() + if(NOT LIBR_HOME) message(FATAL_ERROR "\nUnable to locate R executable.\ \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE cmake variable") diff --git a/R-package/src/install.libs.R b/R-package/src/install.libs.R index d5cdc78dbe38..0a4802e06624 100644 --- a/R-package/src/install.libs.R +++ b/R-package/src/install.libs.R @@ -48,6 +48,17 @@ if (!use_precompile) { } cmake_cmd <- paste0(cmake_cmd, " -DBUILD_FOR_R=ON ") + # Pass in R version, used to help find R executable for linking + R_version_string <- paste( + R.Version()[["major"]] + , R.Version()[["minor"]] + , sep = "." + ) + cmake_cmd <- sprintf( + paste0(cmake_cmd, " -DCMAKE_R_VERSION='%s' ") + , R_version_string + ) + # Check if Windows installation (for gcc vs Visual Studio) if (WINDOWS) { if (use_mingw) { From bd66c7602d0b4516822c8db8682a711e3a0d4097 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Sun, 15 Mar 2020 17:50:34 -0500 Subject: [PATCH 19/41] Removed 32-bit Windows stuff in FindLibR.cmake --- R-package/src/cmake/modules/FindLibR.cmake | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index e41c0609d126..13fb66152536 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -16,10 +16,9 @@ if(NOT R_ARCH) if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") - set(R_ARCH "i386") - else() - set(R_ARCH "x64") + message(FATAL_ERROR "LightGBM's R package currently only supports 64-bit operating systems") endif() + set(R_ARCH "x64") endif() # Creates R.lib and R.def in the build directory for linking with MSVC From 098b4375de9143aad845c83772af565e3f32720d Mon Sep 17 00:00:00 2001 From: James Lamb Date: Sun, 15 Mar 2020 19:57:49 -0500 Subject: [PATCH 20/41] Update R-package/src/cmake/modules/FindLibR.cmake --- R-package/src/cmake/modules/FindLibR.cmake | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 13fb66152536..48954485e1da 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -16,9 +16,14 @@ if(NOT R_ARCH) if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") - message(FATAL_ERROR "LightGBM's R package currently only supports 64-bit operating systems") + set(R_ARCH "i386") + else() + set(R_ARCH "x64") endif() - set(R_ARCH "x64") +endif() + +if(NOT ("${R_ARCH}" STREQUAL "x64")) + message(FATAL_ERROR "LightGBM's R package currently only supports 64-bit operating systems") endif() # Creates R.lib and R.def in the build directory for linking with MSVC From 722b6bd2482c954e9be0cf64af76bc2f25c4ddac Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 08:46:28 -0500 Subject: [PATCH 21/41] Update CMakeLists.txt Co-Authored-By: Nikita Titov --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cf1b47926e92..c028b65b3b77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,7 @@ endif(USE_R35) if(BUILD_FOR_R) list(APPEND CMAKE_MODULE_PATH "${lightgbm_SOURCE_DIR}/cmake/modules") set(CMAKE_R_VERSION ${CMAKE_R_VERSION}) - message(STATUS "passed-in R version: " ${CMAKE_R_VERSION}) + message(STATUS "Passed-in R version: " ${CMAKE_R_VERSION}) find_package(LibR REQUIRED) message(STATUS "LIBR_CORE_LIBRARY " ${LIBR_CORE_LIBRARY}) message(STATUS "LIBR_INCLUDE_DIRS " ${LIBR_INCLUDE_DIRS}) From 36b8fa6ef051dcaf340c3362198def12a3e75b51 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 08:47:07 -0500 Subject: [PATCH 22/41] Update CMakeLists.txt Co-Authored-By: Nikita Titov --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c028b65b3b77..0552659b69b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,7 @@ if(BUILD_FOR_R) set(CMAKE_R_VERSION ${CMAKE_R_VERSION}) message(STATUS "Passed-in R version: " ${CMAKE_R_VERSION}) find_package(LibR REQUIRED) - message(STATUS "LIBR_CORE_LIBRARY " ${LIBR_CORE_LIBRARY}) + message(STATUS "LIBR_CORE_LIBRARY: " ${LIBR_CORE_LIBRARY}) message(STATUS "LIBR_INCLUDE_DIRS " ${LIBR_INCLUDE_DIRS}) include_directories(${LIBR_INCLUDE_DIRS}) ADD_DEFINITIONS(-DLGB_R_BUILD) From cc35fff70742eb7c4611a1417ee4154399e90b97 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 08:47:54 -0500 Subject: [PATCH 23/41] Update R-package/src/cmake/modules/FindLibR.cmake Co-Authored-By: Nikita Titov --- R-package/src/cmake/modules/FindLibR.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 48954485e1da..733724cc3736 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -71,10 +71,10 @@ if(APPLE) find_library(LIBR_LIBRARIES R) if(LIBR_LIBRARIES MATCHES ".*\\.framework") - set(LIBR_HOME "${LIBR_LIBRARIES}/Resources" CACHE PATH "R home directory") - set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include" CACHE PATH "R include directory") - set(LIBR_EXECUTABLE "${LIBR_HOME}/R" CACHE PATH "R executable") - set(LIBR_LIB_DIR "${LIBR_HOME}/lib" CACHE PATH "R lib directory") + set(LIBR_HOME "${LIBR_LIBRARIES}/Resources") + set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include") + set(LIBR_EXECUTABLE "${LIBR_HOME}/R") + set(LIBR_LIB_DIR "${LIBR_HOME}/lib") else() get_filename_component(_LIBR_LIBRARIES "${LIBR_LIBRARIES}" REALPATH) get_filename_component(_LIBR_LIBRARIES_DIR "${_LIBR_LIBRARIES}" DIRECTORY) From 6757692aff2ff163e6f667a9fc70f8b24fc8830e Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 11:08:58 -0500 Subject: [PATCH 24/41] removed some duplication in cmake scripts --- CMakeLists.txt | 9 +++++---- R-package/src/cmake/modules/FindLibR.cmake | 15 ++++----------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0552659b69b7..aeb24cd67ec0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,11 +73,12 @@ endif(USE_R35) if(BUILD_FOR_R) list(APPEND CMAKE_MODULE_PATH "${lightgbm_SOURCE_DIR}/cmake/modules") - set(CMAKE_R_VERSION ${CMAKE_R_VERSION}) - message(STATUS "Passed-in R version: " ${CMAKE_R_VERSION}) find_package(LibR REQUIRED) - message(STATUS "LIBR_CORE_LIBRARY: " ${LIBR_CORE_LIBRARY}) - message(STATUS "LIBR_INCLUDE_DIRS " ${LIBR_INCLUDE_DIRS}) + message(STATUS "LIBR_HOME [${LIBR_HOME}]") + message(STATUS "LIBR_EXECUTABLE [${LIBR_EXECUTABLE}]") + message(STATUS "LIBR_INCLUDE_DIRS [${LIBR_INCLUDE_DIRS}]") + message(STATUS "LIBR_LIB_DIR [${LIBR_LIB_DIR}]") + message(STATUS "LIBR_CORE_LIBRARY [${LIBR_CORE_LIBRARY}]") include_directories(${LIBR_INCLUDE_DIRS}) ADD_DEFINITIONS(-DLGB_R_BUILD) endif(BUILD_FOR_R) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 733724cc3736..5987a73e70ec 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -83,9 +83,9 @@ if(APPLE) COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home())" OUTPUT_VARIABLE LIBR_HOME ) - set(LIBR_HOME ${LIBR_HOME} CACHE PATH "R home directory") - set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include" CACHE PATH "R include directory") - set(LIBR_LIB_DIR "${LIBR_HOME}/lib" CACHE PATH "R lib directory") + set(LIBR_HOME ${LIBR_HOME}) + set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include") + set(LIBR_LIB_DIR "${LIBR_HOME}/lib") endif() # detection for UNIX & Win32 @@ -100,7 +100,7 @@ else() find_program( LIBR_EXECUTABLE NO_DEFAULT_PATH - HINTS "${CMAKE_CURRENT_BINARY_DIR}" "/usr/bin" "/usr/lib/" + HINTS "${CMAKE_CURRENT_BINARY_DIR}" "/usr/bin" "/usr/lib/" "/usr/local/bin/" NAMES R R.exe ) @@ -180,12 +180,6 @@ else() set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include") set(LIBR_LIB_DIR "${LIBR_HOME}/bin/${R_ARCH}") - message(STATUS "LIBR_HOME [${LIBR_HOME}]") - message(STATUS "LIBR_EXECUTABLE [${LIBR_EXECUTABLE}]") - message(STATUS "LIBR_INCLUDE_DIRS [${LIBR_INCLUDE_DIRS}]") - message(STATUS "LIBR_LIB_DIR [${LIBR_LIB_DIR}]") - message(STATUS "LIBR_CORE_LIBRARY [${LIBR_CORE_LIBRARY}]") - endif() endif() @@ -221,7 +215,6 @@ find_package_handle_standard_args(LibR DEFAULT_MSG LIBR_EXECUTABLE LIBR_INCLUDE_DIRS LIBR_LIB_DIR - LIBR_CORE_LIBRARY ) if(LIBR_FOUND) From f54abcb05f192df888c3e410575db0aeee20d5ef Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 11:10:07 -0500 Subject: [PATCH 25/41] Update R-package/src/cmake/modules/FindLibR.cmake Co-Authored-By: Nikita Titov --- R-package/src/cmake/modules/FindLibR.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 5987a73e70ec..012fa884fce6 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -42,7 +42,7 @@ function(create_rlib_for_msvc) find_program(DLLTOOL_EXE dlltool) if(NOT GENDEF_EXE OR NOT DLLTOOL_EXE) - message(FATAL_ERROR "\nEither gendef.exe or dlltool.exe not found!\ + message(FATAL_ERROR "Either gendef.exe or dlltool.exe not found!\ \nDo you have Rtools installed with its MinGW's bin/ in PATH?") endif() From 5bfab696e2e88a6c438339ac979b374c0e4a3d2d Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 11:47:56 -0500 Subject: [PATCH 26/41] Update R-package/src/cmake/modules/FindLibR.cmake Co-Authored-By: Nikita Titov --- R-package/src/cmake/modules/FindLibR.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 012fa884fce6..524f6f6a868b 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -58,7 +58,7 @@ endfunction(create_rlib_for_msvc) # R version information is used to search for R's libraries in # the registry on Windows. Since this code is orchestrated by # an R script (src/install.libs.R), that script uses R's built-ins to -# find the version of R and pass it through as a cmake variable +# find the version of R and pass it through as a CMake variable if(CMAKE_R_VERSION) message("R version passed into FindLibR.cmake: ${CMAKE_R_VERSION}") else() From 1e658db3ab2eb12793f0f6fac6b0d2412a94161f Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 11:48:07 -0500 Subject: [PATCH 27/41] Update R-package/src/cmake/modules/FindLibR.cmake Co-Authored-By: Nikita Titov --- R-package/src/cmake/modules/FindLibR.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 524f6f6a868b..e2a83870ff70 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -12,7 +12,7 @@ # LIBR_INCLUDE_DIRS # LIBR_LIB_DIR # LIBR_CORE_LIBRARY -# and a cmake function to create R.lib for MSVC +# and a CMake function to create R.lib for MSVC if(NOT R_ARCH) if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") From 0ad72993c2b25c73ce25804d0a63df08c60388dc Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 11:48:28 -0500 Subject: [PATCH 28/41] Update R-package/src/cmake/modules/FindLibR.cmake Co-Authored-By: Nikita Titov --- R-package/src/cmake/modules/FindLibR.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index e2a83870ff70..a9fd231bc444 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -105,7 +105,8 @@ else() ) if(LIBR_EXECUTABLE MATCHES ".*lightgbm\\.Rcheck.*") - message(FATAL_ERROR "If you are seeing this error, it means you are running R CMD check and R is using '${LIBR_EXECUTABLE}'. Edit src/cmake/modulesFindLibR.cmake and add your R path to HINTS near this error") + message(FATAL_ERROR "If you are seeing this error, it means you are running R CMD check and R is using '${LIBR_EXECUTABLE}'.\ + \nEdit src/cmake/modulesFindLibR.cmake and add your R path to HINTS near this error") endif() endif() From 7337dcbf9319e5d7484878d7dc02f58ef6c7828f Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 11:49:39 -0500 Subject: [PATCH 29/41] Update R-package/src/cmake/modules/FindLibR.cmake Co-Authored-By: Nikita Titov --- R-package/src/cmake/modules/FindLibR.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index a9fd231bc444..f29ba566d650 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -114,7 +114,7 @@ else() if(NOT LIBR_EXECUTABLE) message(FATAL_ERROR "Unable to locate R executable.\ - \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE cmake variable") + \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE CMake variable") endif() # ask R for the home path From a8a2bbe918a2d2b09c14eb5f961208d70f51a7e3 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 11:49:49 -0500 Subject: [PATCH 30/41] Update R-package/src/cmake/modules/FindLibR.cmake Co-Authored-By: Nikita Titov --- R-package/src/cmake/modules/FindLibR.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index f29ba566d650..ba0e7fbbf46e 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -167,7 +167,7 @@ else() if(NOT LIBR_HOME) message(FATAL_ERROR "\nUnable to locate R executable.\ - \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE cmake variable") + \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE CMake variable") endif() endif() From 7b30a19f156187b913693d5be7aafc1a6a3633de Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 11:52:41 -0500 Subject: [PATCH 31/41] added LIBR_CORE_LIBRARY back --- R-package/src/cmake/modules/FindLibR.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index ba0e7fbbf46e..b869e4e6c96a 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -216,6 +216,7 @@ find_package_handle_standard_args(LibR DEFAULT_MSG LIBR_EXECUTABLE LIBR_INCLUDE_DIRS LIBR_LIB_DIR + LIBR_CORE_LIBRARY ) if(LIBR_FOUND) From 9adc7a94fafeacf29e0bd88ffa320299406bbd65 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 20:20:19 -0500 Subject: [PATCH 32/41] small fixes to CMakeLists --- CMakeLists.txt | 2 +- R-package/src/cmake/modules/FindLibR.cmake | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aeb24cd67ec0..51d552b05a7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,7 +72,7 @@ if(USE_R35) endif(USE_R35) if(BUILD_FOR_R) - list(APPEND CMAKE_MODULE_PATH "${lightgbm_SOURCE_DIR}/cmake/modules") + list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") find_package(LibR REQUIRED) message(STATUS "LIBR_HOME [${LIBR_HOME}]") message(STATUS "LIBR_EXECUTABLE [${LIBR_EXECUTABLE}]") diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index b869e4e6c96a..6ab28155da42 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -47,12 +47,14 @@ function(create_rlib_for_msvc) endif() # extract symbols from R.dll into R.def and R.lib import library - execute_process(COMMAND gendef + execute_process(COMMAND ${GENDEF_EXE} "-" "${LIBR_LIB_DIR}/R.dll" - OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/R.def") - execute_process(COMMAND dlltool + OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/R.def" + ) + execute_process(COMMAND ${DLLTOOL_EXE} "--input-def" "${CMAKE_CURRENT_BINARY_DIR}/R.def" - "--output-lib" "${CMAKE_CURRENT_BINARY_DIR}/R.lib") + "--output-lib" "${CMAKE_CURRENT_BINARY_DIR}/R.lib" + ) endfunction(create_rlib_for_msvc) # R version information is used to search for R's libraries in @@ -195,12 +197,11 @@ if(WIN32 AND MSVC) endif() # look for the core R library -find_library(LIBR_CORE_LIBRARY NAMES R - HINTS "${CMAKE_CURRENT_BINARY_DIR}" "${LIBR_LIB_DIR}" "${LIBR_HOME}/bin" "${LIBR_LIBRARIES}") - -if(LIBR_CORE_LIBRARY-NOTFOUND) - message(STATUS "Could not find R core shared library.") -endif() +find_library( + LIBR_CORE_LIBRARY + NAMES R + HINTS "${CMAKE_CURRENT_BINARY_DIR}" "${LIBR_LIB_DIR}" "${LIBR_HOME}/bin" "${LIBR_LIBRARIES}" +) set(LIBR_HOME ${LIBR_HOME} CACHE PATH "R home directory") set(LIBR_EXECUTABLE ${LIBR_EXECUTABLE} CACHE PATH "R executable") From 20f845255513a862b61ddd236b4bb6633a3ba697 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 21:05:48 -0500 Subject: [PATCH 33/41] simplified FindLibR.cmake --- R-package/src/cmake/modules/FindLibR.cmake | 116 ++++++++------------- 1 file changed, 43 insertions(+), 73 deletions(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 6ab28155da42..56fb467ee63a 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -67,31 +67,22 @@ else() message(FATAL_ERROR "Expected CMAKE_R_VERSION to be passed in but none was provided. Check src/install.libs.R") endif() -# detection for OSX +# Find R executable if(APPLE) find_library(LIBR_LIBRARIES R) if(LIBR_LIBRARIES MATCHES ".*\\.framework") set(LIBR_HOME "${LIBR_LIBRARIES}/Resources") - set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include") set(LIBR_EXECUTABLE "${LIBR_HOME}/R") - set(LIBR_LIB_DIR "${LIBR_HOME}/lib") else() get_filename_component(_LIBR_LIBRARIES "${LIBR_LIBRARIES}" REALPATH) get_filename_component(_LIBR_LIBRARIES_DIR "${_LIBR_LIBRARIES}" DIRECTORY) set(LIBR_EXECUTABLE "${_LIBR_LIBRARIES_DIR}/../bin/R") - execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home())" - OUTPUT_VARIABLE LIBR_HOME - ) - set(LIBR_HOME ${LIBR_HOME}) - set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include") - set(LIBR_LIB_DIR "${LIBR_HOME}/lib") endif() -# detection for UNIX & Win32 -else() +# Unix +elseif(UNIX) # attempt to find R executable if(NOT LIBR_EXECUTABLE) @@ -112,81 +103,64 @@ else() endif() endif() - if(UNIX) - - if(NOT LIBR_EXECUTABLE) - message(FATAL_ERROR "Unable to locate R executable.\ - \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE CMake variable") - endif() - - # ask R for the home path - execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home())" - OUTPUT_VARIABLE LIBR_HOME - ) +# Windows +else() - # ask R for the include dir - execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('include'))" - OUTPUT_VARIABLE LIBR_INCLUDE_DIRS - ) + # if R executable not available, query R_HOME path from registry + if(NOT LIBR_HOME) - # ask R for the lib dir - execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('lib'))" - OUTPUT_VARIABLE LIBR_LIB_DIR + # Try to find R's location in the registry + # ref: https://cran.r-project.org/bin/windows/base/rw-FAQ.html#Does-R-use-the-Registry_003f + get_filename_component( + LIBR_HOME + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\R-core\\R\\${CMAKE_R_VERSION};InstallPath]" + ABSOLUTE ) - # Windows - else() - - # ask R for R_HOME - if(LIBR_EXECUTABLE) - execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(normalizePath(R.home(),winslash='/'))" - OUTPUT_VARIABLE LIBR_HOME - ) - endif() - - # if R executable not available, query R_HOME path from registry if(NOT LIBR_HOME) - - # Try to find R's location in the registry - # ref: https://cran.r-project.org/bin/windows/base/rw-FAQ.html#Does-R-use-the-Registry_003f get_filename_component( LIBR_HOME - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\R-core\\R\\${CMAKE_R_VERSION};InstallPath]" + "[HKEY_CURRENT_USER\\SOFTWARE\\R-core\\R\\${CMAKE_R_VERSION};InstallPath]" ABSOLUTE ) - - if(NOT LIBR_HOME) - get_filename_component( - LIBR_HOME - "[HKEY_CURRENT_USER\\SOFTWARE\\R-core\\R\\${CMAKE_R_VERSION};InstallPath]" - ABSOLUTE - ) - endif() - - if(NOT LIBR_HOME) - message(FATAL_ERROR "\nUnable to locate R executable.\ - \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE CMake variable") - endif() - endif() - # set exe location based on R_ARCH - if(NOT LIBR_EXECUTABLE) - set(LIBR_EXECUTABLE "${LIBR_HOME}/bin/${R_ARCH}/R.exe") + if(NOT LIBR_HOME) + message(FATAL_ERROR "\nUnable to locate R executable.\ + \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE CMake variable") endif() - # set other R paths based on home path - set(LIBR_INCLUDE_DIRS "${LIBR_HOME}/include") - set(LIBR_LIB_DIR "${LIBR_HOME}/bin/${R_ARCH}") + # set exe location based on R_ARCH + set(LIBR_EXECUTABLE "${LIBR_HOME}/bin/${R_ARCH}/R.exe") endif() endif() +if(NOT LIBR_EXECUTABLE) + message(FATAL_ERROR "Unable to locate R executable.\ + \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE CMake variable" + ) +endif() + +# ask R for the home path +execute_process( + COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home())" + OUTPUT_VARIABLE LIBR_HOME +) + +# ask R for the include dir +execute_process( + COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('include'))" + OUTPUT_VARIABLE LIBR_INCLUDE_DIRS +) + +# ask R for the lib dir +execute_process( + COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('lib'))" + OUTPUT_VARIABLE LIBR_LIB_DIR +) + if(WIN32 AND MSVC) # create a local R.lib import library for R.dll if it doesn't exist @@ -219,7 +193,3 @@ find_package_handle_standard_args(LibR DEFAULT_MSG LIBR_LIB_DIR LIBR_CORE_LIBRARY ) - -if(LIBR_FOUND) - message(STATUS "Found R: ${LIBR_EXECUTABLE}") -endif() From 4375584f43badfc8b83efe6f2c752700195c7c5e Mon Sep 17 00:00:00 2001 From: James Lamb Date: Tue, 17 Mar 2020 22:13:15 -0500 Subject: [PATCH 34/41] some fixes for windows --- R-package/src/cmake/modules/FindLibR.cmake | 30 ++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 56fb467ee63a..1270f4f6f91c 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -29,13 +29,15 @@ endif() # Creates R.lib and R.def in the build directory for linking with MSVC function(create_rlib_for_msvc) + message("Creating R.lib and R.def") + # various checks and warnings if(NOT WIN32 OR NOT MSVC) message(FATAL_ERROR "create_rlib_for_msvc() can only be used with MSVC") endif() if(NOT EXISTS "${LIBR_LIB_DIR}") - message(FATAL_ERROR "LIBR_LIB_DIR was not set!") + message(FATAL_ERROR "LIBR_LIB_DIR, '${LIBR_LIB_DIR}', not found") endif() find_program(GENDEF_EXE gendef) @@ -145,31 +147,24 @@ endif() # ask R for the home path execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(R.home())" + COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(normalizePath(R.home(), winslash='/'))" OUTPUT_VARIABLE LIBR_HOME ) # ask R for the include dir execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('include'))" + COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(normalizePath(R.home('include'), winslash='/'))" OUTPUT_VARIABLE LIBR_INCLUDE_DIRS ) +# C:/PROGRA~1/R/R-36~1.1/include + # ask R for the lib dir execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('lib'))" + COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(normalizePath(R.home('lib'), winslash='/'))" OUTPUT_VARIABLE LIBR_LIB_DIR ) -if(WIN32 AND MSVC) - - # create a local R.lib import library for R.dll if it doesn't exist - if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/R.lib") - create_rlib_for_msvc() - endif() - -endif() - # look for the core R library find_library( LIBR_CORE_LIBRARY @@ -183,6 +178,15 @@ set(LIBR_INCLUDE_DIRS ${LIBR_INCLUDE_DIRS} CACHE PATH "R include directory") set(LIBR_LIB_DIR ${LIBR_LIB_DIR} CACHE PATH "R shared libraries directory") set(LIBR_CORE_LIBRARY ${LIBR_CORE_LIBRARY} CACHE PATH "R core shared library") +if(WIN32 AND MSVC) + + # create a local R.lib import library for R.dll if it doesn't exist + if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/R.lib") + create_rlib_for_msvc() + endif() + +endif() + # define find requirements include(FindPackageHandleStandardArgs) From 561ac4ea8a9a8c606bf5645b6e292be03d1feac5 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Sun, 22 Mar 2020 17:51:00 -0500 Subject: [PATCH 35/41] Apply suggestions from code review Co-Authored-By: Nikita Titov --- CMakeLists.txt | 2 +- R-package/src/cmake/modules/FindLibR.cmake | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51d552b05a7f..b061552ed96e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,7 @@ endif(USE_R35) if(BUILD_FOR_R) list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") find_package(LibR REQUIRED) - message(STATUS "LIBR_HOME [${LIBR_HOME}]") + message(STATUS "LIBR_HOME: [${LIBR_HOME}]") message(STATUS "LIBR_EXECUTABLE [${LIBR_EXECUTABLE}]") message(STATUS "LIBR_INCLUDE_DIRS [${LIBR_INCLUDE_DIRS}]") message(STATUS "LIBR_LIB_DIR [${LIBR_LIB_DIR}]") diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 1270f4f6f91c..e342d26870b8 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -65,8 +65,8 @@ endfunction(create_rlib_for_msvc) # find the version of R and pass it through as a CMake variable if(CMAKE_R_VERSION) message("R version passed into FindLibR.cmake: ${CMAKE_R_VERSION}") -else() - message(FATAL_ERROR "Expected CMAKE_R_VERSION to be passed in but none was provided. Check src/install.libs.R") +elseif(WIN32) + message(FATAL_ERROR "Expected CMAKE_R_VERSION to be passed in on Windows but none was provided. Check src/install.libs.R") endif() # Find R executable @@ -128,7 +128,7 @@ else() endif() if(NOT LIBR_HOME) - message(FATAL_ERROR "\nUnable to locate R executable.\ + message(FATAL_ERROR "Unable to locate R executable.\ \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE CMake variable") endif() @@ -141,8 +141,7 @@ endif() if(NOT LIBR_EXECUTABLE) message(FATAL_ERROR "Unable to locate R executable.\ - \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE CMake variable" - ) + \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE CMake variable") endif() # ask R for the home path From 2403a6133c283df64db71e8fadb09a130c53f16f Mon Sep 17 00:00:00 2001 From: James Lamb Date: Sun, 22 Mar 2020 18:13:19 -0500 Subject: [PATCH 36/41] allowed for directly passing LIBR_EXECUTABLE to FindLibR.cmake --- CMakeLists.txt | 10 +-- R-package/src/cmake/modules/FindLibR.cmake | 93 +++++++++++----------- 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b061552ed96e..b3b1029245d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,11 +74,11 @@ endif(USE_R35) if(BUILD_FOR_R) list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") find_package(LibR REQUIRED) - message(STATUS "LIBR_HOME: [${LIBR_HOME}]") - message(STATUS "LIBR_EXECUTABLE [${LIBR_EXECUTABLE}]") - message(STATUS "LIBR_INCLUDE_DIRS [${LIBR_INCLUDE_DIRS}]") - message(STATUS "LIBR_LIB_DIR [${LIBR_LIB_DIR}]") - message(STATUS "LIBR_CORE_LIBRARY [${LIBR_CORE_LIBRARY}]") + message(STATUS "LIBR_HOME: ${LIBR_HOME}") + message(STATUS "LIBR_EXECUTABLE: ${LIBR_EXECUTABLE}") + message(STATUS "LIBR_INCLUDE_DIRS: ${LIBR_INCLUDE_DIRS}") + message(STATUS "LIBR_LIB_DIR: ${LIBR_LIB_DIR}") + message(STATUS "LIBR_CORE_LIBRARY: ${LIBR_CORE_LIBRARY}") include_directories(${LIBR_INCLUDE_DIRS}) ADD_DEFINITIONS(-DLGB_R_BUILD) endif(BUILD_FOR_R) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index e342d26870b8..b88274ab35b8 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -69,55 +69,56 @@ elseif(WIN32) message(FATAL_ERROR "Expected CMAKE_R_VERSION to be passed in on Windows but none was provided. Check src/install.libs.R") endif() -# Find R executable -if(APPLE) +# Find R executable unless it has been provided directly +if (NOT LIBR_EXECUTABLE) + if(APPLE) + + find_library(LIBR_LIBRARIES R) + + if(LIBR_LIBRARIES MATCHES ".*\\.framework") + set(LIBR_HOME "${LIBR_LIBRARIES}/Resources") + set(LIBR_EXECUTABLE "${LIBR_HOME}/R") + else() + get_filename_component(_LIBR_LIBRARIES "${LIBR_LIBRARIES}" REALPATH) + get_filename_component(_LIBR_LIBRARIES_DIR "${_LIBR_LIBRARIES}" DIRECTORY) + set(LIBR_EXECUTABLE "${_LIBR_LIBRARIES_DIR}/../bin/R") + endif() - find_library(LIBR_LIBRARIES R) + elseif(UNIX) - if(LIBR_LIBRARIES MATCHES ".*\\.framework") - set(LIBR_HOME "${LIBR_LIBRARIES}/Resources") - set(LIBR_EXECUTABLE "${LIBR_HOME}/R") - else() - get_filename_component(_LIBR_LIBRARIES "${LIBR_LIBRARIES}" REALPATH) - get_filename_component(_LIBR_LIBRARIES_DIR "${_LIBR_LIBRARIES}" DIRECTORY) - set(LIBR_EXECUTABLE "${_LIBR_LIBRARIES_DIR}/../bin/R") - endif() + # attempt to find R executable + if(NOT LIBR_EXECUTABLE) -# Unix -elseif(UNIX) - - # attempt to find R executable - if(NOT LIBR_EXECUTABLE) + # CRAN may run RD CMD CHECK instead of R CMD CHECK, + # which can lead to this infamous error: + # 'R' should not be used without a path -- see par. 1.6 of the manual + find_program( + LIBR_EXECUTABLE + NO_DEFAULT_PATH + HINTS "${CMAKE_CURRENT_BINARY_DIR}" "/usr/bin" "/usr/lib/" "/usr/local/bin/" + NAMES R + ) - # CRAN may run RD CMD CHECK instead of R CMD CHECK, - # which can lead to this infamous error: - # 'R' should not be used without a path -- see par. 1.6 of the manual - find_program( - LIBR_EXECUTABLE - NO_DEFAULT_PATH - HINTS "${CMAKE_CURRENT_BINARY_DIR}" "/usr/bin" "/usr/lib/" "/usr/local/bin/" - NAMES R R.exe - ) - - if(LIBR_EXECUTABLE MATCHES ".*lightgbm\\.Rcheck.*") - message(FATAL_ERROR "If you are seeing this error, it means you are running R CMD check and R is using '${LIBR_EXECUTABLE}'.\ - \nEdit src/cmake/modulesFindLibR.cmake and add your R path to HINTS near this error") + if(LIBR_EXECUTABLE MATCHES ".*lightgbm\\.Rcheck.*") + message(FATAL_ERROR "If you are seeing this error, it means you are running R CMD check and R is using '${LIBR_EXECUTABLE}'.\ + \nEdit src/cmake/modulesFindLibR.cmake and add your R path to HINTS near this error") + endif() endif() - endif() -# Windows -else() + # Windows + else() - # if R executable not available, query R_HOME path from registry - if(NOT LIBR_HOME) + # if R executable not available, query R_HOME path from registry + if(NOT LIBR_HOME) - # Try to find R's location in the registry - # ref: https://cran.r-project.org/bin/windows/base/rw-FAQ.html#Does-R-use-the-Registry_003f - get_filename_component( - LIBR_HOME - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\R-core\\R\\${CMAKE_R_VERSION};InstallPath]" - ABSOLUTE - ) + # Try to find R's location in the registry + # ref: https://cran.r-project.org/bin/windows/base/rw-FAQ.html#Does-R-use-the-Registry_003f + get_filename_component( + LIBR_HOME + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\R-core\\R\\${CMAKE_R_VERSION};InstallPath]" + ABSOLUTE + ) + endif() if(NOT LIBR_HOME) get_filename_component( @@ -137,11 +138,11 @@ else() endif() -endif() + if(NOT LIBR_EXECUTABLE) + message(FATAL_ERROR "Unable to locate R executable.\ + \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE CMake variable") + endif() -if(NOT LIBR_EXECUTABLE) - message(FATAL_ERROR "Unable to locate R executable.\ - \nEither add its location to PATH or provide it through the LIBR_EXECUTABLE CMake variable") endif() # ask R for the home path @@ -156,8 +157,6 @@ execute_process( OUTPUT_VARIABLE LIBR_INCLUDE_DIRS ) -# C:/PROGRA~1/R/R-36~1.1/include - # ask R for the lib dir execute_process( COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(normalizePath(R.home('lib'), winslash='/'))" From 5b60e8e7ced86e68cab9b374431ebe846c19d48d Mon Sep 17 00:00:00 2001 From: James Lamb Date: Mon, 23 Mar 2020 11:37:38 -0500 Subject: [PATCH 37/41] reorganized FindLibR.cmake to catch more cases --- R-package/src/cmake/modules/FindLibR.cmake | 37 +++++++++++++++------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index b88274ab35b8..244f4836050b 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -69,6 +69,28 @@ elseif(WIN32) message(FATAL_ERROR "Expected CMAKE_R_VERSION to be passed in on Windows but none was provided. Check src/install.libs.R") endif() + +if (NOT LIBR_EXECUTABLE) + find_program( + LIBR_EXECUTABLE + NAMES R R.exe + ) + + # CRAN may run RD CMD CHECK instead of R CMD CHECK, + # which can lead to this infamous error: + # 'R' should not be used without a path -- see par. 1.6 of the manual + if(LIBR_EXECUTABLE MATCHES ".*\\.Rcheck.*") + unset(LIBR_EXECUTABLE PARENT_SCOPE) + unset(LIBR_EXECUTABLE CACHE) + endif() + + # ignore the R bundled with R.app on Mac, since that is GUI-only + if(LIBR_EXECUTABLE MATCHES ".+R\\.app.*") + unset(LIBR_EXECUTABLE PARENT_SCOPE) + unset(LIBR_EXECUTABLE CACHE) + endif() +endif() + # Find R executable unless it has been provided directly if (NOT LIBR_EXECUTABLE) if(APPLE) @@ -88,21 +110,12 @@ if (NOT LIBR_EXECUTABLE) # attempt to find R executable if(NOT LIBR_EXECUTABLE) - - # CRAN may run RD CMD CHECK instead of R CMD CHECK, - # which can lead to this infamous error: - # 'R' should not be used without a path -- see par. 1.6 of the manual find_program( LIBR_EXECUTABLE NO_DEFAULT_PATH HINTS "${CMAKE_CURRENT_BINARY_DIR}" "/usr/bin" "/usr/lib/" "/usr/local/bin/" NAMES R ) - - if(LIBR_EXECUTABLE MATCHES ".*lightgbm\\.Rcheck.*") - message(FATAL_ERROR "If you are seeing this error, it means you are running R CMD check and R is using '${LIBR_EXECUTABLE}'.\ - \nEdit src/cmake/modulesFindLibR.cmake and add your R path to HINTS near this error") - endif() endif() # Windows @@ -147,19 +160,19 @@ endif() # ask R for the home path execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(normalizePath(R.home(), winslash='/'))" + COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "--no-save" "-e" "cat(normalizePath(R.home(), winslash='/'))" OUTPUT_VARIABLE LIBR_HOME ) # ask R for the include dir execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(normalizePath(R.home('include'), winslash='/'))" + COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "--no-save" "-e" "cat(normalizePath(R.home('include'), winslash='/'))" OUTPUT_VARIABLE LIBR_INCLUDE_DIRS ) # ask R for the lib dir execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--no-save" "-e" "cat(normalizePath(R.home('lib'), winslash='/'))" + COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "--no-save" "-e" "cat(normalizePath(R.home('lib'), winslash='/'))" OUTPUT_VARIABLE LIBR_LIB_DIR ) From c9dd50d8bbb4d26b672ccdde7f57b5ea9afa8466 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Mon, 23 Mar 2020 12:11:49 -0500 Subject: [PATCH 38/41] clean up inconsistencies in R calls in FindLibR.cmake --- R-package/src/cmake/modules/FindLibR.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index 244f4836050b..b1ddb6f789d8 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -160,19 +160,19 @@ endif() # ask R for the home path execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "--no-save" "-e" "cat(normalizePath(R.home(), winslash='/'))" + COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(normalizePath(R.home(), winslash='/'))" OUTPUT_VARIABLE LIBR_HOME ) # ask R for the include dir execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "--no-save" "-e" "cat(normalizePath(R.home('include'), winslash='/'))" + COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(normalizePath(R.home('include'), winslash='/'))" OUTPUT_VARIABLE LIBR_INCLUDE_DIRS ) # ask R for the lib dir execute_process( - COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "--no-save" "-e" "cat(normalizePath(R.home('lib'), winslash='/'))" + COMMAND ${LIBR_EXECUTABLE} "--slave" "--vanilla" "-e" "cat(normalizePath(R.home('lib'), winslash='/'))" OUTPUT_VARIABLE LIBR_LIB_DIR ) From c00c92859743c081526472761377411e8d2992e1 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Mon, 23 Mar 2020 17:24:03 -0500 Subject: [PATCH 39/41] Update R-package/src/cmake/modules/FindLibR.cmake Co-Authored-By: Nikita Titov --- R-package/src/cmake/modules/FindLibR.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index b1ddb6f789d8..b077d681065d 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -91,7 +91,7 @@ if (NOT LIBR_EXECUTABLE) endif() endif() -# Find R executable unless it has been provided directly +# Find R executable unless it has been provided directly or already found if (NOT LIBR_EXECUTABLE) if(APPLE) From 20aeb82830f3c474fc4f2a55e4afedb06b5016b5 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Mon, 23 Mar 2020 17:57:30 -0500 Subject: [PATCH 40/41] removed unnecessary log messages --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3b1029245d7..895f2dd26fce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,10 +74,8 @@ endif(USE_R35) if(BUILD_FOR_R) list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") find_package(LibR REQUIRED) - message(STATUS "LIBR_HOME: ${LIBR_HOME}") message(STATUS "LIBR_EXECUTABLE: ${LIBR_EXECUTABLE}") message(STATUS "LIBR_INCLUDE_DIRS: ${LIBR_INCLUDE_DIRS}") - message(STATUS "LIBR_LIB_DIR: ${LIBR_LIB_DIR}") message(STATUS "LIBR_CORE_LIBRARY: ${LIBR_CORE_LIBRARY}") include_directories(${LIBR_INCLUDE_DIRS}) ADD_DEFINITIONS(-DLGB_R_BUILD) From ab870d8895739a6535408f13f4ad1df946dc10a9 Mon Sep 17 00:00:00 2001 From: James Lamb Date: Mon, 23 Mar 2020 18:00:13 -0500 Subject: [PATCH 41/41] removed unnecessary unset() call --- R-package/src/cmake/modules/FindLibR.cmake | 2 -- 1 file changed, 2 deletions(-) diff --git a/R-package/src/cmake/modules/FindLibR.cmake b/R-package/src/cmake/modules/FindLibR.cmake index b077d681065d..20c0a974e1ff 100644 --- a/R-package/src/cmake/modules/FindLibR.cmake +++ b/R-package/src/cmake/modules/FindLibR.cmake @@ -80,13 +80,11 @@ if (NOT LIBR_EXECUTABLE) # which can lead to this infamous error: # 'R' should not be used without a path -- see par. 1.6 of the manual if(LIBR_EXECUTABLE MATCHES ".*\\.Rcheck.*") - unset(LIBR_EXECUTABLE PARENT_SCOPE) unset(LIBR_EXECUTABLE CACHE) endif() # ignore the R bundled with R.app on Mac, since that is GUI-only if(LIBR_EXECUTABLE MATCHES ".+R\\.app.*") - unset(LIBR_EXECUTABLE PARENT_SCOPE) unset(LIBR_EXECUTABLE CACHE) endif() endif()