diff --git a/Makefile b/Makefile index 80507dfde..1eecdf046 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,7 @@ else endif # specify tensor path -.PHONY: clean all lint clean_all +.PHONY: clean all lint clean_all rcpplint Rpack Rbuild Rcheck all: lib/libxgboost.a lib/libxgboost.so xgboost @@ -98,15 +98,50 @@ lib/libxgboost.so: $(ALL_DEP) xgboost: $(CLI_OBJ) lib/libxgboost.a $(LIB_DEP) $(CXX) $(CFLAGS) -o $@ $(filter %.o %.a, $^) $(LDFLAGS) -lint: +rcpplint: + python2 dmlc-core/scripts/lint.py xgboost ${LINT_LANG} R-package/src + +lint: rcpplint python2 dmlc-core/scripts/lint.py xgboost ${LINT_LANG} include src clean: - $(RM) -rf build lib bin *~ */*~ */*/*~ */*/*/*~ $(AMALGA_OBJ) xgboost + $(RM) -rf build lib bin *~ */*~ */*/*~ */*/*/*~ amalgamation/*.o xgboost clean_all: clean cd $(DMLC_CORE); make clean; cd - cd $(RABIT); make clean; cd - +# Script to make a clean installable R package. +Rpack: + make clean_all + rm -rf xgboost xgboost*.tar.gz + cp -r R-package xgboost + rm -rf xgboost/src/*.o xgboost/src/*.so xgboost/src/*.dll + rm -rf xgboost/src/*/*.o + rm -rf xgboost/demo/*.model xgboost/demo/*.buffer xgboost/demo/*.txt + rm -rf xgboost/demo/runall.R + cp -r src xgboost/src/src + cp -r include xgboost/src/include + cp -r amalgamation xgboost/src/amalgamation + mkdir -p xgboost/src/rabit + cp -r rabit/include xgboost/src/rabit/include + cp -r rabit/src xgboost/src/rabit/src + rm -rf xgboost/src/rabit/src/*.o + mkdir -p xgboost/src/dmlc-core + cp -r dmlc-core/include xgboost/src/dmlc-core/include + cp -r dmlc-core/src xgboost/src/dmlc-core/src + cp ./LICENSE xgboost + cat R-package/src/Makevars|sed '2s/.*/PKGROOT=./' | sed '3s/.*/ENABLE_STD_THREAD=0/' > xgboost/src/Makevars + cp xgboost/src/Makevars xgboost/src/Makevars.win + +Rbuild: + make Rpack + R CMD build --no-build-vignettes xgboost + rm -rf xgboost + +Rcheck: + make Rbuild + R CMD check xgboost*.tar.gz + -include build/*.d -include build/*/*.d diff --git a/R-package/src/Makevars b/R-package/src/Makevars index d0eb23b25..0b7d3f084 100644 --- a/R-package/src/Makevars +++ b/R-package/src/Makevars @@ -1,8 +1,10 @@ # package root PKGROOT=../../ +ENABLE_STD_THREAD=1 # _*_ mode: Makefile; _*_ -PKG_CPPFLAGS= -DXGBOOST_CUSTOMIZE_MSG_ -DXGBOOST_CUSTOMIZE_PRNG_ -DXGBOOST_STRICT_CXX98_ -DRABIT_CUSTOMIZE_MSG_ -DRABIT_STRICT_CXX98_ -I$(PKGROOT) +CXX_STD = CXX11 +XGB_RFLAGS = -DXGBOOST_STRICT_R_MODE=1 -DDMLC_LOG_BEFORE_THROW=0 -DDMLC_ENABLE_STD_THREAD=$(ENABLE_STD_THREAD) +PKG_CPPFLAGS= -I$(PKGROOT)/include -I$(PKGROOT)/dmlc-core/include -I$(PKGROOT)/rabit/include $(XGB_RFLAGS) PKG_CXXFLAGS= $(SHLIB_OPENMP_CFLAGS) $(SHLIB_PTHREAD_FLAGS) PKG_LIBS = $(SHLIB_OPENMP_CFLAGS) $(SHLIB_PTHREAD_FLAGS) -OBJECTS= xgboost_R.o xgboost_assert.o $(PKGROOT)/wrapper/xgboost_wrapper.o $(PKGROOT)/src/io/io.o $(PKGROOT)/src/gbm/gbm.o $(PKGROOT)/src/tree/updater.o $(PKGROOT)/subtree/rabit/src/engine_empty.o $(PKGROOT)/src/io/dmlc_simple.o - +OBJECTS= ./xgboost_R.o $(PKGROOT)/amalgamation/xgboost-all0.o $(PKGROOT)/amalgamation/dmlc-minimum0.o $(PKGROOT)/rabit/src/engine_empty.o diff --git a/R-package/src/Makevars.win b/R-package/src/Makevars.win index 56b550e7f..20ad085ba 100644 --- a/R-package/src/Makevars.win +++ b/R-package/src/Makevars.win @@ -1,5 +1,6 @@ # package root PKGROOT=./ +ENABLE_STD_THREAD=0 # _*_ mode: Makefile; _*_ # This file is only used for windows compilation from github @@ -9,11 +10,16 @@ all: $(SHLIB) $(SHLIB): xgblib xgblib: cp -r ../../src . - cp -r ../../wrapper . - cp -r ../../subtree . + cp -r ../../rabit . + cp -r ../../dmlc-core . + cp -r ../../include . + cp -r ../../amalgamation . -PKG_CPPFLAGS= -DXGBOOST_CUSTOMIZE_MSG_ -DXGBOOST_CUSTOMIZE_PRNG_ -DXGBOOST_STRICT_CXX98_ -DRABIT_CUSTOMIZE_MSG_ -DRABIT_STRICT_CXX98_ -I$(PKGROOT) -I../.. +CXX_STD = CXX11 +XGB_RFLAGS = -DXGBOOST_STRICT_R_MODE=1 -DDMLC_LOG_BEFORE_THROW=0 -DDMLC_ENABLE_STD_THREAD=$(ENABLE_STD_THREAD) +PKG_CPPFLAGS= -I$(PKGROOT)/include -I$(PKGROOT)/dmlc-core/include -I$(PKGROOT)/rabit/include $(XGB_RFLAGS) PKG_CXXFLAGS= $(SHLIB_OPENMP_CFLAGS) $(SHLIB_PTHREAD_FLAGS) PKG_LIBS = $(SHLIB_OPENMP_CFLAGS) $(SHLIB_PTHREAD_FLAGS) -OBJECTS= xgboost_R.o xgboost_assert.o $(PKGROOT)/wrapper/xgboost_wrapper.o $(PKGROOT)/src/io/io.o $(PKGROOT)/src/gbm/gbm.o $(PKGROOT)/src/tree/updater.o $(PKGROOT)/subtree/rabit/src/engine_empty.o $(PKGROOT)/src/io/dmlc_simple.o +OBJECTS= ./xgboost_R.o $(PKGROOT)/amalgamation/xgboost-all0.o $(PKGROOT)/amalgamation/dmlc-minimum0.o $(PKGROOT)/rabit/src/engine_empty.o + $(OBJECTS) : xgblib diff --git a/R-package/src/xgboost_R.cc b/R-package/src/xgboost_R.cc new file mode 100644 index 000000000..e2ad6926f --- /dev/null +++ b/R-package/src/xgboost_R.cc @@ -0,0 +1,364 @@ +// Copyright (c) 2014 by Contributors +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "./xgboost_R.h" + +/*! + * \brief macro to annotate begin of api + */ +#define R_API_BEGIN() \ + GetRNGstate(); \ + try { +/*! + * \brief macro to annotate end of api + */ +#define R_API_END() \ + } catch(dmlc::Error& e) { \ + PutRNGstate(); \ + error(e.what()); \ + } \ + PutRNGstate(); + +/*! + * \brief macro to check the call. + */ +#define CHECK_CALL(x) \ + if ((x) != 0) { \ + error(XGBGetLastError()); \ + } + +namespace xgboost { +namespace common { +bool CheckNAN(double v) { + return ISNAN(v); +} +double LogGamma(double v) { + return lgammafn(v); +} +} // namespace common +} // namespace xgboost + +using namespace dmlc; + +SEXP XGCheckNullPtr_R(SEXP handle) { + return ScalarLogical(R_ExternalPtrAddr(handle) == NULL); +} + +void _DMatrixFinalizer(SEXP ext) { + R_API_BEGIN(); + if (R_ExternalPtrAddr(ext) == NULL) return; + CHECK_CALL(XGDMatrixFree(R_ExternalPtrAddr(ext))); + R_ClearExternalPtr(ext); + R_API_END(); +} + +SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent) { + SEXP ret; + R_API_BEGIN(); + DMatrixHandle handle; + CHECK_CALL(XGDMatrixCreateFromFile(CHAR(asChar(fname)), asInteger(silent), &handle)); + ret = PROTECT(R_MakeExternalPtr(handle, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE); + UNPROTECT(1); + R_API_END(); + return ret; +} + +SEXP XGDMatrixCreateFromMat_R(SEXP mat, + SEXP missing) { + SEXP ret; + R_API_BEGIN(); + SEXP dim = getAttrib(mat, R_DimSymbol); + size_t nrow = static_cast(INTEGER(dim)[0]); + size_t ncol = static_cast(INTEGER(dim)[1]); + double *din = REAL(mat); + std::vector data(nrow * ncol); + #pragma omp parallel for schedule(static) + for (omp_ulong i = 0; i < nrow; ++i) { + for (size_t j = 0; j < ncol; ++j) { + data[i * ncol +j] = din[i + nrow * j]; + } + } + DMatrixHandle handle; + CHECK_CALL(XGDMatrixCreateFromMat(BeginPtr(data), nrow, ncol, asReal(missing), &handle)); + ret = PROTECT(R_MakeExternalPtr(handle, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE); + UNPROTECT(1); + R_API_END(); + return ret; +} + +SEXP XGDMatrixCreateFromCSC_R(SEXP indptr, + SEXP indices, + SEXP data) { + SEXP ret; + R_API_BEGIN(); + const int *p_indptr = INTEGER(indptr); + const int *p_indices = INTEGER(indices); + const double *p_data = REAL(data); + int nindptr = length(indptr); + int ndata = length(data); + std::vector col_ptr_(nindptr); + std::vector indices_(ndata); + std::vector data_(ndata); + + for (int i = 0; i < nindptr; ++i) { + col_ptr_[i] = static_cast(p_indptr[i]); + } + #pragma omp parallel for schedule(static) + for (int i = 0; i < ndata; ++i) { + indices_[i] = static_cast(p_indices[i]); + data_[i] = static_cast(p_data[i]); + } + DMatrixHandle handle; + CHECK_CALL(XGDMatrixCreateFromCSC(BeginPtr(col_ptr_), BeginPtr(indices_), + BeginPtr(data_), nindptr, ndata, + &handle)); + ret = PROTECT(R_MakeExternalPtr(handle, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE); + UNPROTECT(1); + R_API_END(); + return ret; +} + +SEXP XGDMatrixSliceDMatrix_R(SEXP handle, SEXP idxset) { + SEXP ret; + R_API_BEGIN(); + int len = length(idxset); + std::vector idxvec(len); + for (int i = 0; i < len; ++i) { + idxvec[i] = INTEGER(idxset)[i] - 1; + } + DMatrixHandle res; + CHECK_CALL(XGDMatrixSliceDMatrix(R_ExternalPtrAddr(handle), + BeginPtr(idxvec), len, + &res)); + ret = PROTECT(R_MakeExternalPtr(res, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE); + UNPROTECT(1); + R_API_END(); + return ret; +} + +void XGDMatrixSaveBinary_R(SEXP handle, SEXP fname, SEXP silent) { + R_API_BEGIN(); + CHECK_CALL(XGDMatrixSaveBinary(R_ExternalPtrAddr(handle), + CHAR(asChar(fname)), + asInteger(silent))); + R_API_END(); +} + +void XGDMatrixSetInfo_R(SEXP handle, SEXP field, SEXP array) { + R_API_BEGIN(); + int len = length(array); + const char *name = CHAR(asChar(field)); + if (!strcmp("group", name)) { + std::vector vec(len); + #pragma omp parallel for schedule(static) + for (int i = 0; i < len; ++i) { + vec[i] = static_cast(INTEGER(array)[i]); + } + CHECK_CALL(XGDMatrixSetGroup(R_ExternalPtrAddr(handle), BeginPtr(vec), len)); + } else { + std::vector vec(len); + #pragma omp parallel for schedule(static) + for (int i = 0; i < len; ++i) { + vec[i] = REAL(array)[i]; + } + CHECK_CALL(XGDMatrixSetFloatInfo(R_ExternalPtrAddr(handle), + CHAR(asChar(field)), + BeginPtr(vec), len)); + } + R_API_END(); +} + +SEXP XGDMatrixGetInfo_R(SEXP handle, SEXP field) { + SEXP ret; + R_API_BEGIN(); + bst_ulong olen; + const float *res; + CHECK_CALL(XGDMatrixGetFloatInfo(R_ExternalPtrAddr(handle), + CHAR(asChar(field)), + &olen, + &res)); + ret = PROTECT(allocVector(REALSXP, olen)); + for (size_t i = 0; i < olen; ++i) { + REAL(ret)[i] = res[i]; + } + UNPROTECT(1); + R_API_END(); + return ret; +} + +SEXP XGDMatrixNumRow_R(SEXP handle) { + bst_ulong nrow; + R_API_BEGIN(); + CHECK_CALL(XGDMatrixNumRow(R_ExternalPtrAddr(handle), &nrow)); + R_API_END(); + return ScalarInteger(static_cast(nrow)); +} + +// functions related to booster +void _BoosterFinalizer(SEXP ext) { + if (R_ExternalPtrAddr(ext) == NULL) return; + CHECK_CALL(XGBoosterFree(R_ExternalPtrAddr(ext))); + R_ClearExternalPtr(ext); +} + +SEXP XGBoosterCreate_R(SEXP dmats) { + SEXP ret; + R_API_BEGIN(); + int len = length(dmats); + std::vector dvec; + for (int i = 0; i < len; ++i) { + dvec.push_back(R_ExternalPtrAddr(VECTOR_ELT(dmats, i))); + } + BoosterHandle handle; + CHECK_CALL(XGBoosterCreate(BeginPtr(dvec), dvec.size(), &handle)); + ret = PROTECT(R_MakeExternalPtr(handle, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ret, _BoosterFinalizer, TRUE); + UNPROTECT(1); + R_API_END(); + return ret; +} + +void XGBoosterSetParam_R(SEXP handle, SEXP name, SEXP val) { + R_API_BEGIN(); + CHECK_CALL(XGBoosterSetParam(R_ExternalPtrAddr(handle), + CHAR(asChar(name)), + CHAR(asChar(val)))); + R_API_END(); +} + +void XGBoosterUpdateOneIter_R(SEXP handle, SEXP iter, SEXP dtrain) { + R_API_BEGIN(); + CHECK_CALL(XGBoosterUpdateOneIter(R_ExternalPtrAddr(handle), + asInteger(iter), + R_ExternalPtrAddr(dtrain))); + R_API_END(); +} + +void XGBoosterBoostOneIter_R(SEXP handle, SEXP dtrain, SEXP grad, SEXP hess) { + R_API_BEGIN(); + CHECK_EQ(length(grad), length(hess)) + << "gradient and hess must have same length"; + int len = length(grad); + std::vector tgrad(len), thess(len); + #pragma omp parallel for schedule(static) + for (int j = 0; j < len; ++j) { + tgrad[j] = REAL(grad)[j]; + thess[j] = REAL(hess)[j]; + } + CHECK_CALL(XGBoosterBoostOneIter(R_ExternalPtrAddr(handle), + R_ExternalPtrAddr(dtrain), + BeginPtr(tgrad), BeginPtr(thess), + len)); + R_API_END(); +} + +SEXP XGBoosterEvalOneIter_R(SEXP handle, SEXP iter, SEXP dmats, SEXP evnames) { + const char *ret; + R_API_BEGIN(); + CHECK_EQ(length(dmats), length(evnames)) + << "dmats and evnams must have same length"; + int len = length(dmats); + std::vector vec_dmats; + std::vector vec_names; + std::vector vec_sptr; + for (int i = 0; i < len; ++i) { + vec_dmats.push_back(R_ExternalPtrAddr(VECTOR_ELT(dmats, i))); + vec_names.push_back(std::string(CHAR(asChar(VECTOR_ELT(evnames, i))))); + } + for (int i = 0; i < len; ++i) { + vec_sptr.push_back(vec_names[i].c_str()); + } + CHECK_CALL(XGBoosterEvalOneIter(R_ExternalPtrAddr(handle), + asInteger(iter), + BeginPtr(vec_dmats), + BeginPtr(vec_sptr), + len, &ret)); + R_API_END(); + return mkString(ret); +} + +SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask, SEXP ntree_limit) { + SEXP ret; + R_API_BEGIN(); + bst_ulong olen; + const float *res; + CHECK_CALL(XGBoosterPredict(R_ExternalPtrAddr(handle), + R_ExternalPtrAddr(dmat), + asInteger(option_mask), + asInteger(ntree_limit), + &olen, &res)); + ret = PROTECT(allocVector(REALSXP, olen)); + for (size_t i = 0; i < olen; ++i) { + REAL(ret)[i] = res[i]; + } + UNPROTECT(1); + R_API_END(); + return ret; +} + +void XGBoosterLoadModel_R(SEXP handle, SEXP fname) { + R_API_BEGIN(); + CHECK_CALL(XGBoosterLoadModel(R_ExternalPtrAddr(handle), CHAR(asChar(fname)))); + R_API_END(); +} + +void XGBoosterSaveModel_R(SEXP handle, SEXP fname) { + R_API_BEGIN(); + CHECK_CALL(XGBoosterSaveModel(R_ExternalPtrAddr(handle), CHAR(asChar(fname)))); + R_API_END(); +} + +void XGBoosterLoadModelFromRaw_R(SEXP handle, SEXP raw) { + R_API_BEGIN(); + CHECK_CALL(XGBoosterLoadModelFromBuffer(R_ExternalPtrAddr(handle), + RAW(raw), + length(raw))); + R_API_END(); +} + +SEXP XGBoosterModelToRaw_R(SEXP handle) { + SEXP ret; + R_API_BEGIN(); + bst_ulong olen; + const char *raw; + CHECK_CALL(XGBoosterGetModelRaw(R_ExternalPtrAddr(handle), &olen, &raw)); + ret = PROTECT(allocVector(RAWSXP, olen)); + if (olen != 0) { + memcpy(RAW(ret), raw, olen); + } + UNPROTECT(1); + R_API_END(); + return ret; +} + +SEXP XGBoosterDumpModel_R(SEXP handle, SEXP fmap, SEXP with_stats) { + SEXP out; + R_API_BEGIN(); + bst_ulong olen; + const char **res; + CHECK_CALL(XGBoosterDumpModel(R_ExternalPtrAddr(handle), + CHAR(asChar(fmap)), + asInteger(with_stats), + &olen, &res)); + out = PROTECT(allocVector(STRSXP, olen)); + for (size_t i = 0; i < olen; ++i) { + std::stringstream stream; + stream << "booster[" << i <<"]\n" << res[i]; + SET_STRING_ELT(out, i, mkChar(stream.str().c_str())); + } + UNPROTECT(1); + R_API_END(); + return out; +} + diff --git a/R-package/src/xgboost_R.cpp b/R-package/src/xgboost_R.cpp deleted file mode 100644 index 1d426c496..000000000 --- a/R-package/src/xgboost_R.cpp +++ /dev/null @@ -1,344 +0,0 @@ -// Copyright (c) 2014 by Contributors -#include -#include -#include -#include -#include -#include -#include "wrapper/xgboost_wrapper.h" -#include "src/utils/utils.h" -#include "src/utils/omp.h" -#include "xgboost_R.h" - -using namespace std; -using namespace xgboost; - -extern "C" { - void XGBoostAssert_R(int exp, const char *fmt, ...); - void XGBoostCheck_R(int exp, const char *fmt, ...); - int XGBoostSPrintf_R(char *buf, size_t size, const char *fmt, ...); -} - -// implements error handling -namespace xgboost { -namespace utils { -extern "C" { - void (*Printf)(const char *fmt, ...) = Rprintf; - int (*SPrintf)(char *buf, size_t size, const char *fmt, ...) = XGBoostSPrintf_R; - void (*Assert)(int exp, const char *fmt, ...) = XGBoostAssert_R; - void (*Check)(int exp, const char *fmt, ...) = XGBoostCheck_R; - void (*Error)(const char *fmt, ...) = error; -} -bool CheckNAN(double v) { - return ISNAN(v); -} -double LogGamma(double v) { - return lgammafn(v); -} -} // namespace utils - -namespace random { -void Seed(unsigned seed) { - // warning("parameter seed is ignored, please set random seed using set.seed"); -} -double Uniform(void) { - return unif_rand(); -} -double Normal(void) { - return norm_rand(); -} -} // namespace random -} // namespace xgboost - -// call before wrapper starts -inline void _WrapperBegin(void) { - GetRNGstate(); -} -// call after wrapper starts -inline void _WrapperEnd(void) { - PutRNGstate(); -} - -// do nothing, check error -inline void CheckErr(int ret) { -} - -extern "C" { - SEXP XGCheckNullPtr_R(SEXP handle) { - return ScalarLogical(R_ExternalPtrAddr(handle) == NULL); - } - void _DMatrixFinalizer(SEXP ext) { - if (R_ExternalPtrAddr(ext) == NULL) return; - XGDMatrixFree(R_ExternalPtrAddr(ext)); - R_ClearExternalPtr(ext); - } - SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent) { - _WrapperBegin(); - DMatrixHandle handle; - CheckErr(XGDMatrixCreateFromFile(CHAR(asChar(fname)), asInteger(silent), &handle)); - _WrapperEnd(); - SEXP ret = PROTECT(R_MakeExternalPtr(handle, R_NilValue, R_NilValue)); - R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE); - UNPROTECT(1); - return ret; - } - SEXP XGDMatrixCreateFromMat_R(SEXP mat, - SEXP missing) { - _WrapperBegin(); - SEXP dim = getAttrib(mat, R_DimSymbol); - size_t nrow = static_cast(INTEGER(dim)[0]); - size_t ncol = static_cast(INTEGER(dim)[1]); - double *din = REAL(mat); - std::vector data(nrow * ncol); - #pragma omp parallel for schedule(static) - for (bst_omp_uint i = 0; i < nrow; ++i) { - for (size_t j = 0; j < ncol; ++j) { - data[i * ncol +j] = din[i + nrow * j]; - } - } - DMatrixHandle handle; - CheckErr(XGDMatrixCreateFromMat(BeginPtr(data), nrow, ncol, asReal(missing), &handle)); - _WrapperEnd(); - SEXP ret = PROTECT(R_MakeExternalPtr(handle, R_NilValue, R_NilValue)); - R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE); - UNPROTECT(1); - return ret; - } - SEXP XGDMatrixCreateFromCSC_R(SEXP indptr, - SEXP indices, - SEXP data) { - _WrapperBegin(); - const int *p_indptr = INTEGER(indptr); - const int *p_indices = INTEGER(indices); - const double *p_data = REAL(data); - int nindptr = length(indptr); - int ndata = length(data); - std::vector col_ptr_(nindptr); - std::vector indices_(ndata); - std::vector data_(ndata); - - for (int i = 0; i < nindptr; ++i) { - col_ptr_[i] = static_cast(p_indptr[i]); - } - #pragma omp parallel for schedule(static) - for (int i = 0; i < ndata; ++i) { - indices_[i] = static_cast(p_indices[i]); - data_[i] = static_cast(p_data[i]); - } - DMatrixHandle handle; - CheckErr(XGDMatrixCreateFromCSC(BeginPtr(col_ptr_), BeginPtr(indices_), - BeginPtr(data_), nindptr, ndata, - &handle)); - _WrapperEnd(); - SEXP ret = PROTECT(R_MakeExternalPtr(handle, R_NilValue, R_NilValue)); - R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE); - UNPROTECT(1); - return ret; - } - SEXP XGDMatrixSliceDMatrix_R(SEXP handle, SEXP idxset) { - _WrapperBegin(); - int len = length(idxset); - std::vector idxvec(len); - for (int i = 0; i < len; ++i) { - idxvec[i] = INTEGER(idxset)[i] - 1; - } - DMatrixHandle res; - CheckErr(XGDMatrixSliceDMatrix(R_ExternalPtrAddr(handle), - BeginPtr(idxvec), len, - &res)); - _WrapperEnd(); - SEXP ret = PROTECT(R_MakeExternalPtr(res, R_NilValue, R_NilValue)); - R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE); - UNPROTECT(1); - return ret; - } - void XGDMatrixSaveBinary_R(SEXP handle, SEXP fname, SEXP silent) { - _WrapperBegin(); - CheckErr(XGDMatrixSaveBinary(R_ExternalPtrAddr(handle), - CHAR(asChar(fname)), asInteger(silent))); - _WrapperEnd(); - } - void XGDMatrixSetInfo_R(SEXP handle, SEXP field, SEXP array) { - _WrapperBegin(); - int len = length(array); - const char *name = CHAR(asChar(field)); - if (!strcmp("group", name)) { - std::vector vec(len); - #pragma omp parallel for schedule(static) - for (int i = 0; i < len; ++i) { - vec[i] = static_cast(INTEGER(array)[i]); - } - CheckErr(XGDMatrixSetGroup(R_ExternalPtrAddr(handle), BeginPtr(vec), len)); - } else { - std::vector vec(len); - #pragma omp parallel for schedule(static) - for (int i = 0; i < len; ++i) { - vec[i] = REAL(array)[i]; - } - CheckErr(XGDMatrixSetFloatInfo(R_ExternalPtrAddr(handle), - CHAR(asChar(field)), - BeginPtr(vec), len)); - } - _WrapperEnd(); - } - SEXP XGDMatrixGetInfo_R(SEXP handle, SEXP field) { - _WrapperBegin(); - bst_ulong olen; - const float *res; - CheckErr(XGDMatrixGetFloatInfo(R_ExternalPtrAddr(handle), - CHAR(asChar(field)), - &olen, - &res)); - _WrapperEnd(); - SEXP ret = PROTECT(allocVector(REALSXP, olen)); - for (size_t i = 0; i < olen; ++i) { - REAL(ret)[i] = res[i]; - } - UNPROTECT(1); - return ret; - } - SEXP XGDMatrixNumRow_R(SEXP handle) { - bst_ulong nrow; - CheckErr(XGDMatrixNumRow(R_ExternalPtrAddr(handle), &nrow)); - return ScalarInteger(static_cast(nrow)); - } - // functions related to booster - void _BoosterFinalizer(SEXP ext) { - if (R_ExternalPtrAddr(ext) == NULL) return; - CheckErr(XGBoosterFree(R_ExternalPtrAddr(ext))); - R_ClearExternalPtr(ext); - } - SEXP XGBoosterCreate_R(SEXP dmats) { - _WrapperBegin(); - int len = length(dmats); - std::vector dvec; - for (int i = 0; i < len; ++i) { - dvec.push_back(R_ExternalPtrAddr(VECTOR_ELT(dmats, i))); - } - BoosterHandle handle; - CheckErr(XGBoosterCreate(BeginPtr(dvec), dvec.size(), &handle)); - _WrapperEnd(); - SEXP ret = PROTECT(R_MakeExternalPtr(handle, R_NilValue, R_NilValue)); - R_RegisterCFinalizerEx(ret, _BoosterFinalizer, TRUE); - UNPROTECT(1); - return ret; - } - void XGBoosterSetParam_R(SEXP handle, SEXP name, SEXP val) { - _WrapperBegin(); - CheckErr(XGBoosterSetParam(R_ExternalPtrAddr(handle), - CHAR(asChar(name)), - CHAR(asChar(val)))); - _WrapperEnd(); - } - void XGBoosterUpdateOneIter_R(SEXP handle, SEXP iter, SEXP dtrain) { - _WrapperBegin(); - CheckErr(XGBoosterUpdateOneIter(R_ExternalPtrAddr(handle), - asInteger(iter), - R_ExternalPtrAddr(dtrain))); - _WrapperEnd(); - } - void XGBoosterBoostOneIter_R(SEXP handle, SEXP dtrain, SEXP grad, SEXP hess) { - _WrapperBegin(); - utils::Check(length(grad) == length(hess), "gradient and hess must have same length"); - int len = length(grad); - std::vector tgrad(len), thess(len); - #pragma omp parallel for schedule(static) - for (int j = 0; j < len; ++j) { - tgrad[j] = REAL(grad)[j]; - thess[j] = REAL(hess)[j]; - } - CheckErr(XGBoosterBoostOneIter(R_ExternalPtrAddr(handle), - R_ExternalPtrAddr(dtrain), - BeginPtr(tgrad), BeginPtr(thess), - len)); - _WrapperEnd(); - } - SEXP XGBoosterEvalOneIter_R(SEXP handle, SEXP iter, SEXP dmats, SEXP evnames) { - _WrapperBegin(); - utils::Check(length(dmats) == length(evnames), "dmats and evnams must have same length"); - int len = length(dmats); - std::vector vec_dmats; - std::vector vec_names; - std::vector vec_sptr; - for (int i = 0; i < len; ++i) { - vec_dmats.push_back(R_ExternalPtrAddr(VECTOR_ELT(dmats, i))); - vec_names.push_back(std::string(CHAR(asChar(VECTOR_ELT(evnames, i))))); - } - for (int i = 0; i < len; ++i) { - vec_sptr.push_back(vec_names[i].c_str()); - } - const char *ret; - CheckErr(XGBoosterEvalOneIter(R_ExternalPtrAddr(handle), - asInteger(iter), - BeginPtr(vec_dmats), - BeginPtr(vec_sptr), - len, &ret)); - _WrapperEnd(); - return mkString(ret); - } - SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask, SEXP ntree_limit) { - _WrapperBegin(); - bst_ulong olen; - const float *res; - CheckErr(XGBoosterPredict(R_ExternalPtrAddr(handle), - R_ExternalPtrAddr(dmat), - asInteger(option_mask), - asInteger(ntree_limit), - &olen, &res)); - _WrapperEnd(); - SEXP ret = PROTECT(allocVector(REALSXP, olen)); - for (size_t i = 0; i < olen; ++i) { - REAL(ret)[i] = res[i]; - } - UNPROTECT(1); - return ret; - } - void XGBoosterLoadModel_R(SEXP handle, SEXP fname) { - _WrapperBegin(); - CheckErr(XGBoosterLoadModel(R_ExternalPtrAddr(handle), CHAR(asChar(fname)))); - _WrapperEnd(); - } - void XGBoosterSaveModel_R(SEXP handle, SEXP fname) { - _WrapperBegin(); - CheckErr(XGBoosterSaveModel(R_ExternalPtrAddr(handle), CHAR(asChar(fname)))); - _WrapperEnd(); - } - void XGBoosterLoadModelFromRaw_R(SEXP handle, SEXP raw) { - _WrapperBegin(); - XGBoosterLoadModelFromBuffer(R_ExternalPtrAddr(handle), - RAW(raw), - length(raw)); - _WrapperEnd(); - } - SEXP XGBoosterModelToRaw_R(SEXP handle) { - bst_ulong olen; - _WrapperBegin(); - const char *raw; - CheckErr(XGBoosterGetModelRaw(R_ExternalPtrAddr(handle), &olen, &raw)); - _WrapperEnd(); - SEXP ret = PROTECT(allocVector(RAWSXP, olen)); - if (olen != 0) { - memcpy(RAW(ret), raw, olen); - } - UNPROTECT(1); - return ret; - } - SEXP XGBoosterDumpModel_R(SEXP handle, SEXP fmap, SEXP with_stats) { - _WrapperBegin(); - bst_ulong olen; - const char **res; - CheckErr(XGBoosterDumpModel(R_ExternalPtrAddr(handle), - CHAR(asChar(fmap)), - asInteger(with_stats), - &olen, &res)); - _WrapperEnd(); - SEXP out = PROTECT(allocVector(STRSXP, olen)); - for (size_t i = 0; i < olen; ++i) { - stringstream stream; - stream << "booster[" << i <<"]\n" << res[i]; - SET_STRING_ELT(out, i, mkChar(stream.str().c_str())); - } - UNPROTECT(1); - return out; - } -} diff --git a/R-package/src/xgboost_R.h b/R-package/src/xgboost_R.h index 768b2ced7..66dd1f1cf 100644 --- a/R-package/src/xgboost_R.h +++ b/R-package/src/xgboost_R.h @@ -4,155 +4,171 @@ * \author Tianqi Chen * \brief R wrapper of xgboost */ -#ifndef XGBOOST_WRAPPER_R_H_ // NOLINT(*) -#define XGBOOST_WRAPPER_R_H_ // NOLINT(*) +#ifndef XGBOOST_R_H_ // NOLINT(*) +#define XGBOOST_R_H_ // NOLINT(*) extern "C" { #include #include #include } +#include -extern "C" { - /*! - * \brief check whether a handle is NULL - * \param handle - * \return whether it is null ptr +/*! + * \brief check whether a handle is NULL + * \param handle + * \return whether it is null ptr + */ +XGB_DLL SEXP XGCheckNullPtr_R(SEXP handle); + +/*! + * \brief load a data matrix + * \param fname name of the content + * \param silent whether print messages + * \return a loaded data matrix + */ +XGB_DLL SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent); + +/*! + * \brief create matrix content from dense matrix + * This assumes the matrix is stored in column major format + * \param data R Matrix object + * \param missing which value to represent missing value + * \return created dmatrix + */ +XGB_DLL SEXP XGDMatrixCreateFromMat_R(SEXP mat, + SEXP missing); +/*! + * \brief create a matrix content from CSC format + * \param indptr pointer to column headers + * \param indices row indices + * \param data content of the data + * \return created dmatrix + */ +XGB_DLL SEXP XGDMatrixCreateFromCSC_R(SEXP indptr, + SEXP indices, + SEXP data); + +/*! + * \brief create a new dmatrix from sliced content of existing matrix + * \param handle instance of data matrix to be sliced + * \param idxset index set + * \return a sliced new matrix + */ +XGB_DLL SEXP XGDMatrixSliceDMatrix_R(SEXP handle, SEXP idxset); + +/*! + * \brief load a data matrix into binary file + * \param handle a instance of data matrix + * \param fname file name + * \param silent print statistics when saving + */ +XGB_DLL void XGDMatrixSaveBinary_R(SEXP handle, SEXP fname, SEXP silent); + +/*! + * \brief set information to dmatrix + * \param handle a instance of data matrix + * \param field field name, can be label, weight + * \param array pointer to float vector + */ +XGB_DLL void XGDMatrixSetInfo_R(SEXP handle, SEXP field, SEXP array); + +/*! + * \brief get info vector from matrix + * \param handle a instance of data matrix + * \param field field name + * \return info vector + */ +XGB_DLL SEXP XGDMatrixGetInfo_R(SEXP handle, SEXP field); + +/*! + * \brief return number of rows + * \param handle a instance of data matrix + */ +XGB_DLL SEXP XGDMatrixNumRow_R(SEXP handle); + +/*! + * \brief create xgboost learner + * \param dmats a list of dmatrix handles that will be cached + */ +XGB_DLL SEXP XGBoosterCreate_R(SEXP dmats); + +/*! + * \brief set parameters + * \param handle handle + * \param name parameter name + * \param val value of parameter + */ +XGB_DLL void XGBoosterSetParam_R(SEXP handle, SEXP name, SEXP val); + +/*! + * \brief update the model in one round using dtrain + * \param handle handle + * \param iter current iteration rounds + * \param dtrain training data + */ +XGB_DLL void XGBoosterUpdateOneIter_R(SEXP ext, SEXP iter, SEXP dtrain); + +/*! + * \brief update the model, by directly specify gradient and second order gradient, + * this can be used to replace UpdateOneIter, to support customized loss function + * \param handle handle + * \param dtrain training data + * \param grad gradient statistics + * \param hess second order gradient statistics + */ +XGB_DLL void XGBoosterBoostOneIter_R(SEXP handle, SEXP dtrain, SEXP grad, SEXP hess); + +/*! + * \brief get evaluation statistics for xgboost + * \param handle handle + * \param iter current iteration rounds + * \param dmats list of handles to dmatrices + * \param evname name of evaluation + * \return the string containing evaluation stati + */ +XGB_DLL SEXP XGBoosterEvalOneIter_R(SEXP handle, SEXP iter, SEXP dmats, SEXP evnames); + +/*! + * \brief make prediction based on dmat + * \param handle handle + * \param dmat data matrix + * \param option_mask output_margin:1 predict_leaf:2 + * \param ntree_limit limit number of trees used in prediction + */ +XGB_DLL SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask, SEXP ntree_limit); +/*! + * \brief load model from existing file + * \param handle handle + * \param fname file name + */ +XGB_DLL void XGBoosterLoadModel_R(SEXP handle, SEXP fname); + +/*! + * \brief save model into existing file + * \param handle handle + * \param fname file name + */ +XGB_DLL void XGBoosterSaveModel_R(SEXP handle, SEXP fname); + +/*! + * \brief load model from raw array + * \param handle handle + */ +XGB_DLL void XGBoosterLoadModelFromRaw_R(SEXP handle, SEXP raw); + +/*! + * \brief save model into R's raw array + * \param handle handle + * \return raw array */ - SEXP XGCheckNullPtr_R(SEXP handle); - /*! - * \brief load a data matrix - * \param fname name of the content - * \param silent whether print messages - * \return a loaded data matrix - */ - SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent); - /*! - * \brief create matrix content from dense matrix - * This assumes the matrix is stored in column major format - * \param data R Matrix object - * \param missing which value to represent missing value - * \return created dmatrix - */ - SEXP XGDMatrixCreateFromMat_R(SEXP mat, - SEXP missing); - /*! - * \brief create a matrix content from CSC format - * \param indptr pointer to column headers - * \param indices row indices - * \param data content of the data - * \return created dmatrix - */ - SEXP XGDMatrixCreateFromCSC_R(SEXP indptr, - SEXP indices, - SEXP data); - /*! - * \brief create a new dmatrix from sliced content of existing matrix - * \param handle instance of data matrix to be sliced - * \param idxset index set - * \return a sliced new matrix - */ - SEXP XGDMatrixSliceDMatrix_R(SEXP handle, SEXP idxset); - /*! - * \brief load a data matrix into binary file - * \param handle a instance of data matrix - * \param fname file name - * \param silent print statistics when saving - */ - void XGDMatrixSaveBinary_R(SEXP handle, SEXP fname, SEXP silent); - /*! - * \brief set information to dmatrix - * \param handle a instance of data matrix - * \param field field name, can be label, weight - * \param array pointer to float vector - */ - void XGDMatrixSetInfo_R(SEXP handle, SEXP field, SEXP array); - /*! - * \brief get info vector from matrix - * \param handle a instance of data matrix - * \param field field name - * \return info vector - */ - SEXP XGDMatrixGetInfo_R(SEXP handle, SEXP field); - /*! - * \brief return number of rows - * \param handle a instance of data matrix - */ - SEXP XGDMatrixNumRow_R(SEXP handle); - /*! - * \brief create xgboost learner - * \param dmats a list of dmatrix handles that will be cached - */ - SEXP XGBoosterCreate_R(SEXP dmats); - /*! - * \brief set parameters - * \param handle handle - * \param name parameter name - * \param val value of parameter - */ - void XGBoosterSetParam_R(SEXP handle, SEXP name, SEXP val); - /*! - * \brief update the model in one round using dtrain - * \param handle handle - * \param iter current iteration rounds - * \param dtrain training data - */ - void XGBoosterUpdateOneIter_R(SEXP ext, SEXP iter, SEXP dtrain); - /*! - * \brief update the model, by directly specify gradient and second order gradient, - * this can be used to replace UpdateOneIter, to support customized loss function - * \param handle handle - * \param dtrain training data - * \param grad gradient statistics - * \param hess second order gradient statistics - */ - void XGBoosterBoostOneIter_R(SEXP handle, SEXP dtrain, SEXP grad, SEXP hess); - /*! - * \brief get evaluation statistics for xgboost - * \param handle handle - * \param iter current iteration rounds - * \param dmats list of handles to dmatrices - * \param evname name of evaluation - * \return the string containing evaluation stati - */ - SEXP XGBoosterEvalOneIter_R(SEXP handle, SEXP iter, SEXP dmats, SEXP evnames); - /*! - * \brief make prediction based on dmat - * \param handle handle - * \param dmat data matrix - * \param option_mask output_margin:1 predict_leaf:2 - * \param ntree_limit limit number of trees used in prediction - */ - SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask, SEXP ntree_limit); - /*! - * \brief load model from existing file - * \param handle handle - * \param fname file name - */ - void XGBoosterLoadModel_R(SEXP handle, SEXP fname); - /*! - * \brief save model into existing file - * \param handle handle - * \param fname file name - */ - void XGBoosterSaveModel_R(SEXP handle, SEXP fname); - /*! - * \brief load model from raw array - * \param handle handle - */ - void XGBoosterLoadModelFromRaw_R(SEXP handle, SEXP raw); - /*! - * \brief save model into R's raw array - * \param handle handle - * \return raw array - */ - SEXP XGBoosterModelToRaw_R(SEXP handle); - /*! - * \brief dump model into a string - * \param handle handle - * \param fmap name to fmap can be empty string - * \param with_stats whether dump statistics of splits - */ - SEXP XGBoosterDumpModel_R(SEXP handle, SEXP fmap, SEXP with_stats); -} +XGB_DLL SEXP XGBoosterModelToRaw_R(SEXP handle); + +/*! + * \brief dump model into a string + * \param handle handle + * \param fmap name to fmap can be empty string + * \param with_stats whether dump statistics of splits + */ +XGB_DLL SEXP XGBoosterDumpModel_R(SEXP handle, SEXP fmap, SEXP with_stats); #endif // XGBOOST_WRAPPER_R_H_ // NOLINT(*) diff --git a/R-package/src/xgboost_assert.c b/R-package/src/xgboost_assert.c deleted file mode 100644 index 072074243..000000000 --- a/R-package/src/xgboost_assert.c +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2014 by Contributors -#include -#include -#include - -// implements error handling -void XGBoostAssert_R(int exp, const char *fmt, ...) { - char buf[1024]; - if (exp == 0) { - va_list args; - va_start(args, fmt); - vsprintf(buf, fmt, args); - va_end(args); - error("AssertError:%s\n", buf); - } -} -void XGBoostCheck_R(int exp, const char *fmt, ...) { - char buf[1024]; - if (exp == 0) { - va_list args; - va_start(args, fmt); - vsprintf(buf, fmt, args); - va_end(args); - error("%s\n", buf); - } -} -int XGBoostSPrintf_R(char *buf, size_t size, const char *fmt, ...) { - int ret; - va_list args; - va_start(args, fmt); - ret = vsnprintf(buf, size, fmt, args); - va_end(args); - return ret; -} diff --git a/amalgamation/dmlc-minimum0.cc b/amalgamation/dmlc-minimum0.cc new file mode 100644 index 000000000..bce61129e --- /dev/null +++ b/amalgamation/dmlc-minimum0.cc @@ -0,0 +1,14 @@ +/*! + * Copyright 2015 by Contributors. + * \brief Mininum DMLC library Amalgamation, used for easy plugin of dmlc lib. + * Normally this is not needed. + */ +#include "../dmlc-core/src/io/line_split.cc" +#include "../dmlc-core/src/io/recordio_split.cc" +#include "../dmlc-core/src/io/input_split_base.cc" +#include "../dmlc-core/src/io/local_filesys.cc" +#include "../dmlc-core/src/data.cc" +#include "../dmlc-core/src/io.cc" +#include "../dmlc-core/src/recordio.cc" + + diff --git a/amalgamation/xgboost-all0.cc b/amalgamation/xgboost-all0.cc index c0f004e40..645695dec 100644 --- a/amalgamation/xgboost-all0.cc +++ b/amalgamation/xgboost-all0.cc @@ -30,8 +30,11 @@ #include "../src/data/data.cc" #include "../src/data/simple_csr_source.cc" #include "../src/data/simple_dmatrix.cc" + +#if DMLC_ENABLE_STD_THREAD #include "../src/data/sparse_page_source.cc" #include "../src/data/sparse_page_dmatrix.cc" +#endif // tress #include "../src/tree/tree_model.cc" diff --git a/dmlc-core b/dmlc-core index c0325077a..ea9b247b6 160000 --- a/dmlc-core +++ b/dmlc-core @@ -1 +1 @@ -Subproject commit c0325077a3ceda08fe04b2aa115e004a3520630a +Subproject commit ea9b247b6f9965c95aa66f42374d0867c46d9abd diff --git a/src/c_api/c_api.cc b/src/c_api/c_api.cc index de7e0b425..b734349c3 100644 --- a/src/c_api/c_api.cc +++ b/src/c_api/c_api.cc @@ -107,7 +107,7 @@ int XGDMatrixCreateFromCSR(const bst_ulong* indptr, for (bst_ulong i = 0; i < nelem; ++i) { mat.row_data_[i] = RowBatch::Entry(indices[i], data[i]); mat.info.num_col = std::max(mat.info.num_col, - static_cast(indices[i] + 1)); + static_cast(indices[i] + 1)); } mat.info.num_row = nindptr - 1; mat.info.num_nonzero = static_cast(nelem); diff --git a/src/common/math.h b/src/common/math.h index 848900407..479cc17d8 100644 --- a/src/common/math.h +++ b/src/common/math.h @@ -103,7 +103,7 @@ inline static bool CmpSecond(const std::pair &a, return a.second > b.second; } -#ifdef XGBOOST_STRICT_R_MODE_ +#if XGBOOST_STRICT_R_MODE // check nan bool CheckNAN(double v); double LogGamma(double v); diff --git a/src/common/thread_local.h b/src/common/thread_local.h index 35301b66e..6ea8eb5ab 100644 --- a/src/common/thread_local.h +++ b/src/common/thread_local.h @@ -6,7 +6,10 @@ #ifndef XGBOOST_COMMON_THREAD_LOCAL_H_ #define XGBOOST_COMMON_THREAD_LOCAL_H_ +#if DMLC_ENABLE_STD_THREAD #include +#endif + #include #include @@ -63,12 +66,19 @@ class ThreadLocalStore { * \param str the string pointer */ void RegisterDelete(T *str) { +#if DMLC_ENABLE_STD_THREAD std::unique_lock lock(mutex_); data_.push_back(str); lock.unlock(); +#else + data_.push_back(str); +#endif } + +#if DMLC_ENABLE_STD_THREAD /*! \brief internal mutex */ std::mutex mutex_; +#endif /*!\brief internal data */ std::vector data_; }; diff --git a/src/data/data.cc b/src/data/data.cc index 024b68c0d..d73c1e8bb 100644 --- a/src/data/data.cc +++ b/src/data/data.cc @@ -8,9 +8,12 @@ #include "./sparse_batch_page.h" #include "./simple_dmatrix.h" #include "./simple_csr_source.h" +#include "../common/io.h" + +#if DMLC_ENABLE_STD_THREAD #include "./sparse_page_source.h" #include "./sparse_page_dmatrix.h" -#include "../common/io.h" +#endif namespace xgboost { // implementation of inline functions @@ -194,11 +197,16 @@ DMatrix* DMatrix::Create(dmlc::Parser* parser, source->CopyFrom(parser); return DMatrix::Create(std::move(source), cache_prefix); } else { +#if DMLC_ENABLE_STD_THREAD if (!data::SparsePageSource::CacheExist(cache_prefix)) { data::SparsePageSource::Create(parser, cache_prefix); } std::unique_ptr source(new data::SparsePageSource(cache_prefix)); return DMatrix::Create(std::move(source), cache_prefix); +#else + LOG(FATAL) << "External memory is not enabled in mingw"; + return nullptr; +#endif } } @@ -214,7 +222,12 @@ DMatrix* DMatrix::Create(std::unique_ptr&& source, if (cache_prefix.length() == 0) { return new data::SimpleDMatrix(std::move(source)); } else { +#if DMLC_ENABLE_STD_THREAD return new data::SparsePageDMatrix(std::move(source), cache_prefix); +#else + LOG(FATAL) << "External memory is not enabled in mingw"; + return nullptr; +#endif } } } // namespace xgboost diff --git a/src/data/simple_csr_source.cc b/src/data/simple_csr_source.cc index 0654853da..db23bb9d7 100644 --- a/src/data/simple_csr_source.cc +++ b/src/data/simple_csr_source.cc @@ -51,7 +51,7 @@ void SimpleCSRSource::CopyFrom(dmlc::Parser* parser) { bst_float fvalue = batch.value == nullptr ? 1.0f : batch.value[i]; row_data_.push_back(SparseBatch::Entry(index, fvalue)); this->info.num_col = std::max(this->info.num_col, - static_cast(index + 1)); + static_cast(index + 1)); } size_t top = row_ptr_.size(); row_ptr_.resize(top + batch.size); diff --git a/src/data/sparse_page_dmatrix.h b/src/data/sparse_page_dmatrix.h index 91e1dcef1..12e9ae165 100644 --- a/src/data/sparse_page_dmatrix.h +++ b/src/data/sparse_page_dmatrix.h @@ -4,15 +4,15 @@ * \brief In-memory version of DMatrix. * \author Tianqi Chen */ -#ifndef XGBOOST_SPARSE_PAGE_DMATRIX_H_ -#define XGBOOST_SPARSE_PAGE_DMATRIX_H_ +#ifndef XGBOOST_DATA_SPARSE_PAGE_DMATRIX_H_ +#define XGBOOST_DATA_SPARSE_PAGE_DMATRIX_H_ #include #include #include #include #include -#include +#include #include "./sparse_batch_page.h" namespace xgboost { @@ -125,4 +125,4 @@ class SparsePageDMatrix : public DMatrix { }; } // namespace data } // namespace xgboost -#endif // XGBOOST_SPARSE_PAGE_DMATRIX_H_ +#endif // XGBOOST_DATA_SPARSE_PAGE_DMATRIX_H_