From 84515cd2a836582be76e0200e0e6828c0e1d3978 Mon Sep 17 00:00:00 2001 From: Tianqi Chen Date: Sat, 25 Apr 2015 15:30:42 -0700 Subject: [PATCH] fix python windows installation problem, enable mingw compile, but seems mingw dll was not fast in loading --- Makefile | 21 +++++++++++++++++---- src/tree/updater_basemaker-inl.hpp | 8 ++++++-- src/tree/updater_histmaker-inl.hpp | 2 +- src/tree/updater_skmaker-inl.hpp | 2 +- wrapper/setup.py | 18 +++++++++++------- wrapper/xgboost.py | 30 ++++++++++++++++++++---------- wrapper/xgboost_wrapper.h | 2 +- 7 files changed, 57 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index a265abb9ca39..e426b797d908 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,11 @@ export MPICXX = mpicxx export LDFLAGS= -pthread -lm export CFLAGS = -Wall -O3 -msse2 -Wno-unknown-pragmas -fPIC +ifeq ($(OS), Windows_NT) + export CXX = g++ -m64 + export CC = gcc -m64 +endif + ifeq ($(no_omp),1) CFLAGS += -DDISABLE_OPENMP else @@ -33,12 +38,20 @@ else LIBDMLC=dmlc_simple.o endif +ifeq ($(OS), Windows_NT) + LIBRABIT = subtree/rabit/lib/librabit_empty.a + SLIB = wrapper/xgboost_wrapper.dll +else + LIBRABIT = subtree/rabit/lib/librabit.a + SLIB = wrapper/libxgboostwrapper.so +endif + # specify tensor path BIN = xgboost MOCKBIN = xgboost.mock OBJ = updater.o gbm.o io.o main.o dmlc_simple.o MPIBIN = -SLIB = wrapper/libxgboostwrapper.so +TARGET = $(BIN) $(OBJ) $(SLIB) .PHONY: clean all mpi python Rpack @@ -52,8 +65,8 @@ dmlc_simple.o: src/io/dmlc_simple.cpp src/utils/*.h gbm.o: src/gbm/gbm.cpp src/gbm/*.hpp src/gbm/*.h io.o: src/io/io.cpp src/io/*.hpp src/utils/*.h src/learner/dmatrix.h src/*.h main.o: src/xgboost_main.cpp src/utils/*.h src/*.h src/learner/*.hpp src/learner/*.h -xgboost: updater.o gbm.o io.o main.o subtree/rabit/lib/librabit.a $(LIBDMLC) -wrapper/libxgboostwrapper.so: wrapper/xgboost_wrapper.cpp src/utils/*.h src/*.h src/learner/*.hpp src/learner/*.h updater.o gbm.o io.o subtree/rabit/lib/librabit.a $(LIBDMLC) +xgboost: updater.o gbm.o io.o main.o $(LIBRABIT) $(LIBDMLC) +wrapper/xgboost_wrapper.dll wrapper/libxgboostwrapper.so: wrapper/xgboost_wrapper.cpp src/utils/*.h src/*.h src/learner/*.hpp src/learner/*.h updater.o gbm.o io.o $(LIBRABIT) $(LIBDMLC) # dependency on rabit subtree/rabit/lib/librabit.a: subtree/rabit/src/engine.cc @@ -72,7 +85,7 @@ $(MOCKBIN) : $(CXX) $(CFLAGS) -o $@ $(filter %.cpp %.o %.c %.cc %.a, $^) $(LDFLAGS) $(SLIB) : - $(CXX) $(CFLAGS) -fPIC -shared -o $@ $(filter %.cpp %.o %.c %.a %.cc, $^) $(LDFLAGS) + $(CXX) $(CFLAGS) -fPIC -shared -o $@ $(filter %.cpp %.o %.c %.a %.cc, $^) $(LDFLAGS) $(DLLFLAGS) $(OBJ) : $(CXX) -c $(CFLAGS) -o $@ $(firstword $(filter %.cpp %.c %.cc, $^) ) diff --git a/src/tree/updater_basemaker-inl.hpp b/src/tree/updater_basemaker-inl.hpp index 1f1d33c77d58..f144ae19991d 100644 --- a/src/tree/updater_basemaker-inl.hpp +++ b/src/tree/updater_basemaker-inl.hpp @@ -343,7 +343,9 @@ class BaseMaker: public IUpdater { // push to sketch sketch->temp.data[sketch->temp.size] = utils::WXQuantileSketch:: - Entry(rmin, rmax, wmin, last_fvalue); + Entry(static_cast(rmin), + static_cast(rmax), + static_cast(wmin), last_fvalue); utils::Assert(sketch->temp.size < max_size, "invalid maximum size max_size=%u, stemp.size=%lu\n", max_size, sketch->temp.size); @@ -377,7 +379,9 @@ class BaseMaker: public IUpdater { // push to sketch sketch->temp.data[sketch->temp.size] = utils::WXQuantileSketch:: - Entry(rmin, rmax, wmin, last_fvalue); + Entry(static_cast(rmin), + static_cast(rmax), + static_cast(wmin), last_fvalue); ++sketch->temp.size; } sketch->PushTemp(); diff --git a/src/tree/updater_histmaker-inl.hpp b/src/tree/updater_histmaker-inl.hpp index f8c194c62b24..d6279592f91c 100644 --- a/src/tree/updater_histmaker-inl.hpp +++ b/src/tree/updater_histmaker-inl.hpp @@ -525,7 +525,7 @@ class CQHistMaker: public HistMaker { if (c[0].fvalue == c[c.length-1].fvalue) { for (size_t i = 0; i < this->qexpand.size(); ++i) { const int nid = this->qexpand[i]; - sbuilder[nid].sketch->Push(c[0].fvalue, sbuilder[nid].sum_total); + sbuilder[nid].sketch->Push(c[0].fvalue, static_cast(sbuilder[nid].sum_total)); } return; } diff --git a/src/tree/updater_skmaker-inl.hpp b/src/tree/updater_skmaker-inl.hpp index 60b83c2a4016..6bc2fc39a1bc 100644 --- a/src/tree/updater_skmaker-inl.hpp +++ b/src/tree/updater_skmaker-inl.hpp @@ -217,7 +217,7 @@ class SketchMaker: public BaseMaker { for (size_t i = 0; i < this->qexpand.size(); ++i) { const int nid = this->qexpand[i]; for (int k = 0; k < 3; ++k) { - sbuilder[3 * nid + k].sketch->Push(c[0].fvalue, sbuilder[3 * nid + k].sum_total); + sbuilder[3 * nid + k].sketch->Push(c[0].fvalue, static_cast(sbuilder[3 * nid + k].sum_total)); } } return; diff --git a/wrapper/setup.py b/wrapper/setup.py index 49b1a787228b..6c38cf69040d 100644 --- a/wrapper/setup.py +++ b/wrapper/setup.py @@ -7,22 +7,26 @@ class XGBoostLibraryNotFound(Exception): pass -cur_dir = os.path.dirname(os.path.abspath(__file__)) +curr_dir = os.path.dirname(os.path.abspath(__file__)) +dll_path = [curr_dir] if os.name == 'nt': - dll_path = os.path.join(cur_dir, - '../windows/x64/Release/xgboost_wrapper.dll') + dll_path.append(os.path.join(curr_dir, '../windows/x64/Release/')) + +if os.name == 'nt': + dll_path = [os.path.join(p, 'xgboost_wrapper.dll') for p in dll_path] else: - dll_path = os.path.join(cur_dir, 'libxgboostwrapper.so') + dll_path = [os.path.join(p, 'libxgboostwrapper.so') for p in dll_path] -if not os.path.exists(dll_path): +lib_path = [p for p in dll_path if os.path.exists(p) and os.path.isfile(p)] + +if len(lib_path) == 0: raise XGBoostLibraryNotFound("XGBoost library not found. Did you run " "../make?") - setup(name="xgboost", version="0.32", description="Python wrappers for XGBoost: eXtreme Gradient Boosting", zip_safe=False, py_modules=['xgboost'], - data_files=[dll_path], + data_files=[('.', [lib_path[0]])], url="https://github.com/dmlc/xgboost") diff --git a/wrapper/xgboost.py b/wrapper/xgboost.py index d6898d74669f..58beb43c9ca4 100644 --- a/wrapper/xgboost.py +++ b/wrapper/xgboost.py @@ -26,6 +26,8 @@ except ImportError: SKLEARN_INSTALLED = False +class XGBoostLibraryNotFound(Exception): + pass __all__ = ['DMatrix', 'CVPack', 'Booster', 'aggcv', 'cv', 'mknfold', 'train'] @@ -36,14 +38,18 @@ def load_xglib(): - dll_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__))) + curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__))) + dll_path = [curr_path] + dll_path.append(os.path.join(curr_path, '../windows/x64/Release/')) + if os.name == 'nt': - dll_path = os.path.join(dll_path, '../windows/x64/Release/xgboost_wrapper.dll') + dll_path = [os.path.join(p, 'xgboost_wrapper.dll') for p in dll_path] else: - dll_path = os.path.join(dll_path, 'libxgboostwrapper.so') - - # load the xgboost wrapper library - lib = ctypes.cdll.LoadLibrary(dll_path) + dll_path = [os.path.join(p, 'libxgboostwrapper.so') for p in dll_path] + lib_path = [p for p in dll_path if os.path.exists(p) and os.path.isfile(p)] + if len(dll_path) == 0: + raise XGBoostLibraryNotFound('cannot find find the files in the candicate path ' + str(dll_path)) + lib = ctypes.cdll.LoadLibrary(lib_path[0]) # DMatrix functions lib.XGDMatrixCreateFromFile.restype = ctypes.c_void_p @@ -762,12 +768,16 @@ def cv(params, dtrain, num_boost_round=10, nfold=3, metrics=(), return results +# used for compatiblity without sklearn XGBModelBase = object +XGBClassifier = object +XGBRegressor = object if SKLEARN_INSTALLED: XGBModelBase = BaseEstimator + XGBRegressor = RegressorMixin + XGBClassifier = ClassifierMixin - -class XGBModel(BaseEstimator): +class XGBModel(XGBModelBase): """ Implementation of the Scikit-Learn API for XGBoost. @@ -844,7 +854,7 @@ def predict(self, X): return self._Booster.predict(testDmatrix) -class XGBClassifier(XGBModel, ClassifierMixin): +class XGBClassifier(XGBModel, XGBClassifier): def __init__(self, max_depth=3, learning_rate=0.1, n_estimators=100, silent=True, objective="binary:logistic", nthread=-1, gamma=0, min_child_weight=1, max_delta_step=0, subsample=1, colsample_bytree=1, base_score=0.5, seed=0): @@ -895,5 +905,5 @@ def predict_proba(self, X): return np.vstack((classzero_probs, classone_probs)).transpose() -class XGBRegressor(XGBModel, RegressorMixin): +class XGBRegressor(XGBModel, XGBRegressor): pass diff --git a/wrapper/xgboost_wrapper.h b/wrapper/xgboost_wrapper.h index d51eb284f941..f1d2cc92a6d1 100644 --- a/wrapper/xgboost_wrapper.h +++ b/wrapper/xgboost_wrapper.h @@ -6,7 +6,7 @@ * \brief a C style wrapper of xgboost * can be used to create wrapper of other languages */ -#ifdef _MSC_VER +#if defined(_MSC_VER) || defined(_WIN32) #define XGB_DLL __declspec(dllexport) #else #define XGB_DLL