@@ -387,155 +387,6 @@ namespace amrex
387387 *first = std::pow (base, stop);
388388 }
389389 }
390-
391- // / \cond DOXYGEN_IGNORE
392- namespace detail {
393-
394- struct clzll_tag {};
395- struct clzl_tag : clzll_tag {};
396- struct clz_tag : clzl_tag {};
397-
398- // in gcc and clang, there are three versions of __builtin_clz taking unsigned int,
399- // unsigned long, and unsigned long long inputs. Because the sizes of these data types
400- // vary on different platforms, we work with fixed-width integer types.
401- // these tags and overloads select the smallest version of __builtin_clz that will hold the input type
402- template <typename T>
403- requires (sizeof (T) <= sizeof (unsigned int ))
404- AMREX_FORCE_INLINE
405- int builtin_clz_wrapper (clz_tag, T x) noexcept
406- {
407- return static_cast <int >(__builtin_clz (x) - (sizeof (unsigned int ) * CHAR_BIT - sizeof (T) * CHAR_BIT ));
408- }
409-
410- template <typename T>
411- requires (sizeof (T) <= sizeof (unsigned long ))
412- AMREX_FORCE_INLINE
413- int builtin_clz_wrapper (clzl_tag, T x) noexcept
414- {
415- return static_cast <int >(__builtin_clzl (x) - (sizeof (unsigned long ) * CHAR_BIT - sizeof (T) * CHAR_BIT ));
416- }
417-
418- template <typename T>
419- requires (sizeof (T) <= sizeof (unsigned long long ))
420- AMREX_FORCE_INLINE
421- int builtin_clz_wrapper (clzll_tag, T x) noexcept
422- {
423- return static_cast <int >(__builtin_clzll (x) - (sizeof (unsigned long long ) * CHAR_BIT - sizeof (T) * CHAR_BIT ));
424- }
425-
426- }
427- // / \endcond
428-
429- // / \ingroup amrex_utilities
430- // ! Return the number of leading zeros present in the unsigned integer \p x.
431- // ! \pre \p x must be nonzero.
432- template <class T >
433- requires (std::same_as<std::remove_cvref_t <T>,std::uint8_t > ||
434- std::same_as<std::remove_cvref_t <T>,std::uint16_t > ||
435- std::same_as<std::remove_cvref_t <T>,std::uint32_t > ||
436- std::same_as<std::remove_cvref_t <T>,std::uint64_t >)
437- AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
438- int clz (T x) noexcept ;
439-
440- // / \cond DOXYGEN_IGNORE
441-
442- AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
443- int clz_generic (std::uint8_t x) noexcept
444- {
445- #if !defined(__NVCOMPILER)
446- static constexpr int clz_lookup[16 ] = { 4 , 3 , 2 , 2 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
447- #else
448- constexpr int clz_lookup[16 ] = { 4 , 3 , 2 , 2 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
449- #endif
450- auto upper = x >> 4 ;
451- auto lower = x & 0xF ;
452- return upper ? clz_lookup[upper] : 4 + clz_lookup[lower];
453- }
454-
455- AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
456- int clz_generic (std::uint16_t x) noexcept
457- {
458- auto upper = std::uint8_t (x >> 8 );
459- auto lower = std::uint8_t (x & 0xFF );
460- return upper ? clz (upper) : 8 + clz (lower);
461- }
462-
463- AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
464- int clz_generic (std::uint32_t x) noexcept
465- {
466- auto upper = std::uint16_t (x >> 16 );
467- auto lower = std::uint16_t (x & 0xFFFF );
468- return upper ? clz (upper) : 16 + clz (lower);
469- }
470-
471- AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
472- int clz_generic (std::uint64_t x) noexcept
473- {
474- auto upper = std::uint32_t (x >> 32 );
475- auto lower = std::uint32_t (x & 0xFFFFFFFF );
476- return upper ? clz (upper) : 32 + clz (lower);
477- }
478-
479- // / \endcond
480-
481- #if defined AMREX_USE_CUDA
482-
483- // / \cond DOXYGEN_IGNORE
484- namespace detail {
485- // likewise with CUDA, there are __clz functions that take (signed) int and long long int
486- template <typename T>
487- requires (sizeof (T) <= sizeof (int ))
488- AMREX_GPU_DEVICE AMREX_FORCE_INLINE
489- int clz_wrapper (clz_tag, T x) noexcept
490- {
491- return __clz ((int ) x) - (sizeof (int ) * CHAR_BIT - sizeof (T) * CHAR_BIT );
492- }
493-
494- template <typename T>
495- requires (sizeof (T) <= sizeof (long long int ))
496- AMREX_GPU_DEVICE AMREX_FORCE_INLINE
497- int clz_wrapper (clzll_tag, T x) noexcept
498- {
499- return __clzll ((long long int ) x) - (sizeof (long long int ) * CHAR_BIT - sizeof (T) * CHAR_BIT );
500- }
501- }
502- // / \endcond
503-
504- template <class T >
505- requires (std::same_as<std::remove_cvref_t <T>,std::uint8_t > ||
506- std::same_as<std::remove_cvref_t <T>,std::uint16_t > ||
507- std::same_as<std::remove_cvref_t <T>,std::uint32_t > ||
508- std::same_as<std::remove_cvref_t <T>,std::uint64_t >)
509- AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
510- int clz (T x) noexcept
511- {
512- AMREX_IF_ON_DEVICE ((return detail::clz_wrapper (detail::clz_tag{}, x);))
513- #if AMREX_HAS_BUILTIN_CLZ
514- AMREX_IF_ON_HOST ((return detail::builtin_clz_wrapper (detail::clz_tag{}, x);))
515- #else
516- AMREX_IF_ON_HOST ((return clz_generic (x);))
517- #endif
518- }
519-
520- #else // !defined AMREX_USE_CUDA
521-
522- template <class T >
523- requires (std::same_as<std::remove_cvref_t <T>,std::uint8_t > ||
524- std::same_as<std::remove_cvref_t <T>,std::uint16_t > ||
525- std::same_as<std::remove_cvref_t <T>,std::uint32_t > ||
526- std::same_as<std::remove_cvref_t <T>,std::uint64_t >)
527- AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
528- int clz (T x) noexcept
529- {
530- #if (!AMREX_DEVICE_COMPILE && AMREX_HAS_BUILTIN_CLZ)
531- return detail::builtin_clz_wrapper (detail::clz_tag{}, x);
532- #else
533- return clz_generic (x);
534- #endif
535- }
536-
537- #endif // defined AMREX_USE_CUDA
538-
539390}
540391
541392#endif
0 commit comments