diff --git a/jvm-packages/xgboost4j/src/native/xgboost4j.cpp b/jvm-packages/xgboost4j/src/native/xgboost4j.cpp index 8b08a869f..de0383143 100644 --- a/jvm-packages/xgboost4j/src/native/xgboost4j.cpp +++ b/jvm-packages/xgboost4j/src/native/xgboost4j.cpp @@ -556,11 +556,12 @@ JNIEXPORT jint JNICALL Java_ml_dmlc_xgboost4j_java_XGBoostJNI_XGBoosterPredict bst_ulong len; float *result; int ret = XGBoosterPredict(handle, dmat, joption_mask, (unsigned int) jntree_limit, &len, (const float **) &result); - - jsize jlen = (jsize) len; - jfloatArray jarray = jenv->NewFloatArray(jlen); - jenv->SetFloatArrayRegion(jarray, 0, jlen, (jfloat *) result); - jenv->SetObjectArrayElement(jout, 0, jarray); + if (len) { + jsize jlen = (jsize) len; + jfloatArray jarray = jenv->NewFloatArray(jlen); + jenv->SetFloatArrayRegion(jarray, 0, jlen, (jfloat *) result); + jenv->SetObjectArrayElement(jout, 0, jarray); + } return ret; } diff --git a/src/c_api/c_api.cc b/src/c_api/c_api.cc index 569fff016..d5d1747db 100644 --- a/src/c_api/c_api.cc +++ b/src/c_api/c_api.cc @@ -650,6 +650,7 @@ XGB_DLL int XGDMatrixSliceDMatrix(DMatrixHandle handle, std::unique_ptr source(new data::SimpleCSRSource()); API_BEGIN(); + CHECK_HANDLE(); data::SimpleCSRSource src; src.CopyFrom(static_cast*>(handle)->get()); data::SimpleCSRSource& ret = *source; @@ -694,6 +695,7 @@ XGB_DLL int XGDMatrixSliceDMatrix(DMatrixHandle handle, XGB_DLL int XGDMatrixFree(DMatrixHandle handle) { API_BEGIN(); + CHECK_HANDLE(); delete static_cast*>(handle); API_END(); } @@ -702,6 +704,7 @@ XGB_DLL int XGDMatrixSaveBinary(DMatrixHandle handle, const char* fname, int silent) { API_BEGIN(); + CHECK_HANDLE(); static_cast*>(handle)->get()->SaveToLocalFile(fname); API_END(); } @@ -711,6 +714,7 @@ XGB_DLL int XGDMatrixSetFloatInfo(DMatrixHandle handle, const bst_float* info, xgboost::bst_ulong len) { API_BEGIN(); + CHECK_HANDLE(); static_cast*>(handle) ->get()->Info().SetInfo(field, info, kFloat32, len); API_END(); @@ -721,6 +725,7 @@ XGB_DLL int XGDMatrixSetUIntInfo(DMatrixHandle handle, const unsigned* info, xgboost::bst_ulong len) { API_BEGIN(); + CHECK_HANDLE(); static_cast*>(handle) ->get()->Info().SetInfo(field, info, kUInt32, len); API_END(); @@ -730,6 +735,7 @@ XGB_DLL int XGDMatrixSetGroup(DMatrixHandle handle, const unsigned* group, xgboost::bst_ulong len) { API_BEGIN(); + CHECK_HANDLE(); auto *pmat = static_cast*>(handle); MetaInfo& info = pmat->get()->Info(); info.group_ptr_.resize(len + 1); @@ -745,6 +751,7 @@ XGB_DLL int XGDMatrixGetFloatInfo(const DMatrixHandle handle, xgboost::bst_ulong* out_len, const bst_float** out_dptr) { API_BEGIN(); + CHECK_HANDLE(); const MetaInfo& info = static_cast*>(handle)->get()->Info(); const std::vector* vec = nullptr; if (!std::strcmp(field, "label")) { @@ -766,6 +773,7 @@ XGB_DLL int XGDMatrixGetUIntInfo(const DMatrixHandle handle, xgboost::bst_ulong *out_len, const unsigned **out_dptr) { API_BEGIN(); + CHECK_HANDLE(); const MetaInfo& info = static_cast*>(handle)->get()->Info(); const std::vector* vec = nullptr; if (!std::strcmp(field, "root_index")) { @@ -781,6 +789,7 @@ XGB_DLL int XGDMatrixGetUIntInfo(const DMatrixHandle handle, XGB_DLL int XGDMatrixNumRow(const DMatrixHandle handle, xgboost::bst_ulong *out) { API_BEGIN(); + CHECK_HANDLE(); *out = static_cast( static_cast*>(handle)->get()->Info().num_row_); API_END(); @@ -789,6 +798,7 @@ XGB_DLL int XGDMatrixNumRow(const DMatrixHandle handle, XGB_DLL int XGDMatrixNumCol(const DMatrixHandle handle, xgboost::bst_ulong *out) { API_BEGIN(); + CHECK_HANDLE(); *out = static_cast( static_cast*>(handle)->get()->Info().num_col_); API_END(); @@ -809,6 +819,7 @@ XGB_DLL int XGBoosterCreate(const DMatrixHandle dmats[], XGB_DLL int XGBoosterFree(BoosterHandle handle) { API_BEGIN(); + CHECK_HANDLE(); delete static_cast(handle); API_END(); } @@ -817,6 +828,7 @@ XGB_DLL int XGBoosterSetParam(BoosterHandle handle, const char *name, const char *value) { API_BEGIN(); + CHECK_HANDLE(); static_cast(handle)->SetParam(name, value); API_END(); } @@ -825,6 +837,7 @@ XGB_DLL int XGBoosterUpdateOneIter(BoosterHandle handle, int iter, DMatrixHandle dtrain) { API_BEGIN(); + CHECK_HANDLE(); auto* bst = static_cast(handle); auto *dtr = static_cast*>(dtrain); @@ -841,6 +854,7 @@ XGB_DLL int XGBoosterBoostOneIter(BoosterHandle handle, xgboost::bst_ulong len) { HostDeviceVector& tmp_gpair = XGBAPIThreadLocalStore::Get()->tmp_gpair; API_BEGIN(); + CHECK_HANDLE(); auto* bst = static_cast(handle); auto* dtr = static_cast*>(dtrain); @@ -863,6 +877,7 @@ XGB_DLL int XGBoosterEvalOneIter(BoosterHandle handle, const char** out_str) { std::string& eval_str = XGBAPIThreadLocalStore::Get()->ret_str; API_BEGIN(); + CHECK_HANDLE(); auto* bst = static_cast(handle); std::vector data_sets; std::vector data_names; @@ -887,6 +902,7 @@ XGB_DLL int XGBoosterPredict(BoosterHandle handle, HostDeviceVector& preds = XGBAPIThreadLocalStore::Get()->ret_vec_float; API_BEGIN(); + CHECK_HANDLE(); auto *bst = static_cast(handle); bst->LazyInit(); bst->learner()->Predict( @@ -904,6 +920,7 @@ XGB_DLL int XGBoosterPredict(BoosterHandle handle, XGB_DLL int XGBoosterLoadModel(BoosterHandle handle, const char* fname) { API_BEGIN(); + CHECK_HANDLE(); std::unique_ptr fi(dmlc::Stream::Create(fname, "r")); static_cast(handle)->LoadModel(fi.get()); API_END(); @@ -911,6 +928,7 @@ XGB_DLL int XGBoosterLoadModel(BoosterHandle handle, const char* fname) { XGB_DLL int XGBoosterSaveModel(BoosterHandle handle, const char* fname) { API_BEGIN(); + CHECK_HANDLE(); std::unique_ptr fo(dmlc::Stream::Create(fname, "w")); auto *bst = static_cast(handle); bst->LazyInit(); @@ -922,6 +940,7 @@ XGB_DLL int XGBoosterLoadModelFromBuffer(BoosterHandle handle, const void* buf, xgboost::bst_ulong len) { API_BEGIN(); + CHECK_HANDLE(); common::MemoryFixSizeBuffer fs((void*)buf, len); // NOLINT(*) static_cast(handle)->LoadModel(&fs); API_END(); @@ -934,6 +953,7 @@ XGB_DLL int XGBoosterGetModelRaw(BoosterHandle handle, raw_str.resize(0); API_BEGIN(); + CHECK_HANDLE(); common::MemoryBufferStream fo(&raw_str); auto *bst = static_cast(handle); bst->LazyInit(); @@ -976,6 +996,7 @@ XGB_DLL int XGBoosterDumpModelEx(BoosterHandle handle, xgboost::bst_ulong* len, const char*** out_models) { API_BEGIN(); + CHECK_HANDLE(); FeatureMap featmap; if (strlen(fmap) != 0) { std::unique_ptr fs( @@ -1006,6 +1027,7 @@ XGB_DLL int XGBoosterDumpModelExWithFeatures(BoosterHandle handle, xgboost::bst_ulong* len, const char*** out_models) { API_BEGIN(); + CHECK_HANDLE(); FeatureMap featmap; for (int i = 0; i < fnum; ++i) { featmap.PushBack(i, fname[i], ftype[i]); @@ -1021,6 +1043,7 @@ XGB_DLL int XGBoosterGetAttr(BoosterHandle handle, auto* bst = static_cast(handle); std::string& ret_str = XGBAPIThreadLocalStore::Get()->ret_str; API_BEGIN(); + CHECK_HANDLE(); if (bst->learner()->GetAttr(key, &ret_str)) { *out = ret_str.c_str(); *success = 1; @@ -1036,6 +1059,7 @@ XGB_DLL int XGBoosterSetAttr(BoosterHandle handle, const char* value) { auto* bst = static_cast(handle); API_BEGIN(); + CHECK_HANDLE(); if (value == nullptr) { bst->learner()->DelAttr(key); } else { @@ -1051,6 +1075,7 @@ XGB_DLL int XGBoosterGetAttrNames(BoosterHandle handle, std::vector& charp_vecs = XGBAPIThreadLocalStore::Get()->ret_vec_charp; auto *bst = static_cast(handle); API_BEGIN(); + CHECK_HANDLE(); str_vecs = bst->learner()->GetAttrNames(); charp_vecs.resize(str_vecs.size()); for (size_t i = 0; i < str_vecs.size(); ++i) { @@ -1064,6 +1089,7 @@ XGB_DLL int XGBoosterGetAttrNames(BoosterHandle handle, XGB_DLL int XGBoosterLoadRabitCheckpoint(BoosterHandle handle, int* version) { API_BEGIN(); + CHECK_HANDLE(); auto* bst = static_cast(handle); *version = rabit::LoadCheckPoint(bst->learner()); if (*version != 0) { @@ -1074,6 +1100,7 @@ XGB_DLL int XGBoosterLoadRabitCheckpoint(BoosterHandle handle, XGB_DLL int XGBoosterSaveRabitCheckpoint(BoosterHandle handle) { API_BEGIN(); + CHECK_HANDLE(); auto* bst = static_cast(handle); if (bst->learner()->AllowLazyCheckPoint()) { rabit::LazyCheckPoint(bst->learner()); diff --git a/src/c_api/c_api_error.h b/src/c_api/c_api_error.h index 3c0899228..648a4b961 100644 --- a/src/c_api/c_api_error.h +++ b/src/c_api/c_api_error.h @@ -15,6 +15,8 @@ /*! \brief every function starts with API_BEGIN(); and finishes with API_END() or API_END_HANDLE_ERROR */ #define API_END() } catch(dmlc::Error &_except_) { return XGBAPIHandleException(_except_); } return 0; // NOLINT(*) +#define CHECK_HANDLE() if (handle == nullptr) \ + LOG(FATAL) << "DMatrix/Booster has not been intialized or has already been disposed."; /*! * \brief every function starts with API_BEGIN(); * and finishes with API_END() or API_END_HANDLE_ERROR