MSCCL:如何运行自定义集合通信算法

        MSCCL是微软开源的一个支持自定义集合通信算法的开源集合通信库

        GitHub网址:GitHub - microsoft/msccl: Microsoft Collective Communication Library

        使用MSCCL需要输入自定义的集合通信算法,自定义的算法需要以MSCCL规定的表示存在XML文件里,也就是MSCCL_XML_FILES环境变量指定的XML文件。

        也就是说,如果想自己设置集合通信算法,并在GPUs上运行,总共分为以下几步:

        ① 克隆MSCCL到本地,然后按照GitHub上给的指南进行编译

        ② 按照MSCCL规定的格式撰写XML文件

        ③ 设置MSCCL_XML_FILES环境变量为XML文件所在的路径,并且设置NCCL_ALGO环境变量为MSCCL(也可以不设,只要满足条件,MSCCL会优先使用MSCCL自定义算法)

        注意:MSCCL只有在满足以下条件的情况下才会使用自定义算法

if ((mscclAlgo->isValid) && (info->comm->bandwidths[info->coll][NCCL_ALGO_MSCCL][mscclAlgo->protocol] > 0) 
            && (mscclAlgo->collectiveType == info->coll) && (inPlace == mscclAlgo->inPlace) && (mscclAlgo->ngpus == info->comm->nRanks)
            && ((totalCount % mscclAlgo->nchunksPerLoop) == 0) && (info->nBytes >= mscclAlgo->minBytes) && (info->nBytes < mscclAlgo->maxBytes)) {
          info->algorithm = NCCL_ALGO_MSCCL;
          info->protocol = mscclAlgo->protocol;
          info->mscclInfo.mscclAlgoIndex = i;
          return ncclSuccess;
        }

        XML文件的格式和各个参数含义如下所示:

<algo name="taccl" nchannels="1" nchunksperloop="4" proto="Simple" coll="allgather" inplace="1" redop="nop" ngpus="4" minBytes="0" maxBytes="1073741824">
//name:算法名称,这个无关紧要
//nchannels:channel的数量,后续可以通过chan来指定该Block属于哪个channel
//nchunksperloop:一次循环可以结束多少个chunk的操作(不仅仅是自己的是单次循环所有的,例如AllGather算法本rank有1个chunk,那么nchunksperloop就是nranks个chunk)
//proto:底层协议,总共有三个协议:Simple,LL,LL128;Simple是一次传输中间缓冲区的一半,相当于每次都传最多的量;LL是一次传输一个小包,延迟比较低,数据传了立马收,不等攒够;LL128是Simple和LL的折中,包没有LL那么小,设置为128字节
//coll:集合通信算法的名称,执行相应名称的集合通信算法时会用MSCCL的这个算法替换
//inplace:设置该算法是否是原地执行,即sendbuffer(inputbuffer)与recvbuffer(outputbuffer)相同,如果上层调用的不是这个算法的原地类型则不执行MSCCL的这个算法(比如上层调用时sendbuff==recvbuff,但是inplace为0则不会调用这个算法,而是会调用NCCL默认算法中的最优算法)
//redop:MSCCL里没说
//ngpus:指定GPU的数量,MSCCL会根据这个参数接收后面的操作,写的是几就接收几个<gpu>
//minBytes:指定使用自定义算法的最小字节数,为了能保证使用自定义算法,建议设置为0,即任何情况下均满足最小字节数的约束
//maxBytes:指定使用自定义算法的最大字节数,不添加此参数的话,MSCCL会设置其为128MB,如果有需求可以设置得非常大(例子中设置为1GB,注意是字节数目的十进制表示)

  <gpu id="0" i_chunks="1" o_chunks="4" s_chunks="0">
  //id:GPU的rank号
  //i_chunks:input的chunk数量
  //o_chunks:output的chunk数量
  //s_chunks:临时缓冲区的chunk数量,后续MSCCL会根据ScratchChunk的大小来分配相同大小的缓冲区(该临时缓冲区和中间缓冲区不一样,该临时缓冲区叫ScratchBuffer是MSCCL特有的,和NCCL后端使用的中间缓冲区是不同的缓冲区)

    <copy i_off="0" o_off="0"/>
    //copy:copy操作,意思是把前面的内容存储进后面的存储空间里,比如这一句的操作就是把inputbuffer里面0号chunk复制到outputbuffer的0号chunk所在位置(MSCCL里没有,看上去是这个意思)

    <tb id="0" send="-1" recv="1" chan="0">
    //tb:一个tb里面的内容表示一个Block的所有操作
    //id:该Block的序号,不能重复,比如这句的意思就是该Block为0号Block
    //send:发送给几号rank,不发就是-1
    //recv:从几号rank接收,不接收就是-1
    //chan:该Block属于几号channel,不同channel同一个peer的中间buffer不同,但是同一个channel下同一个peer的中间buffer是同一个

      <step s="0" type="r" srcbuf="o" srcoff="1" dstbuf="o" dstoff="1" cnt="1" depid="-1" deps="-1" hasdep="0"/>
      //step:Block操作的第几步,同一步只能是一种操作,可以一次可以多次
      //type:MSCCL会根据type值不同来调用不同的NCCL后端原语,TACCL里面只有s和r两种;但是实际上还有rcs,rrs,rrc等操作,TACCL的AllReduce比NCCL慢就是因为使用的原语效率不高
      //srcbuf:指定数据从本GPU的哪个buffer取,这里写的是o,说明从本GPU的outputbuffer里面取
      //srcoff:源偏移量,标识取源buffer的第几个chunk
      //desbuf:指定想要传输给对端哪个buffer,这里写的是o,说明想传给outputbuffer
      //dstoff:目的偏移量,标识传给目的buffer的第几个chunk所在的位置
      //cnt:该操作重复多少次之后进入下一个step
      //depid:表示该操作依赖于几号Block的操作
      //deps:表示该操作依赖于第几个Step
      //hasdep:该步操作的数据是否是别的Block需要的,0是不需要,1是需要;比如0号Block在Step1时recv的chunk是1号Block在Step2时send所需要的,即1号Block依赖于0号Block,那么这个值就应该是1表示需要进行数据存储同步

    </tb>//括回

  </gpu>//括回
  
</algo>//括回
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值