Files
TheRock/rocm-libraries/projects/hipthreads/inc/hip/__thread/id.h
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

195 lines
7.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __LIBHIPTHREADS___THREAD_ID_H
#define __LIBHIPTHREADS___THREAD_ID_H
#include <iostream>
#include "hip/thread_config"
/**
* @file
* @brief Lightweight GPU thread identifier type and helper I/O operator.
* @ingroup thread
*
* Provides cuda::__thread_id, a trivially copyable identifier for a GPU fiber
* produced by cuda::this_thread::get_id() and cuda::wthread::get_id().
* Semantics mirror (a subset of) std::thread::id:
*
* - Default constructed id compares equal only to other default ids.
* - Value 0 is a reserved sentinel used to impose a strict weak ordering
* where the sentinel is always the least element.
* - Comparison operators provide total ordering (C++20: three-way comparison).
* - Stream insertion operator writes a stable textual form (implementation detail).
*
* Notes:
* - Underlying representation is an opaque 32-bit value; no guarantees about
* reuse after a thread completes.
* - Equality of ids implies they refer (or referred) to the same logical
* execution context; inequality does not guarantee concurrency.
* - API is in flux. It may change in the future so all fibers in the same
* `hip::wthread` share the same id. A "sub-ID" may be introduced instead for
* identifying individual fibers.
*/
namespace cuda {
class _LIBHIPTHREADS_EXPORTED_FROM_ABI __thread_id;
namespace this_thread {
__device__ _LIBHIPTHREADS_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT;
} // namespace this_thread
namespace internal {
class wthread;
struct WorkNode_Header;
struct ThreadData;
}
} // namespace cuda
template <class _CharT, class _Traits>
_LIBHIPTHREADS_HIDE_FROM_ABI ::std::basic_ostream<_CharT, _Traits>&
operator<<(::std::basic_ostream<_CharT, _Traits>& __os, hip::__thread_id __id);
namespace cuda {
/**
* @class __thread_id
* @brief Opaque handle identifying a logical GPU thread (work node lane).
* @ingroup thread
*
* Acts similarly to std::thread::id but for the hipThreads runtime. A default
* constructed id (value 0) represents “no thread” and is always ordered
* before any non‑default id. Instances are obtained via:
* - cuda::this_thread::get_id()
* - cuda::wthread::get_id()
*
* Ordering:
* - All non‑zero ids are ordered by underlying integral value.
* - Zero (sentinel) < any non‑zero.
*
* Lifetime:
* - An id may outlive the associated thread; equality remains valid for
* comparison but does not retain resources.
*/
class _LIBHIPTHREADS_TEMPLATE_VIS __thread_id {
using underlying_type = uint32_t;
underlying_type __id_;
__host__ __device__ static _LIBHIPTHREADS_HIDE_FROM_ABI bool
__lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT { // id==0 is always less than any other thread_id
if (__x.__id_ == 0)
return __y.__id_ != 0;
if (__y.__id_ == 0)
return false;
return __x.__id_ < __y.__id_;
}
public:
/// Constructs a sentinel (non-joinable / no-thread) id (value 0).
__host__ __device__ _LIBHIPTHREADS_HIDE_FROM_ABI __thread_id() _NOEXCEPT : __id_(0) {}
/// Resets this id back to the sentinel (value 0).
__host__ __device__ _LIBHIPTHREADS_HIDE_FROM_ABI void __reset() { __id_ = 0; }
__host__ __device__ friend _LIBHIPTHREADS_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT;
# if _LIBHIPTHREADS_STD_VER <= 17
__host__ __device__ friend _LIBHIPTHREADS_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT;
# else // _LIBHIPTHREADS_STD_VER <= 17
__host__ __device__ friend _LIBHIPTHREADS_HIDE_FROM_ABI ::std::strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept;
# endif // _LIBHIPTHREADS_STD_VER <= 17
template <class _CharT, class _Traits>
friend _LIBHIPTHREADS_HIDE_FROM_ABI ::std::basic_ostream<_CharT, _Traits>&
::operator<<(::std::basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
private:
__host__ __device__ _LIBHIPTHREADS_HIDE_FROM_ABI __thread_id(underlying_type __id) : __id_(__id) {}
__host__ __device__ _LIBHIPTHREADS_HIDE_FROM_ABI friend underlying_type __get_underlying_id(const __thread_id __id) { return __id.__id_; }
friend __device__ __thread_id this_thread::get_id() _NOEXCEPT;
friend class internal::wthread;
friend struct internal::ThreadData;
};
__host__ __device__ inline _LIBHIPTHREADS_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT {
// Don't pass id==0 to underlying routines
if (__x.__id_ == 0)
return __y.__id_ == 0;
if (__y.__id_ == 0)
return false;
return __x.__id_ == __y.__id_;
}
# if _LIBHIPTHREADS_STD_VER <= 17
__host__ __device__ inline _LIBHIPTHREADS_HIDE_FROM_ABI bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x == __y); }
__host__ __device__ inline _LIBHIPTHREADS_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT {
return __thread_id::__lt_impl(__x, __y);
}
__host__ __device__ inline _LIBHIPTHREADS_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); }
__host__ __device__ inline _LIBHIPTHREADS_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; }
__host__ __device__ inline _LIBHIPTHREADS_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); }
# else // _LIBHIPTHREADS_STD_VER <= 17
__host__ __device__ inline _LIBHIPTHREADS_HIDE_FROM_ABI ::std::strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept {
if (__x == __y)
return ::std::strong_ordering::equal;
if (__thread_id::__lt_impl(__x, __y))
return ::std::strong_ordering::less;
return ::std::strong_ordering::greater;
}
# endif // _LIBHIPTHREADS_STD_VER <= 17
} // namespace cuda
/**
* @brief Stream insertion for cuda::__thread_id.
* @ingroup thread
*
* Produces a textual representation; distinct ids yield distinct text,
* equal ids yield identical text (except default constructed which prints 0).
*/
template <class _CharT, class _Traits>
_LIBHIPTHREADS_HIDE_FROM_ABI ::std::basic_ostream<_CharT, _Traits>&
operator<<(::std::basic_ostream<_CharT, _Traits>& __os, hip::__thread_id __id) {
// [thread.thread.id]/9
// Effects: Inserts the text representation for charT of id into out.
//
// [thread.thread.id]/2
// The text representation for the character type charT of an
// object of type wthread::id is an unspecified sequence of charT
// such that, for two objects of type wthread::id x and y, if
// x == y is true, the wthread::id objects have the same text
// representation, and if x != y is true, the wthread::id objects
// have distinct text representations.
//
// Since various flags in the output stream can affect how the
// thread id is represented (e.g. numpunct or showbase), we
// use a temporary stream instead and just output the thread
// id representation as a string.
::std::basic_ostringstream<_CharT, _Traits> __sstr;
__sstr.imbue(::std::locale::classic());
__sstr << __id.__id_;
return __os << __sstr.str();
}
#endif // __LIBHIPTHREADS___THREAD_ID_H