diff --git a/README.md b/README.md index 7c2766c1e..c1624897f 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ oneMath is part of the [UXL Foundation](http://www.uxlfoundation.org). - oneMath - oneMath selector + oneMath + oneMath selector Intel(R) oneAPI Math Kernel Library (oneMKL) x86 CPU, Intel GPU @@ -52,6 +52,10 @@ oneMath is part of the [UXL Foundation](http://www.uxlfoundation.org). Arm Performance Libraries aarch64 CPU + + Arm OpenRNG + x86 and aarch64 CPU + AMD rocBLAS AMD GPU @@ -282,18 +286,28 @@ Supported compilers include: Dynamic, Static - RNG - x86 CPU + RNG + x86 CPU Intel(R) oneMKL Intel DPC++
AdaptiveCpp Dynamic, Static - aarch64 CPU + Arm OpenRNG + Open DPC++
AdaptiveCpp + Dynamic, Static + + + aarch64 CPU Arm Performance Libraries Open DPC++
AdaptiveCpp Dynamic, Static + + Arm OpenRNG + Open DPC++
AdaptiveCpp + Dynamic, Static + Intel GPU Intel(R) oneMKL diff --git a/cmake/FindARMPL.cmake b/cmake/FindARMPL.cmake index 2572eeb0a..911842314 100644 --- a/cmake/FindARMPL.cmake +++ b/cmake/FindARMPL.cmake @@ -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$-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) -# 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 \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 \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() diff --git a/cmake/FindOpenRNG.cmake b/cmake/FindOpenRNG.cmake new file mode 100644 index 000000000..940571d6a --- /dev/null +++ b/cmake/FindOpenRNG.cmake @@ -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() diff --git a/docs/building_the_project_with_dpcpp.rst b/docs/building_the_project_with_dpcpp.rst index 2f4e9b67d..3be8bec20 100644 --- a/docs/building_the_project_with_dpcpp.rst +++ b/docs/building_the_project_with_dpcpp.rst @@ -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=`` 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 diff --git a/examples/rng/device/CMakeLists.txt b/examples/rng/device/CMakeLists.txt index 14e9713b4..a2781ac8d 100644 --- a/examples/rng/device/CMakeLists.txt +++ b/examples/rng/device/CMakeLists.txt @@ -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 diff --git a/examples/rng/run_time_dispatching/CMakeLists.txt b/examples/rng/run_time_dispatching/CMakeLists.txt index f1de7074e..78f37d1df 100644 --- a/examples/rng/run_time_dispatching/CMakeLists.txt +++ b/examples/rng/run_time_dispatching/CMakeLists.txt @@ -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 diff --git a/include/oneapi/math/detail/backends_table.hpp b/include/oneapi/math/detail/backends_table.hpp index 832d47005..1af3487db 100644 --- a/include/oneapi/math/detail/backends_table.hpp +++ b/include/oneapi/math/detail/backends_table.hpp @@ -181,7 +181,10 @@ static std::map>> 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, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 57b65c0d5..8b849720b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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}) diff --git a/src/config.hpp.in b/src/config.hpp.in index f7a6c1df5..9b737853e 100644 --- a/src/config.hpp.in +++ b/src/config.hpp.in @@ -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 diff --git a/src/rng/backends/armpl/CMakeLists.txt b/src/rng/backends/armpl/CMakeLists.txt index a3280ddc9..6394c7d2d 100644 --- a/src/rng/backends/armpl/CMakeLists.txt +++ b/src/rng/backends/armpl/CMakeLists.txt @@ -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 $,ONEMATH::OpenRNG::OpenRNG,${ARMPL_LINK}>) set_target_properties(${LIB_OBJ} PROPERTIES POSITION_INDEPENDENT_CODE ON diff --git a/src/rng/backends/armpl/armpl_common.hpp b/src/rng/backends/armpl/armpl_common.hpp index c3028f702..6a08deca0 100644 --- a/src/rng/backends/armpl/armpl_common.hpp +++ b/src/rng/backends/armpl/armpl_common.hpp @@ -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 static inline auto host_task_internal(H& cgh, F f, int) -> decltype(cgh.host_task(f)) {