<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>ReduceScatter on Echo的技术博客</title><link>https://cybersecurityerial.github.io/echo_blog/tags/reducescatter/</link><description>Recent content in ReduceScatter on Echo的技术博客</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sun, 05 Jul 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://cybersecurityerial.github.io/echo_blog/tags/reducescatter/index.xml" rel="self" type="application/rss+xml"/><item><title>LLM System: 通信计算融合算子实现 01 - sm80GEMM + ReduceScatter</title><link>https://cybersecurityerial.github.io/echo_blog/posts/llm-system-comm-comp-fusion-operators-01-ampere-gemm-rs/</link><pubDate>Sun, 05 Jul 2026 00:00:00 +0800</pubDate><guid>https://cybersecurityerial.github.io/echo_blog/posts/llm-system-comm-comp-fusion-operators-01-ampere-gemm-rs/</guid><description>&lt;h2 id="flux实现sm80-gemmrs"&gt;flux实现：sm80 gemm+rs&lt;/h2&gt;
&lt;p&gt;看flux的论文来说，原理并不难，修改的是ffn的第二个gemm的epi阶段，让epi阶段的写回操作变成写入reducescatter的通信buffer，相当于做了一次零拷贝。
几个关键的点：1. 如何用cutlass自定义epi阶段。2. 用了什么ptx。3. 清零？&lt;/p&gt;
&lt;h2 id="cutlass自定义epiloguesm80"&gt;cutlass自定义epilogue&amp;ndash;sm80&lt;/h2&gt;
&lt;p&gt;常规的epi，写回gmem，这里改成写在scatter-aware-memory（我自己起的名字）。cutlass封装自定义epi的逻辑抽象是：输出tile存到哪里，以及做什么运算，这分别是两个模版类：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; EVT_D &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;decltype&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;evt_d(kparams));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; StoreD &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;decltype&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;evt_store_d(kparams));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;using&lt;/span&gt; EVT &lt;span style="color:#f92672"&gt;=&lt;/span&gt; cutlass&lt;span style="color:#f92672"&gt;::&lt;/span&gt;epilogue&lt;span style="color:#f92672"&gt;::&lt;/span&gt;threadblock&lt;span style="color:#f92672"&gt;::&lt;/span&gt;Sm80EVT&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;StoreD, EVT_D&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;StoreD就是规定了怎么存，EVTD就是规定了怎么算。
EVT全称epilogue visitor tree就是定义了一个epi阶段的计算-访存操作流，用树状图的形式保存epi阶段的一堆操作（做成图应该是为了方便接入nvcc？不懂为啥非得在这强调是tree）一个树节点（操作）是一个visitor。&lt;/p&gt;
&lt;h3 id="custom_evt_d"&gt;custom_evt_d()&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;EVT_Compute0 = alpha * accumulator
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;代码里对应 VisitorCompute&amp;lt;cutlass::multiplies, &amp;hellip;&amp;gt;，两个输入是 VisitorScalarBroadcast&lt;!-- raw HTML omitted --&gt; 和 VisitorAccFetch。第一个负责广播 alpha，第二个v从 GEMM accumulator 里拿当前 tile 的结果，然后 multiply&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;EVT_Compute1 = beta * C + EVT_Compute0 = beta * C + alpha * accumulator
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;代码里对应 VisitorAuxLoadGemmk 先把 C/bias 读进 epilogue，然后 VisitorCompute&amp;lt;cutlass::multiply_add, &amp;hellip;&amp;gt; 做 beta * C + alpha * acc。因为CUTLASS 2.x 没有 SM90 那种 SrcFetch 替代物，所以这里用 VisitorAuxLoadGemmk 来读 C。&lt;/p&gt;</description></item></channel></rss>