├── include └── PRNG │ ├── MWC64X.hpp │ ├── TinyMT.hpp │ └── concepts │ ├── SeedSequence.hpp │ ├── InputIterator.hpp │ └── Prelude.hpp ├── .vsts.yaml ├── azure-pipelines.yml ├── examples ├── CMakeLists.txt ├── RandomSeed.cpp └── SYCL-RandomSeed.cpp ├── CMakeLists.txt ├── LICENSE.md ├── README.md └── cmake └── Modules └── FindComputeCpp.cmake /include/PRNG/MWC64X.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wigner-GPU-Lab/SYCL-PRNG/HEAD/include/PRNG/MWC64X.hpp -------------------------------------------------------------------------------- /include/PRNG/TinyMT.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wigner-GPU-Lab/SYCL-PRNG/HEAD/include/PRNG/TinyMT.hpp -------------------------------------------------------------------------------- /.vsts.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - repo: self 3 | queue: 4 | name: Hosted VS2017 5 | demands: cmake 6 | steps: 7 | - task: CMake@1 8 | displayName: 'CMake ' 9 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # https://aka.ms/yaml 2 | 3 | pool: 4 | name: 'Wigner GPU-Lab' 5 | 6 | steps: 7 | - script: | 8 | export COMPUTECPP_DIR=/opt/Codeplay/ComputeCpp/latest 9 | cmake -G Ninja -D CMAKE_BUILD_TYPE=Release -B$(Build.StagingDirectory) -H$(Build.SourcesDirectory) 10 | displayName: 'CMake configuration' 11 | 12 | - script: cmake --build $(Build.StagingDirectory) 13 | displayName: 'CMake build' 14 | 15 | - script: | 16 | echo Add other tasks to build, test, and deploy your project. 17 | echo See https://aka.ms/yaml 18 | displayName: 'Run a multi-line script' 19 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # C++11 examples 2 | #foreach (Example IN ITEMS RandomSeed) 3 | # 4 | # add_executable (${Example} ${Example}.cpp) 5 | # 6 | # target_include_directories (${Example} PRIVATE ${PROJECT_SOURCE_DIR}/include) 7 | # 8 | # set_target_properties (${Example} PROPERTIES CXX_STANDARD 11 9 | # CXX_STANDARD_REQUIRED ON 10 | # CXX_EXTENSIONS OFF) 11 | #endforeach (Example) 12 | 13 | # SYCL C++14 examples 14 | foreach (Example IN ITEMS RandomSeed 15 | SYCL-RandomSeed) 16 | 17 | add_executable (${Example} ${Example}.cpp) 18 | 19 | target_include_directories (${Example} PRIVATE ${PROJECT_SOURCE_DIR}/include) 20 | 21 | set_target_properties (${Example} PROPERTIES CXX_STANDARD 14 22 | CXX_STANDARD_REQUIRED ON 23 | CXX_EXTENSIONS OFF) 24 | 25 | add_sycl_to_target(TARGET ${Example} 26 | SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/${Example}.cpp) 27 | 28 | endforeach (Example) -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Top level CMakeLists.txt file for the SYCL-RNG repo 4 | # Hacker: Mate Ferenc Nagy-Egri 5 | # Last modified: 2018.08.01. (yyyy.mm.dd.) 6 | # 7 | ############################################################################### 8 | 9 | ######################### 10 | # # 11 | # CMake # 12 | # # 13 | ######################### 14 | 15 | # The minimum version of 'cmake' necessary to build this project 16 | cmake_minimum_required (VERSION 3.2.2) 17 | 18 | # The project name and version, release numbers 19 | project (SYCL-PRNG LANGUAGES CXX 20 | VERSION 0.0.1) 21 | 22 | # Behavioural options for the project 23 | option (BUILD_EXAMPLES "Build example applications" ON) 24 | option (USE_SYCL "Turn on SYCL API support" ON) 25 | 26 | # Find dependencies 27 | if (USE_SYCL) 28 | set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules) 29 | find_package(ComputeCpp) 30 | endif (USE_SYCL) 31 | 32 | # Recurse into target directories 33 | if (BUILD_EXAMPLES) 34 | add_subdirectory (examples) 35 | endif (BUILD_EXAMPLES) -------------------------------------------------------------------------------- /include/PRNG/concepts/SeedSequence.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // SYCL-PRNG includes 4 | #include 5 | #include 6 | 7 | // Standard C++ includes 8 | #include // std::uint_least32_t 9 | #include // std::size_t 10 | 11 | namespace prng 12 | { 13 | namespace meta 14 | { 15 | namespace member 16 | { 17 | // TODO: return types and const qualifiers not really tested 18 | template using generate = decltype(std::declval().generate(std::declval(), std::declval())); 19 | template using size = decltype(std::declval().size()); 20 | } 21 | } 22 | 23 | namespace concepts 24 | { 25 | template 26 | constexpr bool SeedSequence = 27 | meta::require< 28 | //meta::exists, 29 | //meta::either< 30 | // meta::identical_to, 31 | // meta::identical_to 32 | //>, 33 | DefaultConstructible//, 34 | //Constructible, std::istreambuf_iterator>, 35 | //Constructible>, 36 | //meta::identical_to, void>, 37 | //meta::identical_to, std::size_t> 38 | >; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2011, David Thomas 4 | Copyright (c) 2011, 2013 Mutsuo Saito, Makoto Matsumoto, 5 | Hiroshima University and The University of Tokyo. 6 | Copyright (c) 2018, Wigner RCP GPU-Laboratory 7 | All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without 10 | modification, are permitted provided that the following conditions are met: 11 | 12 | * Redistributions of source code must retain the above copyright notice, this 13 | list of conditions and the following disclaimer. 14 | 15 | * Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | * Neither the name of the copyright holder nor the names of its 20 | contributors may be used to endorse or promote products derived from 21 | this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /include/PRNG/concepts/InputIterator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // SYCL-PRNG includes 4 | #include // LOTS 5 | 6 | // Standard C++ includes 7 | #include // std::input_iterator_tag 8 | 9 | 10 | namespace prng 11 | { 12 | namespace meta 13 | { 14 | namespace alias 15 | { 16 | template 17 | using iterator_category = typename std::iterator_traits::iterator_category; 18 | } 19 | 20 | } 21 | 22 | namespace concepts 23 | { 24 | template 25 | constexpr bool Iterator = 26 | meta::require< 27 | CopyConstructible, 28 | CopyAssignable, 29 | Destructible, 30 | Swappable, 31 | meta::exists, 32 | meta::exists, 33 | meta::exists 34 | >; 35 | 36 | template 37 | constexpr bool InputIterator = 38 | Pointer or 39 | meta::require< 40 | EqualityComparable, 41 | Iterator, 42 | meta::exists, 43 | meta::exists, 44 | meta::either< 45 | meta::identical_to, meta::ops::dereference, T>, 46 | meta::converts_to, meta::ops::dereference, T> 47 | >, 48 | meta::identical_to, meta::ops::arrow, T>, 49 | meta::converts_to, meta::ops::dereference, T&>, 50 | meta::converts_to 51 | >; 52 | 53 | } // namespace concepts 54 | } 55 | -------------------------------------------------------------------------------- /examples/RandomSeed.cpp: -------------------------------------------------------------------------------- 1 | // SYCL-PRNG includes 2 | #include 3 | #include 4 | 5 | // Standard C++ includes 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | int main() 15 | { 16 | static_assert(std::is_standard_layout::value, "TinyMT 64 is not standard layout."); 17 | static_assert(std::is_standard_layout::value, "TinyMT 32 is not standard layout."); 18 | static_assert(std::is_standard_layout::value, "MWC64X 32 is not standard layout."); 19 | 20 | std::vector tmt64{ prng::tinymt_64{} }; // default CTOR 21 | std::vector tmt32{ prng::tinymt_32{} }; // default CTOR 22 | std::vector mwc32{ prng::mwc64x_32{} }; // default CTOR 23 | 24 | { 25 | std::random_device rd; 26 | std::generate_n(std::back_inserter(tmt64), 10, [&]() { return prng::tinymt_64{ rd() }; }); // random seeding 27 | std::generate_n(std::back_inserter(tmt32), 10, [&]() { return prng::tinymt_32{ rd() }; }); // random seeding 28 | std::generate_n(std::back_inserter(mwc32), 10, [&]() { return prng::mwc64x_32{ rd() }; }); // random seeding 29 | } 30 | 31 | std::vector tmt64_ref( tmt64.cbegin(), tmt64.cend() ); // copy CTOR 32 | std::vector tmt32_ref( tmt32.cbegin(), tmt32.cend() ); // copy CTOR 33 | std::vector mwc32_ref( mwc32.cbegin(), mwc32.cend() ); // copy CTOR 34 | 35 | auto skip_function_discard = [](auto prng, const std::int64_t& distance) // copy CTOR 36 | { 37 | prng.discard(distance); // discard 38 | return prng; 39 | }; 40 | auto next_stepping_discard = [](auto prng, const std::int64_t& distance) // copy CTOR 41 | { 42 | for (std::int64_t i = 0; i < distance; ++i) prng(); // operator() 43 | return prng; 44 | }; 45 | 46 | std::default_random_engine re; 47 | std::uniform_int_distribution dist{ 9'000, 11'000 }; 48 | 49 | std::vector distances; 50 | std::generate_n(std::back_inserter(distances), tmt64.size(), [&]() { return dist(re); }); 51 | 52 | auto match_skip_vs_step = [&](auto& skip_seq, auto& step_seq) 53 | { 54 | std::transform(skip_seq.cbegin(), skip_seq.cend(), distances.cbegin(), skip_seq.begin(), skip_function_discard); 55 | std::transform(step_seq.cbegin(), step_seq.cend(), distances.cbegin(), step_seq.begin(), next_stepping_discard); 56 | 57 | auto iters = std::mismatch(skip_seq.cbegin(), skip_seq.cend(), step_seq.cbegin()); // operator== 58 | 59 | if (iters.first != skip_seq.cend() || 60 | iters.second != step_seq.cend()) 61 | { 62 | std::cerr << "Skip vs. step differs for " << 63 | typeid(skip_seq.at(0)).name() << 64 | " when discarding " << 65 | distances.at(std::distance(skip_seq.cbegin(), iters.first)) << 66 | " elements." << 67 | std::endl; 68 | 69 | std::exit(EXIT_FAILURE); 70 | } 71 | }; 72 | 73 | match_skip_vs_step(tmt64, tmt64_ref); 74 | match_skip_vs_step(tmt32, tmt32_ref); 75 | match_skip_vs_step(mwc32, mwc32_ref); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SYCL-PRNG Readme !! PRE-ALPHA !! 2 | 3 | ## Introduction 4 | 5 | This is the README document for SYCL-PRNG, a header-only library implementing various standard layout pseudo random number generators to be used with SYCL. The generators satisfy the concepts defined by the STL and integrate with `#include ` as well. 6 | 7 | The library provides the following PRNGs under the [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause): 8 | 9 | - Tiny Mersenne Twister, both the 32/64-bit word derivates. Code is largely based on the original code which can be found in [this repository](https://github.com/MersenneTwister-Lab/TinyMT). 10 | - MWC64X, a mostly 32-bit word implementation. Code is largely based on the original code which can be found [here](http://cas.ee.ic.ac.uk/people/dt10/research/rngs-gpu-mwc64x.html). 11 | 12 | ## Contents 13 | 14 | * bench/ 15 | - Some benchmarks, used to track the performance of SYCL-PRNG. 16 | * cmake/ 17 | - Contains helper files and functions for downloading dependencies and performing common tasks (like adding tests, libraries etc.). 18 | * CMakeLists.txt 19 | - The root CMakeLists.txt file, refer to this when building SYCL-PRNG. 20 | * CONTRIBUTING.md 21 | - Information about how to contribute bug reports, code, or other works to this project. 22 | * include/ 23 | - The directory under which the public interface is stored. 24 | * LICENSE 25 | - The license is still to be decided upon. 26 | * README.md 27 | - This readme file. 28 | * examples/ 29 | - Example programs to get inspiration from how to use the library. 30 | * test/ 31 | - All tests are bundled in this folder and are the mark of correctness when doing pre-merge tests. 32 | 33 | ## Requirements 34 | 35 | * SYCL-PRNG is tested against most recent releases of ComputeCpp and triSYCL. It is likely however, that it will be compatible with multiple versions concurrently as the SYCL interface is fixed. 36 | 37 | * OpenCL 1.2-capable hardware and drivers with SPIR 1.2/SPIR-V/PTX support 38 | 39 | * A C++-11 compiler and STL implementation 40 | 41 | * CMake version 3.2.2 42 | 43 | ## Setup 44 | 45 | SYCL-PRNG uses CMake as its build system and unit test framework. SYCL-PRNG has no dependencies, other than a SYCL SDK, which the library tries to find on it's own via designated CMake features. By default, the tests and library will be built, but not the benchmarks. 46 | 47 | Please note, that if your development environment is not set up to find your SYCL SDK without manual intervention, then using: 48 | 49 | - FindComputeCpp.cmake requires the variable `COMPUTECPP_PACKAGE_ROOT_DIR` to be set when configuring. It should point to the folder where bin/, lib/ etc. are. This should be the only argument that is mandatory, everything else should be optional. The default build type is Release, though this can be overridden. 50 | 51 | ## Troubleshooting 52 | 53 | The master branch of SYCL-PRNG should always compile and tests should always pass on our supported platforms. Ideally we should be writing portable, standards-compliant SYCL code, and as such it should pass tests on all compatible OpenCL hardware. See CONTRIBUTING.md for details about creating bug reports for this project. 54 | 55 | ## Maintainers 56 | 57 | This project is written and maintained by the 58 | [Wigner GPU-Laboratory](http://gpu.wigner.mta.hu/en). 59 | Please get in touch if you have any issues or questions - you can reach us at 60 | [gpu@wigner.mta.hu](mailto:gpu@wigner.mta.hu). 61 | 62 | ## Contributions 63 | 64 | Please see the file CONTRIBUTIONS.md for further details if you would like to contribute code, build systems, bug fixes or similar. -------------------------------------------------------------------------------- /include/PRNG/concepts/Prelude.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _WIN32 4 | #define not ! 5 | #define and && 6 | #define or || 7 | #endif 8 | 9 | // Standard C++ includes 10 | #include // LOTS 11 | #include 12 | 13 | 14 | namespace prng 15 | { 16 | namespace meta 17 | { 18 | /////////////////////////////// 19 | // Detection idiom foot work // 20 | /////////////////////////////// 21 | 22 | template using bool_constant = std::integral_constant; 23 | 24 | template using void_t = void; 25 | template struct identity { using type = T; }; 26 | 27 | template class, class...> 28 | struct detector : 29 | identity 30 | { 31 | using value_t = std::false_type; 32 | }; 33 | 34 | template class U, class... Args> 35 | struct detector>, U, Args...> : 36 | identity> 37 | { 38 | using value_t = std::true_type; 39 | }; 40 | 41 | struct nonesuch final { 42 | nonesuch(nonesuch const&) = delete; 43 | nonesuch() = delete; 44 | ~nonesuch() = delete; 45 | 46 | void operator = (nonesuch const&) = delete; 47 | }; 48 | 49 | template class U, class... Args> 50 | using detected_or = detector; 51 | 52 | template