Skip to content

[RNG][ARMPL] Support using OpenRNG in place of ArmPL #660

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

Merged
merged 4 commits into from
May 12, 2025
Merged
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
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -18,8 +18,8 @@ oneMath is part of the [UXL Foundation](http://www.uxlfoundation.org).
</thead>
<tbody>
<tr>
<td rowspan=15 align="center">oneMath</td>
<td rowspan=15 align="center">oneMath selector</td>
<td rowspan=16 align="center">oneMath</td>
<td rowspan=16 align="center">oneMath selector</td>
<td align="center"><a href="https://software.intel.com/en-us/oneapi/onemkl">Intel(R) oneAPI Math Kernel Library (oneMKL)</a></td>
<td align="center">x86 CPU, Intel GPU</td>
</tr>
@@ -52,6 +52,10 @@ oneMath is part of the [UXL Foundation](http://www.uxlfoundation.org).
<td align="center"><a href="https://www.arm.com/products/development-tools/server-and-hpc/allinea-studio/performance-libraries">Arm Performance Libraries</a></td>
<td align="center">aarch64 CPU</td>
</tr>
<tr>
<td align="center"><a href="https://gitlab.arm.com/libraries/openrng">Arm OpenRNG</a></td>
<td align="center">x86 and aarch64 CPU</td>
</tr>
<tr>
<td align="center"><a href="https://rocblas.readthedocs.io/en/rocm-4.5.2/"> AMD rocBLAS</a></td>
<td align="center">AMD GPU</td>
@@ -282,18 +286,28 @@ Supported compilers include:
<td align="center">Dynamic, Static</td>
</tr>
<tr>
<td rowspan=5 align="center">RNG</td>
<td align="center">x86 CPU</td>
<td rowspan=7 align="center">RNG</td>
<td rowspan=2 align="center">x86 CPU</td>
<td align="center">Intel(R) oneMKL</td>
<td align="center">Intel DPC++</br>AdaptiveCpp</td>
<td align="center">Dynamic, Static</td>
</tr>
<tr>
<td align="center">aarch64 CPU</td>
<td align="center">Arm OpenRNG</td>
<td align="center">Open DPC++</br>AdaptiveCpp</td>
<td align="center">Dynamic, Static</td>
</tr>
<tr>
<td rowspan=2 align="center">aarch64 CPU</td>
<td align="center">Arm Performance Libraries</td>
<td align="center">Open DPC++</br>AdaptiveCpp</td>
<td align="center">Dynamic, Static</td>
</tr>
<tr>
<td align="center">Arm OpenRNG</td>
<td align="center">Open DPC++</br>AdaptiveCpp</td>
<td align="center">Dynamic, Static</td>
</tr>
<tr>
<td align="center">Intel GPU</td>
<td align="center">Intel(R) oneMKL</td>
92 changes: 47 additions & 45 deletions cmake/FindARMPL.cmake
Original file line number Diff line number Diff line change
@@ -32,50 +32,52 @@ else()
endif()
find_package_handle_standard_args(ARMPL REQUIRED_VARS ARMPL_LIBRARY)

get_filename_component(ARMPL_LIB_DIR ${ARMPL_LIBRARY} DIRECTORY)
find_path(ARMPL_INCLUDE armpl.h HINTS ${ARMPL_ROOT} $ENV{ARMPLROOT} PATH_SUFFIXES include)
#cmake replaces fullpath to libarmpl by -larmpl (because SONAME is absent) and -Wl,-rpath is not enough for some compilers as hint
#so we need to add -L to compiler, otherwise we need to set LIBRARY_PATH manually when building
if(UNIX)
list(APPEND ARMPL_LINK "-Wl,-rpath,${ARMPL_LIB_DIR} -L${ARMPL_LIB_DIR}")
endif()
list(APPEND ARMPL_LINK ${ARMPL_LIBRARY})
list(APPEND ARMPL_LINK ${ARMPL_LIBRARY})
message(${ARMPL_LINK})
find_package_handle_standard_args(ARMPL REQUIRED_VARS ARMPL_INCLUDE ARMPL_LINK)
if (ARMPL_FOUND AND NOT TARGET ONEMKL::ARMPL::ARMPL)
get_filename_component(ARMPL_LIB_DIR ${ARMPL_LIBRARY} DIRECTORY)
find_path(ARMPL_INCLUDE armpl.h HINTS ${ARMPL_ROOT} $ENV{ARMPLROOT} PATH_SUFFIXES include)
#cmake replaces fullpath to libarmpl by -larmpl (because SONAME is absent) and -Wl,-rpath is not enough for some compilers as hint
#so we need to add -L to compiler, otherwise we need to set LIBRARY_PATH manually when building
if(UNIX)
list(APPEND ARMPL_LINK "-Wl$<COMMA>-rpath$<COMMA>${ARMPL_LIB_DIR} -L${ARMPL_LIB_DIR}")
endif()
list(APPEND ARMPL_LINK ${ARMPL_LIBRARY})
list(APPEND ARMPL_LINK ${ARMPL_LIBRARY})
message(${ARMPL_LINK})
find_package_handle_standard_args(ARMPL REQUIRED_VARS ARMPL_INCLUDE ARMPL_LINK)

# Check ARMPL version (only versions higher or equal to 22.0.1 are supported)
set(ARMPL_MAJOR 22)
set(ARMPL_MINOR 0)
set(ARMPL_BUILD 1)
file(WRITE ${CMAKE_BINARY_DIR}/armplversion.cpp
"#include <stdio.h>\n"
"\n"
"#include \"armpl.h\"\n"
"\n"
"int main(void) {\n"
" int major, minor, build;\n"
" char *tag;\n"
" armplversion(&major, &minor, &build, (const char **)&tag);\n"
" if (major > MAJOR) {\n"
" return 0;\n"
" }\n"
" else if (major == MAJOR && minor > MINOR) {\n"
" return 0;\n"
" }\n"
" else if (major == MAJOR && minor == MINOR && build >= BUILD) {\n"
" return 0;\n"
" }\n"
" printf(\"You are using version %d.%d.%d\\n\", major, minor, build);\n"
" return 1;\n"
"}\n")
execute_process(COMMAND ${CMAKE_CXX_COMPILER} armplversion.cpp -O0 -I${ARMPL_INCLUDE} -Wl,-rpath,${ARMPL_LIB_DIR} -larmpl -DMAJOR=${ARMPL_MAJOR} -DMINOR=${ARMPL_MINOR} -DBUILD=${ARMPL_BUILD} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
execute_process(COMMAND ./a.out WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE ARMPL_CHECK_VERSION)
execute_process(COMMAND rm ./a.out WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
execute_process(COMMAND rm armplversion.cpp WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
if(ARMPL_CHECK_VERSION)
message(FATAL_ERROR "ARMPL backend does not support ARMPL version prior to version ${ARMPL_MAJOR}.${ARMPL_MINOR}.${ARMPL_BUILD}")
endif()
# Check ARMPL version (only versions higher or equal to 22.0.1 are supported)
set(ARMPL_MAJOR 22)
set(ARMPL_MINOR 0)
set(ARMPL_BUILD 1)
file(WRITE ${CMAKE_BINARY_DIR}/armplversion.cpp
"#include <stdio.h>\n"
"\n"
"#include \"armpl.h\"\n"
"\n"
"int main(void) {\n"
" int major, minor, build;\n"
" char *tag;\n"
" armplversion(&major, &minor, &build, (const char **)&tag);\n"
" if (major > MAJOR) {\n"
" return 0;\n"
" }\n"
" else if (major == MAJOR && minor > MINOR) {\n"
" return 0;\n"
" }\n"
" else if (major == MAJOR && minor == MINOR && build >= BUILD) {\n"
" return 0;\n"
" }\n"
" printf(\"You are using version %d.%d.%d\\n\", major, minor, build);\n"
" return 1;\n"
"}\n")
execute_process(COMMAND ${CMAKE_CXX_COMPILER} armplversion.cpp -O0 -I${ARMPL_INCLUDE} -Wl,-rpath,${ARMPL_LIB_DIR} -larmpl -DMAJOR=${ARMPL_MAJOR} -DMINOR=${ARMPL_MINOR} -DBUILD=${ARMPL_BUILD} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
execute_process(COMMAND ./a.out WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE ARMPL_CHECK_VERSION)
execute_process(COMMAND rm ./a.out WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
execute_process(COMMAND rm armplversion.cpp WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
if(ARMPL_CHECK_VERSION)
message(FATAL_ERROR "ARMPL backend does not support ARMPL version prior to version ${ARMPL_MAJOR}.${ARMPL_MINOR}.${ARMPL_BUILD}")
endif()

add_library(ONEMKL::ARMPL::ARMPL UNKNOWN IMPORTED)
set_target_properties(ONEMKL::ARMPL::ARMPL PROPERTIES IMPORTED_LOCATION ${ARMPL_LIBRARY})
add_library(ONEMKL::ARMPL::ARMPL UNKNOWN IMPORTED)
set_target_properties(ONEMKL::ARMPL::ARMPL PROPERTIES IMPORTED_LOCATION ${ARMPL_LIBRARY})
endif()
42 changes: 42 additions & 0 deletions cmake/FindOpenRNG.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#==========================================================================
# Copyright (C) Codeplay Software Limited
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# For your convenience, a copy of the License has been included in this
# repository.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#=========================================================================

include_guard()

include(FindPackageHandleStandardArgs)
find_library(OpenRNG_LIBRARY
NAMES openrng
HINTS ${OpenRNG_ROOT}
PATH_SUFFIXES lib lib64)
find_path(OpenRNG_INCLUDE_DIR
NAMES openrng.h
HINTS ${OpenRNG_ROOT}
PATH_SUFFIXES include)
find_package_handle_standard_args(OpenRNG
REQUIRED_VARS
OpenRNG_LIBRARY
OpenRNG_INCLUDE_DIR
VERSION_VAR OpenRNG_VERSION)

if (OpenRNG_FOUND AND NOT TARGET ONEMATH::OpenRNG::OpenRNG)
add_library(ONEMATH::OpenRNG::OpenRNG UNKNOWN IMPORTED)
set_target_properties(ONEMATH::OpenRNG::OpenRNG PROPERTIES
IMPORTED_LOCATION ${OpenRNG_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${OpenRNG_INCLUDE_DIR})
endif()
11 changes: 11 additions & 0 deletions docs/building_the_project_with_dpcpp.rst
Original file line number Diff line number Diff line change
@@ -115,6 +115,9 @@ The most important supported build options are:
* - ENABLE_ARMPL_OMP
- True, False
- True
* - ENABLE_ARMPL_OPENRNG
- True, False
- False
* - ENABLE_ROCBLAS_BACKEND
- True, False
- False
@@ -334,6 +337,14 @@ ArmPL is to be used, ``-DARMPL_ROOT=<armpl_install_prefix>`` can be used.
Default behavior is to used the OpenMP flavor of ArmPL libraries, this can be
changed using the ``-DENABLE_ARMPL_OMP=True/False`` flag.

ArmPL bundles the OpenRNG project as its implementation of the random number
generator interface. The oneMath ArmPL backend for the RNG domain can be built
with the open-source version of OpenRNG in place of ArmPL. This build supports
both aarch64 and x86_64 CPU architectures. When building oneMath with
`-DTARGET_DOMAINS=rng -DENABLE_ARMPL_BACKEND=True` while ArmPL binaries are not
available, the build will switch to using OpenRNG by default. The use of OpenRNG
can also be forced with the option `-DENABLE_ARMPL_OPENRNG=True`.

.. _build_additional_options_dpcpp:

Additional Build Options
2 changes: 1 addition & 1 deletion examples/rng/device/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@
# If users build more than one backend (i.e. mklcpu and mklgpu, or mklcpu and CUDA), they may need to
# overwrite ONEAPI_DEVICE_SELECTOR in their environment to run on the desired backend
set(DEVICE_FILTERS "")
if(ENABLE_MKLCPU_BACKEND)
if(ENABLE_MKLCPU_BACKEND OR ENABLE_ARMPL_BACKEND)
list(APPEND DEVICE_FILTERS "opencl:cpu")
endif()
# RNG only supports mklcpu backend on Windows
2 changes: 1 addition & 1 deletion examples/rng/run_time_dispatching/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@
# If users build more than one backend (i.e. mklcpu and mklgpu, or mklcpu and CUDA), they may need to
# overwrite ONEAPI_DEVICE_SELECTOR in their environment to run on the desired backend
set(DEVICE_FILTERS "")
if(ENABLE_MKLCPU_BACKEND)
if(ENABLE_MKLCPU_BACKEND OR ENABLE_ARMPL_BACKEND)
list(APPEND DEVICE_FILTERS "opencl:cpu")
endif()
# RNG only supports mklcpu backend on Windows
5 changes: 4 additions & 1 deletion include/oneapi/math/detail/backends_table.hpp
Original file line number Diff line number Diff line change
@@ -181,7 +181,10 @@ static std::map<domain, std::map<device, std::vector<const char*>>> libraries =
{ { device::x86cpu,
{
#ifdef ONEMATH_ENABLE_MKLCPU_BACKEND
LIB_NAME("rng_mklcpu")
LIB_NAME("rng_mklcpu"),
#endif
#ifdef ONEMATH_ENABLE_ARMPL_BACKEND
LIB_NAME("rng_armpl")
#endif
} },
{ device::aarch64cpu,
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -89,6 +89,7 @@ function(generate_header_file)
set(ONEMATH_ENABLE_ROCBLAS_BACKEND ${ENABLE_ROCBLAS_BACKEND})
set(ONEMATH_ENABLE_NETLIB_BACKEND ${ENABLE_NETLIB_BACKEND})
set(ONEMATH_ENABLE_ARMPL_BACKEND ${ENABLE_ARMPL_BACKEND})
set(ONEMATH_ENABLE_ARMPL_OPENRNG ${ENABLE_ARMPL_OPENRNG})
set(ONEMATH_ENABLE_GENERIC_BLAS_BACKEND ${ENABLE_GENERIC_BLAS_BACKEND})
set(ONEMATH_ENABLE_CURAND_BACKEND ${ENABLE_CURAND_BACKEND})
set(ONEMATH_ENABLE_ROCRAND_BACKEND ${ENABLE_ROCRAND_BACKEND})
1 change: 1 addition & 0 deletions src/config.hpp.in
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@
#define ONEMATH_CONFIG_H

#cmakedefine ONEMATH_ENABLE_ARMPL_BACKEND
#cmakedefine ONEMATH_ENABLE_ARMPL_OPENRNG
#cmakedefine ONEMATH_ENABLE_CUBLAS_BACKEND
#cmakedefine ONEMATH_ENABLE_CUFFT_BACKEND
#cmakedefine ONEMATH_ENABLE_CURAND_BACKEND
19 changes: 17 additions & 2 deletions src/rng/backends/armpl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -21,7 +21,22 @@
set(LIB_NAME onemath_rng_armpl)
set(LIB_OBJ ${LIB_NAME}_obj)

find_package(ARMPL REQUIRED)
option(ENABLE_ARMPL_OPENRNG "Use the open-source OpenRNG library for ARMPL RNG backend" OFF)

if (ENABLE_ARMPL_OPENRNG)
find_package(OpenRNG REQUIRED)
else()
find_package(ARMPL)
if (NOT ARMPL_FOUND)
message(STATUS "ARMPL not found, trying OpenRNG instead")
set(ENABLE_ARMPL_OPENRNG ON CACHE BOOL "Use the open-source OpenRNG library for ARMPL RNG backend" FORCE)
find_package(OpenRNG)
endif()
endif()

if (NOT ARMPL_FOUND AND NOT OpenRNG_FOUND)
message(FATAL_ERROR "Could NOT find ARMPL or OpenRNG")
endif()

set(SOURCES armpl_common.hpp
philox4x32x10.cpp
@@ -45,7 +60,7 @@ if (USE_ADD_SYCL_TO_TARGET_INTEGRATION)
add_sycl_to_target(TARGET ${LIB_OBJ} SOURCES ${SOURCES})
endif()

target_link_libraries(${LIB_OBJ} PUBLIC ONEMATH::SYCL::SYCL ${ARMPL_LINK})
target_link_libraries(${LIB_OBJ} PUBLIC ONEMATH::SYCL::SYCL $<IF:$<BOOL:${ENABLE_ARMPL_OPENRNG}>,ONEMATH::OpenRNG::OpenRNG,${ARMPL_LINK}>)

set_target_properties(${LIB_OBJ} PROPERTIES
POSITION_INDEPENDENT_CODE ON
11 changes: 11 additions & 0 deletions src/rng/backends/armpl/armpl_common.hpp
Original file line number Diff line number Diff line change
@@ -31,13 +31,23 @@
#define __fp16 _Float16
#define INTEGER64 1

#ifdef ONEMATH_ENABLE_ARMPL_OPENRNG
#include "openrng.h"
#else
#include "armpl.h"
#endif

namespace oneapi {
namespace math {
namespace rng {
namespace armpl {

#ifdef ONEMATH_ENABLE_ARMPL_OPENRNG
// There is no version check API in OpenRNG
inline int check_armpl_version(int, int, int, const char*) {
return 0;
}
#else
inline int check_armpl_version(armpl_int_t major_req, armpl_int_t minor_req, armpl_int_t build_req,
const char* message) {
armpl_int_t major, minor, build;
@@ -54,6 +64,7 @@ inline int check_armpl_version(armpl_int_t major_req, armpl_int_t minor_req, arm
}
throw oneapi::math::unimplemented("rng", "version support", message);
}
#endif

template <typename K, typename H, typename F>
static inline auto host_task_internal(H& cgh, F f, int) -> decltype(cgh.host_task(f)) {
Loading
Oops, something went wrong.