Skip to content

Commit b90d4c7

Browse files
vrpascuzzimkrainiuk
authored andcommitted
Add cuRAND support (uxlfoundation#75)
This commit adds a cuRAND backend to oneMKL. The implementation follows closely to that of the existing x86 and Intel GPU, with the following limitations: (1) the cuRAND Host API does not support copy-construction for generators; (2) cuRAND does not support initializer lists for seeding generators; (3) cuRAND uses inverse cumulative distribution function (ICDF) methods only for quasi-random number generators; and (4) cuRAND does not support custom ranges on the output sequence of random numbers. Functionality requiring any of 1-3 above are not implemented here but could be added at a later time. Additional kernels were added to support (4).
1 parent 9f81245 commit b90d4c7

File tree

18 files changed

+2269
-23
lines changed

18 files changed

+2269
-23
lines changed

CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ if(ENABLE_MKLCPU_BACKEND)
4747
option(ENABLE_MKLCPU_THREAD_TBB "" ON)
4848
endif()
4949
option(ENABLE_CUBLAS_BACKEND "" OFF)
50+
option(ENABLE_CURAND_BACKEND "" OFF)
5051
option(ENABLE_NETLIB_BACKEND "" OFF)
5152

5253
## Domains
@@ -58,7 +59,8 @@ if(ENABLE_MKLCPU_BACKEND
5859
list(APPEND DOMAINS_LIST "blas")
5960
endif()
6061
if(ENABLE_MKLCPU_BACKEND
61-
OR ENABLE_MKLGPU_BACKEND)
62+
OR ENABLE_MKLGPU_BACKEND
63+
OR ENABLE_CURAND_BACKEND)
6264
list(APPEND DOMAINS_LIST "rng")
6365
endif()
6466

cmake/FindCompiler.cmake

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,25 @@ if(is_dpcpp)
3131

3232
add_library(ONEMKL::SYCL::SYCL INTERFACE IMPORTED)
3333
if(UNIX)
34-
set_target_properties(ONEMKL::SYCL::SYCL PROPERTIES
35-
INTERFACE_COMPILE_OPTIONS "-fsycl"
36-
INTERFACE_LINK_OPTIONS "-fsycl"
37-
INTERFACE_LINK_LIBRARIES ${SYCL_LIBRARY})
34+
set(UNIX_INTERFACE_COMPILE_OPTIONS -fsycl)
35+
set(UNIX_INTERFACE_LINK_OPTIONS -fsycl)
36+
if(ENABLE_CURAND_BACKEND)
37+
list(APPEND UNIX_INTERFACE_COMPILE_OPTIONS
38+
-fsycl-targets=nvptx64-nvidia-cuda-sycldevice -fsycl-unnamed-lambda)
39+
list(APPEND UNIX_INTERFACE_LINK_OPTIONS
40+
-fsycl-targets=nvptx64-nvidia-cuda-sycldevice)
41+
endif()
42+
if(ENABLE_CURAND_BACKEND)
43+
set_target_properties(ONEMKL::SYCL::SYCL PROPERTIES
44+
INTERFACE_COMPILE_OPTIONS "${UNIX_INTERFACE_COMPILE_OPTIONS}"
45+
INTERFACE_LINK_OPTIONS "${UNIX_INTERFACE_LINK_OPTIONS}"
46+
INTERFACE_LINK_LIBRARIES ${SYCL_LIBRARY})
47+
else()
48+
set_target_properties(ONEMKL::SYCL::SYCL PROPERTIES
49+
INTERFACE_COMPILE_OPTIONS "-fsycl"
50+
INTERFACE_LINK_OPTIONS "-fsycl"
51+
INTERFACE_LINK_LIBRARIES ${SYCL_LIBRARY})
52+
endif()
3853
else()
3954
set_target_properties(ONEMKL::SYCL::SYCL PROPERTIES
4055
INTERFACE_COMPILE_OPTIONS "-fsycl"

cmake/FindcuRAND.cmake

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#===============================================================================
2+
# Copyright 2021 Intel Corporation
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing,
11+
# software distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions
14+
# and limitations under the License.
15+
#
16+
#
17+
# SPDX-License-Identifier: Apache-2.0
18+
#===============================================================================
19+
20+
find_package(CUDA 10.0 REQUIRED)
21+
get_filename_component(SYCL_BINARY_DIR ${CMAKE_CXX_COMPILER} DIRECTORY)
22+
# the OpenCL include file from cuda is opencl 1.1 and it is not compatible with DPC++
23+
# the OpenCL include headers 1.2 onward is required. This is used to bypass NVIDIA OpenCL headers
24+
find_path(OPENCL_INCLUDE_DIR CL/cl.h OpenCL/cl.h
25+
HINTS
26+
${OPENCL_INCLUDE_DIR}
27+
${SYCL_BINARY_DIR}/../include/sycl/
28+
)
29+
# this is work around to avoid duplication half creation in both cuda and SYCL
30+
add_compile_definitions(CUDA_NO_HALF)
31+
32+
find_package(Threads REQUIRED)
33+
34+
include(FindPackageHandleStandardArgs)
35+
find_package_handle_standard_args(cuRAND
36+
REQUIRED_VARS
37+
CUDA_TOOLKIT_INCLUDE
38+
CUDA_curand_LIBRARY
39+
CUDA_LIBRARIES
40+
CUDA_CUDA_LIBRARY
41+
OPENCL_INCLUDE_DIR
42+
)
43+
if(NOT TARGET ONEMKL::cuRAND::cuRAND)
44+
add_library(ONEMKL::cuRAND::cuRAND SHARED IMPORTED)
45+
set_target_properties(ONEMKL::cuRAND::cuRAND PROPERTIES
46+
IMPORTED_LOCATION ${CUDA_curand_LIBRARY}
47+
INTERFACE_INCLUDE_DIRECTORIES "${OPENCL_INCLUDE_DIR};${CUDA_TOOLKIT_INCLUDE}"
48+
INTERFACE_LINK_LIBRARIES "Threads::Threads;${CUDA_CUDA_LIBRARY};${CUDA_LIBRARIES}"
49+
)
50+
51+
endif()

include/oneapi/mkl/detail/backends.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@
2626
namespace oneapi {
2727
namespace mkl {
2828

29-
enum class backend { mklcpu, mklgpu, cublas, netlib, unsupported };
29+
enum class backend { mklcpu, mklgpu, cublas, curand, netlib, unsupported };
3030

3131
typedef std::map<backend, std::string> backendmap;
3232

33-
static backendmap backend_map = { { backend::mklcpu, "mklcpu" },
34-
{ backend::mklgpu, "mklgpu" },
35-
{ backend::cublas, "cublas" },
36-
{ backend::netlib, "netlib" },
37-
{ backend::unsupported, "unsupported" } };
33+
static backendmap backend_map = {
34+
{ backend::mklcpu, "mklcpu" }, { backend::mklgpu, "mklgpu" },
35+
{ backend::cublas, "cublas" }, { backend::curand, "curand" },
36+
{ backend::netlib, "netlib" }, { backend::unsupported, "unsupported" }
37+
};
3838

3939
} //namespace mkl
4040
} //namespace oneapi

include/oneapi/mkl/detail/backends_table.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ static std::map<domain, std::map<device, std::vector<const char*>>> libraries =
7474
{
7575
#ifdef ENABLE_MKLGPU_BACKEND
7676
LIB_NAME("rng_mklgpu")
77+
#endif
78+
} },
79+
{ device::nvidiagpu,
80+
{
81+
#ifdef ENABLE_CURAND_BACKEND
82+
LIB_NAME("rng_curand")
7783
#endif
7884
} } } }
7985
};
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*******************************************************************************
2+
* Copyright 2020 Intel Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing,
11+
* software distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions
14+
* and limitations under the License.
15+
*
16+
*
17+
* SPDX-License-Identifier: Apache-2.0
18+
*******************************************************************************/
19+
20+
#ifndef _ONEMKL_RNG_CURAND_HPP_
21+
#define _ONEMKL_RNG_CURAND_HPP_
22+
23+
#include <cstdint>
24+
#include <CL/sycl.hpp>
25+
26+
#include "oneapi/mkl/detail/export.hpp"
27+
#include "oneapi/mkl/rng/detail/engine_impl.hpp"
28+
29+
namespace oneapi {
30+
namespace mkl {
31+
namespace rng {
32+
namespace curand {
33+
34+
ONEMKL_EXPORT oneapi::mkl::rng::detail::engine_impl* create_philox4x32x10(cl::sycl::queue queue,
35+
std::uint64_t seed);
36+
37+
ONEMKL_EXPORT oneapi::mkl::rng::detail::engine_impl* create_philox4x32x10(
38+
cl::sycl::queue queue, std::initializer_list<std::uint64_t> seed);
39+
40+
ONEMKL_EXPORT oneapi::mkl::rng::detail::engine_impl* create_mrg32k3a(cl::sycl::queue queue,
41+
std::uint32_t seed);
42+
43+
ONEMKL_EXPORT oneapi::mkl::rng::detail::engine_impl* create_mrg32k3a(
44+
cl::sycl::queue queue, std::initializer_list<std::uint32_t> seed);
45+
46+
} // namespace curand
47+
} // namespace rng
48+
} // namespace mkl
49+
} // namespace oneapi
50+
51+
#endif //_ONEMKL_RNG_CURAND_HPP_

include/oneapi/mkl/rng/engines.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
#ifdef ENABLE_MKLGPU_BACKEND
3838
#include "oneapi/mkl/rng/detail/mklgpu/onemkl_rng_mklgpu.hpp"
3939
#endif
40+
#ifdef ENABLE_CURAND_BACKEND
41+
#include "oneapi/mkl/rng/detail/curand/onemkl_rng_curand.hpp"
42+
#endif
4043

4144
namespace oneapi {
4245
namespace mkl {
@@ -76,6 +79,15 @@ class philox4x32x10 {
7679
: pimpl_(mklgpu::create_philox4x32x10(selector.get_queue(), seed)) {}
7780
#endif
7881

82+
#ifdef ENABLE_CURAND_BACKEND
83+
philox4x32x10(backend_selector<backend::curand> selector, std::uint64_t seed = default_seed)
84+
: pimpl_(curand::create_philox4x32x10(selector.get_queue(), seed)) {}
85+
86+
philox4x32x10(backend_selector<backend::curand> selector,
87+
std::initializer_list<std::uint64_t> seed)
88+
: pimpl_(curand::create_philox4x32x10(selector.get_queue(), seed)) {}
89+
#endif
90+
7991
philox4x32x10(const philox4x32x10& other) {
8092
pimpl_.reset(other.pimpl_.get()->copy_state());
8193
}
@@ -149,6 +161,14 @@ class mrg32k3a {
149161
: pimpl_(mklgpu::create_mrg32k3a(selector.get_queue(), seed)) {}
150162
#endif
151163

164+
#ifdef ENABLE_CURAND_BACKEND
165+
mrg32k3a(backend_selector<backend::curand> selector, std::uint32_t seed = default_seed)
166+
: pimpl_(curand::create_mrg32k3a(selector.get_queue(), seed)) {}
167+
168+
mrg32k3a(backend_selector<backend::curand> selector, std::initializer_list<std::uint32_t> seed)
169+
: pimpl_(curand::create_mrg32k3a(selector.get_queue(), seed)) {}
170+
#endif
171+
152172
mrg32k3a(const mrg32k3a& other) {
153173
pimpl_.reset(other.pimpl_.get()->copy_state());
154174
}

src/config.hpp.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define ONEMKL_CONFIG_H
2222

2323
#cmakedefine ENABLE_CUBLAS_BACKEND
24+
#cmakedefine ENABLE_CURAND_BACKEND
2425
#cmakedefine ENABLE_MKLCPU_BACKEND
2526
#cmakedefine ENABLE_MKLGPU_BACKEND
2627
#cmakedefine ENABLE_NETLIB_BACKEND

src/rng/backends/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,7 @@ endif()
2424
if(ENABLE_MKLGPU_BACKEND)
2525
add_subdirectory(mklgpu)
2626
endif()
27+
28+
if(ENABLE_CURAND_BACKEND AND UNIX)
29+
add_subdirectory(curand)
30+
endif()
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#===============================================================================
2+
# Copyright 2021 Intel Corporation
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing,
11+
# software distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions
14+
# and limitations under the License.
15+
#
16+
#
17+
# SPDX-License-Identifier: Apache-2.0
18+
#===============================================================================
19+
20+
set(LIB_NAME onemkl_rng_curand)
21+
set(LIB_OBJ ${LIB_NAME}_obj)
22+
find_package(cuRAND REQUIRED)
23+
24+
add_library(${LIB_NAME})
25+
add_library(${LIB_OBJ} OBJECT
26+
philox4x32x10.cpp
27+
mrg32k3a.cpp
28+
$<$<BOOL:${BUILD_SHARED_LIBS}>: mkl_rng_curand_wrappers.cpp>
29+
)
30+
31+
target_include_directories(${LIB_OBJ}
32+
PRIVATE ${PROJECT_SOURCE_DIR}/include
33+
${PROJECT_SOURCE_DIR}/src
34+
${CMAKE_BINARY_DIR}/bin
35+
${MKL_INCLUDE}
36+
)
37+
38+
target_link_libraries(${LIB_OBJ} PUBLIC ONEMKL::SYCL::SYCL ONEMKL::cuRAND::cuRAND)
39+
target_compile_features(${LIB_OBJ} PUBLIC cxx_std_11)
40+
set_target_properties(${LIB_OBJ} PROPERTIES
41+
POSITION_INDEPENDENT_CODE ON
42+
)
43+
44+
target_link_libraries(${LIB_NAME} PUBLIC ${LIB_OBJ})
45+
46+
# Add major version to the library
47+
set_target_properties(${LIB_NAME} PROPERTIES
48+
SOVERSION ${PROJECT_VERSION_MAJOR}
49+
)
50+
51+
# Add dependencies rpath to the library
52+
list(APPEND CMAKE_BUILD_RPATH $<TARGET_FILE_DIR:${LIB_NAME}>)
53+
54+
# Add the library to install package
55+
install(TARGETS ${LIB_OBJ} EXPORT oneMKLTargets)
56+
install(TARGETS ${LIB_NAME} EXPORT oneMKLTargets
57+
RUNTIME DESTINATION bin
58+
ARCHIVE DESTINATION lib
59+
LIBRARY DESTINATION lib
60+
)

0 commit comments

Comments
 (0)