HIP hip::Stream 对象:功能与底层实现

1. 概述

hip::Stream 是 HIP 运行时(ROCclr/hipamd 层)中**命令流(stream/queue)**的核心实现类。用户通过公开句柄 hipStream_t 操作它,而运行时内部将该句柄 reinterpret_cast 成 hip::Stream* 来访问真正的对象。

一个 stream 表示一条按 FIFO 顺序执行的 GPU 命令队列:同一 stream 内的 kernel 启动、内存拷贝、memset、event 等命令按提交顺序串行执行;不同 stream 之间可并发。

定义位置:

  • 声明:projects/clr/hipamd/src/hip_internal.hpp
  • 实现:projects/clr/hipamd/src/hip_stream.cpp

2. 类层次与底层映射

cpp 复制代码
class Stream : public amd::HostQueue { ... };

hip::Stream 继承自 amd::HostQueue,这是关键的架构事实:

因此,stream 在底层就是一个 ROCclr 命令队列 。在 hip_memory.cpp 等处看到的 command->enqueue()、command->queue()->finishCommand()、stream.finish() 等调用,本质上都是在操作这条 HostQueue。队列再向下对接 HSA/ROCr,由 GPU 的硬件队列(AQL queue)、SDMA 拷贝引擎或 compute shader 执行实际工作。


3. 构造与生命周期

3.1 构造函数

cpp 复制代码
Stream::Stream(hip::Device* dev, Priority p, unsigned int f, bool null_stream,
               const std::vector<uint32_t>& cuMask, hipStreamCaptureStatus captureStatus)
    : amd::HostQueue(*dev->asContext(), *dev->devices()[0], 0,
                     amd::CommandQueue::RealTimeDisabled,
                     convertToQueuePriority(p), cuMask, null_stream),
      device_(dev), priority_(p), flags_(f), null_(null_stream),
      cuMask_(cuMask), stream_id_(GenerateStreamId()),
      captureStatus_(captureStatus) {
  device_->AddStream(this);
}

构造时:

  1. 初始化基类 amd::HostQueue,绑定到设备的 amd::Context 和 amd::Device,并传入优先级与 CU mask。
  2. 生成进程内唯一的 stream_id_(单调递增)。
  3. 调用 device_->AddStream(this) 把自己注册到所属 hip::Device。

3.2 创建、销毁、终止

方法 作用
Create() 调用基类 create() 真正分配底层队列资源
Destroy() 从活动队列与设备注销,设置强制销毁标志后 release()
terminate() 调用 HostQueue::terminate() 清理

注意析构函数 ~Stream() = default 被声明为 private ,因为 HostQueue 是引用计数对象,生命周期由 retain()/release() 管理,不能直接 delete。

创建流程(公开 API 入口):
#mermaid-svg-TLwlELzvTXLJeFfP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TLwlELzvTXLJeFfP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TLwlELzvTXLJeFfP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TLwlELzvTXLJeFfP .error-icon{fill:#552222;}#mermaid-svg-TLwlELzvTXLJeFfP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TLwlELzvTXLJeFfP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TLwlELzvTXLJeFfP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TLwlELzvTXLJeFfP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TLwlELzvTXLJeFfP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TLwlELzvTXLJeFfP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TLwlELzvTXLJeFfP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TLwlELzvTXLJeFfP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TLwlELzvTXLJeFfP .marker.cross{stroke:#333333;}#mermaid-svg-TLwlELzvTXLJeFfP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TLwlELzvTXLJeFfP p{margin:0;}#mermaid-svg-TLwlELzvTXLJeFfP .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-TLwlELzvTXLJeFfP .cluster-label text{fill:#333;}#mermaid-svg-TLwlELzvTXLJeFfP .cluster-label span{color:#333;}#mermaid-svg-TLwlELzvTXLJeFfP .cluster-label span p{background-color:transparent;}#mermaid-svg-TLwlELzvTXLJeFfP .label text,#mermaid-svg-TLwlELzvTXLJeFfP span{fill:#333;color:#333;}#mermaid-svg-TLwlELzvTXLJeFfP .node rect,#mermaid-svg-TLwlELzvTXLJeFfP .node circle,#mermaid-svg-TLwlELzvTXLJeFfP .node ellipse,#mermaid-svg-TLwlELzvTXLJeFfP .node polygon,#mermaid-svg-TLwlELzvTXLJeFfP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TLwlELzvTXLJeFfP .rough-node .label text,#mermaid-svg-TLwlELzvTXLJeFfP .node .label text,#mermaid-svg-TLwlELzvTXLJeFfP .image-shape .label,#mermaid-svg-TLwlELzvTXLJeFfP .icon-shape .label{text-anchor:middle;}#mermaid-svg-TLwlELzvTXLJeFfP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-TLwlELzvTXLJeFfP .rough-node .label,#mermaid-svg-TLwlELzvTXLJeFfP .node .label,#mermaid-svg-TLwlELzvTXLJeFfP .image-shape .label,#mermaid-svg-TLwlELzvTXLJeFfP .icon-shape .label{text-align:center;}#mermaid-svg-TLwlELzvTXLJeFfP .node.clickable{cursor:pointer;}#mermaid-svg-TLwlELzvTXLJeFfP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-TLwlELzvTXLJeFfP .arrowheadPath{fill:#333333;}#mermaid-svg-TLwlELzvTXLJeFfP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-TLwlELzvTXLJeFfP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-TLwlELzvTXLJeFfP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TLwlELzvTXLJeFfP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-TLwlELzvTXLJeFfP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TLwlELzvTXLJeFfP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-TLwlELzvTXLJeFfP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-TLwlELzvTXLJeFfP .cluster text{fill:#333;}#mermaid-svg-TLwlELzvTXLJeFfP .cluster span{color:#333;}#mermaid-svg-TLwlELzvTXLJeFfP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-TLwlELzvTXLJeFfP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-TLwlELzvTXLJeFfP rect.text{fill:none;stroke-width:0;}#mermaid-svg-TLwlELzvTXLJeFfP .icon-shape,#mermaid-svg-TLwlELzvTXLJeFfP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TLwlELzvTXLJeFfP .icon-shape p,#mermaid-svg-TLwlELzvTXLJeFfP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-TLwlELzvTXLJeFfP .icon-shape .label rect,#mermaid-svg-TLwlELzvTXLJeFfP .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TLwlELzvTXLJeFfP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-TLwlELzvTXLJeFfP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-TLwlELzvTXLJeFfP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 成功
失败
hipStreamCreate / WithFlags / WithPriority
ihipStreamCreate
new hip::Stream(...)
hStream->Create()
*stream = reinterpret_cast(hStream)
Stream::Destroy -> hipErrorOutOfMemory


4. 关键属性

成员 含义
device_ 所属 hip::Device
priority_ 调度优先级:High(-1) / Normal(0) / Low(1)
flags_ 创建标志,如 hipStreamNonBlocking
null_ 是否为 null(默认遗留)流
cuMask_ CU 掩码,限制可用的计算单元
stream_id_ 进程内唯一流 ID
captureStatus_ 等 图捕获(graph capture)相关状态
detached_ green context 生命周期标志

4.1 优先级

Priority 枚举定义为 High = -1, Normal = 0, Low = 1,通过 convertToQueuePriority() 映射到 amd::CommandQueue::Priority。优先级范围由 hipDeviceGetStreamPriorityRange 暴露。


5. 特殊 stream 语义

5.1 Null stream(默认流)

传 nullptr 或 hipStreamLegacy 时,运行时使用设备的 null stream。它与其他 stream 有隐式同步 语义。isValid 对 null/legacy 直接返回 true。

5.2 Per-thread default stream

hipStreamPerThread 通过 StreamPerThread 为每线程、每设备惰性创建一个独立默认流:

cpp 复制代码
hipStream_t StreamPerThread::Get() {
  const int currDev = hip::getCurrentDevice()->deviceId();
  if (streams_.empty()) streams_.resize(g_devices.size());
  if (streams_[currDev] == nullptr || !hip::isValid(streams_[currDev])) {
    ihipStreamCreate(&streams_[currDev], hipStreamDefault, Priority::Normal);
  }
  return streams_[currDev];
}

它对 hipDeviceReset 做了防御性重建。解析入口为 getStreamPerThread。

5.3 句柄解析流程

#mermaid-svg-YEttLi26GHOyPf2F{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YEttLi26GHOyPf2F .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YEttLi26GHOyPf2F .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YEttLi26GHOyPf2F .error-icon{fill:#552222;}#mermaid-svg-YEttLi26GHOyPf2F .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YEttLi26GHOyPf2F .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YEttLi26GHOyPf2F .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YEttLi26GHOyPf2F .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YEttLi26GHOyPf2F .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YEttLi26GHOyPf2F .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YEttLi26GHOyPf2F .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YEttLi26GHOyPf2F .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YEttLi26GHOyPf2F .marker.cross{stroke:#333333;}#mermaid-svg-YEttLi26GHOyPf2F svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YEttLi26GHOyPf2F p{margin:0;}#mermaid-svg-YEttLi26GHOyPf2F .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YEttLi26GHOyPf2F .cluster-label text{fill:#333;}#mermaid-svg-YEttLi26GHOyPf2F .cluster-label span{color:#333;}#mermaid-svg-YEttLi26GHOyPf2F .cluster-label span p{background-color:transparent;}#mermaid-svg-YEttLi26GHOyPf2F .label text,#mermaid-svg-YEttLi26GHOyPf2F span{fill:#333;color:#333;}#mermaid-svg-YEttLi26GHOyPf2F .node rect,#mermaid-svg-YEttLi26GHOyPf2F .node circle,#mermaid-svg-YEttLi26GHOyPf2F .node ellipse,#mermaid-svg-YEttLi26GHOyPf2F .node polygon,#mermaid-svg-YEttLi26GHOyPf2F .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YEttLi26GHOyPf2F .rough-node .label text,#mermaid-svg-YEttLi26GHOyPf2F .node .label text,#mermaid-svg-YEttLi26GHOyPf2F .image-shape .label,#mermaid-svg-YEttLi26GHOyPf2F .icon-shape .label{text-anchor:middle;}#mermaid-svg-YEttLi26GHOyPf2F .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YEttLi26GHOyPf2F .rough-node .label,#mermaid-svg-YEttLi26GHOyPf2F .node .label,#mermaid-svg-YEttLi26GHOyPf2F .image-shape .label,#mermaid-svg-YEttLi26GHOyPf2F .icon-shape .label{text-align:center;}#mermaid-svg-YEttLi26GHOyPf2F .node.clickable{cursor:pointer;}#mermaid-svg-YEttLi26GHOyPf2F .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YEttLi26GHOyPf2F .arrowheadPath{fill:#333333;}#mermaid-svg-YEttLi26GHOyPf2F .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YEttLi26GHOyPf2F .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YEttLi26GHOyPf2F .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YEttLi26GHOyPf2F .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YEttLi26GHOyPf2F .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YEttLi26GHOyPf2F .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YEttLi26GHOyPf2F .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YEttLi26GHOyPf2F .cluster text{fill:#333;}#mermaid-svg-YEttLi26GHOyPf2F .cluster span{color:#333;}#mermaid-svg-YEttLi26GHOyPf2F div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YEttLi26GHOyPf2F .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YEttLi26GHOyPf2F rect.text{fill:none;stroke-width:0;}#mermaid-svg-YEttLi26GHOyPf2F .icon-shape,#mermaid-svg-YEttLi26GHOyPf2F .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YEttLi26GHOyPf2F .icon-shape p,#mermaid-svg-YEttLi26GHOyPf2F .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YEttLi26GHOyPf2F .icon-shape .label rect,#mermaid-svg-YEttLi26GHOyPf2F .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YEttLi26GHOyPf2F .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YEttLi26GHOyPf2F .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YEttLi26GHOyPf2F :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} nullptr / hipStreamLegacy
hipStreamPerThread
普通句柄
hipStream_t 句柄
值?
设备 null stream
getStreamPerThread -> 线程局部流
reinterpret_cast
hip::Stream*


6. 执行与同步

因为 hip::Stream 就是 HostQueue,命令执行依托基类接口:

  • 提交 :command->enqueue() 把命令放入队列尾部。
  • 同步整条流 :stream.finish()(阻塞 host 直到队列清空),见 hipStreamSynchronize_common。
  • 同步单条命令 :command->queue()->finishCommand(command)。
  • 依赖串接 :getLastQueuedCommand() + amd::Marker 在跨队列时建立依赖(见 ihipMemcpy 尾部逻辑)。

hipStreamSynchronize 的处理:

cpp 复制代码
hipError_t hipStreamSynchronize_common(hipStream_t stream) {
  getStreamPerThread(stream);
  if (stream == nullptr) {               // null 流:只同步阻塞流
    getCurrentDevice()->SyncAllStreams(false, /*blockingOnly*/ true);
    return hipSuccess;
  }
  CHECK_STREAM_DETACHED(stream);
  if (stream != hipStreamLegacy && hip::Stream::StreamCaptureOngoing(stream))
    HIP_RETURN(hipErrorStreamCaptureUnsupported);  // 捕获中不允许同步
  auto hip_stream = hip::getStream(stream, /*wait*/ false);
  hip_stream->finish();
  hip_stream->GetDevice()->ReleaseFreedMemory();
  return hipSuccess;
}

7. 流捕获(Stream Capture / HIP Graph)

hip::Stream 承担了把一串命令录制成 hip::Graph 的职责。相关状态机:

状态 含义
hipStreamCaptureStatusNone 未捕获
hipStreamCaptureStatusActive 正在捕获
hipStreamCaptureStatusInvalidated 捕获被破坏(非法操作触发)

关键机制:

  • SetCaptureGraph() 开始捕获,状态置为 Active。
  • lastCapturedNodes_ / removedDependencies_ 维护图节点依赖关系。
  • parallelCaptureStreams_ 记录 fork 出的并行分支,EndCapture() 会递归结束它们。
  • captureEvents_ 把 event 绑定到当前捕获。

StreamCaptureOngoing 实现了三种捕获模式下的跨流失效策略:

  • Relaxed:不干扰其他流。
  • Global:使所有线程中正在捕获的流失效。
  • ThreadLocal:仅使当前线程的捕获流失效。

正因为捕获期间不允许隐式同步,像 hipMemcpyWithStream 这类"异步+同步"的 API 会先检查 StreamCaptureOngoing 并在捕获中返回 hipErrorStreamCaptureUnsupported。


8. 执行上下文(Green Context)与 Detach

为支持 green context 资源隔离,stream 引入了 detached_ 原子标志:

cpp 复制代码
void Stream::Detach() {
  if (captureStatus_ == hipStreamCaptureStatusActive) {
    captureStatus_ = hipStreamCaptureStatusInvalidated;
    for (auto s : parallelCaptureStreams_)
      reinterpret_cast<hip::Stream*>(s)->SetCaptureStatus(hipStreamCaptureStatusInvalidated);
  }
  detached_.store(true, std::memory_order_release);
}

当拥有该流的 ExecutionCtx 被销毁时调用 Detach():

  • 正在进行的捕获被置为 invalidated(含所有并行分支)。
  • 之后对该流的提交/同步 API 须返回 hipErrorStreamDetached(由 CHECK_STREAM_DETACHED 宏强制)。
  • hipStreamDestroy 对已 detach 的流仍可成功。

9. 有效性与设备注册

  • 每个 hip::Device 维护其 stream 集合,通过 AddStream / RemoveStream / StreamExists 管理。
  • hip::isValid(stream) 遍历所有设备确认句柄仍被某设备持有,用于 API 入口的健壮性校验。

10. 典型调用链示例(以内存拷贝为例)

HSA/ROCr + SDMA/CU amd::*MemoryCommand hip::Stream (HostQueue) hipMemcpyWithStream 用户代码 HSA/ROCr + SDMA/CU amd::*MemoryCommand hip::Stream (HostQueue) hipMemcpyWithStream 用户代码 #mermaid-svg-CJEinOJG0kZfi2ve{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CJEinOJG0kZfi2ve .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CJEinOJG0kZfi2ve .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CJEinOJG0kZfi2ve .error-icon{fill:#552222;}#mermaid-svg-CJEinOJG0kZfi2ve .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CJEinOJG0kZfi2ve .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CJEinOJG0kZfi2ve .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CJEinOJG0kZfi2ve .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CJEinOJG0kZfi2ve .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CJEinOJG0kZfi2ve .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CJEinOJG0kZfi2ve .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CJEinOJG0kZfi2ve .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CJEinOJG0kZfi2ve .marker.cross{stroke:#333333;}#mermaid-svg-CJEinOJG0kZfi2ve svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CJEinOJG0kZfi2ve p{margin:0;}#mermaid-svg-CJEinOJG0kZfi2ve .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-CJEinOJG0kZfi2ve text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-CJEinOJG0kZfi2ve .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-CJEinOJG0kZfi2ve .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-CJEinOJG0kZfi2ve .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-CJEinOJG0kZfi2ve .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-CJEinOJG0kZfi2ve #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-CJEinOJG0kZfi2ve .sequenceNumber{fill:white;}#mermaid-svg-CJEinOJG0kZfi2ve #sequencenumber{fill:#333;}#mermaid-svg-CJEinOJG0kZfi2ve #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-CJEinOJG0kZfi2ve .messageText{fill:#333;stroke:none;}#mermaid-svg-CJEinOJG0kZfi2ve .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-CJEinOJG0kZfi2ve .labelText,#mermaid-svg-CJEinOJG0kZfi2ve .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-CJEinOJG0kZfi2ve .loopText,#mermaid-svg-CJEinOJG0kZfi2ve .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-CJEinOJG0kZfi2ve .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-CJEinOJG0kZfi2ve .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-CJEinOJG0kZfi2ve .noteText,#mermaid-svg-CJEinOJG0kZfi2ve .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-CJEinOJG0kZfi2ve .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-CJEinOJG0kZfi2ve .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-CJEinOJG0kZfi2ve .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-CJEinOJG0kZfi2ve .actorPopupMenu{position:absolute;}#mermaid-svg-CJEinOJG0kZfi2ve .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-CJEinOJG0kZfi2ve .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-CJEinOJG0kZfi2ve .actor-man circle,#mermaid-svg-CJEinOJG0kZfi2ve line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-CJEinOJG0kZfi2ve :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 传入 hipStream_tisValid / StreamCaptureOngoing 校验hip::getStream(stream) 解析ihipMemcpy 构造拷贝命令command->>enqueue()提交到底层硬件队列finishCommand (同步型) 等待完成数据搬运完成


11. 小结

维度 实现要点
本质 继承 amd::HostQueue 的 FIFO 命令队列
句柄 hipStream_t 与 hip::Stream* 直接 reinterpret_cast
执行 enqueue 提交,finish/finishCommand 同步,底层对接 HSA/ROCr
特殊流 null stream(隐式同步)、per-thread default(线程+设备惰性创建)
调度 优先级(High/Normal/Low)+ CU mask
高级特性 Stream capture(HIP Graph 录制)、green context detach
生命周期 引用计数管理,private 析构,设备注册表跟踪

hip::Stream 是连接 HIP 公开 API 与 ROCclr 命令执行引擎的枢纽:对上提供 CUDA 兼容的 stream 语义,对下将所有 GPU 操作组织为有序、可并发、可录制的命令队列。