Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Breaking] Add global versioning. #4936

Merged
merged 12 commits into from
Oct 23, 2019
10 changes: 4 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
message(FATAL_ERROR "GCC version must be at least 5.0!")
endif()

message(STATUS "xgboost VERSION: ${xgboost_VERSION}")
set(XGBOOST_DEFINITIONS
${XGBOOST_DEFINITIONS}
-DXGBOOST_VER_MAJOR=${xgboost_VERSION_MAJOR}
-DXGBOOST_VER_MINOR=${xgboost_VERSION_MINOR}
-DXGBOOST_VER_PATCH=${xgboost_VERSION_PATCH})
include(${xgboost_SOURCE_DIR}/cmake/FindPrefetchIntrinsics.cmake)
find_prefetch_intrinsics()
include(${xgboost_SOURCE_DIR}/cmake/Version.cmake)
write_version()
set_default_configuration_release()

#-- Options
Expand Down
1 change: 1 addition & 0 deletions amalgamation/xgboost-all0.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#include "../src/common/hist_util.cc"
#include "../src/common/json.cc"
#include "../src/common/io.cc"
#include "../src/common/version.cc"

// c_api
#include "../src/c_api/c_api.cc"
Expand Down
22 changes: 22 additions & 0 deletions cmake/FindPrefetchIntrinsics.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function (find_prefetch_intrinsics)
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <xmmintrin.h>
int main() {
char data = 0;
const char* address = &data;
_mm_prefetch(address, _MM_HINT_NTA);
return 0;
}
" XGBOOST_MM_PREFETCH_PRESENT)
check_cxx_source_compiles("
int main() {
char data = 0;
const char* address = &data;
__builtin_prefetch(address, 0, 0);
return 0;
}
" XGBOOST_BUILTIN_PREFETCH_PRESENT)
set(XGBOOST_MM_PREFETCH_PRESENT ${XGBOOST_MM_PREFETCH_PRESENT} PARENT_SCOPE)
set(XGBOOST_BUILTIN_PREFETCH_PRESENT ${XGBOOST_BUILTIN_PREFETCH_PRESENT} PARENT_SCOPE)
endfunction (find_prefetch_intrinsics)
1 change: 1 addition & 0 deletions cmake/Python_version.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@xgboost_VERSION_MAJOR@.@xgboost_VERSION_MINOR@.@xgboost_VERSION_PATCH@-SNAPSHOT
10 changes: 10 additions & 0 deletions cmake/Version.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function (write_version)
message(STATUS "xgboost VERSION: ${xgboost_VERSION}")
configure_file(
${xgboost_SOURCE_DIR}/cmake/build_config.h.in
${xgboost_SOURCE_DIR}/include/xgboost/build_config.h @ONLY)
configure_file(
${xgboost_SOURCE_DIR}/cmake/Python_version.in
${xgboost_SOURCE_DIR}/python-package/xgboost/VERSION
)
endfunction (write_version)
17 changes: 17 additions & 0 deletions cmake/build_config.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*!
* Copyright 2019 by Contributors
* \file build_config.h
*
* Generated from `cmake/build_config.h.in` by cmake.
*/
#ifndef XGBOOST_BUILD_CONFIG_H_
#define XGBOOST_BUILD_CONFIG_H_

#cmakedefine XGBOOST_MM_PREFETCH_PRESENT
#cmakedefine XGBOOST_BUILTIN_PREFETCH_PRESENT

#define XGBOOST_VER_MAJOR @xgboost_VERSION_MAJOR@
#define XGBOOST_VER_MINOR @xgboost_VERSION_MINOR@
#define XGBOOST_VER_PATCH @xgboost_VERSION_PATCH@

#endif // XGBOOST_BUILD_CONFIG_H_
2 changes: 2 additions & 0 deletions include/xgboost/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ const bst_float kRtEps = 1e-6f;
using omp_ulong = dmlc::omp_ulong; // NOLINT
/*! \brief define unsigned int for openmp loop */
using bst_omp_uint = dmlc::omp_uint; // NOLINT
/*! \brief Type used for representing version number in binary form.*/
using XGBoostVersionT = int32_t;

/*!
* \brief define compatible keywords in g++
Expand Down
6 changes: 6 additions & 0 deletions include/xgboost/build_config.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/*!
* Copyright 2019 by Contributors
* \file build_config.h
*
* Generated from `cmake/build_config.h.in` by cmake.
*/
#ifndef XGBOOST_BUILD_CONFIG_H_
#define XGBOOST_BUILD_CONFIG_H_
Expand All @@ -19,4 +21,8 @@

#endif // !defined(XGBOOST_MM_PREFETCH_PRESENT) && !defined()

#define XGBOOST_VER_MAJOR 1
#define XGBOOST_VER_MINOR 0
#define XGBOOST_VER_PATCH 0

#endif // XGBOOST_BUILD_CONFIG_H_
10 changes: 10 additions & 0 deletions include/xgboost/c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ typedef struct { // NOLINT(*)
float* value;
} XGBoostBatchCSR;

/*!
* \brief Return the version of the XGBoost library being currently used.
*
* The output variable is only written if it's not NULL.
*
* \param major Store the major version number
* \param minor Store the minor version number
* \param patch Store the patch (revision) number
*/
XGB_DLL void XGBoostVersion(int* major, int* minor, int* patch);

/*!
* \brief Callback to set the data to handle,
Expand Down
4 changes: 0 additions & 4 deletions include/xgboost/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,6 @@ class MetaInfo {
* can be used to specify initial prediction to boost from.
*/
HostDeviceVector<bst_float> base_margin_;
/*! \brief version flag, used to check version of this info */
static const int kVersion = 3;
/*! \brief version that contains qid field */
static const int kVersionWithQid = 2;
/*! \brief default constructor */
MetaInfo() = default;
/*!
Expand Down
10 changes: 10 additions & 0 deletions include/xgboost/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,9 @@ class Json {
static void Dump(Json json, std::ostream* stream,
bool pretty = ConsoleLogger::ShouldLog(
ConsoleLogger::LogVerbosity::kDebug));
static void Dump(Json json, std::string* out,
bool pretty = ConsoleLogger::ShouldLog(
ConsoleLogger::LogVerbosity::kDebug));

Json() : ptr_{new JsonNull} {}

Expand Down Expand Up @@ -400,6 +403,13 @@ class Json {
return *ptr_ == *(rhs.ptr_);
}

friend std::ostream& operator<<(std::ostream& os, Json const& j) {
std::string str;
Json::Dump(j, &str);
os << str;
return os;
}

private:
std::shared_ptr<Value> ptr_;
};
Expand Down
29 changes: 0 additions & 29 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,25 +1,6 @@
file(GLOB_RECURSE CPU_SOURCES *.cc *.h)
list(REMOVE_ITEM CPU_SOURCES ${PROJECT_SOURCE_DIR}/src/cli_main.cc)

include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <xmmintrin.h>
int main() {
char data = 0;
const char* address = &data;
_mm_prefetch(address, _MM_HINT_NTA);
return 0;
}
" XGBOOST_MM_PREFETCH_PRESENT)
check_cxx_source_compiles("
int main() {
char data = 0;
const char* address = &data;
__builtin_prefetch(address, 0, 0);
return 0;
}
" XGBOOST_BUILTIN_PREFETCH_PRESENT)

#-- Object library
# Object library is necessary for jvm-package, which creates its own shared
# library.
Expand Down Expand Up @@ -82,16 +63,6 @@ target_compile_definitions(objxgboost
-DDMLC_LOG_CUSTOMIZE=1 # enable custom logging
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:_MWAITXINTRIN_H_INCLUDED>
${XGBOOST_DEFINITIONS})
if (XGBOOST_MM_PREFETCH_PRESENT)
target_compile_definitions(objxgboost
PRIVATE
-DXGBOOST_MM_PREFETCH_PRESENT=1)
endif(XGBOOST_MM_PREFETCH_PRESENT)
if (XGBOOST_BUILTIN_PREFETCH_PRESENT)
target_compile_definitions(objxgboost
PRIVATE
-DXGBOOST_BUILTIN_PREFETCH_PRESENT=1)
endif (XGBOOST_BUILTIN_PREFETCH_PRESENT)

if (USE_OPENMP)
find_package(OpenMP REQUIRED)
Expand Down
12 changes: 12 additions & 0 deletions src/c_api/c_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,18 @@ struct XGBAPIThreadLocalEntry {
std::vector<GradientPair> tmp_gpair;
};

XGB_DLL void XGBoostVersion(int* major, int* minor, int* patch) {
if (major) {
*major = XGBOOST_VER_MAJOR;
}
if (minor) {
*minor = XGBOOST_VER_MINOR;
}
if (patch) {
*patch = XGBOOST_VER_PATCH;
}
}

// define the threadlocal store.
using XGBAPIThreadLocalStore = dmlc::ThreadLocalStore<XGBAPIThreadLocalEntry>;

Expand Down
8 changes: 8 additions & 0 deletions src/common/json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -718,5 +718,13 @@ void Json::Dump(Json json, std::ostream *stream, bool pretty) {
writer.Save(json);
}

void Json::Dump(Json json, std::string* str, bool pretty) {
GlobalCLocale guard;
std::stringstream ss;
JsonWriter writer(&ss, pretty);
writer.Save(json);
*str = ss.str();
}

Json& Json::operator=(Json const &other) = default;
} // namespace xgboost
90 changes: 90 additions & 0 deletions src/common/version.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*!
* Copyright 2019 XGBoost contributors
*/
#include <dmlc/io.h>

#include <string>
#include <tuple>
#include <vector>

#include "xgboost/logging.h"
#include "xgboost/json.h"
#include "version.h"

namespace xgboost {

const Version::TripletT Version::kInvalid {-1, -1, -1};

Version::TripletT Version::Load(Json const& in, bool check) {
if (get<Object const>(in).find("version") == get<Object const>(in).cend()) {
return kInvalid;
}
Integer::Int major {0}, minor {0}, patch {0};
try {
auto const& j_version = get<Array const>(in["version"]);
std::tie(major, minor, patch) = std::make_tuple(
get<Integer const>(j_version.at(0)),
get<Integer const>(j_version.at(1)),
get<Integer const>(j_version.at(2)));
} catch (dmlc::Error const& e) {
LOG(FATAL) << "Invaid version format in loaded JSON object: " << in;
}

return std::make_tuple(major, minor, patch);
}

Version::TripletT Version::Load(dmlc::Stream* fi) {
XGBoostVersionT major{0}, minor{0}, patch{0};
// This is only used in DMatrix serialization, so doesn't break model compability.
std::string msg { "Incorrect version format found in binary file. "
"Binary file from XGBoost < 1.0.0 is no longer supported. "
"Please generate it again." };
std::string verstr { u8"version:" }, read;
read.resize(verstr.size(), 0);

CHECK_EQ(fi->Read(&read[0], verstr.size()), verstr.size()) << msg;
if (verstr != read) {
// read might contain `\0` that terminates the string.
LOG(FATAL) << msg;
}

CHECK_EQ(fi->Read(&major, sizeof(major)), sizeof(major)) << msg;
CHECK_EQ(fi->Read(&minor, sizeof(major)), sizeof(minor)) << msg;
CHECK_EQ(fi->Read(&patch, sizeof(major)), sizeof(patch)) << msg;

return std::make_tuple(major, minor, patch);
}

void Version::Save(Json* out) {
Integer::Int major, minor, patch;
std::tie(major, minor, patch)= Self();
(*out)["version"] = std::vector<Json>{Json(Integer{major}),
Json(Integer{minor}),
Json(Integer{patch})};
}

void Version::Save(dmlc::Stream* fo) {
XGBoostVersionT major, minor, patch;
std::tie(major, minor, patch) = Self();
std::string verstr { u8"version:" };
fo->Write(&verstr[0], verstr.size());
fo->Write(&major, sizeof(major));
fo->Write(&minor, sizeof(minor));
fo->Write(&patch, sizeof(patch));
}

std::string Version::String(TripletT const& version) {
std::stringstream ss;
ss << std::get<0>(version) << "." << get<1>(version) << "." << get<2>(version);
return ss.str();
}

Version::TripletT Version::Self() {
return std::make_tuple(XGBOOST_VER_MAJOR, XGBOOST_VER_MINOR, XGBOOST_VER_PATCH);
}

bool Version::Same(TripletT const& triplet) {
return triplet == Self();
}

} // namespace xgboost
35 changes: 35 additions & 0 deletions src/common/version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*!
* Copyright 2019 XGBoost contributors
*/
#ifndef XGBOOST_COMMON_VERSION_H_
#define XGBOOST_COMMON_VERSION_H_

#include <dmlc/io.h>
#include <string>
#include <tuple>

#include "xgboost/base.h"

namespace xgboost {
class Json;
// a static class for handling version info
struct Version {
using TripletT = std::tuple<XGBoostVersionT, XGBoostVersionT, XGBoostVersionT>;
static const TripletT kInvalid;

// Save/Load version info to Json document
static TripletT Load(Json const& in, bool check = false);
static void Save(Json* out);

// Save/Load version info to dmlc::Stream
static Version::TripletT Load(dmlc::Stream* fi);
static void Save(dmlc::Stream* fo);

static std::string String(TripletT const& version);
static TripletT Self();

static bool Same(TripletT const& triplet);
};

} // namespace xgboost
#endif // XGBOOST_COMMON_VERSION_H_
Loading