NCCL集合通信算子DEMO及性能测试

2024-04-13 05:44

本文主要是介绍NCCL集合通信算子DEMO及性能测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

NCCL集合通信算子DEMO及性能测试

  • 一.复现代码

以下代码用于测试NCCL算子的性能及正确性

一.复现代码

tee ccl_benchmark.py <<-'EOF'
import os
import torch
import argparse
import torch.distributed as dist
from torch.distributed import ReduceOp
from datetime import datetime
import time
import argparse
import numpy as np
dev_type="cuda"class Timer:def __init__(self,duration):        self.duration=durationdef __enter__(self):dist.barrier()self.beg= datetime.now().timestamp() * 1e6def __exit__(self, exc_type, exc_val, exc_tb):dist.barrier()self.end=datetime.now().timestamp() * 1e6self.duration.append(self.end-self.beg)op_mapping={}
class ccl_benchmark:def __init__(self,func):global op_mapping  op_mapping[func.__name__]=funcself.func=funcdef __call__(self,*args,**kwargs):return self.func(*args,**kwargs)@ccl_benchmark
def all_gather(shape,device,rank,world_size,iters=5):'''将每个rank input_tensor的数据在dim 0维度拼接在一起'''duration=[]input_tensor=(torch.ones((shape[0]//world_size,shape[1]),dtype=torch.int64)*(100+rank)).to(device)gather_list=[torch.zeros((shape[0]//world_size,shape[1]),dtype=torch.int64).to(device) for _ in range(world_size)]for _ in range(iters):with Timer(duration):dist.all_gather(gather_list,input_tensor)   output=torch.cat(gather_list,dim=0)gt=[torch.ones((shape[0]//world_size,shape[1]),dtype=torch.int64)*(100+i) for i in range(world_size)]gt=torch.cat(gt,dim=0)return duration,(output.cpu()==gt).all()@ccl_benchmark
def scatter(shape,device,rank,world_size,iters=5):'''将每个rank从scatter_list[rank]取数据到output_tensor'''duration=[]output_tensor=torch.zeros((shape[0]//world_size,shape[1]),dtype=torch.int64).to(device)scatter_list=[(torch.ones((shape[0]//world_size,shape[1]),dtype=torch.int64)*i).to(device) for i in range(world_size)]for _ in range(iters):with Timer(duration):if rank == 0:dist.scatter(output_tensor,scatter_list=scatter_list,src =0)else:dist.scatter(output_tensor,src  = 0)gt=torch.ones((shape[0]//world_size,shape[1]),dtype=torch.int64)*rankreturn duration,(output_tensor.cpu()==gt).all()@ccl_benchmark
def gather(shape,device,rank,world_size,iters=5):'''将每个rank input_tensor的数据在dim 0维度拼接在一起 只在批定的rank做'''duration=[]input_tensor=(torch.ones((shape[0]//world_size,shape[1]),dtype=torch.int64)*(100+rank)).to(device)gather_list=[torch.zeros((shape[0]//world_size,shape[1]),dtype=torch.int64).to(device) for _ in range(world_size)]for _ in range(iters):with Timer(duration):if rank == 0:dist.gather(input_tensor,gather_list=gather_list,dst=0)else:dist.gather(input_tensor,dst=0)ret=Trueif rank==0:output=torch.cat(gather_list,dim=0)gt=[torch.ones((shape[0]//world_size,shape[1]),dtype=torch.int64)*(100+i) for i in range(world_size)]gt=torch.cat(gt,dim=0)ret=(output.cpu()==gt).all()return duration,ret@ccl_benchmark
def reduce(shape,device,rank,world_size,iters=5):'''将每个rank input_tensor的数据在dim 0维度拼接在一起 只在批定的rank做'''duration=[]   for _ in range(iters):input_tensor=(torch.ones((shape[0],shape[1]),dtype=torch.int64)*(100+rank)).to(device)# input_tensor的内容会被修改,所以放在循环里with Timer(duration):dist.reduce(input_tensor,dst=0,op=dist.ReduceOp.SUM)ret=Trueif rank==0:gt=[torch.ones((shape[0],shape[1]),dtype=torch.int64)*(100+i) for i in range(world_size)]gt_=gt[0]       for i in range(1,world_size):gt_=gt_+gt[i]ret=(input_tensor.cpu()==gt_).all()return duration,ret@ccl_benchmark
def broadcast(shape,device,rank,world_size,iters=5):'''将src的rank的数据广播到其它rank'''duration=[]   for _ in range(iters):input_tensor=(torch.ones((shape[0],shape[1]),dtype=torch.int64)*(100+rank)).to(device)with Timer(duration):dist.broadcast(input_tensor,src=0)gt=(torch.ones((shape[0],shape[1]),dtype=torch.int64)*(100+0)).to('cpu')ret=(input_tensor.cpu()==gt).all()return duration,ret@ccl_benchmark
def p2p(shape,device,rank,world_size,iters=5):'''将src的rank的数据广播到其它rank'''duration=[]   for _ in range(iters):input_tensor=(torch.ones((shape[0],shape[1]),dtype=torch.int64)*(100+rank)).to(device)with Timer(duration):if rank!=0:dist.recv(input_tensor,rank-1)               if rank!=world_size-1:               dist.send(input_tensor,dst=rank+1)   gt=(torch.ones((shape[0],shape[1]),dtype=torch.int64)*(100+0)).to('cpu')ret=(input_tensor.cpu()==gt).all()return duration,ret@ccl_benchmark
def all_reduce(shape,device,rank,world_size,iters=5):'''将每个rank input_tensor的数据在dim 0维度拼接在一起'''duration=[]   for _ in range(iters):input_tensor=(torch.ones((shape[0],shape[1]),dtype=torch.int64)*(100+rank)).to(device)# input_tensor的内容会被修改,所以放在循环里with Timer(duration):dist.all_reduce(input_tensor,op=dist.ReduceOp.SUM)gt=[torch.ones((shape[0],shape[1]),dtype=torch.int64)*(100+i) for i in range(world_size)]gt_=gt[0]       for i in range(1,world_size):gt_=gt_+gt[i]ret=(input_tensor.cpu()==gt_).all()return duration,ret@ccl_benchmark
def reduce_scatter(shape,device,rank,world_size,iters=5):''''''duration=[]output_tensor=torch.zeros((shape[0]//world_size,shape[1]),dtype=torch.int64).to(device)input_list=[(torch.ones((shape[0]//world_size,shape[1]),dtype=torch.int64)*(100*rank)+chunk_id).to(device) for chunk_id in range(world_size)]for _ in range(iters):with Timer(duration):dist.reduce_scatter(output_tensor,input_list=input_list,op=dist.ReduceOp.SUM)gt_list=[(torch.ones((shape[0]//world_size,shape[1]),dtype=torch.int64)*(100*rk)+rank).to('cpu') for rk in range(world_size)]gt_=gt_list[0]       for i in range(1,world_size):gt_=gt_+gt_list[i]    return duration,(output_tensor.cpu()==gt_).all()def main():dist.init_process_group(backend='nccl')if not torch.distributed.is_initialized():returnparser = argparse.ArgumentParser(description='test')parser.add_argument('--shape', type=str, default="(1024,8192)", help='Number of epochs to train.')parser.add_argument('--iters', type=int, default=5, help='Number of epochs to train.')parser.add_argument('--op', type=str, default="", help='Number of epochs to train.')args = parser.parse_args()global op_mappingif args.op in op_mapping:torch.manual_seed(1)world_size = torch.distributed.get_world_size()rank = torch.distributed.get_rank()local_rank=int(os.environ['LOCAL_RANK'])torch.cuda.set_device(local_rank)device = torch.device(dev_type,local_rank)shape=eval(args.shape)duration,passed=op_mapping[args.op](shape,device,rank,world_size,args.iters)time.sleep(0.1*rank)print("rank:{} op:{} shape:{} iters:{} mean(us):{:.3f} passed:{}".format(rank,args.op,shape,args.iters,np.mean(duration[len(duration)//2:]),passed))dist.destroy_process_group()if __name__=='__main__':main()EOFexport NCCL_DEBUG=error
export NCCL_SOCKET_IFNAME=ens8
export NCCL_IB_DISABLE=1  
torchrun -m --nnodes=1 --nproc_per_node=4 ccl_benchmark --op=all_gather --shape="(1024,4096)" --iters=5
torchrun -m --nnodes=1 --nproc_per_node=4 ccl_benchmark --op=scatter --shape="(1024,4096)" --iters=5
torchrun -m --nnodes=1 --nproc_per_node=4 ccl_benchmark --op=gather --shape="(1024,4096)" --iters=5
torchrun -m --nnodes=1 --nproc_per_node=4 ccl_benchmark --op=reduce --shape="(1024,4096)" --iters=5
torchrun -m --nnodes=1 --nproc_per_node=4 ccl_benchmark --op=broadcast --shape="(1024,4096)" --iters=5
torchrun -m --nnodes=1 --nproc_per_node=4 ccl_benchmark --op=p2p --shape="(1024,4096)" --iters=5
torchrun -m --nnodes=1 --nproc_per_node=4 ccl_benchmark --op=all_reduce --shape="(1024,4096)" --iters=5
torchrun -m --nnodes=1 --nproc_per_node=4 ccl_benchmark --op=reduce_scatter --shape="(1024,4096)" --iters=5

这篇关于NCCL集合通信算子DEMO及性能测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/899274

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

黑神话,XSKY 星飞全闪单卷性能突破310万

当下,云计算仍然是企业主要的基础架构,随着关键业务的逐步虚拟化和云化,对于块存储的性能要求也日益提高。企业对于低延迟、高稳定性的存储解决方案的需求日益迫切。为了满足这些日益增长的 IO 密集型应用场景,众多云服务提供商正在不断推陈出新,推出具有更低时延和更高 IOPS 性能的云硬盘产品。 8 月 22 日 2024 DTCC 大会上(第十五届中国数据库技术大会),XSKY星辰天合正式公布了基于星

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2