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_OPENMP_HPP 46 #define KOKKOS_OPENMP_HPP 47 48 #include <Kokkos_Macros.hpp> 49 #if defined(KOKKOS_ENABLE_OPENMP) 50 51 #include <Kokkos_Core_fwd.hpp> 52 53 #include <cstddef> 54 #include <iosfwd> 55 #include <Kokkos_HostSpace.hpp> 56 57 #ifdef KOKKOS_ENABLE_HBWSPACE 58 #include <Kokkos_HBWSpace.hpp> 59 #endif 60 61 #include <Kokkos_ScratchSpace.hpp> 62 #include <Kokkos_Parallel.hpp> 63 #include <Kokkos_TaskScheduler.hpp> 64 #include <Kokkos_Layout.hpp> 65 #include <impl/Kokkos_Tags.hpp> 66 #include <impl/Kokkos_Profiling_Interface.hpp> 67 #include <impl/Kokkos_ExecSpaceInitializer.hpp> 68 69 #include <vector> 70 71 /*--------------------------------------------------------------------------*/ 72 73 namespace Kokkos { 74 75 namespace Impl { 76 class OpenMPExec; 77 } 78 79 /// \class OpenMP 80 /// \brief Kokkos device for multicore processors in the host memory space. 81 class OpenMP { 82 public: 83 //! Tag this class as a kokkos execution space 84 using execution_space = OpenMP; 85 86 using memory_space = 87 #ifdef KOKKOS_ENABLE_HBWSPACE 88 Experimental::HBWSpace; 89 #else 90 HostSpace; 91 #endif 92 93 //! This execution space preferred device_type 94 using device_type = Kokkos::Device<execution_space, memory_space>; 95 using array_layout = LayoutRight; 96 using size_type = memory_space::size_type; 97 using scratch_memory_space = ScratchMemorySpace<OpenMP>; 98 99 /// \brief Print configuration information to the given output stream. 100 static void print_configuration(std::ostream&, const bool verbose = false); 101 102 /// \brief is the instance running a parallel algorithm 103 inline static bool in_parallel(OpenMP const& = OpenMP()) noexcept; 104 105 /// \brief Wait until all dispatched functors complete on the given instance 106 /// 107 /// This is a no-op on OpenMP 108 static void impl_static_fence(OpenMP const& = OpenMP()) noexcept; 109 110 void fence() const; 111 112 /// \brief Does the given instance return immediately after launching 113 /// a parallel algorithm 114 /// 115 /// This always returns false on OpenMP 116 inline static bool is_asynchronous(OpenMP const& = OpenMP()) noexcept; 117 118 /// \brief Partition the default instance into new instances without creating 119 /// new masters 120 /// 121 /// This is a no-op on OpenMP since the default instance cannot be partitioned 122 /// without promoting other threads to 'master' 123 static std::vector<OpenMP> partition(...); 124 125 /// Non-default instances should be ref-counted so that when the last 126 /// is destroyed the instance resources are released 127 /// 128 /// This is a no-op on OpenMP since a non default instance cannot be created 129 static OpenMP create_instance(...); 130 131 /// \brief Partition the default instance and call 'f' on each new 'master' 132 /// thread 133 /// 134 /// Func is a functor with the following signiture 135 /// void( int partition_id, int num_partitions ) 136 template <typename F> 137 static void partition_master(F const& f, int requested_num_partitions = 0, 138 int requested_partition_size = 0); 139 140 // use UniqueToken 141 static int concurrency(); 142 143 static void impl_initialize(int thread_count = -1); 144 145 /// \brief is the default execution space initialized for current 'master' 146 /// thread 147 static bool impl_is_initialized() noexcept; 148 149 /// \brief Free any resources being consumed by the default execution space 150 static void impl_finalize(); 151 152 inline static int impl_thread_pool_size() noexcept; 153 154 /** \brief The rank of the executing thread in this thread pool */ 155 KOKKOS_INLINE_FUNCTION 156 static int impl_thread_pool_rank() noexcept; 157 158 inline static int impl_thread_pool_size(int depth); 159 160 // use UniqueToken 161 inline static int impl_max_hardware_threads() noexcept; 162 163 // use UniqueToken 164 KOKKOS_INLINE_FUNCTION 165 static int impl_hardware_thread_id() noexcept; 166 167 static int impl_get_current_max_threads() noexcept; 168 name()169 static constexpr const char* name() noexcept { return "OpenMP"; } impl_instance_id() const170 uint32_t impl_instance_id() const noexcept { return 0; } 171 }; 172 173 namespace Tools { 174 namespace Experimental { 175 template <> 176 struct DeviceTypeTraits<OpenMP> { 177 static constexpr DeviceType id = DeviceType::OpenMP; 178 }; 179 } // namespace Experimental 180 } // namespace Tools 181 182 namespace Impl { 183 184 class OpenMPSpaceInitializer : public ExecSpaceInitializerBase { 185 public: 186 OpenMPSpaceInitializer() = default; 187 ~OpenMPSpaceInitializer() = default; 188 void initialize(const InitArguments& args) final; 189 void finalize(const bool) final; 190 void fence() final; 191 void print_configuration(std::ostream& msg, const bool detail) final; 192 }; 193 194 } // namespace Impl 195 } // namespace Kokkos 196 197 /*--------------------------------------------------------------------------*/ 198 /*--------------------------------------------------------------------------*/ 199 200 namespace Kokkos { 201 namespace Impl { 202 203 template <> 204 struct MemorySpaceAccess<Kokkos::OpenMP::memory_space, 205 Kokkos::OpenMP::scratch_memory_space> { 206 enum : bool { assignable = false }; 207 enum : bool { accessible = true }; 208 enum : bool { deepcopy = false }; 209 }; 210 211 } // namespace Impl 212 } // namespace Kokkos 213 214 /*--------------------------------------------------------------------------*/ 215 /*--------------------------------------------------------------------------*/ 216 217 #include <OpenMP/Kokkos_OpenMP_Exec.hpp> 218 #include <OpenMP/Kokkos_OpenMP_Team.hpp> 219 #include <OpenMP/Kokkos_OpenMP_Parallel.hpp> 220 #include <OpenMP/Kokkos_OpenMP_Task.hpp> 221 222 #include <KokkosExp_MDRangePolicy.hpp> 223 /*--------------------------------------------------------------------------*/ 224 225 #endif /* #if defined( KOKKOS_ENABLE_OPENMP ) && defined( _OPENMP ) */ 226 #endif /* #ifndef KOKKOS_OPENMP_HPP */ 227