Expose build info (#7399)

This commit is contained in:
Jiaming Yuan 2021-11-12 18:22:46 +08:00 committed by GitHub
parent 937fa282b5
commit 46726ec176
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 158 additions and 11 deletions

View File

@ -42,6 +42,15 @@ typedef void *BoosterHandle; // NOLINT(*)
*/
XGB_DLL void XGBoostVersion(int* major, int* minor, int* patch);
/*!
* \brief Get compile information of shared library.
*
* \param out string encoded JSON object containing build flags and dependency version.
*
* \return 0 for success, -1 for failure
*/
XGB_DLL int XGBBuildInfo(char const **out);
/*!
* \brief get string message of the last error
*

View File

@ -6,7 +6,7 @@ Contributors: https://github.com/dmlc/xgboost/blob/master/CONTRIBUTORS.md
import os
from .core import DMatrix, DeviceQuantileDMatrix, Booster, DataIter
from .core import DMatrix, DeviceQuantileDMatrix, Booster, DataIter, build_info
from .training import train, cv
from . import rabit # noqa
from . import tracker # noqa
@ -21,14 +21,34 @@ try:
except ImportError:
pass
VERSION_FILE = os.path.join(os.path.dirname(__file__), 'VERSION')
VERSION_FILE = os.path.join(os.path.dirname(__file__), "VERSION")
with open(VERSION_FILE, encoding="ascii") as f:
__version__ = f.read().strip()
__all__ = ['DMatrix', 'DeviceQuantileDMatrix', 'Booster', 'DataIter',
'train', 'cv',
'RabitTracker',
'XGBModel', 'XGBClassifier', 'XGBRegressor', 'XGBRanker',
'XGBRFClassifier', 'XGBRFRegressor',
'plot_importance', 'plot_tree', 'to_graphviz', 'dask',
'set_config', 'get_config', 'config_context']
__all__ = [
# core
"DMatrix",
"DeviceQuantileDMatrix",
"Booster",
"DataIter",
"train",
"cv",
# utilities
"RabitTracker",
"build_info",
"plot_importance",
"plot_tree",
"to_graphviz",
"set_config",
"get_config",
"config_context",
# sklearn
"XGBModel",
"XGBClassifier",
"XGBRegressor",
"XGBRanker",
"XGBRFClassifier",
"XGBRFRegressor",
# dask
"dask",
]

View File

@ -192,6 +192,22 @@ def _check_call(ret: int) -> None:
raise XGBoostError(py_str(_LIB.XGBGetLastError()))
def build_info() -> dict:
"""Build information of XGBoost. The returned value format is not stable. Also, please
note that build time dependency is not the same as runtime dependency. For instance,
it's possible to build XGBoost with older CUDA version but run it with the lastest
one.
.. versionadded:: 1.6.0
"""
j_info = ctypes.c_char_p()
_check_call(_LIB.XGBBuildInfo(ctypes.byref(j_info)))
assert j_info.value is not None
res = json.loads(j_info.value.decode()) # pylint: disable=no-member
return res
def _numpy2ctypes_type(dtype):
_NUMPY_TO_CTYPES_MAPPING = {
np.float32: ctypes.c_float,

View File

@ -42,6 +42,68 @@ XGB_DLL void XGBoostVersion(int* major, int* minor, int* patch) {
}
}
using GlobalConfigAPIThreadLocalStore = dmlc::ThreadLocalStore<XGBAPIThreadLocalEntry>;
#if !defined(XGBOOST_USE_CUDA)
namespace xgboost {
void XGBBuildInfoDevice(Json *p_info) {
auto &info = *p_info;
info["USE_CUDA"] = Boolean{false};
info["USE_NCCL"] = Boolean{false};
info["USE_RMM"] = Boolean{false};
}
} // namespace xgboost
#endif
XGB_DLL int XGBBuildInfo(char const **out) {
API_BEGIN();
CHECK(out) << "Invalid input pointer";
Json info{Object{}};
#if defined(XGBOOST_BUILTIN_PREFETCH_PRESENT)
info["BUILTIN_PREFETCH_PRESENT"] = Boolean{true};
#else
info["BUILTIN_PREFETCH_PRESENT"] = Boolean{false};
#endif
#if defined(XGBOOST_MM_PREFETCH_PRESENT)
info["MM_PREFETCH_PRESENT"] = Boolean{true};
#else
info["MM_PREFETCH_PRESENT"] = Boolean{false};
#endif
#if defined(_OPENMP)
info["USE_OPENMP"] = Boolean{true};
#else
info["USE_OPENMP"] = Boolean{false};
#endif
#if defined(__GNUC__) && !defined(__clang__)
info["GCC_VERSION"] = std::vector<Json>{Json{Integer{__GNUC__}}, Json{Integer{__GNUC_MINOR__}},
Json{Integer{__GNUC_PATCHLEVEL__}}};
#endif
#if defined(__clang__)
info["CLANG_VERSION"] =
std::vector<Json>{Json{Integer{__clang_major__}}, Json{Integer{__clang_minor__}},
Json{Integer{__clang_patchlevel__}}};
#endif
#if !defined(NDEBUG)
info["DEBUG"] = Boolean{true};
#else
info["DEBUG"] = Boolean{false};
#endif
XGBBuildInfoDevice(&info);
auto &out_str = GlobalConfigAPIThreadLocalStore::Get()->ret_str;
Json::Dump(info, &out_str);
*out = out_str.c_str();
API_END();
}
XGB_DLL int XGBRegisterLogCallback(void (*callback)(const char*)) {
API_BEGIN_UNGUARD();
LogCallbackRegistry* registry = LogCallbackRegistryStore::Get();
@ -95,8 +157,6 @@ XGB_DLL int XGBSetGlobalConfig(const char* json_str) {
API_END();
}
using GlobalConfigAPIThreadLocalStore = dmlc::ThreadLocalStore<XGBAPIThreadLocalEntry>;
XGB_DLL int XGBGetGlobalConfig(const char** json_str) {
API_BEGIN();
auto const& global_config = *GlobalConfigThreadLocalStore::Get();

View File

@ -7,6 +7,37 @@
#include "../data/device_adapter.cuh"
namespace xgboost {
void XGBBuildInfoDevice(Json *p_info) {
auto &info = *p_info;
info["USE_CUDA"] = true;
std::vector<Json> v{Json{Integer{THRUST_MAJOR_VERSION}}, Json{Integer{THRUST_MINOR_VERSION}},
Json{Integer{THRUST_SUBMINOR_VERSION}}};
info["THRUST_VERSION"] = v;
v = {Json{Integer{dh::CUDAVersion().first}}, Json{Integer{dh::CUDAVersion().second}}};
info["CUDA_VERSION"] = v;
#if defined(XGBOOST_USE_NCCL)
info["USE_NCCL"] = Boolean{true};
v = {Json{Integer{NCCL_MAJOR}}, Json{Integer{NCCL_MINOR}}, Json{Integer{NCCL_PATCH}}};
info["NCCL_VERSION"] = v;
#else
info["USE_NCCL"] = Boolean{false};
#endif
#if defined(XGBOOST_USE_RMM)
info["USE_RMM"] = Boolean{true};
v = {Json{Integer{RMM_VERSION_MAJOR}}, Json{Integer{RMM_VERSION_MINOR}},
Json{Integer{RMM_VERSION_PATCH}}};
info["RMM_VERSION"] = v;
#else
info["USE_RMM"] = Boolean{false};
#endif
}
void XGBoostAPIGuard::SetGPUAttribute() {
try {
device_id_ = dh::CurrentDevice();

View File

@ -239,5 +239,7 @@ inline void GenerateFeatureMap(Learner const *learner,
}
CHECK_EQ(feature_map.Size(), n_features);
}
void XGBBuildInfoDevice(Json* p_info);
} // namespace xgboost
#endif // XGBOOST_C_API_C_API_UTILS_H_

View File

@ -278,4 +278,13 @@ TEST(CAPI, XGBGlobalConfig) {
ASSERT_EQ(err.find("verbosity"), std::string::npos);
}
}
TEST(CAPI, BuildInfo) {
char const* out;
XGBBuildInfo(&out);
auto loaded = Json::Load(StringView{out});
ASSERT_TRUE(get<Object const>(loaded).find("USE_OPENMP") != get<Object const>(loaded).cend());
ASSERT_TRUE(get<Object const>(loaded).find("USE_CUDA") != get<Object const>(loaded).cend());
ASSERT_TRUE(get<Object const>(loaded).find("USE_NCCL") != get<Object const>(loaded).cend());
}
} // namespace xgboost