1 /* 2 //@HEADER 3 // ************************************************************************ 4 // 5 // Kokkos v. 3.0 6 // Copyright (2020) National Technology & Engineering 7 // Solutions of Sandia, LLC (NTESS). 8 // 9 // Under the terms of Contract DE-NA0003525 with NTESS, 10 // the U.S. Government retains certain rights in this software. 11 // 12 // Redistribution and use in source and binary forms, with or without 13 // modification, are permitted provided that the following conditions are 14 // met: 15 // 16 // 1. Redistributions of source code must retain the above copyright 17 // notice, this list of conditions and the following disclaimer. 18 // 19 // 2. Redistributions in binary form must reproduce the above copyright 20 // notice, this list of conditions and the following disclaimer in the 21 // documentation and/or other materials provided with the distribution. 22 // 23 // 3. Neither the name of the Corporation nor the names of the 24 // contributors may be used to endorse or promote products derived from 25 // this software without specific prior written permission. 26 // 27 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY 28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE 31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 // 39 // Questions? Contact Christian R. Trott (crtrott@sandia.gov) 40 // 41 // ************************************************************************ 42 //@HEADER 43 */ 44 45 #ifndef KOKKOS_OPENMPTARGET_UNIQUE_TOKEN_HPP 46 #define KOKKOS_OPENMPTARGET_UNIQUE_TOKEN_HPP 47 48 #include <Kokkos_Macros.hpp> 49 #ifdef KOKKOS_ENABLE_OPENMPTARGET 50 51 #include <Kokkos_OpenMPTargetSpace.hpp> 52 #include <Kokkos_UniqueToken.hpp> 53 #include <impl/Kokkos_SharedAlloc.hpp> 54 #include <impl/Kokkos_ConcurrentBitset.hpp> 55 56 namespace Kokkos { 57 namespace Experimental { 58 59 // both global and instance Unique Tokens are implemented in the same way 60 template <> 61 class UniqueToken<OpenMPTarget, UniqueTokenScope::Global> { 62 protected: 63 uint32_t volatile* m_buffer; 64 uint32_t m_count; 65 66 public: 67 using execution_space = OpenMPTarget; 68 using size_type = int32_t; 69 70 explicit UniqueToken(execution_space const& = execution_space()); 71 72 KOKKOS_DEFAULTED_FUNCTION 73 UniqueToken(const UniqueToken&) = default; 74 75 KOKKOS_DEFAULTED_FUNCTION 76 UniqueToken(UniqueToken&&) = default; 77 78 KOKKOS_DEFAULTED_FUNCTION 79 UniqueToken& operator=(const UniqueToken&) = default; 80 81 KOKKOS_DEFAULTED_FUNCTION 82 UniqueToken& operator=(UniqueToken&&) = default; 83 84 /// \brief upper bound for acquired values, i.e. 0 <= value < size() 85 KOKKOS_INLINE_FUNCTION size() const86 size_type size() const noexcept { return m_count; } 87 88 /// \brief acquire value such that 0 <= value < size() 89 KOKKOS_INLINE_FUNCTION acquire() const90 size_type acquire() const { 91 const Kokkos::pair<int, int> result = 92 Kokkos::Impl::concurrent_bitset::acquire_bounded( 93 m_buffer, m_count, Kokkos::Impl::clock_tic() % m_count); 94 95 if (result.first < 0) { 96 Kokkos::abort( 97 "UniqueToken<OpenMPTarget> failure to acquire tokens, no tokens " 98 "available"); 99 } 100 101 return result.first; 102 } 103 104 /// \brief release an acquired value 105 KOKKOS_INLINE_FUNCTION release(size_type i) const106 void release(size_type i) const noexcept { 107 Kokkos::Impl::concurrent_bitset::release(m_buffer, i); 108 } 109 }; 110 111 template <> 112 class UniqueToken<OpenMPTarget, UniqueTokenScope::Instance> 113 : public UniqueToken<OpenMPTarget, UniqueTokenScope::Global> { 114 private: 115 Kokkos::View<uint32_t*, ::Kokkos::Experimental::OpenMPTargetSpace> 116 m_buffer_view; 117 118 public: UniqueToken(execution_space const & arg=execution_space ())119 explicit UniqueToken(execution_space const& arg = execution_space()) 120 : UniqueToken<OpenMPTarget, UniqueTokenScope::Global>(arg) {} 121 UniqueToken(size_type max_size,execution_space const &=execution_space ())122 UniqueToken(size_type max_size, execution_space const& = execution_space()) 123 : m_buffer_view( 124 "Kokkos::UniqueToken::m_buffer_view", 125 ::Kokkos::Impl::concurrent_bitset::buffer_bound(max_size)) { 126 m_buffer = m_buffer_view.data(); 127 m_count = max_size; 128 } 129 }; 130 131 } // namespace Experimental 132 } // namespace Kokkos 133 134 #endif // KOKKOS_ENABLE_OPENMPTARGET 135 #endif // KOKKOS_OPENMPTARGET_UNIQUE_TOKEN_HPP 136