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

Add support inference on SYCL devices #9800

Merged
merged 23 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from 10 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
46 changes: 46 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,52 @@ jobs:
cd build
ctest --extra-verbose

gtest-cpu-sycl:
name: Test Google C++ unittest (CPU SYCL)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.8"]
steps:
- uses: actions/checkout@e2f20e631ae6d7dd3b768f56a5d2af784dd54791 # v2.5.0
with:
submodules: 'true'
- uses: mamba-org/provision-with-micromamba@f347426e5745fe3dfc13ec5baf20496990d0281f # v14
with:
cache-downloads: true
cache-env: true
environment-name: linux_sycl_test
environment-file: tests/ci_build/conda_env/linux_sycl_test.yml

- name: Display Conda env
run: |
conda info
conda list
- name: Build and install XGBoost
shell: bash -l {0}
run: |
mkdir build
cd build
# modify variable to build xgboost with g++ and plugin with icxp
export CXX=g++
export CC=gcc
export CXXFLAGS=${CXXFLAGS/' -isystem '$CONDA_PREFIX'/include'}
export DEBUG_CXXFLAGS=${DEBUG_CXXFLAGS/' -isystem '$CONDA_PREFIX'/include'}
export CPPFLAGS=${CPPFLAGS/' -isystem '$CONDA_PREFIX'/include'}
export DEBUG_CPPFLAGS=${DEBUG_CPPFLAGS/' -isystem '$CONDA_PREFIX'/include'}
trivialfis marked this conversation as resolved.
Show resolved Hide resolved
cmake .. -DGOOGLE_TEST=ON -DUSE_DMLC_GTEST=ON -DPLUGIN_SYCL=ON -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX
make -j$(nproc)
- name: Run gtest binary for SYCL
run: |
cd build
./testxgboost --gtest_filter=Sycl*
- name: Run gtest binary for non SYCL
run: |
cd build
./testxgboost --gtest_filter=-Sycl*

c-api-demo:
name: Test installing XGBoost lib + building the C API demo
runs-on: ${{ matrix.os }}
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/python_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,49 @@ jobs:
run: |
pytest -s -v -rxXs --durations=0 ./tests/test_distributed/test_with_spark

python-sycl-tests-on-ubuntu:
name: Test XGBoost Python package with SYCL on ${{ matrix.config.os }}
runs-on: ${{ matrix.config.os }}
timeout-minutes: 90
strategy:
matrix:
config:
- {os: ubuntu-latest, python-version: "3.8"}

steps:
- uses: actions/checkout@v2
with:
submodules: 'true'

- uses: mamba-org/provision-with-micromamba@f347426e5745fe3dfc13ec5baf20496990d0281f # v14
with:
cache-downloads: true
cache-env: true
environment-name: linux_sycl_test
environment-file: tests/ci_build/conda_env/linux_sycl_test.yml

- name: Display Conda env
run: |
conda info
conda list
- name: Build XGBoost on Ubuntu
run: |
mkdir build
cd build
export CXX=g++
export CC=gcc
trivialfis marked this conversation as resolved.
Show resolved Hide resolved
cmake .. -DPLUGIN_SYCL=ON -DCMAKE_PREFIX_PATH=$CONDA_PREFIX
make -j$(nproc)
- name: Install Python package
run: |
cd python-package
python --version
pip install -v .
- name: Test Python package
run: |
pytest -s -v -rxXs --durations=0 ./tests/python-sycl/


python-system-installation-on-ubuntu:
name: Test XGBoost Python package System Installation on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
Expand Down
11 changes: 10 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ option(PLUGIN_DENSE_PARSER "Build dense parser plugin" OFF)
option(PLUGIN_RMM "Build with RAPIDS Memory Manager (RMM)" OFF)
option(PLUGIN_FEDERATED "Build with Federated Learning" OFF)
## TODO: 1. Add check if DPC++ compiler is used for building
option(PLUGIN_UPDATER_ONEAPI "DPC++ updater" OFF)
option(PLUGIN_SYCL "SYCL plugin" OFF)
option(ADD_PKGCONFIG "Add xgboost.pc into system." ON)

#-- Checks for building XGBoost
Expand Down Expand Up @@ -301,6 +301,15 @@ if(PLUGIN_RMM)
get_target_property(rmm_link_libs rmm::rmm INTERFACE_LINK_LIBRARIES)
endif()

if(PLUGIN_SYCL)
set(CMAKE_CXX_LINK_EXECUTABLE
"icpx <FLAGS> <CMAKE_CXX_LINK_FLAGS> -qopenmp <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_CXX_CREATE_SHARED_LIBRARY
"icpx <CMAKE_SHARED_LIBRARY_CXX_FLAGS> -qopenmp <LANGUAGE_COMPILE_FLAGS> \
<CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG>,<TARGET_SONAME> \
-o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
endif()

#-- library
if(BUILD_STATIC_LIB)
add_library(xgboost STATIC)
Expand Down
14 changes: 10 additions & 4 deletions include/xgboost/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,16 @@ struct Context : public XGBoostParameter<Context> {
default:
// Do not use the device name as this is likely an internal error, the name
// wouldn't be valid.
LOG(FATAL) << "Unknown device type:"
<< static_cast<std::underlying_type_t<DeviceOrd::Type>>(this->Device().device);
break;
if (this->Device().IsSycl()) {
LOG(WARNING) << "The requested feature doesn't have SYCL specific implementation yet. "
<< "CPU implementation is used";
return cpu_fn();
} else {
LOG(FATAL) << "Unknown device type:"
<< "is sycl = " << this->Device().IsSycl() << "; "
<< static_cast<std::underlying_type_t<DeviceOrd::Type>>(this->Device().device);
trivialfis marked this conversation as resolved.
Show resolved Hide resolved
break;
}
}
return std::invoke_result_t<CPUFn>();
}
Expand All @@ -262,7 +269,6 @@ struct Context : public XGBoostParameter<Context> {
*/
template <typename CPUFn, typename CUDAFn, typename SYCLFn>
decltype(auto) DispatchDevice(CPUFn&& cpu_fn, CUDAFn&& cuda_fn, SYCLFn&& sycl_fn) const {
static_assert(std::is_same_v<std::invoke_result_t<CPUFn>, std::invoke_result_t<CUDAFn>>);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case of non-sycl device, the DispatchDevice with this assert will be called. So, it was just a duplicated assert.

static_assert(std::is_same_v<std::invoke_result_t<CPUFn>, std::invoke_result_t<SYCLFn>>);
if (this->Device().IsSycl()) {
return sycl_fn();
Expand Down
28 changes: 15 additions & 13 deletions plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,32 @@ if(PLUGIN_DENSE_PARSER)
target_sources(objxgboost PRIVATE ${xgboost_SOURCE_DIR}/plugin/dense_parser/dense_libsvm.cc)
endif()

if(PLUGIN_UPDATER_ONEAPI)
add_library(oneapi_plugin OBJECT
${xgboost_SOURCE_DIR}/plugin/updater_oneapi/regression_obj_oneapi.cc
${xgboost_SOURCE_DIR}/plugin/updater_oneapi/predictor_oneapi.cc)
target_include_directories(oneapi_plugin
if(PLUGIN_SYCL)
set(CMAKE_CXX_COMPILER "icpx")
add_library(plugin_sycl OBJECT
${xgboost_SOURCE_DIR}/plugin/sycl/device_manager.cc
${xgboost_SOURCE_DIR}/plugin/sycl/predictor/predictor.cc)
target_include_directories(plugin_sycl
PRIVATE
${xgboost_SOURCE_DIR}/include
${xgboost_SOURCE_DIR}/dmlc-core/include
${xgboost_SOURCE_DIR}/rabit/include)
target_compile_definitions(oneapi_plugin PUBLIC -DXGBOOST_USE_ONEAPI=1)
target_link_libraries(oneapi_plugin PUBLIC -fsycl)
set_target_properties(oneapi_plugin PROPERTIES
target_compile_definitions(plugin_sycl PUBLIC -DXGBOOST_USE_SYCL=1)
target_link_libraries(plugin_sycl PUBLIC -fsycl)
set_target_properties(plugin_sycl PROPERTIES
COMPILE_FLAGS -fsycl
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
POSITION_INDEPENDENT_CODE ON)
if(USE_OPENMP)
find_package(OpenMP REQUIRED)
target_link_libraries(oneapi_plugin PUBLIC OpenMP::OpenMP_CXX)
set_target_properties(plugin_sycl PROPERTIES
COMPILE_FLAGS "-fsycl -qopenmp")
endif()
# Get compilation and link flags of oneapi_plugin and propagate to objxgboost
target_link_libraries(objxgboost PUBLIC oneapi_plugin)
# Add all objects of oneapi_plugin to objxgboost
target_sources(objxgboost INTERFACE $<TARGET_OBJECTS:oneapi_plugin>)
# Get compilation and link flags of plugin_sycl and propagate to objxgboost
target_link_libraries(objxgboost PUBLIC plugin_sycl)
# Add all objects of plugin_sycl to objxgboost
target_sources(objxgboost INTERFACE $<TARGET_OBJECTS:plugin_sycl>)
endif()

# Add the Federate Learning plugin if enabled.
Expand Down
32 changes: 32 additions & 0 deletions plugin/sycl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SYCL-based Algorithm for Tree Construction
trivialfis marked this conversation as resolved.
Show resolved Hide resolved
This plugin adds support of SYCL programming model for prediction algorithms to XGBoost.
trivialfis marked this conversation as resolved.
Show resolved Hide resolved

## Usage
Specify the 'device' parameter as one of the following options to offload model training and inference on SYCL device.
razdoburdin marked this conversation as resolved.
Show resolved Hide resolved

### Algorithms
| device | Description |
| --- | --- |
sycl | use default sycl device |
sycl:gpu | use default sycl gpu |
sycl:cpu | use default sycl cpu |
trivialfis marked this conversation as resolved.
Show resolved Hide resolved
sycl:gpu:N | use sycl gpu number N |
sycl:cpu:N | use sycl cpu number N |

Python example:
```python
param['device'] = 'sycl:gpu:0'
```

## Dependencies
Building the plugin requires Data Parallel C++ Compiler (https://software.intel.com/content/www/us/en/develop/tools/oneapi/components/dpc-compiler.html)
razdoburdin marked this conversation as resolved.
Show resolved Hide resolved

## Build
From the command line on Linux starting from the xgboost directory:
razdoburdin marked this conversation as resolved.
Show resolved Hide resolved

```bash
$ mkdir build
$ cd build
$ cmake .. -DPLUGIN_SYCL=ON
$ make -j
```
Loading
Loading