Skip to main content

单线程多Stream

原理介绍

在pyACL中,Stream是一个任务队列,应用程序通过Stream来管理任务的并行,一个Stream内部的任务保序执行,即Stream根据发送过来的任务依次执行;不同Stream中的任务并行执行。一个默认Context下会挂一个默认Stream,如果不显式创建Stream,可使用默认Stream。默认Stream作为接口入参时,直接传0。

父主题: Stream管理

多Stream接口调用流程

开发应用时,如果涉及多Stream之间的任务等待,则应用程序中必须包含相关的代码逻辑,关于该场景的接口调用流程,请依次参见pyACL接口调用流程以及本节中的说明。

图1 同步等待流程_多Stream场景

多Stream之间任务的同步等待可以利用Event实现,调用acl.rt.stream_wait_event接口阻塞指定Stream的运行,直到指定的Event完成。需在调用acl.rt.stream_wait_event接口前,先调用acl.rt.record_event接口。调用示例请参见关于Stream间任务的同步等待

模型加载与执行的流程请参见开发基础推理应用

算子加载与执行的流程请参见单算子调用

父主题: Stream管理

单线程单Stream

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

import acl
## ......
ACL_MEMCPY_HOST_TO_DEVICE = 1

## 显式创建一个Stream。
stream, ret = acl.rt.create_stream()

## 调用触发任务的接口,传入stream参数。
ret = acl.rt.memcpy_async(dev_ptr, dev_size, host_ptr, host_size, ACL_MEMCPY_HOST_TO_DEVICE, stream)
## 调用acl.rt.synchronize_stream接口,阻塞应用程序运行,直到指定Stream中的所有任务都完成。
ret = acl.rt.synchronize_stream(stream)

## Stream使用结束后,显式销毁Stream。
ret = acl.rt.destroy_stream(stream)
## ......

父主题: Stream管理

单线程多Stream

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

import acl
## ......

device_id = 0
model_id_1 = 0
model_id_2 = 1

## 如果只创建了一个Context,线程默认将这个Context作为线程当前的Context。
## 如果是多个Context,则需要调用acl.rt.create_context接口设置当前线程的Context。
context, ret = acl.rt.create_context(device_id)

stream1, ret = acl.rt.create_stream()
## 调用触发任务的接口,例如异步模型推理,任务下发在stream1。
ret = acl.mdl.execute_async(model_id_1, dataset_in_1, dataset_out_1, stream1)

stream2, ret = acl.rt.create_stream()
## 调用触发任务的接口,例如异步模型推理, 任务下发在stream2。
ret = acl.mdl.execute_async(model_id_2, dataset_in_2, dataset_out_2, stream2)

## 流同步。
ret = acl.rt.synchronize_stream(stream1)
ret = acl.rt.synchronize_stream(stream2)

## 释放资源。
ret = acl.rt.destroy_stream(stream2)
ret = acl.rt.destroy_stream(stream1)
ret = acl.rt.destroy_context(context)

## ....

父主题: Stream管理

多线程多Stream

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>python<br>import acl<br># ......<br>def run_thread(stream):<br> device_id = 0<br> # 如果只创建了一个Context,线程默认将这个Context作为线程当前的Context。<br> # 如果是多个Context,则需要调用acl.rt.set_context接口设置当前线程的Context。<br> context, ret = acl.rt.create_context(device_id)<br> stream, ret = acl.rt.create_stream()<br> # 调用触发任务的接口。<br> # ....<br> # 释放资源。<br> ret = acl.rt.destroy_stream(stream)<br> ret = acl.rt.destroy_context(context)<br> <br># 创建2个线程,每个线程对应一个Stream。<br>thread_id1, ret = acl.util.start_thread(run_thread, stream1)<br>thread_id2, ret = acl.util.start_thread(run_thread, stream2)<br># 显式调用join函数确保结束线程。<br>ret = acl.util.stop_thread(thread_id1)<br>ret = acl.util.stop_thread(thread_id2)<br>

父主题: Stream管理

基本原理

同步机制

pyACL提供以下几种同步机制:

  • Event的同步等待:调用acl.rt.synchronize_event接口,阻塞应用程序运行,等待Event完成。
  • Stream内任务的同步等待:调用acl.rt.synchronize_stream接口,阻塞应用程序运行,直到指定Stream中的所有任务都完成。
  • Stream间任务的同步等待:调用acl.rt.stream_wait_event接口,阻塞指定Stream的运行,直到指定的Event完成。支持多个Stream等待同一个Event的场景。接口调用流程请参见多Stream接口调用流程
  • Device的同步等待:调用acl.rt.synchronize_device接口,阻塞应用程序运行,直到正在运算中的Device完成运算。

父主题: 同步等待

关于Event的同步等待

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>python<br>import acl<br># ......<br># 创建一个Event。<br>event, ret = acl.rt.create_event()<br># 创建一个Stream。<br>stream, ret = acl.rt.create_stream()<br># stream末尾添加了一个event。<br>ret = acl.rt.record_event(event, stream)<br># 阻塞应用程序运行,等待event发生,也就是stream执行完成。<br># stream完成后产生event,唤醒执行应用程序的控制流,开始执行程序。<br>ret = acl.rt.synchronize_event(event)<br># 显式销毁资源。<br>ret = acl.rt.destroy_stream(stream)<br>ret = acl.rt.destroy_event(event)<br># ......<br>

父主题: 同步等待

在线提单