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

xgboost: new recipe #23673

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions recipes/xgboost/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
sources:
"2.0.3":
xgboost:
url: "https://github.com/dmlc/xgboost/archive/refs/tags/v2.0.3.tar.gz"
sha256: "94e5deb27133459ec4172f3fed83971383366ad2a7d646b6f0b51f63484c5138"
dmlc-core:
url: "https://github.com/dmlc/dmlc-core/archive/ea21135fbb141ae103fb5fc960289b5601b468f2.zip"
sha256: "f5bc8789556752d268f0939d4dfd86288954b273e2e35b375649cd062d79c8ee"
gputreeshap:
url: "https://github.com/rapidsai/gputreeshap/archive/787259b412c18ab8d5f24bf2b8bd6a59ff8208f3.zip"
sha256: "071f9aacd0c55ac85059fe7b08768e2e410540e402c55594f7bdc5acd46e3fce"
175 changes: 175 additions & 0 deletions recipes/xgboost/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.build import check_min_cppstd, cross_building, stdcpp_library
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
from conan.tools.env import VirtualBuildEnv
from conan.tools.files import copy, get, rm, rmdir, save
from conan.tools.microsoft import is_msvc_static_runtime
from conan.tools.scm import Version
import os

required_conan_version = ">=1.56.0 <2 || >=2.0.6"


class XgboostConan(ConanFile):
name = "xgboost"
description = ("Scalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library. "
"Runs on single machine, Hadoop, Spark, Dask, Flink and DataFlow")
license = "Apache-2.0"
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://github.com/dmlc/xgboost"
topics = ("machine-learning", "boosting", "distributed-systems")

package_type = "library"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
"openmp": [True, False],
"cuda": [True, False],
"nccl": [True, False],
"per_thread_default_stream": [True, False],
"plugin_rmm": [True, False],
"plugin_federated": [True, False],
"plugin_sycl": [True, False]
}
default_options = {
"shared": False,
"fPIC": True,
"openmp": True,
"cuda": False,
"nccl": False,
"per_thread_default_stream": True,
"plugin_rmm": False,
"plugin_federated": False,
"plugin_sycl": False,
}
options_description = {
"openmp": "Build with OpenMP support",
# CUDA
"cuda": "Build with GPU acceleration",
"nccl": "Build with NCCL to enable distributed GPU support",
"per_thread_default_stream": "Build with per-thread default stream (CUDA)",
# Plugins
"plugin_rmm": "Build with RAPIDS Memory Manager (RMM)",
"plugin_federated": "Build with Federated Learning",
"plugin_sycl": "SYCL plugin (requires Intel icpx compiler)",
}

@property
def _min_cppstd(self):
return 17

@property
def _compilers_minimum_version(self):
# https://github.com/dmlc/xgboost/blob/v2.0.3/CMakeLists.txt#L17-L35
return {
"apple-clang": "11",
"clang": "9",
"gcc": "8",
"msvc": "192",
"Visual Studio": "16",
}

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
if cross_building(self) or self.settings.os == "Windows":
del self.options.plugin_federated
if self.settings.compiler != "intel-cc":
del self.options.plugin_sycl

def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")
def layout(self):
cmake_layout(self, src_folder="src")

def requirements(self):
if self.options.openmp:
self.requires("llvm-openmp/18.1.8")
if self.options.plugin_rmm:
self.requires("rmm/24.04.00")
if self.options.get_safe("plugin_federated"):
self.requires("grpc/1.54.3")
self.requires("protobuf/3.21.12")

def validate(self):
if self.settings.compiler.cppstd:
check_min_cppstd(self, self._min_cppstd)
minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False)
if minimum_version and Version(self.settings.compiler.version) < minimum_version:
raise ConanInvalidConfiguration(
f"{self.ref} requires C++{self._min_cppstd}, which your compiler does not support."
)

# Checks from https://github.com/dmlc/xgboost/blob/v2.0.3/CMakeLists.txt#L92-L148
if self.options.nccl and not self.options.cuda:
raise ConanInvalidConfiguration("`nccl` must be enabled with `cuda` option.")
if self.options.cuda and not self.options.plugin_rmm:
raise ConanInvalidConfiguration("`plugin_rmm` must be enabled with `cuda` option.")
if self.options.get_safe("plugin_federated") and not self.options.shared:
raise ConanInvalidConfiguration("Cannot build static lib with federated learning support")

def build_requirements(self):
self.tool_requires("cmake/[>=3.18 <4]")
if self.options.get_safe("plugin_federated"):
self.tool_requires("protobuf/<host_version>")

def source(self):
get(self, **self.conan_data["sources"][self.version]["xgboost"], strip_root=True)
# TODO: unvendor
get(self, **self.conan_data["sources"][self.version]["dmlc-core"], strip_root=True, destination="dmlc-core")
get(self, **self.conan_data["sources"][self.version]["gputreeshap"], strip_root=True, destination="gputreeshap")

def generate(self):
tc = CMakeToolchain(self)
tc.variables["USE_OPENMP"] = self.options.openmp
tc.variables["FORCE_SHARED_CRT"] = not is_msvc_static_runtime(self)
tc.variables["USE_CUDA"] = self.options.cuda
tc.variables["USE_NCCL"] = self.options.nccl
tc.variables["USE_PER_THREAD_DEFAULT_STREAM"] = self.options.per_thread_default_stream
tc.variables["PLUGIN_RMM"] = self.options.plugin_rmm
tc.variables["PLUGIN_FEDERATED"] = self.options.get_safe("plugin_federated", False)
tc.variables["PLUGIN_SYCL"] = self.options.get_safe("plugin_sycl", False)
tc.generate()
tc = CMakeDeps(self)
tc.generate()
venv = VirtualBuildEnv(self)
venv.generate()

def _patch_sources(self):
# Don't build the 'xgboost' executable,
# which has been deprecated in the upcoming release anyway
save(self, os.path.join(self.source_folder, "CMakeLists.txt"),
"\nset_target_properties(runxgboost PROPERTIES EXCLUDE_FROM_ALL TRUE)\n", append=True)

def build(self):
self._patch_sources()
cmake = CMake(self)
cmake.configure()
cmake.build()

def package(self):
copy(self, "LICENSE", self.source_folder, os.path.join(self.package_folder, "licenses"))
cmake = CMake(self)
cmake.install()
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
rmdir(self, os.path.join(self.package_folder, "lib", "cmake"))
rm(self, "*.pdb", self.package_folder, recursive=True)

def package_info(self):
self.cpp_info.set_property("cmake_file_name", "xgboost")
self.cpp_info.set_property("cmake_target_name", "xgboost::xgboost")
self.cpp_info.set_property("pkg_config_name", "xgboost")

self.cpp_info.libs = ["xgboost"]
# TODO: unvendor dmlc-core
self.cpp_info.libs.append("dmlc")

if self.settings.os in ["Linux", "FreeBSD"]:
self.cpp_info.system_libs.extend(["m", "pthread"])

# For the C API
if stdcpp_library(self):
self.cpp_info.system_libs.append(stdcpp_library(self))
8 changes: 8 additions & 0 deletions recipes/xgboost/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.15)
project(test_package LANGUAGES C)

find_package(xgboost REQUIRED CONFIG)

add_executable(${PROJECT_NAME} test_package.c)
target_link_libraries(${PROJECT_NAME} PRIVATE xgboost::xgboost)
target_compile_features(${PROJECT_NAME} PRIVATE c_std_99)
26 changes: 26 additions & 0 deletions recipes/xgboost/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import cmake_layout, CMake
import os


class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
test_type = "explicit"

def requirements(self):
self.requires(self.tested_reference_str)

def layout(self):
cmake_layout(self)

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindir, "test_package")
self.run(bin_path, env="conanrun")
7 changes: 7 additions & 0 deletions recipes/xgboost/all/test_package/test_package.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <xgboost/c_api.h>

int main() {
int silent = 0;
DMatrixHandle dtrain;
XGDMatrixCreateFromFile("missing.txt", silent, &dtrain);
}
3 changes: 3 additions & 0 deletions recipes/xgboost/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
versions:
"2.0.3":
folder: all
Loading