1 1.1 mrg // -*- C++ -*- 2 1.1 mrg 3 1.1.1.12 mrg // Copyright (C) 2007-2024 Free Software Foundation, Inc. 4 1.1 mrg // 5 1.1 mrg // This file is part of the GNU ISO C++ Library. This library is free 6 1.1 mrg // software; you can redistribute it and/or modify it under the terms 7 1.1 mrg // of the GNU General Public License as published by the Free Software 8 1.1 mrg // Foundation; either version 3, or (at your option) any later 9 1.1 mrg // version. 10 1.1 mrg 11 1.1 mrg // This library is distributed in the hope that it will be useful, but 12 1.1 mrg // WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 1.1 mrg // General Public License for more details. 15 1.1 mrg 16 1.1 mrg // Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg // permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg // 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg // You should have received a copy of the GNU General Public License and 21 1.1 mrg // a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg // <http://www.gnu.org/licenses/>. 24 1.1 mrg 25 1.1 mrg /** @file parallel/base.h 26 1.1 mrg * @brief Sequential helper functions. 27 1.1 mrg * This file is a GNU parallel extension to the Standard C++ Library. 28 1.1 mrg */ 29 1.1 mrg 30 1.1 mrg // Written by Johannes Singler. 31 1.1 mrg 32 1.1 mrg #ifndef _GLIBCXX_PARALLEL_BASE_H 33 1.1 mrg #define _GLIBCXX_PARALLEL_BASE_H 1 34 1.1 mrg 35 1.1 mrg #include <bits/c++config.h> 36 1.1 mrg #include <bits/stl_function.h> 37 1.1 mrg #include <omp.h> 38 1.1 mrg #include <parallel/features.h> 39 1.1 mrg #include <parallel/basic_iterator.h> 40 1.1 mrg #include <parallel/parallel.h> 41 1.1 mrg 42 1.1 mrg // Parallel mode namespaces. 43 1.1 mrg 44 1.1 mrg /** 45 1.1 mrg * @namespace std::__parallel 46 1.1 mrg * @brief GNU parallel code, replaces standard behavior with parallel behavior. 47 1.1 mrg */ 48 1.1.1.2 mrg namespace std _GLIBCXX_VISIBILITY(default) 49 1.1 mrg { 50 1.1 mrg namespace __parallel { } 51 1.1 mrg } 52 1.1 mrg 53 1.1 mrg /** 54 1.1 mrg * @namespace __gnu_parallel 55 1.1 mrg * @brief GNU parallel code for public use. 56 1.1 mrg */ 57 1.1 mrg namespace __gnu_parallel 58 1.1 mrg { 59 1.1 mrg // Import all the parallel versions of components in namespace std. 60 1.1 mrg using namespace std::__parallel; 61 1.1 mrg } 62 1.1 mrg 63 1.1 mrg /** 64 1.1 mrg * @namespace __gnu_sequential 65 1.1 mrg * @brief GNU sequential classes for public use. 66 1.1 mrg */ 67 1.1 mrg namespace __gnu_sequential 68 1.1 mrg { 69 1.1 mrg // Import whatever is the serial version. 70 1.1 mrg #ifdef _GLIBCXX_PARALLEL 71 1.1.1.2 mrg using namespace std::_GLIBCXX_STD_A; 72 1.1 mrg #else 73 1.1 mrg using namespace std; 74 1.1 mrg #endif 75 1.1 mrg } 76 1.1 mrg 77 1.1 mrg 78 1.1 mrg namespace __gnu_parallel 79 1.1 mrg { 80 1.1 mrg // NB: Including this file cannot produce (unresolved) symbols from 81 1.1 mrg // the OpenMP runtime unless the parallel mode is actually invoked 82 1.1 mrg // and active, which imples that the OpenMP runtime is actually 83 1.1 mrg // going to be linked in. 84 1.1 mrg inline _ThreadIndex 85 1.1 mrg __get_max_threads() 86 1.1 mrg { 87 1.1 mrg _ThreadIndex __i = omp_get_max_threads(); 88 1.1 mrg return __i > 1 ? __i : 1; 89 1.1 mrg } 90 1.1 mrg 91 1.1 mrg 92 1.1 mrg inline bool 93 1.1 mrg __is_parallel(const _Parallelism __p) { return __p != sequential; } 94 1.1 mrg 95 1.1 mrg 96 1.1 mrg /** @brief Calculates the rounded-down logarithm of @c __n for base 2. 97 1.1 mrg * @param __n Argument. 98 1.1 mrg * @return Returns 0 for any argument <1. 99 1.1 mrg */ 100 1.1 mrg template<typename _Size> 101 1.1 mrg inline _Size 102 1.1 mrg __rd_log2(_Size __n) 103 1.1 mrg { 104 1.1 mrg _Size __k; 105 1.1 mrg for (__k = 0; __n > 1; __n >>= 1) 106 1.1 mrg ++__k; 107 1.1 mrg return __k; 108 1.1 mrg } 109 1.1 mrg 110 1.1 mrg /** @brief Encode two integers into one gnu_parallel::_CASable. 111 1.1 mrg * @param __a First integer, to be encoded in the most-significant @c 112 1.1 mrg * _CASable_bits/2 bits. 113 1.1 mrg * @param __b Second integer, to be encoded in the least-significant 114 1.1 mrg * @c _CASable_bits/2 bits. 115 1.1 mrg * @return value encoding @c __a and @c __b. 116 1.1 mrg * @see __decode2 117 1.1 mrg */ 118 1.1 mrg inline _CASable 119 1.1 mrg __encode2(int __a, int __b) //must all be non-negative, actually 120 1.1 mrg { 121 1.1 mrg return (((_CASable)__a) << (_CASable_bits / 2)) | (((_CASable)__b) << 0); 122 1.1 mrg } 123 1.1 mrg 124 1.1 mrg /** @brief Decode two integers from one gnu_parallel::_CASable. 125 1.1 mrg * @param __x __gnu_parallel::_CASable to decode integers from. 126 1.1 mrg * @param __a First integer, to be decoded from the most-significant 127 1.1 mrg * @c _CASable_bits/2 bits of @c __x. 128 1.1 mrg * @param __b Second integer, to be encoded in the least-significant 129 1.1 mrg * @c _CASable_bits/2 bits of @c __x. 130 1.1 mrg * @see __encode2 131 1.1 mrg */ 132 1.1 mrg inline void 133 1.1 mrg __decode2(_CASable __x, int& __a, int& __b) 134 1.1 mrg { 135 1.1 mrg __a = (int)((__x >> (_CASable_bits / 2)) & _CASable_mask); 136 1.1 mrg __b = (int)((__x >> 0 ) & _CASable_mask); 137 1.1 mrg } 138 1.1 mrg 139 1.1 mrg //needed for parallel "numeric", even if "algorithm" not included 140 1.1 mrg 141 1.1 mrg /** @brief Equivalent to std::min. */ 142 1.1 mrg template<typename _Tp> 143 1.1.1.2 mrg inline const _Tp& 144 1.1 mrg min(const _Tp& __a, const _Tp& __b) 145 1.1 mrg { return (__a < __b) ? __a : __b; } 146 1.1 mrg 147 1.1 mrg /** @brief Equivalent to std::max. */ 148 1.1 mrg template<typename _Tp> 149 1.1.1.2 mrg inline const _Tp& 150 1.1 mrg max(const _Tp& __a, const _Tp& __b) 151 1.1 mrg { return (__a > __b) ? __a : __b; } 152 1.1 mrg 153 1.1 mrg /** @brief Constructs predicate for equality from strict weak 154 1.1 mrg * ordering predicate 155 1.1 mrg */ 156 1.1 mrg template<typename _T1, typename _T2, typename _Compare> 157 1.1 mrg class _EqualFromLess : public std::binary_function<_T1, _T2, bool> 158 1.1 mrg { 159 1.1 mrg private: 160 1.1 mrg _Compare& _M_comp; 161 1.1 mrg 162 1.1 mrg public: 163 1.1 mrg _EqualFromLess(_Compare& __comp) : _M_comp(__comp) { } 164 1.1 mrg 165 1.1 mrg bool operator()(const _T1& __a, const _T2& __b) 166 1.1 mrg { return !_M_comp(__a, __b) && !_M_comp(__b, __a); } 167 1.1 mrg }; 168 1.1 mrg 169 1.1 mrg 170 1.1 mrg /** @brief Similar to std::unary_negate, 171 1.1 mrg * but giving the argument types explicitly. */ 172 1.1 mrg template<typename _Predicate, typename argument_type> 173 1.1 mrg class __unary_negate 174 1.1 mrg : public std::unary_function<argument_type, bool> 175 1.1 mrg { 176 1.1 mrg protected: 177 1.1 mrg _Predicate _M_pred; 178 1.1 mrg 179 1.1 mrg public: 180 1.1 mrg explicit 181 1.1 mrg __unary_negate(const _Predicate& __x) : _M_pred(__x) { } 182 1.1 mrg 183 1.1 mrg bool 184 1.1 mrg operator()(const argument_type& __x) 185 1.1 mrg { return !_M_pred(__x); } 186 1.1 mrg }; 187 1.1 mrg 188 1.1 mrg /** @brief Similar to std::binder1st, 189 1.1 mrg * but giving the argument types explicitly. */ 190 1.1 mrg template<typename _Operation, typename _FirstArgumentType, 191 1.1 mrg typename _SecondArgumentType, typename _ResultType> 192 1.1 mrg class __binder1st 193 1.1 mrg : public std::unary_function<_SecondArgumentType, _ResultType> 194 1.1 mrg { 195 1.1 mrg protected: 196 1.1 mrg _Operation _M_op; 197 1.1 mrg _FirstArgumentType _M_value; 198 1.1 mrg 199 1.1 mrg public: 200 1.1 mrg __binder1st(const _Operation& __x, const _FirstArgumentType& __y) 201 1.1 mrg : _M_op(__x), _M_value(__y) { } 202 1.1 mrg 203 1.1 mrg _ResultType 204 1.1 mrg operator()(const _SecondArgumentType& __x) 205 1.1 mrg { return _M_op(_M_value, __x); } 206 1.1 mrg 207 1.1 mrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 208 1.1 mrg // 109. Missing binders for non-const sequence elements 209 1.1 mrg _ResultType 210 1.1 mrg operator()(_SecondArgumentType& __x) const 211 1.1 mrg { return _M_op(_M_value, __x); } 212 1.1 mrg }; 213 1.1 mrg 214 1.1 mrg /** 215 1.1 mrg * @brief Similar to std::binder2nd, but giving the argument types 216 1.1 mrg * explicitly. 217 1.1 mrg */ 218 1.1 mrg template<typename _Operation, typename _FirstArgumentType, 219 1.1 mrg typename _SecondArgumentType, typename _ResultType> 220 1.1 mrg class __binder2nd 221 1.1 mrg : public std::unary_function<_FirstArgumentType, _ResultType> 222 1.1 mrg { 223 1.1 mrg protected: 224 1.1 mrg _Operation _M_op; 225 1.1 mrg _SecondArgumentType _M_value; 226 1.1 mrg 227 1.1 mrg public: 228 1.1 mrg __binder2nd(const _Operation& __x, const _SecondArgumentType& __y) 229 1.1 mrg : _M_op(__x), _M_value(__y) { } 230 1.1 mrg 231 1.1 mrg _ResultType 232 1.1 mrg operator()(const _FirstArgumentType& __x) const 233 1.1 mrg { return _M_op(__x, _M_value); } 234 1.1 mrg 235 1.1 mrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 236 1.1 mrg // 109. Missing binders for non-const sequence elements 237 1.1 mrg _ResultType 238 1.1 mrg operator()(_FirstArgumentType& __x) 239 1.1 mrg { return _M_op(__x, _M_value); } 240 1.1 mrg }; 241 1.1 mrg 242 1.1 mrg /** @brief Similar to std::equal_to, but allows two different types. */ 243 1.1 mrg template<typename _T1, typename _T2> 244 1.1 mrg struct _EqualTo : std::binary_function<_T1, _T2, bool> 245 1.1 mrg { 246 1.1 mrg bool operator()(const _T1& __t1, const _T2& __t2) const 247 1.1 mrg { return __t1 == __t2; } 248 1.1 mrg }; 249 1.1 mrg 250 1.1 mrg /** @brief Similar to std::less, but allows two different types. */ 251 1.1 mrg template<typename _T1, typename _T2> 252 1.1 mrg struct _Less : std::binary_function<_T1, _T2, bool> 253 1.1 mrg { 254 1.1 mrg bool 255 1.1 mrg operator()(const _T1& __t1, const _T2& __t2) const 256 1.1 mrg { return __t1 < __t2; } 257 1.1 mrg 258 1.1 mrg bool 259 1.1 mrg operator()(const _T2& __t2, const _T1& __t1) const 260 1.1 mrg { return __t2 < __t1; } 261 1.1 mrg }; 262 1.1 mrg 263 1.1 mrg // Partial specialization for one type. Same as std::less. 264 1.1 mrg template<typename _Tp> 265 1.1 mrg struct _Less<_Tp, _Tp> 266 1.1 mrg : public std::less<_Tp> { }; 267 1.1 mrg 268 1.1 mrg /** @brief Similar to std::plus, but allows two different types. */ 269 1.1 mrg template<typename _Tp1, typename _Tp2, typename _Result 270 1.1.1.2 mrg = __typeof__(*static_cast<_Tp1*>(0) 271 1.1.1.2 mrg + *static_cast<_Tp2*>(0))> 272 1.1 mrg struct _Plus : public std::binary_function<_Tp1, _Tp2, _Result> 273 1.1 mrg { 274 1.1 mrg _Result 275 1.1 mrg operator()(const _Tp1& __x, const _Tp2& __y) const 276 1.1 mrg { return __x + __y; } 277 1.1 mrg }; 278 1.1 mrg 279 1.1 mrg // Partial specialization for one type. Same as std::plus. 280 1.1 mrg template<typename _Tp> 281 1.1 mrg struct _Plus<_Tp, _Tp, _Tp> 282 1.1 mrg : public std::plus<_Tp> { }; 283 1.1 mrg 284 1.1 mrg /** @brief Similar to std::multiplies, but allows two different types. */ 285 1.1 mrg template<typename _Tp1, typename _Tp2, typename _Result 286 1.1.1.2 mrg = __typeof__(*static_cast<_Tp1*>(0) 287 1.1.1.2 mrg * *static_cast<_Tp2*>(0))> 288 1.1 mrg struct _Multiplies : public std::binary_function<_Tp1, _Tp2, _Result> 289 1.1 mrg { 290 1.1 mrg _Result 291 1.1 mrg operator()(const _Tp1& __x, const _Tp2& __y) const 292 1.1 mrg { return __x * __y; } 293 1.1 mrg }; 294 1.1 mrg 295 1.1 mrg // Partial specialization for one type. Same as std::multiplies. 296 1.1 mrg template<typename _Tp> 297 1.1 mrg struct _Multiplies<_Tp, _Tp, _Tp> 298 1.1 mrg : public std::multiplies<_Tp> { }; 299 1.1 mrg 300 1.1 mrg /** @brief _Iterator associated with __gnu_parallel::_PseudoSequence. 301 1.1 mrg * If features the usual random-access iterator functionality. 302 1.1 mrg * @param _Tp Sequence _M_value type. 303 1.1.1.2 mrg * @param _DifferenceTp Sequence difference type. 304 1.1 mrg */ 305 1.1 mrg template<typename _Tp, typename _DifferenceTp> 306 1.1 mrg class _PseudoSequenceIterator 307 1.1 mrg { 308 1.1 mrg public: 309 1.1 mrg typedef _DifferenceTp _DifferenceType; 310 1.1 mrg 311 1.1 mrg _PseudoSequenceIterator(const _Tp& __val, _DifferenceType __pos) 312 1.1 mrg : _M_val(__val), _M_pos(__pos) { } 313 1.1 mrg 314 1.1 mrg // Pre-increment operator. 315 1.1 mrg _PseudoSequenceIterator& 316 1.1 mrg operator++() 317 1.1 mrg { 318 1.1 mrg ++_M_pos; 319 1.1 mrg return *this; 320 1.1 mrg } 321 1.1 mrg 322 1.1 mrg // Post-increment operator. 323 1.1 mrg _PseudoSequenceIterator 324 1.1 mrg operator++(int) 325 1.1 mrg { return _PseudoSequenceIterator(_M_pos++); } 326 1.1 mrg 327 1.1 mrg const _Tp& 328 1.1 mrg operator*() const 329 1.1 mrg { return _M_val; } 330 1.1 mrg 331 1.1 mrg const _Tp& 332 1.1 mrg operator[](_DifferenceType) const 333 1.1 mrg { return _M_val; } 334 1.1 mrg 335 1.1 mrg bool 336 1.1 mrg operator==(const _PseudoSequenceIterator& __i2) 337 1.1 mrg { return _M_pos == __i2._M_pos; } 338 1.1 mrg 339 1.1 mrg bool 340 1.1 mrg operator!=(const _PseudoSequenceIterator& __i2) 341 1.1 mrg { return _M_pos != __i2._M_pos; } 342 1.1 mrg 343 1.1 mrg _DifferenceType 344 1.1 mrg operator-(const _PseudoSequenceIterator& __i2) 345 1.1 mrg { return _M_pos - __i2._M_pos; } 346 1.1 mrg 347 1.1 mrg private: 348 1.1 mrg const _Tp& _M_val; 349 1.1 mrg _DifferenceType _M_pos; 350 1.1 mrg }; 351 1.1 mrg 352 1.1 mrg /** @brief Sequence that conceptually consists of multiple copies of 353 1.1 mrg the same element. 354 1.1 mrg * The copies are not stored explicitly, of course. 355 1.1 mrg * @param _Tp Sequence _M_value type. 356 1.1.1.2 mrg * @param _DifferenceTp Sequence difference type. 357 1.1 mrg */ 358 1.1 mrg template<typename _Tp, typename _DifferenceTp> 359 1.1 mrg class _PseudoSequence 360 1.1 mrg { 361 1.1 mrg public: 362 1.1 mrg typedef _DifferenceTp _DifferenceType; 363 1.1 mrg 364 1.1 mrg // Better cast down to uint64_t, than up to _DifferenceTp. 365 1.1 mrg typedef _PseudoSequenceIterator<_Tp, uint64_t> iterator; 366 1.1 mrg 367 1.1 mrg /** @brief Constructor. 368 1.1.1.2 mrg * @param __val Element of the sequence. 369 1.1 mrg * @param __count Number of (virtual) copies. 370 1.1 mrg */ 371 1.1 mrg _PseudoSequence(const _Tp& __val, _DifferenceType __count) 372 1.1 mrg : _M_val(__val), _M_count(__count) { } 373 1.1 mrg 374 1.1 mrg /** @brief Begin iterator. */ 375 1.1 mrg iterator 376 1.1 mrg begin() const 377 1.1 mrg { return iterator(_M_val, 0); } 378 1.1 mrg 379 1.1 mrg /** @brief End iterator. */ 380 1.1 mrg iterator 381 1.1 mrg end() const 382 1.1 mrg { return iterator(_M_val, _M_count); } 383 1.1 mrg 384 1.1 mrg private: 385 1.1 mrg const _Tp& _M_val; 386 1.1 mrg _DifferenceType _M_count; 387 1.1 mrg }; 388 1.1 mrg 389 1.1 mrg /** @brief Compute the median of three referenced elements, 390 1.1 mrg according to @c __comp. 391 1.1 mrg * @param __a First iterator. 392 1.1 mrg * @param __b Second iterator. 393 1.1 mrg * @param __c Third iterator. 394 1.1 mrg * @param __comp Comparator. 395 1.1 mrg */ 396 1.1 mrg template<typename _RAIter, typename _Compare> 397 1.1 mrg _RAIter 398 1.1 mrg __median_of_three_iterators(_RAIter __a, _RAIter __b, 399 1.1 mrg _RAIter __c, _Compare __comp) 400 1.1 mrg { 401 1.1 mrg if (__comp(*__a, *__b)) 402 1.1 mrg if (__comp(*__b, *__c)) 403 1.1 mrg return __b; 404 1.1 mrg else 405 1.1 mrg if (__comp(*__a, *__c)) 406 1.1 mrg return __c; 407 1.1 mrg else 408 1.1 mrg return __a; 409 1.1 mrg else 410 1.1 mrg { 411 1.1 mrg // Just swap __a and __b. 412 1.1 mrg if (__comp(*__a, *__c)) 413 1.1 mrg return __a; 414 1.1 mrg else 415 1.1 mrg if (__comp(*__b, *__c)) 416 1.1 mrg return __c; 417 1.1 mrg else 418 1.1 mrg return __b; 419 1.1 mrg } 420 1.1 mrg } 421 1.1 mrg 422 1.1.1.4 mrg #if _GLIBCXX_PARALLEL_ASSERTIONS && defined(__glibcxx_assert_impl) 423 1.1.1.11 mrg # define _GLIBCXX_PARALLEL_ASSERT(_Condition) \ 424 1.1.1.11 mrg do { __glibcxx_assert_impl(_Condition); } while (false) 425 1.1.1.4 mrg #else 426 1.1.1.11 mrg # define _GLIBCXX_PARALLEL_ASSERT(_Condition) do { } while (false) 427 1.1.1.4 mrg #endif 428 1.1 mrg 429 1.1 mrg } //namespace __gnu_parallel 430 1.1 mrg 431 1.1 mrg #endif /* _GLIBCXX_PARALLEL_BASE_H */ 432