Skip to content

Commit e7290ae

Browse files
author
Alexander Johnston
committed
[SYCL][CUDA] Initial Implementation of the CUDA backend
Contributors Alan Forbes <[email protected]> Alexander Johnston <[email protected]> Bjoern Knafla <[email protected]> Daniel Soutar <[email protected]> David Wood <[email protected]> Kumudha Narasimhan <[email protected]> Mehdi Goli <[email protected]> Przemek Malon <[email protected]> Ruyman Reyes <[email protected]> Stuart Adams <[email protected]> Svetlozar Georgiev <[email protected]> Steffen Larsen <[email protected]> Victor Lomuller <[email protected]> Signed-off-by: Alexander Johnston <[email protected]>
1 parent 3670b79 commit e7290ae

File tree

189 files changed

+7034
-308
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

189 files changed

+7034
-308
lines changed

buildbot/configure.py

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,49 @@ def do_configure(args):
1111
sycl_dir = os.path.join(args.src_dir, "sycl")
1212
spirv_dir = os.path.join(args.src_dir, "llvm-spirv")
1313
ocl_header_dir = os.path.join(args.obj_dir, "OpenCL-Headers")
14-
icd_loader_lib = ''
14+
icd_loader_lib = os.path.join(args.obj_dir, "OpenCL-ICD-Loader", "build")
15+
llvm_targets_to_build = 'X86'
16+
llvm_enable_projects = 'clang;llvm-spirv;sycl;opencl-aot'
17+
libclc_targets_to_build = ''
18+
sycl_build_pi_cuda = 'OFF'
19+
llvm_enable_assertions = 'OFF'
1520

1621
if platform.system() == 'Linux':
17-
icd_loader_lib = os.path.join(args.obj_dir, "OpenCL-ICD-Loader", "build", "libOpenCL.so")
22+
icd_loader_lib = os.path.join(icd_loader_lib, "libOpenCL.so")
1823
else:
19-
icd_loader_lib = os.path.join(args.obj_dir, "OpenCL-ICD-Loader", "build", "OpenCL.lib")
24+
icd_loader_lib = os.path.join(icd_loader_lib, "OpenCL.lib")
25+
26+
if args.cuda:
27+
llvm_targets_to_build += ';NVPTX'
28+
llvm_enable_projects += ';libclc'
29+
libclc_targets_to_build = 'nvptx64--;nvptx64--nvidiacl'
30+
sycl_build_pi_cuda = 'ON'
31+
32+
if args.assertions:
33+
llvm_enable_assertions = 'ON'
2034

2135
install_dir = os.path.join(args.obj_dir, "install")
2236

23-
cmake_cmd = ["cmake",
24-
"-G", "Ninja",
25-
"-DCMAKE_BUILD_TYPE={}".format(args.build_type),
26-
"-DLLVM_EXTERNAL_PROJECTS=sycl;llvm-spirv;opencl-aot",
27-
"-DLLVM_EXTERNAL_SYCL_SOURCE_DIR={}".format(sycl_dir),
28-
"-DLLVM_EXTERNAL_LLVM_SPIRV_SOURCE_DIR={}".format(spirv_dir),
29-
"-DLLVM_ENABLE_PROJECTS=clang;sycl;llvm-spirv;opencl-aot",
30-
"-DOpenCL_INCLUDE_DIR={}".format(ocl_header_dir),
31-
"-DOpenCL_LIBRARY={}".format(icd_loader_lib),
32-
"-DLLVM_BUILD_TOOLS=ON",
33-
"-DSYCL_ENABLE_WERROR=ON",
34-
"-DLLVM_ENABLE_ASSERTIONS=ON",
35-
"-DCMAKE_INSTALL_PREFIX={}".format(install_dir),
36-
"-DSYCL_INCLUDE_TESTS=ON", # Explicitly include all kinds of SYCL tests.
37-
llvm_dir]
37+
cmake_cmd = [
38+
"cmake",
39+
"-G", "Ninja",
40+
"-DCMAKE_BUILD_TYPE={}".format(args.build_type),
41+
"-DLLVM_ENABLE_ASSERTIONS={}".format(llvm_enable_assertions),
42+
"-DLLVM_TARGETS_TO_BUILD={}".format(llvm_targets_to_build),
43+
"-DLLVM_EXTERNAL_PROJECTS=sycl;llvm-spirv;opencl-aot",
44+
"-DLLVM_EXTERNAL_SYCL_SOURCE_DIR={}".format(sycl_dir),
45+
"-DLLVM_EXTERNAL_LLVM_SPIRV_SOURCE_DIR={}".format(spirv_dir),
46+
"-DLLVM_ENABLE_PROJECTS={}".format(llvm_enable_projects),
47+
"-DLIBCLC_TARGETS_TO_BUILD={}".format(libclc_targets_to_build),
48+
"-DOpenCL_INCLUDE_DIR={}".format(ocl_header_dir),
49+
"-DOpenCL_LIBRARY={}".format(icd_loader_lib),
50+
"-DSYCL_BUILD_PI_CUDA={}".format(sycl_build_pi_cuda),
51+
"-DLLVM_BUILD_TOOLS=ON",
52+
"-DSYCL_ENABLE_WERROR=ON",
53+
"-DCMAKE_INSTALL_PREFIX={}".format(install_dir),
54+
"-DSYCL_INCLUDE_TESTS=ON", # Explicitly include all kinds of SYCL tests.
55+
llvm_dir
56+
]
3857

3958
print(cmake_cmd)
4059

@@ -63,6 +82,8 @@ def main():
6382
parser.add_argument("-o", "--obj-dir", metavar="OBJ_DIR", required=True, help="build directory")
6483
parser.add_argument("-t", "--build-type",
6584
metavar="BUILD_TYPE", required=True, help="build type, debug or release")
85+
parser.add_argument("--cuda", action='store_true', help="switch from OpenCL to CUDA")
86+
parser.add_argument("--assertions", action='store_true', help="build with assertions")
6687

6788
args = parser.parse_args()
6889

@@ -74,4 +95,3 @@ def main():
7495
ret = main()
7596
exit_code = 0 if ret else 1
7697
sys.exit(exit_code)
77-

sycl/CMakeLists.txt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ install(DIRECTORY ${OPENCL_INCLUDE}/CL
139139

140140
# Configure SYCL version macro
141141
set(sycl_inc_dir ${CMAKE_CURRENT_SOURCE_DIR}/include)
142+
set(sycl_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/source)
143+
set(sycl_detail_inc_dir ${CMAKE_CURRENT_SOURCE_DIR}/include/CL/sycl/detail)
144+
set(sycl_detail_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/source/detail)
142145
string(TIMESTAMP __SYCL_COMPILER_VERSION "%Y%m%d")
143146
set(version_header "${sycl_inc_dir}/CL/sycl/version.hpp")
144147
configure_file("${version_header}.in" "${version_header}")
@@ -197,7 +200,6 @@ add_subdirectory( source )
197200
# SYCL toolchain builds all components: compiler, libraries, headers, etc.
198201
add_custom_target( sycl-toolchain
199202
DEPENDS ${SYCL_RT_LIBS}
200-
pi_opencl
201203
clang
202204
clang-offload-wrapper
203205
clang-offload-bundler
@@ -256,6 +258,20 @@ set( SYCL_TOOLCHAIN_DEPLOY_COMPONENTS
256258
pi_opencl
257259
)
258260

261+
262+
if(SYCL_BUILD_PI_CUDA)
263+
# Ensure that libclc is enabled.
264+
list(FIND LLVM_ENABLE_PROJECTS libclc LIBCLC_FOUND)
265+
if( LIBCLC_FOUND EQUAL -1 )
266+
message(FATAL_ERROR
267+
"CUDA support requires adding \"libclc\" to the CMake argument \"LLVM_ENABLE_PROJECTS\"")
268+
endif()
269+
270+
add_dependencies(sycl-toolchain libspirv-builtins)
271+
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS libspirv-builtins)
272+
endif()
273+
274+
259275
# Use it as fake dependency in order to force another command(s) to execute.
260276
add_custom_command(OUTPUT __force_it
261277
COMMAND "${CMAKE_COMMAND}" -E echo

sycl/doc/GetStartedWithSYCLCompiler.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ OpenCL&trade; API to offload computations to accelerators.
1010
* [Create SYCL workspace](#create-sycl-workspace)
1111
* [Build SYCL toolchain](#build-sycl-toolchain)
1212
* [Build SYCL toolchain with libc++ library](#build-sycl-toolchain-with-libc-library)
13+
* [Build SYCL toolchain with support for NVIDIA CUDA](#build-sycl-toolchain-with-support-for-nvidia-cuda)
1314
* [Use SYCL toolchain](#use-sycl-toolchain)
1415
* [Install low level runtime](#install-low-level-runtime)
1516
* [Test SYCL toolchain](#test-sycl-toolchain)
1617
* [Run simple SYCL application](#run-simple-sycl-application)
1718
* [C++ standard](#c-standard)
1819
* [Known Issues and Limitations](#known-issues-and-limitations)
20+
* [CUDA backend limitations](#cuda-backend-limitations)
1921
* [Find More](#find-more)
2022

2123
# Prerequisites
@@ -115,6 +117,28 @@ should be used.
115117
-DSYCL_LIBCXX_LIBRARY_PATH=<path to libc++ and libc++abi libraries>
116118
```
117119

120+
## Build SYCL toolchain with support for NVIDIA CUDA
121+
122+
There is experimental support for SYCL for CUDA devices.
123+
124+
To enable support for CUDA devices, the following arguments need to be added to
125+
the CMake command when building the SYCL compiler.
126+
127+
```
128+
-DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda/ \
129+
-DLLVM_ENABLE_PROJECTS="clang;llvm-spirv;sycl;libclc"
130+
-DSYCL_BUILD_PI_CUDA=ON
131+
```
132+
133+
Enabling this flag requires an installation of
134+
[CUDA 10.1](https://developer.nvidia.com/cuda-10.1-download-archive-update2) on the system,
135+
refer to
136+
[NVIDIA CUDA Installation Guide for Linux](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html).
137+
138+
Currently, the only combination tested is Ubuntu 18.04 with CUDA 10.2 using
139+
a Titan RTX GPU (SM 71), but it should work on any GPU compatible with SM 50 or
140+
above.
141+
118142
# Use SYCL toolchain
119143

120144
## Install low level runtime
@@ -354,15 +378,32 @@ and run following command:
354378
clang++ -fsycl simple-sycl-app.cpp -o simple-sycl-app.exe
355379
```
356380

381+
When building for CUDA, use the CUDA target triple as follows:
382+
383+
```bash
384+
clang++ -fsycl -fsycl-targets=nvptx64-nvidia-cuda-sycldevice \
385+
simple-sycl-app.cpp -o simple-sycl-app-cuda.exe
386+
```
387+
357388
This `simple-sycl-app.exe` application doesn't specify SYCL device for
358389
execution, so SYCL runtime will use `default_selector` logic to select one
359390
of accelerators available in the system or SYCL host device.
360391

392+
Note: `nvptx64-nvidia-cuda-sycldevice` is usable with `-fsycl-targets`
393+
if clang was built with the cmake option `SYCL_BUILD_PI_CUDA=ON`.
394+
361395
**Linux & Windows**
362396
```bash
363397
./simple-sycl-app.exe
364398
The results are correct!
365399
```
400+
**Note**:
401+
Currently, when the application has been built with the CUDA target, the CUDA backend
402+
must be selected at runtime using the `SYCL_BE` environment variable.
403+
404+
```bash
405+
SYCL_BE=PI_CUDA ./simple-sycl-app-cuda.exe
406+
```
366407

367408
NOTE: SYCL developer can specify SYCL device for execution using device
368409
selectors (e.g. `cl::sycl::cpu_selector`, `cl::sycl::gpu_selector`,
@@ -414,7 +455,28 @@ int main() {
414455

415456
```
416457

458+
The device selector below selects an NVIDIA device only, and won't
459+
execute if there is none.
460+
461+
```c++
462+
class CUDASelector : public cl::sycl::device_selector {
463+
public:
464+
int operator()(const cl::sycl::device &Device) const override {
465+
using namespace cl::sycl::info;
466+
467+
const std::string DeviceName = Device.get_info<device::name>();
468+
const std::string DeviceVendor = Device.get_info<device::vendor>();
469+
470+
if (Device.is_gpu() && (DeviceName.find("NVIDIA") != std::string::npos)) {
471+
return 1;
472+
};
473+
return -1;
474+
}
475+
};
476+
```
477+
417478
# C++ standard
479+
418480
- Minimally support C++ standard is c++11 on Linux and c++14 on Windows.
419481

420482
# Known Issues and Limitations
@@ -426,6 +488,15 @@ int main() {
426488
- SYCL works only with OpenCL implementations supporting out-of-order queues.
427489
- On Windows linking SYCL applications with `/MTd` flag is known to cause crashes.
428490

491+
## CUDA back-end limitations
492+
493+
- Backend is only supported on Linux
494+
- The only combination tested is Ubuntu 18.04 with CUDA 10.2 using
495+
a Titan RTX GPU (SM 71), but it should work on any GPU compatible with SM 50 or
496+
above
497+
- The NVIDIA OpenCL headers conflict with the OpenCL headers required for this project
498+
and may cause compilation issues on some platforms
499+
429500
# Find More
430501

431502
SYCL 1.2.1 specification: [www.khronos.org/registry/SYCL/specs/sycl-1.2.1.pdf](https://www.khronos.org/registry/SYCL/specs/sycl-1.2.1.pdf)

0 commit comments

Comments
 (0)