Skip to content

Commit

Permalink
SYCL wheel packaging
Browse files Browse the repository at this point in the history
Do not use lld - linker errors
Add dpcpp-cpp-rt as python dependency for sycl wheel. Update DSO rpath to use python venv DSOs.
numpy>=2 is OK
sycl docs
  • Loading branch information
ssheorey committed Jan 1, 2025
1 parent 1c99a2b commit 6457398
Show file tree
Hide file tree
Showing 20 changed files with 202 additions and 39 deletions.
10 changes: 0 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -292,19 +292,9 @@ endif()
if(BUILD_SYCL_MODULE AND NOT GLIBCXX_USE_CXX11_ABI)
message(FATAL_ERROR "BUILD_SYCL_MODULE=ON requires GLIBCXX_USE_CXX11_ABI=ON")
endif()
# if(BUILD_SYCL_MODULE AND BUILD_TENSORFLOW_OPS)
# message(FATAL_ERROR "BUILD_SYCL_MODULE=ON requires BUILD_TENSORFLOW_OPS=OFF")
# endif()
# if(BUILD_SYCL_MODULE AND BUILD_PYTORCH_OPS)
# message(FATAL_ERROR "BUILD_SYCL_MODULE=ON requires BUILD_PYTORCH_OPS=OFF")
# endif()
if(BUILD_SYCL_MODULE AND BUILD_CUDA_MODULE)
message(FATAL_ERROR "BUILD_SYCL_MODULE and BUILD_SYCL_MODULE cannot be on at the same time for now.")
endif()
# Use LLD with icpx for faster linking
if (CMAKE_CXX_COMPILER_ID MATCHES "IntelLLVM")
add_link_options("-fuse-ld=lld")
endif()

# Global flag to set CXX standard.
# This does not affect 3rd party libraries.
Expand Down
9 changes: 5 additions & 4 deletions cmake/Open3DSetGlobalProperties.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ function(open3d_enable_strip target)
endif()
endfunction()

# RPATH handling (for TBB DSO). Check current folder, one folder above and the lib sibling folder
# RPATH handling (for TBB DSO). Check current folder, one folder above and the lib sibling folder.
# Also check the Python virtual env /lib folder for 3rd party dependency libraries installed with `pip install`
set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
if (APPLE)
# Add options to cover the various ways in which open3d shaed lib or apps can be installed wrt TBB DSO
set(CMAKE_INSTALL_RPATH "@loader_path;@loader_path/../;@loader_path/../lib/")
# Add options to cover the various ways in which open3d shared lib or apps can be installed wrt TBB DSO
set(CMAKE_INSTALL_RPATH "@loader_path;@loader_path/../;@loader_path/../lib/;@loader_path/../../../../")
# pybind with open3d shared lib is copied, not cmake-installed, so we need to add .. to build rpath
set(CMAKE_BUILD_RPATH "@loader_path/../")
elseif(UNIX)
set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/../;$ORIGIN/../lib/")
set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/../;$ORIGIN/../lib/;$ORIGIN/../../../../")
set(CMAKE_BUILD_RPATH "$ORIGIN/../")
endif()

Expand Down
2 changes: 1 addition & 1 deletion cpp/open3d/core/Indexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ class Indexer {
class IndexerIterator {
public:
struct Iterator {
Iterator() {};
Iterator(){};
Iterator(const Indexer& indexer);
Iterator(Iterator&& other) = default;

Expand Down
3 changes: 3 additions & 0 deletions cpp/open3d/core/SYCLContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ namespace open3d {
namespace core {
namespace sy {

OPEN3D_DLL_LOCAL std::string GetDeviceTypeName(const sycl::device &device);

SYCLContext &SYCLContext::GetInstance() {
static thread_local SYCLContext instance;
return instance;
Expand Down Expand Up @@ -46,6 +48,7 @@ SYCLDevice::SYCLDevice(const sycl::device &sycl_device) {
device = sycl_device;
queue = sycl::queue(device);
name = device.get_info<sid::name>();
device_type = GetDeviceTypeName(device);
max_work_group_size = device.get_info<sid::max_work_group_size>();
auto aspects = device.get_info<sid::aspects>();
fp64 = std::find(aspects.begin(), aspects.end(), sycl::aspect::fp64) !=
Expand Down
1 change: 1 addition & 0 deletions cpp/open3d/core/SYCLContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace sy {
struct SYCLDevice {
SYCLDevice(const sycl::device& sycl_device);
std::string name; ///< Fiendlly / descriptive name of the device.
std::string device_type; ///< cpu, gpu, host, acc, custom, unknown.
sycl::device device; ///< SYCL device.
sycl::queue queue; ///< Default queue for this device.
size_t max_work_group_size; ///< Preferred work group size
Expand Down
18 changes: 17 additions & 1 deletion cpp/open3d/core/SYCLUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ int SYCLDemo() {

#ifdef BUILD_SYCL_MODULE

static std::string GetDeviceTypeName(const sycl::device &device) {
OPEN3D_DLL_LOCAL std::string GetDeviceTypeName(const sycl::device &device) {
auto device_type = device.get_info<sycl::info::device::device_type>();
switch (device_type) {
case sycl::info::device_type::cpu:
Expand All @@ -95,6 +95,8 @@ static std::string GetDeviceTypeName(const sycl::device &device) {
return "host";
case sycl::info::device_type::accelerator:
return "acc";
case sycl::info::device_type::custom:
return "custom";
default:
return "unknown";
}
Expand Down Expand Up @@ -210,6 +212,20 @@ bool IsDeviceAvailable(const Device &device) {
#endif
}

std::string GetDeviceType(const Device &device) {
#ifdef BUILD_SYCL_MODULE
if (IsDeviceAvailable(device)) {
return SYCLContext::GetInstance()
.GetDeviceProperties(device)
.device_type;
} else {
return "";
}
#else
return "";
#endif
}

std::vector<Device> GetAvailableSYCLDevices() {
#ifdef BUILD_SYCL_MODULE
return SYCLContext::GetInstance().GetAvailableSYCLDevices();
Expand Down
4 changes: 4 additions & 0 deletions cpp/open3d/core/SYCLUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ bool IsAvailable();
/// Returns true if the specified SYCL device is available.
bool IsDeviceAvailable(const Device& device);

/// Returns the device type (cpu / gpu / accelerator / custom) of the specified
/// device as a string. Returns empty string if the device is not available.
std::string GetDeviceType(const Device& device);

/// Return a list of available SYCL devices.
std::vector<Device> GetAvailableSYCLDevices();

Expand Down
1 change: 1 addition & 0 deletions cpp/pybind/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ add_custom_target(python-package
-DOPEN3D_ML_ROOT=${OPEN3D_ML_ROOT}
-DBUILD_GUI=${BUILD_GUI}
-DBUILD_CUDA_MODULE=${BUILD_CUDA_MODULE}
-DBUILD_SYCL_MODULE=${BUILD_SYCL_MODULE}
-DGUI_RESOURCE_DIR=${GUI_RESOURCE_DIR}
-DPROJECT_EMAIL=${PROJECT_EMAIL}
-DPROJECT_HOMEPAGE_URL=${PROJECT_HOMEPAGE_URL}
Expand Down
5 changes: 5 additions & 0 deletions cpp/pybind/core/sycl_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ void pybind_sycl_utils_definitions(py::module& m) {
"Enables the JIT cache for SYCL. This sets an environment "
"variable and "
"will affect the entire process and any child processes.");

m_sycl.def("get_device_type", sy::GetDeviceType, "device"_a,
"Returns the device type (cpu / gpu / accelerator / custom) of "
"the specified device as a string. Returns empty string if the "
"device is not available.");
}

} // namespace core
Expand Down
21 changes: 12 additions & 9 deletions cpp/pybind/make_python_package.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ if (BUNDLE_OPEN3D_ML)
file(RENAME "${PYTHON_PACKAGE_DST_DIR}/open3d/ml3d" "${PYTHON_PACKAGE_DST_DIR}/open3d/_ml3d")
endif()

set(requirement_files ${PYTHON_PACKAGE_SRC_DIR}/requirements.txt)
# Build Jupyter plugin.
if (BUILD_JUPYTER_EXTENSION)
if (WIN32 OR UNIX AND NOT LINUX_AARCH64)
Expand Down Expand Up @@ -113,17 +114,19 @@ if (BUILD_JUPYTER_EXTENSION)
"npm install -g yarn.")
endif()

# Append requirements_jupyter_install.txt to requirements.txt
# These will be installed when `pip install open3d`.
execute_process(COMMAND ${CMAKE_COMMAND} -E cat
${PYTHON_PACKAGE_SRC_DIR}/requirements.txt
${PYTHON_PACKAGE_SRC_DIR}/requirements_jupyter_install.txt
OUTPUT_VARIABLE ALL_REQUIREMENTS
)
# The double-quote "" is important as it keeps the semicolons.
file(WRITE ${PYTHON_PACKAGE_DST_DIR}/requirements.txt "${ALL_REQUIREMENTS}")
list(APPEND requirement_files
${PYTHON_PACKAGE_SRC_DIR}/requirements_jupyter_install.txt)
endif()

if (BUILD_SYCL_MODULE)
list(APPEND requirement_files ${PYTHON_PACKAGE_SRC_DIR}/requirements_sycl.txt)
endif()

# These will be installed when the user does `pip install open3d`.
execute_process(COMMAND ${CMAKE_COMMAND} -E cat ${requirement_files}
OUTPUT_FILE ${PYTHON_PACKAGE_DST_DIR}/requirements.txt
)

if (BUILD_GUI)
file(MAKE_DIRECTORY "${PYTHON_PACKAGE_DST_DIR}/open3d/resources/")
file(COPY ${GUI_RESOURCE_DIR}
Expand Down
9 changes: 6 additions & 3 deletions cpp/tests/core/CoreTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,12 @@ std::vector<core::Device> PermuteDevicesWithSYCL::TestCases() {
std::vector<core::Device> devices = PermuteDevices::TestCases();
std::vector<core::Device> sycl_devices =
core::Device::GetAvailableSYCLDevices();
if (!sycl_devices.empty()) {
// devices.push_back(sycl_devices[0]); // only the first SYCL device
devices.insert(devices.end(), sycl_devices.begin(), sycl_devices.end());
// Skip the last SYCL device - this is the CPU fallback and support is
// untested.
if (sycl_devices.size() > 1) {
devices.push_back(sycl_devices[0]);
// devices.insert(devices.end(), sycl_devices.begin(),
// sycl_devices.end());
}
return devices;
}
Expand Down
3 changes: 3 additions & 0 deletions cpp/tests/core/Linalg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,9 @@ TEST_P(LinalgPermuteDevices, LeastSquares) {
const float EPSILON = 1e-5;

core::Device device = GetParam();
if (sy::GetDeviceType(device) == "cpu") {
GTEST_SKIP() << "MKL unsupported SYCL device.";
}
core::Dtype dtype = core::Float32;

// Solve test.
Expand Down
9 changes: 9 additions & 0 deletions cpp/tests/core/Tensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2245,6 +2245,11 @@ TEST_P(TensorPermuteDevicesWithSYCL, ReduceMaxFloatLimit) {

TEST_P(TensorPermuteDevicesWithSYCL, ReduceArgMin) {
core::Device device = GetParam();
if (core::sy::GetDeviceType(device) == "cpu") {
GTEST_SKIP() << "allocateMemSubBuffer() API failed with unknown error "
"on CPU.";
}

core::Tensor src = core::Tensor::Init<float>(
{{{22, 23, 20, 9}, {6, 14, 18, 13}, {15, 3, 17, 0}},
{{7, 21, 11, 1}, {4, 2, 10, 19}, {5, 8, 16, 12}}},
Expand Down Expand Up @@ -2273,6 +2278,10 @@ TEST_P(TensorPermuteDevicesWithSYCL, ReduceArgMin) {

TEST_P(TensorPermuteDevicesWithSYCL, ReduceArgMax) {
core::Device device = GetParam();
if (core::sy::GetDeviceType(device) == "cpu") {
GTEST_SKIP() << "allocateMemSubBuffer() API failed with unknown error "
"on CPU.";
}
core::Tensor src = core::Tensor::Init<float>(
{{{22, 23, 20, 9}, {6, 14, 18, 13}, {15, 3, 17, 0}},
{{7, 21, 11, 1}, {4, 2, 10, 19}, {5, 8, 16, 12}}},
Expand Down
8 changes: 6 additions & 2 deletions docker/Dockerfile.ci
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,14 @@ RUN apt-get update && apt-get install -y \
libffi-dev \
liblzma-dev \
&& if [ "${BUILD_SYCL_MODULE}" = "ON" ]; then \
apt-get install -y g++-11; \
add-apt-repository -y ppa:ubuntu-toolchain-r/test \
&& apt-get install -y g++-11 \
&& update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 11 \
&& update-alternatives --set g++ /usr/bin/g++-11 \
&& c++ -v; \
fi \
&& rm -rf /var/lib/apt/lists/*
# OneDPL TBB backend requires libstdc++ >= v11
# OneDPL TBB backend requires libstdc++ >= v11. This makes the created wheel UBuntu 22.04+ only.

# pyenv
# The pyenv python paths are used during docker run, in this way docker run
Expand Down
14 changes: 7 additions & 7 deletions docker/docker_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -456,12 +456,12 @@ sycl-shared_export_env() {
export BUILD_CUDA_MODULE=OFF
export BUILD_TENSORFLOW_OPS=ON
export BUILD_PYTORCH_OPS=ON
export PACKAGE=OFF
export PACKAGE=ON
export BUILD_SYCL_MODULE=ON

export IGC_EnableDPEmulation=1 # Enable float64 emulation during compilation
export SYCL_CACHE_PERSISTENT=1 # Cache SYCL kernel binaries.
export OverrideDefaultFP64Settings=1 # Enable double precision emulation at runtime.
export IGC_EnableDPEmulation=1 # Enable float64 emulation during compilation
export SYCL_CACHE_PERSISTENT=1 # Cache SYCL kernel binaries.
export OverrideDefaultFP64Settings=1 # Enable double precision emulation at runtime.
}

sycl-static_export_env() {
Expand All @@ -480,9 +480,9 @@ sycl-static_export_env() {
export PACKAGE=OFF
export BUILD_SYCL_MODULE=ON

export IGC_EnableDPEmulation=1 # Enable float64 emulation during compilation
export SYCL_CACHE_PERSISTENT=1 # Cache SYCL kernel binaries.
export OverrideDefaultFP64Settings=1 # Enable double precision emulation at runtime.
export IGC_EnableDPEmulation=1 # Enable float64 emulation during compilation
export SYCL_CACHE_PERSISTENT=1 # Cache SYCL kernel binaries.
export OverrideDefaultFP64Settings=1 # Enable double precision emulation at runtime.
}

function main() {
Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Open3D: A Modern Library for 3D Data Processing
builddocs
docker
arm
sycl
open3d_ml

.. toctree::
Expand Down
Loading

0 comments on commit 6457398

Please sign in to comment.