pytorch Stream 多流处理

news/2025/2/5 22:52:17/

CUD Stream

  • https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#c-language-extensions
    中指出在kenel的调用函数中最后一个可选参数表示该核函数处在哪个流之中。
    在这里插入图片描述
- 参数Dg用于定义整个grid的维度和尺寸,即一个grid有多少个block。为dim3类型。Dim3 Dg(Dg.x, Dg.y, 1)表示grid中每行有Dg.x个block,每列有Dg.y个block,第三维恒为1(目前一个核函数只有一个grid)。整个grid中共有Dg.x*Dg.y个block,其中Dg.x和Dg.y最大值为65535- 参数Db用于定义一个block的维度和尺寸,即一个block有多少个thread。为dim3类型。Dim3 Db(Db.x, Db.y, Db.z)表示整个block中每行有Db.x个thread,每列有Db.y个thread,高度为Db.z。Db.x和Db.y最大值为512,Db.z最大值为62。 一个block中共有Db.x*Db.y*Db.z个thread。计算能力为1.0,1.1的硬件该乘积的最大值为768,计算能力为1.2,1.3的硬件支持的最大值为1024- Ns 的类型为 size_t,用于设置每个block除了静态分配的shared Memory以外,最多能动态分配的shared memory大小,单位为byte。不需要动态分配时该值为0或省略不写。如[__shared__](https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared)中所述,此动态分配的内存由声明为外部数组的任何变量使用; 
- 参数S是一个cudaStream_t类型的可选参数,初始值为零,表示该核函数处在哪个流之中。
  • CUDA编程中,默认使用默认流非并行执行kernel,每个kernel由许多thread并行的执行在GPU上。Stream的概念是相对Grid level来说的,使得kernel在一个device上同时执行。
    https://developer.download.nvidia.com/CUDA/training/StreamsAndConcurrencyWebinar.pdf

  • 官方提供的用例

// https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#streams
cudaStream_t stream[2];
for (int i = 0; i < 2; ++i)cudaStreamCreate(&stream[i]);
float* hostPtr;
cudaMallocHost(&hostPtr, 2 * size);
// 以下代码示例将其中每个流定义为从主机到设备的一个内存副本、一个内核启动和一个从设备到主机的内存副本的序列:
for (int i = 0; i < 2; ++i) {cudaMemcpyAsync(inputDevPtr + i * size, hostPtr + i * size,size, cudaMemcpyHostToDevice, stream[i]);MyKernel <<<100, 512, 0, stream[i]>>>(outputDevPtr + i * size, inputDevPtr + i * size, size);cudaMemcpyAsync(hostPtr + i * size, outputDevPtr + i * size,size, cudaMemcpyDeviceToHost, stream[i]);
}
// 通过调用 释放流
for (int i = 0; i < 2; ++i)cudaStreamDestroy(stream[i]);

PyTorch Stream

  • 在PyTorch中,默认情况下,GPU上的操作是在默认流(default stream)中执行的。默认流是一个序列化的流,其中的操作按照它们出现的顺序逐个执行。这意味着在没有显式指定其他流的情况下,所有的操作都会在默认流中执行。

  • 然而,PyTorch还提供了功能可以将操作提交到其他流中执行,以充分利用GPU的并行性。这对于并行处理多个任务或同时执行多个独立操作非常有用。

  • 您可以使用torch.cuda.Stream()来创建其他流,并使用torch.cuda.current_stream()来获取当前流。然后,您可以将操作提交到指定的流中执行,例如:

import torchdevice = torch.device('cuda')# 创建一个默认流
default_stream = torch.cuda.current_stream()# 创建一个自定义流
custom_stream = torch.cuda.Stream()# 在默认流中执行操作
with torch.cuda.stream(default_stream):# 执行操作...# 在自定义流中执行操作
with torch.cuda.stream(custom_stream):# 执行操作...

例子

import torch
s1 = torch.cuda.Stream()
s2 = torch.cuda.Stream()
# Initialise cuda tensors here. E.g.:
A = torch.rand(1000, 1000, device = 'cuda')
B = torch.rand(1000, 1000, device = 'cuda')
# Wait for the above tensors to initialise.
torch.cuda.synchronize()
with torch.cuda.stream(s1):C = torch.mm(A, A)
with torch.cuda.stream(s2):D = torch.mm(B, B)
# Wait for C and D to be computed.
torch.cuda.synchronize()
# Do stuff with C and D.
print(C)
print(D)
// https://stackoverflow.com/questions/70128833/why-and-when-to-use-torch-cuda-stream

这样可以利用多个流来并行执行计算,并在计算和数据传输之间实现重叠。这对于提高GPU利用率和加速训练或推理过程非常有帮助。

错误示例

  • 没有使用 synchronize() 或者 wait_stream()进行同步,可能导致再未完成归一化前执行求和
// https://pytorch.org/docs/stable/notes/cuda.html
cuda = torch.device('cuda')
s = torch.cuda.Stream()  # Create a new stream.
A = torch.empty((100, 100), device=cuda).normal_(0.0, 1.0)
with torch.cuda.stream(s):# sum() may start execution before normal_() finishes!B = torch.sum(A)

CG

  • https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#streams

  • https://pytorch.org/docs/stable/notes/cuda.html#multistream-capture

  • https://pytorch.org/cppdocs/notes/tensor_cuda_stream.html

  • https://pypi.org/project/pytorch-stream/

  • CUDA 的 Stream and Event https://zhuanlan.zhihu.com/p/369367933

  • GITHUBGIST Gist就是小型代码片段的分享https://www.cnblogs.com/leader755/p/14284716.html

  • [JIT] 在 TorchScript 中支持 CUDA 流 https://github.com/pytorch/pytorch/issues/41355

  • https://pytorch.org/docs/stable/notes/cuda.html#cuda-semantics

  • https://github.com/pytorch/pytorch/issues/41355

多设备

// https://pytorch.org/docs/stable/notes/cuda.html#cuda-semantics
cuda = torch.device('cuda')     # Default CUDA device
cuda0 = torch.device('cuda:0')
cuda2 = torch.device('cuda:2')  # GPU 2 (these are 0-indexed)x = torch.tensor([1., 2.], device=cuda0)
# x.device is device(type='cuda', index=0)
y = torch.tensor([1., 2.]).cuda()
# y.device is device(type='cuda', index=0)with torch.cuda.device(1):# allocates a tensor on GPU 1a = torch.tensor([1., 2.], device=cuda)# transfers a tensor from CPU to GPU 1b = torch.tensor([1., 2.]).cuda()# a.device and b.device are device(type='cuda', index=1)# You can also use ``Tensor.to`` to transfer a tensor:b2 = torch.tensor([1., 2.]).to(device=cuda)# b.device and b2.device are device(type='cuda', index=1)c = a + b# c.device is device(type='cuda', index=1)z = x + y# z.device is device(type='cuda', index=0)# even within a context, you can specify the device# (or give a GPU index to the .cuda call)d = torch.randn(2, device=cuda2)e = torch.randn(2).to(cuda2)f = torch.randn(2).cuda(cuda2)# d.device, e.device, and f.device are all device(type='cuda', index=2)

http://www.ppmy.cn/news/1017387.html

相关文章

Python爬虫在电商数据挖掘中的应用

作为一名长期扎根在爬虫行业的专业的技术员&#xff0c;我今天要和大家分享一些有关Python爬虫在电商数据挖掘中的应用与案例分析。在如今数字化的时代&#xff0c;电商数据蕴含着丰富的信息&#xff0c;通过使用爬虫技术&#xff0c;我们可以轻松获取电商网站上的产品信息、用…

前端中常见的设计模式

1.单例模式 描述&#xff1a;保证一个类仅有实例&#xff0c;并提供一个可以全局访问他的点&#xff0c;它通常用于管理应用程序的全局状态或资源&#xff0c;例如一个唯一的状态管理器。 代码示例&#xff1a; class Singleton {constructor() {if (!Singleton.instance) {…

com.alibaba.fastjson.JSONObject循环给同一对象赋值会出现“$ref“:“$[0]“现象问题

文章目录 1、问题介绍2、如何解决fastjson中$ref对象重复引用问题3、举例说明 1、问题介绍 有些场景下&#xff0c;我们会选择用JSONObject代替Map来处理业务逻辑&#xff0c;但是使用JSONObject时有一个需要注意的地方&#xff1a;在处理JSONObject对象时&#xff0c;引用的c…

k8s之Pod控制器

目录 一、Pod控制器及其功用二、pod控制器的多种类型2.1 pod容器中的有状态和无状态的区别 三、Deployment 控制器四、SatefulSet 控制器4.1 StatefulSet由以下几个部分组成4.2 为什么要有headless&#xff1f;4.3 为什么要有volumeClaimTemplate&#xff1f;4.4 滚动更新4.5 扩…

开源数据集分类汇总(医学,卫星,分割,分类,人脸,农业,姿势等)

本文汇总了医学图像、卫星图像、语义分割、自动驾驶、图像分类、人脸、农业、打架识别等多个方向的数据集资源&#xff0c;均附有下载链接。 该文章仅用于学习记录&#xff0c;禁止商业使用&#xff01; 1.医学图像 疟疾细胞图像数据集 下载链接&#xff1a;http://suo.nz/2V…

七牛云获取qn(url、bucket、access-key、secret-key)

1.注册账号 2.access-key和secret-key&#xff1a; 点击“密钥管理” 复制AK和SK即可 域名&#xff1a; bucket&#xff1a; 这个就是对象存储空间名字 先新建一个空间&#xff08;没买需要先购买&#xff09;&#xff0c;步骤如下&#xff1a; 填写存储空间名字&#xff0…

在qemu中挂载镜像文件

将镜像文件作为交换分区 创建镜像文件&#xff1a; dd if/dev/zero ofswap.img bs512 count131072 qemu-system-arm -nographic -M vexpress-a9 -m 64M -kernel arch/arm/boot/zImage -append "rdinit/linuxrc consolettyAMA0 loglevel8" -dtb arch/arm/boot/dts/…

优雅的使用 Dockerfile 定制镜像

一、使用 Dockerfile 定制镜像 1.1、Dockerfile 定制镜像 1.2、FROM 指定基础镜像 1.3、RUN 执行命令 1.4、构建镜像 1.5、镜像构建上下文&#xff08;Context&#xff09; 1.6、其他 docker build 的用法 二、Dockerfile 指令 2.1、COPY 2.2、ADD 2.3、CMD 2.4、EN…