<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Blog</title>
    <description>Internet and Technology.</description>
    <link>https://erickguan.me/</link>
    <atom:link href="https://erickguan.me/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>LLM can accumulate cognitive debt</title>
        <description>&lt;p&gt;I read &lt;a href=&quot;https://arxiv.org/abs/2506.08872&quot;&gt;“Your Brain on ChatGPT: Accumulation of Cognitive Debt When Using an AI Assistant for Essay Writing Task.”&lt;/a&gt; &lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; It’s useful for deciding when to use LLMs in research and writing.&lt;/p&gt;

&lt;p&gt;Cognitive debt is when repeated reliance on external systems (like LLMs) displaces the effortful processes of independent thinking - saving effort now but costing depth, recall, and agency later.&lt;/p&gt;

&lt;p&gt;The study finds higher neural engagement when drafting unaided. So think first, write first, then ask an LLM for critique, revise, or fact-check.&lt;/p&gt;

&lt;h2 id=&quot;what-the-study-did&quot;&gt;What the study did&lt;/h2&gt;

&lt;p&gt;Participants completed three essay-writing sessions in one of three conditions, plus an crossover session.
Essays were written under electroencephalogram (EEG), with NLP and interviews used for analysis.
N=54 completed sessions 1-3; N=18 returned for session 4. Each essay takes about 20 minutes.
The 3 groups were:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;LLM: GPT-4o only&lt;/li&gt;
  &lt;li&gt;Search Engine: Google with “-ai” to suppress AI answers&lt;/li&gt;
  &lt;li&gt;Brain-only: no tools&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The study ran over 4 months.&lt;/p&gt;

&lt;h2 id=&quot;what-they-found&quot;&gt;What they found&lt;/h2&gt;

&lt;p&gt;I am interested in how should we use the technology itself from reading the paper. So I will only choose relevant conclusions. The paper offers a result of comparisons.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2025/yboc-tbl1.png&quot; alt=&quot;Results about comparison 1&quot; /&gt;
&lt;img src=&quot;/assets/images/2025/yboc-tbl2.png&quot; alt=&quot;Results about comparison 2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;First of all, there is evidence indicating that the brain-only group write essays using their brain “harder”.&lt;/p&gt;

&lt;p&gt;For example, brain-only participants showed higher activation levels in EEG and greater overall cognitive load. Writing unaided requires the brain to generate ideas, organize, and compose ideas internally. By contrast, with LLM assistance - though the essay often scored higher and were easier to write - the LLM group exerted less effort in self-monitoring. They also showed weaker memory traces and fragmented authorship.&lt;/p&gt;

&lt;p&gt;Moreover, participants in the Brain-to-LLM group (writing first unaided, then revising with LLM) showed greater meta-cognitive engagement. They likely invested more effort in coordinating with the model and making edits to LLM’s output.&lt;/p&gt;

&lt;p&gt;Finally, the paper finds a link between neural connectivity and behavioral quoting failures.
Participants more reliant on tools encoded information more shallowly. However, meta-cognitive engagement was generally higher for the Brain-to-LLM group.&lt;/p&gt;

&lt;h2 id=&quot;how-to-use-llm-without-cognitive-debt&quot;&gt;How to use LLM without “cognitive debt”&lt;/h2&gt;

&lt;p&gt;In a word, when writing something new, it’s better to &lt;strong&gt;draft firstly, unaided&lt;/strong&gt; and ask an LLM to check or refine your work.&lt;/p&gt;

&lt;p&gt;For “vibe coding” or day-to-day drafting, letting an agent like Claude run might not be the best approach for writing and learning.&lt;/p&gt;

&lt;p&gt;Using your brain earlier helps you memorize and think deeper. Using agents or LLM engages us differently. Still, quality can be significantly improved by layering in LLM checks at the end.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;Kosmyna, Nataliya, Eugene Hauptmann, Ye Tong Yuan, et al. “Your Brain on ChatGPT: Accumulation of Cognitive Debt When Using an AI Assistant for Essay Writing Task.” arXiv:2506.08872. Preprint, June 10, 2025. https://doi.org/10.48550/arXiv.2506.08872. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Wed, 01 Oct 2025 00:00:00 +0200</pubDate>
        <link>https://erickguan.me/2025/using-llm-cognition-effort</link>
        <guid isPermaLink="true">https://erickguan.me/2025/using-llm-cognition-effort</guid>
      </item>
    
      <item>
        <title>Latency values for programmers in 2024</title>
        <description>&lt;p&gt;Latency matters in software. As hardware evolves, the assumptions we make about computer systems must evolve with it. Programs often spend time waiting—on disk or network I/O, on another thread to finish work, or on a remote service to respond. Within a system, a database lock can stall other connections, and a global interpreter lock (GIL) can block parallel threads. These forms of contention are common and important to address. Although hardware has grown dramatically faster over the decades, the fundamental latency challenges remain. Below is what I learned in 2024.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Operation&lt;/th&gt;
      &lt;th&gt;Time in nanosecond&lt;/th&gt;
      &lt;th&gt;Time in microsecond&lt;/th&gt;
      &lt;th&gt;Time in millisecond&lt;/th&gt;
      &lt;th&gt;Comparison&lt;/th&gt;
      &lt;th&gt;Reference&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;L1 cache reference&lt;/td&gt;
      &lt;td&gt;0.7&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;Zen 5 numbers&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;L2 cache reference&lt;/td&gt;
      &lt;td&gt;2.5&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Branch mispredict&lt;/td&gt;
      &lt;td&gt;8&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;L3 cache reference&lt;/td&gt;
      &lt;td&gt;8&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Mutex lock/unlock&lt;/td&gt;
      &lt;td&gt;25&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Main memory reference&lt;/td&gt;
      &lt;td&gt;70&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;100x L1&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Send 2 kB over 10 Gbps network&lt;/td&gt;
      &lt;td&gt;1600&lt;/td&gt;
      &lt;td&gt;1.6&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Compress 1K bytes with Snappy&lt;/td&gt;
      &lt;td&gt;2000&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Read 1 MB sequentially from memory&lt;/td&gt;
      &lt;td&gt;10000&lt;/td&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;~50 GB/s DDR5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Read 4K randomly from SSD&lt;/td&gt;
      &lt;td&gt;20000&lt;/td&gt;
      &lt;td&gt;20&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;~10 GB/s NVMe&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Read 1 MB sequentially from NVMe&lt;/td&gt;
      &lt;td&gt;100000&lt;/td&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Round trip within same datacenter&lt;/td&gt;
      &lt;td&gt;100000&lt;/td&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;~0.5GB/sec SSD, 100x memory, 20x NVMe&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;SSD seek time&lt;/td&gt;
      &lt;td&gt;160,000&lt;/td&gt;
      &lt;td&gt;160&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;2,000x main memory&lt;/td&gt;
      &lt;td&gt;~150MB/sec&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Read 1 MB sequentially from SSD&lt;/td&gt;
      &lt;td&gt;2,000,000&lt;/td&gt;
      &lt;td&gt;2000&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;AWS region round trip&lt;/td&gt;
      &lt;td&gt;2,000,000&lt;/td&gt;
      &lt;td&gt;2000&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Read 1 MB sequentially from HDD&lt;/td&gt;
      &lt;td&gt;6,000,000&lt;/td&gt;
      &lt;td&gt;6000&lt;/td&gt;
      &lt;td&gt;6&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Send 1 MB over 1 Gbps network&lt;/td&gt;
      &lt;td&gt;10,000,000&lt;/td&gt;
      &lt;td&gt;10000&lt;/td&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;HDD random seek time&lt;/td&gt;
      &lt;td&gt;10,000,000&lt;/td&gt;
      &lt;td&gt;10000&lt;/td&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;Often times, data are located close by. The typical seek time should be lower.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Send packet CA-&amp;gt;Netherlands-&amp;gt;CA&lt;/td&gt;
      &lt;td&gt;150,000,000&lt;/td&gt;
      &lt;td&gt;150000&lt;/td&gt;
      &lt;td&gt;150&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Storage device and compute device innovations are most relevant to software applications. Apart from latency numbers, DDR5 runs at 6,000 MT/s, so this is 48,000 MB/s (random access). SSDs perform surprisingly well in terms of sequential read/write nowadays.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Sources&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://static.googleusercontent.com/media/sre.google/en/static/pdf/rule-of-thumb-latency-numbers-letter.pdf&quot;&gt;https://static.googleusercontent.com/media/sre.google/en//static/pdf/rule-of-thumb-latency-numbers-letter.pdf&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;http://web.archive.org/web/20240815121029/https:/gist.github.com/BlackHC/2d0a3a21542b524a7cf2f8eac977481e&quot;&gt;https://gist.github.com/BlackHC/2d0a3a21542b524a7cf2f8eac977481e&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://colin-scott.github.io/personal_website/research/interactive_latency.html&quot;&gt;https://colin-scott.github.io/personal_website/research/interactive_latency.html&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://cloud.ibm.com/docs/vpc?topic=vpc-network-latency-dashboard&quot;&gt;https://cloud.ibm.com/docs/vpc?topic=vpc-network-latency-dashboard&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://en.wikipedia.org/w/index.php?title=Hard_disk_drive_performance_characteristics&amp;amp;oldid=1221433550&quot;&gt;https://en.wikipedia.org/wiki/Hard_disk_drive_performance_characteristics&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
</description>
        <pubDate>Thu, 26 Sep 2024 00:00:00 +0200</pubDate>
        <link>https://erickguan.me/2024/latency-values</link>
        <guid isPermaLink="true">https://erickguan.me/2024/latency-values</guid>
      </item>
    
      <item>
        <title>WebAssembly vs. JVM: An Informal Peek</title>
        <description>&lt;p&gt;Recently, WebAssembly (WASM) has gained traction as a reference runtime, providing a way to run programs written in different programming languages. However, the Java Virtual Machine (JVM) is another popular platform for achieving similar functionality. When it comes to running programs on a virtual machine or compiling them into machine code, it’s also worth considering LLVM. In this blog post, I’ll share some thoughts based on my reading, although it’s not a complete analysis but rather a collection of ideas to encourage thinking and exploration.&lt;/p&gt;

&lt;h2 id=&quot;representation&quot;&gt;Representation&lt;/h2&gt;

&lt;p&gt;LLVM offers three different forms: an in-memory compiler Intermediate Representation (IR), an on-disk bitcode representation (optimized for fast loading by Just-In-Time compilers), and a human-readable assembly language representation. It’s important to note that LLVM itself is not a runtime. On the other hand, the JVM uses a binary representation for classes and interfaces, while WASM utilizes binary and text formats.&lt;/p&gt;

&lt;p&gt;Despite the differences in representation, the core principle of linking a program and executing it remains the same. Instructions and data can be represented in either text or binary formats on disk. The program must be loaded into memory, either dynamically or statically, before execution can take place.&lt;/p&gt;

&lt;p&gt;In my exploration, I found that the &lt;a href=&quot;https://webassembly.github.io/spec/core/exec/modules.html&quot;&gt;WASM specification&lt;/a&gt; surprisingly offers a simpler approach compared to LLVM and JVM. This simplicity may stem from the focus on optimization and features within the LLVM and JVM ecosystems. It’s worth noting that WASM is relatively new and primarily targets browser and integrated environments. Additionally, WASM’s streamability sets it apart from other tools.&lt;/p&gt;

&lt;h3 id=&quot;modules-in-wasm&quot;&gt;Modules in WASM&lt;/h3&gt;

&lt;p&gt;WASM organizes code structure into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modules&lt;/code&gt;, which serve as the unit of loading and compilation. Unlike JVM, modules are not equivalent to interfaces or classes. Instead, a module encompasses types, functions, memory, global variables, data, and execution symbols. In contrast, JVM represents these structures through a ClassFile, which contains metadata such as types, constants, methods, fields, and attributes. Instructions are stored as an attribute. LLVM’s representation, on the other hand, aligns more closely with machine code. Ultimately, LLVM supports compiler backends to translate its representation into machine code.&lt;/p&gt;

&lt;h3 id=&quot;instructions-in-wasm&quot;&gt;Instructions in WASM&lt;/h3&gt;

&lt;p&gt;Based on the high-level constructs mentioned earlier, WASM offers various types of instructions, including numerical, memory, table, variable, parametric, reference, vector, and control instructions. Some of these instructions resemble assembly code, while others bear similarities to JVM instructions. However, JVM includes additional instructions for handling null values, basic types, exceptions, and inheritance-related operations.&lt;/p&gt;

&lt;p&gt;By comparing these different platforms and their instruction sets, we can gain a better understanding of their respective strengths and use cases. How it is built is in details of course.&lt;/p&gt;

&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/bytecodealliance/wasmtime&quot;&gt;wasmtime&lt;/a&gt; serves as a standalone runtime for WebAssembly (WASM) and provides a clear structure outlined in its &lt;a href=&quot;https://docs.wasmtime.dev/contributing-architecture.html&quot;&gt;Architecture&lt;/a&gt; document. The runtime revolves around the concept of an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Engine&lt;/code&gt;, which serves as the global compilation context. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Store&lt;/code&gt; maintains the context and isolates WASM objects within a thread. The document also explains the compilation and execution processes, although the validation process will be excluded from this blog.&lt;/p&gt;

&lt;p&gt;Similar to the JVM, the runtime keeps track of all loaded modules. In the JVM, code is typically compiled into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.class&lt;/code&gt; files, and the JVM and class loaders collaborate to load symbols and instructions for a program. On the other hand, wasmtime seems to have a module linking procedure. While the multithreaded environment of the JVM is often discussed, the details regarding multithreading in wasmtime are not mentioned as prominently, which piques my interest.&lt;/p&gt;

&lt;h2 id=&quot;discussions&quot;&gt;Discussions&lt;/h2&gt;

&lt;p&gt;WASM defines a straightforward structure that allows programs to run on a runtime (or even without one). This approach facilitates the creation of desired characteristics across multiple programming languages. It differs from the approach taken by GraalVM. The ability to run different programming languages within a single runtime can significantly increase productivity. Integrating various programs and libraries into one runtime fosters better integration and reduces the cost of building blocks.&lt;/p&gt;

</description>
        <pubDate>Thu, 18 May 2023 00:00:00 +0200</pubDate>
        <link>https://erickguan.me/2023/wasm-jvm-informal-peek</link>
        <guid isPermaLink="true">https://erickguan.me/2023/wasm-jvm-informal-peek</guid>
      </item>
    
      <item>
        <title>Popular connectors for computers</title>
        <description>&lt;p&gt;&lt;sup&gt;Pin out tables, some photos and parts of data come from Wikipedia.&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Computers have various of connectors for their diverse use case. Overtime, old standard become obselete and new connector emerges. Some of them established their ground and dominates in their domains. It’s interesting to note their capability and how they got where they are. I am going to list some of them in this post and summarize key features. If you know a little bit about past standards, you might be amazed how technology eveolves step by step. Had if you know nothing about past standards, these connectors and standards would become old in the next decade or further in the future.&lt;/p&gt;

&lt;h2 id=&quot;usb&quot;&gt;USB&lt;/h2&gt;

&lt;p&gt;Starting from a golden standard of physical peripheral, this connector is &lt;em&gt;Universal Serial Bus&lt;/em&gt; (&lt;em&gt;USB&lt;/em&gt;). USB is everywhere. You can find them in laptops, cameras, drones, headsets, gaming consoles, and even industry machines. For example, latest Macbook Pro (2020) has 4 USB-C while their old predecessors have Thunderbolt connectors. Nowadays, most Android phones come with a USB-C connector.&lt;/p&gt;

&lt;p&gt;USB has become complicated and confusing industry standard. The confusing part comes with multiple physical connector types and its different versions. Motherboards usually have different types of USB 3.x receptacles or jump wires. Despite its historical burden, the latest version, USB-C aims to move forward with all advantages and drawbacks from its past versions and receptacles. In the past, USB’s standard series are widely used. It has a larger connector than other series which is called Type-A. Type-A usually presents on a PC. Type-B has a more or less square shape. It is usually used in a display. Apart from those large receptacles, the mini series can be generally found in mobile phones. You can find a table on &lt;a href=&quot;https://en.wikipedia.org/wiki/USB#Receptacle_(socket)_identification&quot;&gt;Wikipedia&lt;/a&gt; about different versions and receptacles. The interesting part of the chart is USB-C and USB4 as they are the only combination that are not deprecated after 2019.&lt;/p&gt;

&lt;p&gt;USB offers comfort to users. Devices can be hot-plugged. Devices can configure themselves with operating systems and take power from USB cables. USB also provides great abstraction for manufacturers and developers. They can focus on device functions instead of physical connectors and protocol designs.&lt;/p&gt;

&lt;p&gt;USB4 is the current standard which has only 1 receptacle (Type-C) with many technologies packed together. Considering USB 3.x series, USB 3.0, 3.1, 3.2 specification support a transfer mode of 5, 10, 20 Gbit/s.
By the way, they were rebranded with a new set of confusing names, USB 3.2 Gen 1, USB 3.2 Gen 2, USB 3.2 Gen 2x2. Speaking of USB’s simplicity, the user shall be able to connect to a receptacle and expect a device to set up itself. You are not suppose to connect a cable to a USB recepatacle and wonder why things were wrong. With past standards, you wouldn’t be able to connect a cable that does not fit the receptacles. But their speed difference can be huge. For instance, USB disks can be extremly slow with USB 2 receptacle and USB 3 cable. That won’t be the problem for USB 4 (Type-C).&lt;/p&gt;

&lt;p&gt;Type-C has 24 pins other than USB3’s 9 pins. Physically, USB Type-C receptacle looks smaller than its predecessor. It’s thin and packed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2020/connectors.jpeg&quot; alt=&quot;Different Connectors&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2020/USB_Type-C_Receptacle_Pinout.svg&quot; alt=&quot;USB Type-C pinouts&quot; /&gt;&lt;/p&gt;

&lt;table class=&quot;wikitable&quot; style=&quot;display: inline-table;&quot;&gt;
&lt;caption&gt;USB-C receptacle A pin layout
&lt;/caption&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th scope=&quot;col&quot;&gt;Pin
&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Name
&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Description
&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A1
&lt;/th&gt;
&lt;td&gt;GND
&lt;/td&gt;
&lt;td&gt;Ground return
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A2
&lt;/th&gt;
&lt;td&gt;SSTXp1
&lt;/td&gt;
&lt;td&gt;SuperSpeed differential pair #1, TX, positive
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A3
&lt;/th&gt;
&lt;td&gt;SSTXn1
&lt;/td&gt;
&lt;td&gt;SuperSpeed differential pair #1, TX, negative
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A4
&lt;/th&gt;
&lt;td&gt;V&lt;sub&gt;BUS&lt;/sub&gt;
&lt;/td&gt;
&lt;td&gt;Bus power
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A5
&lt;/th&gt;
&lt;td&gt;CC1
&lt;/td&gt;
&lt;td&gt;Configuration channel
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A6
&lt;/th&gt;
&lt;td&gt;Dp1
&lt;/td&gt;
&lt;td&gt;USB 2.0 differential pair, position 1, positive
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A7
&lt;/th&gt;
&lt;td&gt;Dn1
&lt;/td&gt;
&lt;td&gt;USB 2.0 differential pair, position 1, negative
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A8
&lt;/th&gt;
&lt;td&gt;SBU1
&lt;/td&gt;
&lt;td&gt;Sideband use (SBU)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A9
&lt;/th&gt;
&lt;td&gt;V&lt;sub&gt;BUS&lt;/sub&gt;
&lt;/td&gt;
&lt;td&gt;Bus power
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A10
&lt;/th&gt;
&lt;td&gt;SSRXn2
&lt;/td&gt;
&lt;td&gt;SuperSpeed differential pair #4, RX, negative
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A11
&lt;/th&gt;
&lt;td&gt;SSRXp2
&lt;/td&gt;
&lt;td&gt;SuperSpeed differential pair #4, RX, positive
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;A12
&lt;/th&gt;
&lt;td&gt;GND
&lt;/td&gt;
&lt;td&gt;Ground return
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;table class=&quot;wikitable&quot; style=&quot;display: inline-table;&quot;&gt;
&lt;caption&gt;USB-C receptacle B pin layout
&lt;/caption&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th scope=&quot;col&quot;&gt;Pin
&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Name
&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Description
&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B12
&lt;/th&gt;
&lt;td&gt;GND
&lt;/td&gt;
&lt;td&gt;Ground return
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B11
&lt;/th&gt;
&lt;td&gt;SSRXp1
&lt;/td&gt;
&lt;td&gt;SuperSpeed differential pair #2, RX, positive
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B10
&lt;/th&gt;
&lt;td&gt;SSRXn1
&lt;/td&gt;
&lt;td&gt;SuperSpeed differential pair #2, RX, negative
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B9
&lt;/th&gt;
&lt;td&gt;V&lt;sub&gt;BUS&lt;/sub&gt;
&lt;/td&gt;
&lt;td&gt;Bus power
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B8
&lt;/th&gt;
&lt;td&gt;SBU2
&lt;/td&gt;
&lt;td&gt;Sideband use (SBU)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B7
&lt;/th&gt;
&lt;td&gt;Dn2
&lt;/td&gt;
&lt;td&gt;USB 2.0 differential pair, position 2, negative&amp;lt;/sup&amp;gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B6
&lt;/th&gt;
&lt;td&gt;Dp2
&lt;/td&gt;
&lt;td&gt;USB 2.0 differential pair, position 2, positive&amp;lt;/sup&amp;gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B5
&lt;/th&gt;
&lt;td&gt;CC2
&lt;/td&gt;
&lt;td&gt;Configuration channel
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B4
&lt;/th&gt;
&lt;td&gt;V&lt;sub&gt;BUS&lt;/sub&gt;
&lt;/td&gt;
&lt;td&gt;Bus power
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B3
&lt;/th&gt;
&lt;td&gt;SSTXn2
&lt;/td&gt;
&lt;td&gt;SuperSpeed differential pair #3, TX, negative
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B2
&lt;/th&gt;
&lt;td&gt;SSTXp2
&lt;/td&gt;
&lt;td&gt;SuperSpeed differential pair #3, TX, positive
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;B1
&lt;/th&gt;
&lt;td&gt;GND
&lt;/td&gt;
&lt;td&gt;Ground return
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Type-C has 4 power and 4 ground pins, 2 differential pairs for USB 2.0 data, 4 shielded differential pairs for USB 3.x data, and other pins. With USB Power Deliviery standard, a series of power profiles are supported. So a USB cable and power source can support 0.5W to 100W. Of course, it depends on the cable, host and devices for the power and data speed. USB 4 shall provide a maximum 40Gbit data link.&lt;/p&gt;

&lt;p&gt;USB 4 introduces 5 alternate modes to support converters and other protocols. There are 3 types of USB Type-C cables. Firstly, full featured Type-C cable supports USB3.2 performance and other alternate connection such as DisplayPort, MHL, HDMI and Thunderbolt.
Secondly, Thunderbolt 3 Type-C to Type-C (40Gbit/s) is another type of cable which can only be used as USB2 cable other than Thunderbolt 3. Lastly, adapter cables will be available. They will have their signs indicating their ability. The best option seems to be use full featured USB 4 Type-C cables and connectors. Otherwise, we have to respect what type of USB cables are. They might not work as expected even they look like the same.&lt;/p&gt;

&lt;h2 id=&quot;lightning&quot;&gt;Lightning&lt;/h2&gt;

&lt;p&gt;Apple built Lightning connector and used it in every Apple mobile devices since 2012. It’s a great connector for its use. Lightning connector is not even replaced by USB-C while Macbook Pro strives to push forward the industry standard practice.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2020/440px-Lightning_pins.png&quot; alt=&quot;Lightning connector pin outs&quot; /&gt;&lt;/p&gt;

&lt;table&gt;&lt;caption&gt;Lightning Connector pin outs&lt;/caption&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 1&lt;/th&gt;&lt;td&gt;
GND&lt;/td&gt;&lt;td&gt;
Ground&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 2&lt;/th&gt;&lt;td&gt;
L0p&lt;/td&gt;&lt;td&gt;
Lane 0 positive&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 3&lt;/th&gt;&lt;td&gt;
L0n&lt;/td&gt;&lt;td&gt;
Lane 0 negative&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 4&lt;/th&gt;&lt;td&gt;
ID0&lt;/td&gt;&lt;td&gt;
Identification/control 0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 5&lt;/th&gt;&lt;td&gt;
PWR&lt;/td&gt;&lt;td&gt;
Power (charger or battery)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 6&lt;/th&gt;&lt;td&gt;
L1n&lt;/td&gt;&lt;td&gt;
Lane 1 negative&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 7&lt;/th&gt;&lt;td&gt;
L1p&lt;/td&gt;&lt;td&gt;
Lane 1 positive&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 8&lt;/th&gt;&lt;td&gt;
ID1&lt;/td&gt;&lt;td&gt;
Identification/control 1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; style=&quot;text-align:center&quot;&gt;
Lane 0 and 1 may swap in IC of device connector (lanes don&apos;t swap if the accessory identification chip is connected to the ID0 pin)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;While the connector has certain layout, Lightning cables can be adapative because of Apple certified chip included in the cable. All pins seem to be able to switch between data and power. iPhone supports fast charging so the connector can support 18W charger at least. However, the speed is a secret. Sidecar feature which extends macOS screen to an iPad shows the eviendence of a fast transfering speed.&lt;/p&gt;

&lt;h2 id=&quot;hdmi&quot;&gt;HDMI&lt;/h2&gt;

&lt;p&gt;HDMI is usually used to connect a display device which is surprisingly popular. It’s not replaced by thunderbolt/USB4 yet, allegedly because of its price advantage.
Being a audio/video transmission interface, HDMI has its roots with its predecessor DVI.
Starting from HDMI 2.1, its encoding becomes similiar to USB3 and supports 48Gbit/s data transfering speed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2020/HDMI_Connector_Pinout.svg&quot; alt=&quot;HDMI standard connector pinouts&quot; /&gt;&lt;/p&gt;

&lt;table&gt;
&lt;caption&gt;HDMI (High-Definition Multimedia Interface) Type A Receptacle Pin out&lt;/caption&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 1&lt;/th&gt;&lt;td&gt;
TMDS Data2+&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 2&lt;/th&gt;&lt;td&gt;
TMDS Data2 Shield&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 3&lt;/th&gt;&lt;td&gt;
TMDS Data2−&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 4&lt;/th&gt;&lt;td&gt;
TMDS Data1+&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 5&lt;/th&gt;&lt;td&gt;
TMDS Data1 Shield&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 6&lt;/th&gt;&lt;td&gt;
TMDS Data1−&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 7&lt;/th&gt;&lt;td&gt;
TMDS Data0+&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 8&lt;/th&gt;&lt;td&gt;
TMDS Data0 Shield&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 9&lt;/th&gt;&lt;td&gt;
TMDS Data0−&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 10&lt;/th&gt;&lt;td&gt;
TMDS Clock+&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 11&lt;/th&gt;&lt;td&gt;
TMDS Clock Shield&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 12&lt;/th&gt;&lt;td&gt;
TMDS Clock−&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 13&lt;/th&gt;&lt;td&gt;
&lt;a href=&quot;/wiki/Consumer_Electronics_Control&quot; title=&quot;Consumer Electronics Control&quot;&gt;CEC&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 14&lt;/th&gt;&lt;td&gt;
&lt;div class=&quot;plainlist&quot;&gt;&lt;ul&gt;&lt;li&gt;Reserved (HDMI 1.0–1.3a)&lt;/li&gt;&lt;li&gt;Utility/HEAC+ (HDMI 1.4+, optional, &lt;a href=&quot;/wiki/HDMI_Ethernet_Channel&quot; class=&quot;mw-redirect&quot; title=&quot;HDMI Ethernet Channel&quot;&gt;HDMI Ethernet Channel&lt;/a&gt; and &lt;a href=&quot;/wiki/Audio_Return_Channel&quot; class=&quot;mw-redirect&quot; title=&quot;Audio Return Channel&quot;&gt;Audio Return Channel&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 15&lt;/th&gt;&lt;td&gt;
SCL (&lt;a href=&quot;/wiki/I%C2%B2C&quot; title=&quot;I²C&quot;&gt;I²C&lt;/a&gt; serial clock for &lt;a href=&quot;/wiki/Display_Data_Channel&quot; title=&quot;Display Data Channel&quot;&gt;DDC&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 16&lt;/th&gt;&lt;td&gt;
SDA (I²C serial data for DDC)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 17&lt;/th&gt;&lt;td&gt;
Ground (for DDC, CEC, ARC, and HEC)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 18&lt;/th&gt;&lt;td&gt;
+5&amp;nbsp;V (min. 0.055&amp;nbsp;A)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope=&quot;row&quot;&gt;Pin 19&lt;/th&gt;&lt;td&gt;
&lt;div class=&quot;plainlist&quot;&gt;&lt;ul&gt;&lt;li&gt;Hot Plug Detect (all versions)&lt;/li&gt;&lt;li&gt;HEAC− (HDMI 1.4+, optional, HDMI Ethernet Channel and Audio Return Channel)&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;h2 id=&quot;sata&quot;&gt;SATA&lt;/h2&gt;

&lt;p&gt;SATA (Serial AT Attachment) can be commonly found with storage devices. Various of hard drives and SSDs use SATA for power and data transfer. M.2 connector may also use SATA bus but those devices does not use SATA connectors.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2020/500px-SATA_Ports.jpg&quot; alt=&quot;SATA connectors&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Its data connector has 7 pins and is much smaller than PATA connector.&lt;/p&gt;

&lt;table&gt;
&lt;caption&gt;SATA Standard connector, data segment
&lt;/caption&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th colspan=&quot;2&quot;&gt;Pin #&lt;/th&gt;
&lt;th&gt;Mating&lt;/th&gt;
&lt;th&gt;Function
&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background:black;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;1
&lt;/td&gt;
&lt;td style=&quot;text-align:left;&quot;&gt;1st
&lt;/td&gt;
&lt;td&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;background:blue;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;2
&lt;/td&gt;
&lt;td style=&quot;text-align:right;&quot;&gt;2nd
&lt;/td&gt;
&lt;td&gt;A+ (transmit)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3
&lt;/td&gt;
&lt;td style=&quot;text-align:right;&quot;&gt;2nd
&lt;/td&gt;
&lt;td&gt;A− (transmit)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background:black;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;4
&lt;/td&gt;
&lt;td style=&quot;text-align:left;&quot;&gt;1st
&lt;/td&gt;
&lt;td&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;background:blue;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;5
&lt;/td&gt;
&lt;td style=&quot;text-align:right;&quot;&gt;2nd
&lt;/td&gt;
&lt;td&gt;B− (receive)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6
&lt;/td&gt;
&lt;td style=&quot;text-align:right;&quot;&gt;2nd
&lt;/td&gt;
&lt;td&gt;B+ (receive)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background:black;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;7
&lt;/td&gt;
&lt;td style=&quot;text-align:left;&quot;&gt;1st
&lt;/td&gt;
&lt;td&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;3&quot; style=&quot;text-align:center;&quot;&gt;&amp;nbsp;—&lt;/td&gt;
&lt;td&gt;Coding notch
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Its power connector has a 15 pin connector with various of voltages.&lt;/p&gt;

&lt;table&gt;
&lt;caption&gt;SATA Standard connector, power segment
&lt;/caption&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th colspan=&quot;2&quot;&gt;Pin #&lt;/th&gt;
&lt;th&gt;Mating&lt;/th&gt;
&lt;th&gt;Function
&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;3&quot; style=&quot;text-align:center;&quot;&gt;&amp;nbsp;—&lt;/td&gt;
&lt;td&gt;Coding notch
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td rowspan=&quot;3&quot; style=&quot;background:orange;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;1
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3rd
&lt;/td&gt;
&lt;td rowspan=&quot;2&quot;&gt;3.3&amp;nbsp;V Power
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3rd
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;2nd
&lt;/td&gt;
&lt;td&gt;Enter/exit Power Disable (PWDIS) mode&lt;br /&gt;(3.3&amp;nbsp;V Power, Pre-charge prior to SATA 3.3)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td rowspan=&quot;3&quot; style=&quot;background:black;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;4
&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1st
&lt;/td&gt;
&lt;td rowspan=&quot;3&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;2nd
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;2nd
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td rowspan=&quot;3&quot; style=&quot;background:red;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;7
&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;2nd
&lt;/td&gt;
&lt;td&gt;5&amp;nbsp;V Power, Pre-charge
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3rd
&lt;/td&gt;
&lt;td rowspan=&quot;2&quot;&gt;5&amp;nbsp;V Power
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3rd
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background:black;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;10
&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;2nd
&lt;/td&gt;
&lt;td&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background:gray;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;11
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3rd
&lt;/td&gt;
&lt;td&gt;Staggered spinup/activity
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background:black;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;12
&lt;/td&gt;
&lt;td&gt;1st
&lt;/td&gt;
&lt;td&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td rowspan=&quot;3&quot; style=&quot;background:yellow;&quot;&gt;
&lt;/td&gt;
&lt;td&gt;13
&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;2nd
&lt;/td&gt;
&lt;td&gt;12&amp;nbsp;V Power, Pre-charge
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3rd
&lt;/td&gt;
&lt;td rowspan=&quot;2&quot;&gt;12&amp;nbsp;V Power
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3rd
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;The latest standard supports 6Gbit/s transfering speed.&lt;/p&gt;

&lt;h2 id=&quot;pci-express&quot;&gt;PCI Express&lt;/h2&gt;

&lt;p&gt;PCI-E has been the primary choices for devices that are inter-connected on the motherboard. PCI-E device communicates point-to-point with each other and use packets. PCI-E link varies from one to 32 lanes. Devices can be plugged into another PCI-E sockets. Link speed is negotiated to the maximum possible speed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2020/PCIe_J1900_SoC_ITX_Mainboard_IMG_1820.jpeg&quot; alt=&quot;PCI-E connector&quot; /&gt;&lt;/p&gt;

&lt;table&gt;
&lt;caption&gt;PCI Express connector pinout (x1, x4, x8 and x16 variants)
&lt;/caption&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;Pin&lt;/th&gt;
&lt;th&gt;Side B&lt;/th&gt;
&lt;th&gt;Side A&lt;/th&gt;
&lt;th&gt;Description
&lt;/th&gt;
&lt;td rowspan=&quot;54&quot;&gt;
&lt;/td&gt;
&lt;th&gt;Pin&lt;/th&gt;
&lt;th&gt;Side B&lt;/th&gt;
&lt;th&gt;Side A&lt;/th&gt;
&lt;th&gt;Description
&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;visibility:hidden;color:transparent;&quot;&gt;0&lt;/span&gt;1
&lt;/th&gt;
&lt;td style=&quot;background:silver&quot;&gt;+12&amp;nbsp;V&lt;/td&gt;
&lt;td style=&quot;background:#9f9&quot;&gt;PRSNT1#&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Must connect to farthest PRSNT2# pin
&lt;/td&gt;
&lt;th&gt;50
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(8)&lt;/td&gt;
&lt;td style=&quot;background:#ff9&quot;&gt;Reserved&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 8 transmit data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;visibility:hidden;color:transparent;&quot;&gt;0&lt;/span&gt;2
&lt;/th&gt;
&lt;td style=&quot;background:silver&quot;&gt;+12&amp;nbsp;V&lt;/td&gt;
&lt;td style=&quot;background:silver&quot;&gt;+12&amp;nbsp;V&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; align=&quot;left&quot;&gt;Main power pins
&lt;/td&gt;
&lt;th&gt;51
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(8)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;visibility:hidden;color:transparent;&quot;&gt;0&lt;/span&gt;3
&lt;/th&gt;
&lt;td style=&quot;background:silver&quot;&gt;+12&amp;nbsp;V&lt;/td&gt;
&lt;td style=&quot;background:silver&quot;&gt;+12&amp;nbsp;V
&lt;/td&gt;
&lt;th&gt;52
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(8)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 8 receive data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;visibility:hidden;color:transparent;&quot;&gt;0&lt;/span&gt;4
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;th&gt;53
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(8)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;visibility:hidden;color:transparent;&quot;&gt;0&lt;/span&gt;5
&lt;/th&gt;
&lt;td style=&quot;background:#fc6&quot;&gt;SMCLK&lt;/td&gt;
&lt;td style=&quot;background:#99f&quot;&gt;TCK&lt;/td&gt;
&lt;td rowspan=&quot;5&quot; style=&quot;text-align:left;&quot;&gt;&lt;a href=&quot;/wiki/SMBus&quot; class=&quot;mw-redirect&quot; title=&quot;SMBus&quot;&gt;SMBus&lt;/a&gt; and &lt;a href=&quot;/wiki/JTAG&quot; title=&quot;JTAG&quot;&gt;JTAG&lt;/a&gt; port pins
&lt;/td&gt;
&lt;th&gt;54
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(9)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 9 transmit data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;visibility:hidden;color:transparent;&quot;&gt;0&lt;/span&gt;6
&lt;/th&gt;
&lt;td style=&quot;background:#fc6&quot;&gt;SMDAT&lt;/td&gt;
&lt;td style=&quot;background:#99f&quot;&gt;TDI
&lt;/td&gt;
&lt;th&gt;55
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(9)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;visibility:hidden;color:transparent;&quot;&gt;0&lt;/span&gt;7
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;TDO
&lt;/td&gt;
&lt;th&gt;56
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(9)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 9 receive data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;visibility:hidden;color:transparent;&quot;&gt;0&lt;/span&gt;8
&lt;/th&gt;
&lt;td style=&quot;background:silver&quot;&gt;+3.3&amp;nbsp;V&lt;/td&gt;
&lt;td style=&quot;background:#99f&quot;&gt;TMS
&lt;/td&gt;
&lt;th&gt;57
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(9)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;visibility:hidden;color:transparent;&quot;&gt;0&lt;/span&gt;9
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;TRST#&lt;/td&gt;
&lt;td style=&quot;background:silver&quot;&gt;+3.3&amp;nbsp;V
&lt;/td&gt;
&lt;th&gt;58
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(10)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 10 transmit data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;10
&lt;/th&gt;
&lt;td style=&quot;background:silver&quot;&gt;+3.3&amp;nbsp;V aux&lt;/td&gt;
&lt;td style=&quot;background:silver&quot;&gt;+3.3&amp;nbsp;V&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;/wiki/Standby_power&quot; title=&quot;Standby power&quot;&gt;Standby power&lt;/a&gt;
&lt;/td&gt;
&lt;th&gt;59
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(10)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;11
&lt;/th&gt;
&lt;td style=&quot;background:#fc6&quot;&gt;WAKE#&lt;/td&gt;
&lt;td style=&quot;background:#99f&quot;&gt;PERST#&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Link reactivation; fundamental reset
&lt;/td&gt;
&lt;th&gt;60
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(10)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 10 receive data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th colspan=&quot;4&quot;&gt;Key notch
&lt;/th&gt;
&lt;th&gt;61
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(10)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;12
&lt;/th&gt;
&lt;td style=&quot;background:#fc6&quot;&gt;CLKREQ#&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Clock Request Signal
&lt;/td&gt;
&lt;th&gt;62
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(11)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 11 transmit data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;13
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#99f&quot;&gt;REFCLK+&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Reference clock differential pair
&lt;/td&gt;
&lt;th&gt;63
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(11)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;14
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(0)&lt;/td&gt;
&lt;td style=&quot;background:#99f&quot;&gt;REFCLK−&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 0 transmit data, + and −
&lt;/td&gt;
&lt;th&gt;64
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(11)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 11 receive data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;15
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(0)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;
&lt;th&gt;65
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(11)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;16
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(0)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 0 receive data, + and −
&lt;/td&gt;
&lt;th&gt;66
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(12)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 12 transmit data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;17
&lt;/th&gt;
&lt;td style=&quot;background:#9f9&quot;&gt;PRSNT2#&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(0)
&lt;/td&gt;
&lt;th&gt;67
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(12)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;18
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;th&gt;68
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(12)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 12 receive data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;4&quot;&gt;PCI Express x1 cards end at pin 18
&lt;/td&gt;
&lt;th&gt;69
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(12)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;19
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(1)&lt;/td&gt;
&lt;td style=&quot;background:#ff9&quot;&gt;Reserved&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 1 transmit data, + and −
&lt;/td&gt;
&lt;th&gt;70
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(13)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 13 transmit data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;20
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(1)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;
&lt;th&gt;71
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(13)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;21
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(1)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 1 receive data, + and −
&lt;/td&gt;
&lt;th&gt;72
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(13)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 13 receive data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;22
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(1)
&lt;/td&gt;
&lt;th&gt;73
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(13)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;23
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(2)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 2 transmit data, + and −
&lt;/td&gt;
&lt;th&gt;74
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(14)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 14 transmit data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;24
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(2)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;
&lt;th&gt;75
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(14)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;25
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(2)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 2 receive data, + and −
&lt;/td&gt;
&lt;th&gt;76
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(14)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 14 receive data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;26
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(2)
&lt;/td&gt;
&lt;th&gt;77
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(14)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;27
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(3)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 3 transmit data, + and −
&lt;/td&gt;
&lt;th&gt;78
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(15)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 15 transmit data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;28
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(3)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;
&lt;th&gt;79
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(15)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;29
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(3)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 3 receive data, + and −
&lt;/td&gt;
&lt;th&gt;80
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(15)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 15 receive data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;30
&lt;/th&gt;
&lt;td style=&quot;background:#fc6&quot;&gt;PWRBRK#&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(3)
&lt;/td&gt;
&lt;th&gt;81
&lt;/th&gt;
&lt;td style=&quot;background:#9f9&quot;&gt;PRSNT2#&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(15)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;31
&lt;/th&gt;
&lt;td style=&quot;background:#9f9&quot;&gt;PRSNT2#&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot;&gt;
&lt;/td&gt;
&lt;th&gt;82
&lt;/th&gt;
&lt;td style=&quot;background:#ff9&quot;&gt;Reserved&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;32
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#ff9&quot;&gt;Reserved
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;4&quot;&gt;PCI Express x4 cards end at pin 32
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;33
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(4)&lt;/td&gt;
&lt;td style=&quot;background:#ff9&quot;&gt;Reserved&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 4 transmit data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;34
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(4)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;35
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(4)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 4 receive data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;36
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(4)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;37
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(5)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 5 transmit data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;38
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(5)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;39
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(5)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 5 receive data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;40
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(5)
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;41
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(6)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 6 transmit data, + and −
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;42
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(6)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;43
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(6)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 6 receive data, + and −
&lt;/td&gt;
&lt;th colspan=&quot;4&quot;&gt;Legend
&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;44
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(6)
&lt;/td&gt;
&lt;th style=&quot;background:#999&quot; colspan=&quot;2&quot;&gt;Ground pin
&lt;/th&gt;
&lt;td colspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Zero volt reference
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;45
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOp(7)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 7 transmit data, + and −
&lt;/td&gt;
&lt;th style=&quot;background:silver&quot; colspan=&quot;2&quot;&gt;Power pin
&lt;/th&gt;
&lt;td colspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Supplies power to the PCIe card
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;46
&lt;/th&gt;
&lt;td style=&quot;background:#99f&quot;&gt;HSOn(7)&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground
&lt;/td&gt;
&lt;th style=&quot;background:#f9f&quot; colspan=&quot;2&quot;&gt;Card-to-host pin
&lt;/th&gt;
&lt;td colspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Signal from the card to the motherboard
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;47
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIp(7)&lt;/td&gt;
&lt;td rowspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Lane 7 receive data, + and −
&lt;/td&gt;
&lt;th style=&quot;background:#99f&quot; colspan=&quot;2&quot;&gt;Host-to-card pin
&lt;/th&gt;
&lt;td colspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Signal from the motherboard to the card
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;48
&lt;/th&gt;
&lt;td style=&quot;background:#9f9&quot;&gt;PRSNT2#&lt;/td&gt;
&lt;td style=&quot;background:#f9f&quot;&gt;HSIn(7)
&lt;/td&gt;
&lt;th style=&quot;background:#fc6&quot; colspan=&quot;2&quot;&gt;&lt;a href=&quot;/wiki/Open_drain&quot; class=&quot;mw-redirect&quot; title=&quot;Open drain&quot;&gt;Open drain&lt;/a&gt;
&lt;/th&gt;
&lt;td colspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;May be pulled low or sensed by multiple cards
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;49
&lt;/th&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td style=&quot;background:#999&quot;&gt;Ground&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;th style=&quot;background:#9f9&quot; colspan=&quot;2&quot;&gt;Sense pin
&lt;/th&gt;
&lt;td colspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Tied together on card
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;4&quot;&gt;PCI Express x8 cards end at pin 49
&lt;/td&gt;
&lt;th style=&quot;background:#ff9&quot; colspan=&quot;2&quot;&gt;Reserved
&lt;/th&gt;
&lt;td colspan=&quot;2&quot; style=&quot;text-align:left;&quot;&gt;Not presently used, do not connect
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Connectors have different shapes optimized for different tasks. When devices or system evovles, connectors follows. A standard might try to extend its usage with designs but it does not fit every devices or future use cases. All these connectors provide essential functions such as power delivery, data transfering, some sorts of confugration pins. The way they were designed depends on its historical design and constraints.&lt;/p&gt;
</description>
        <pubDate>Sun, 28 Jun 2020 00:00:00 +0200</pubDate>
        <link>https://erickguan.me/2020/popular-connectors-for-computers</link>
        <guid isPermaLink="true">https://erickguan.me/2020/popular-connectors-for-computers</guid>
      </item>
    
      <item>
        <title>A decade with Wikipedia</title>
        <description>&lt;p&gt;I’ve spent a decade with Wikipedia.&lt;/p&gt;

&lt;p&gt;I was lucky to know internet when I was young. And it didn’t take me long to know Wikipedia. When I started my journey with Wikipedia at 2008, it was quite new for Chinese too. Growing with Chinese Wikipedia community certainly gave me a very different value than my peer classmates. I just didn’t know we were growing with an new era in Chinese history.&lt;/p&gt;

&lt;p&gt;Chinese Wikipedia has dramatic “modern” value comparing to the government. We adopt &lt;a href=&quot;[https://en.wikipedia.org/wiki/Wikipedia:Five_pillars](https://en.wikipedia.org/wiki/Wikipedia:Five_pillars)&quot;&gt;Five pillars&lt;/a&gt;. However, seeking consesus is not a trivial task for the community.&lt;/p&gt;

&lt;h2 id=&quot;history&quot;&gt;History&lt;/h2&gt;

&lt;p&gt;Chinese Wikipedia was established at 2002. Few people chose the translation for “wiki”(维基). It gets blocked next year. What kind of world they lived in? P.R.China ranks the sixth on GDP. iPhone doesn’t exist.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2019/internet-users.png&quot; alt=&quot;Internet users&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At that time, surfing on the internet was expensive and difficult. It was probabaly the elites can access the internet. Key people in the community laid out the foundation and governace model for Chinese Wikipedia. Over time, idealists were replaced by rational people following every bits of protocol. Once people started auditing every change, new people would feel attacked by this culture for being unfamiliar with the rules. With ever growing power in the community, the change on governance stagnate.  English Wikipedia has more powerfule mechanics like &lt;a href=&quot;[https://en.wikipedia.org/wiki/Wikipedia:Arbitration_Committee](https://en.wikipedia.org/wiki/Wikipedia:Arbitration_Committee)&quot;&gt;Arbitration​ Committee&lt;/a&gt;. Smaller Wikipedia might have knowledgeable and kind volunteers (e.g. Swedish Wikipedia).&lt;/p&gt;

&lt;p&gt;Despite the downside, Chinese Wikipedia grows stronger. The significant engineering effort brought two major language varaints together. That marked history. People from Taiwan, Hong Kong, and Singapore can contribute to Wikipedia together. And rules among political conflicts were established.&lt;/p&gt;

&lt;h2 id=&quot;access-problem&quot;&gt;Access problem&lt;/h2&gt;

&lt;p&gt;But in the reality, most of contributors are students who has abduant free time. Nevertheless, some students contributed professional articles but they were few. It’s unlikely for us to get more professional article in science. When the community became more picky, it created higher barrier for writing. In contray, students can only write about traffic, and ACG (Anime, Comics, and Games).&lt;/p&gt;

&lt;p&gt;When the government finally started to block Chinese Wikipedia, it’s a working community consist of people from different background and views.&lt;/p&gt;

&lt;h2 id=&quot;a-darker-image&quot;&gt;A darker image&lt;/h2&gt;

&lt;p&gt;Appearntly, Wikipedia communities in Asia don’t grow much as communities in western countries. There might be some reasons. People have less time because of economy. There are many conflicts in society. Educated people are also limited. Moreover, in particular of Chinese Wikipedia, political influence from government is strong. Despite direct influence on Wikipedia, Baidu launched their own encylopedia that has 16 million articles now (as of 2019). So the audience even become less aware about the quality on references.&lt;/p&gt;

&lt;h2 id=&quot;where-we-are-at&quot;&gt;Where we are at?&lt;/h2&gt;

&lt;p&gt;Wikipedia communities have become strong. Successful conferences were hold. Wikimedia affliates have large impact. But the technology is lacking. Running such large scale of project, only a few people are working on strategy of tracks.&lt;/p&gt;
</description>
        <pubDate>Tue, 14 May 2019 00:00:00 +0200</pubDate>
        <link>https://erickguan.me/2019/a-decade-with-wikipedia</link>
        <guid isPermaLink="true">https://erickguan.me/2019/a-decade-with-wikipedia</guid>
      </item>
    
      <item>
        <title>How PyTorch implements DataParallel?</title>
        <description>&lt;p&gt;PyTorch can send batches and models to different GPUs automatically with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataParallel(model)&lt;/code&gt;. How is it possible? I assume you know PyTorch uses dynamic computational graph as well as Python GIL. And PyTorch version is v1.0.1.&lt;/p&gt;

&lt;p&gt;This is a complicated question and I asked on the PyTorch forum. I got &lt;a href=&quot;https://discuss.pytorch.org/t/how-pytorchs-parallel-method-and-distributed-method-works/30349/2?u=fantasticfears&quot;&gt;a reply&lt;/a&gt; from &lt;a href=&quot;https://discuss.pytorch.org/u/rasbt&quot;&gt;Sebastian Raschka&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2018/dataparallel.png&quot; alt=&quot;Data parallel’s process in a high level&quot; /&gt;&lt;/p&gt;

&lt;p&gt;TL;DR:&lt;/p&gt;

&lt;p&gt;PyTorch trys hard in zero-copying. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataParallel&lt;/code&gt; splits tensor by its total size instead of along any axis.&lt;/p&gt;

&lt;h1 id=&quot;dataparallel-interface&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataParallel&lt;/code&gt; interface&lt;/h1&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Module&lt;/code&gt; defines its constructor and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forward&lt;/code&gt; function. And &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataParallel&lt;/code&gt; does the same. Let’s focus on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forward&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;scatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device_ids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Step 1, 2
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# ...
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Build graph
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;replicas&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;replicate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device_ids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)])&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Step 3
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;outputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;parallel_apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Step 4
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gather&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Step 5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are 4 methods extracted and defined as instance methods which are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scatter&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;replicate&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gather&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parallel_apply&lt;/code&gt;. They executes the step 1, 2; step 3; step 4; step 5 respectively.&lt;/p&gt;

&lt;p&gt;Firstly, we have to recognize PyTorch utilize dynamic computational graph. That’s why module is invoked to build nodes. It builds the graph, parameters, grads and buffers.&lt;/p&gt;

&lt;h2 id=&quot;and-how-function-works&quot;&gt;And how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Function&lt;/code&gt; works&lt;/h2&gt;

&lt;p&gt;Before we start to look into diffierent steps, let’s look at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Function&lt;/code&gt;. We are going to see it many times.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;with_metaclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FunctionMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_FunctionBase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_ContextMethodMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_HookMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@staticmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;...
        It must accept a context ctx as the first argument, followed by any
        number of arguments (tensors or other types).

        The context can be used to store tensors that can be then retrieved
        during the backward pass.
        &lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NotImplementedError&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@staticmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;backward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grad_outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NotImplementedError&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Some helper functions used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Function&lt;/code&gt; as the base class. Moreover, since you will see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Function.apply&lt;/code&gt; a lot in the following, we should see how it works. (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metaclass&lt;/code&gt; is tricky.)&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;with_metaclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Create a base class with a metaclass.&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# This requires a bit of explanation: the basic idea is to make a dummy
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# metaclass for one level of class instantiation that replaces itself with
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# the actual metaclass.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;metaclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__new__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;this_bases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;__new__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metaclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;temporary_class&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is tricky. We have to start from Python’s object design. Starting from Python 3, everything is an object. And all objects are constructed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class type(name, bases, dict)&lt;/code&gt;. Each parameter would become class object’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__name__&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__bases__&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__dict__&lt;/code&gt;. So &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;type&lt;/code&gt; is the dynamic way to build a class. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;with_metaclass&lt;/code&gt; is a helper to build a metaclass without defining &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__dict__&lt;/code&gt; yet. Namely, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;with_metaclass(FunctionMeta, _C._FunctionBase, _ContextMethodMixin, _HookMixin))&lt;/code&gt; reads &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FunctionMeta&lt;/code&gt; is the metaclass but the bases are in the tuple.&lt;/p&gt;

&lt;p&gt;Then we are not far away from how it works.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FunctionMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;backward_fn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Backward&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BackwardCFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;_forward_cls&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;setattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;_backward_cls&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;backward_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FunctionMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Basically a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;backward_fn&lt;/code&gt; is defined and stored in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_backward_cls&lt;/code&gt;. Its base class is simple.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BackwardCFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_FunctionBase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_ContextMethodMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_HookMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_forward_cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;backward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It will invoke the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Function&lt;/code&gt; class’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;backward&lt;/code&gt; method. Therefore &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_C._FunctionBase&lt;/code&gt; is more interesting.  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C._FunctionBase&lt;/code&gt; is defined by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;THPFunctionType&lt;/code&gt;. And the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;THPFunction&lt;/code&gt; defines its data structure.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PyMethodDef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;THPFunction_methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;apply&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyCFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;THPFunction_apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;METH_CLASS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;METH_VARARGS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;_do_forward&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyCFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;THPFunction_do_forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;METH_VARARGS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;_do_backward&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyCFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;THPFunction_do_backward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;METH_VARARGS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;_register_hook_dict&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyCFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;THPFunction__register_hook_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;METH_O&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;register_hook&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyCFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;THPFunction_register_hook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;METH_O&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It defines the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; method. That’s something we are interested.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;THPFunction_apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;THPObjectPtr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;backward_cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyObject_GetAttrString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;_backward_cls&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backward_cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;THPObjectPtr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx_obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyObject_CallFunctionObjArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backward_cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx_obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;THPFunction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;THPFunction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx_obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Prepare inputs and allocate context (grad fn)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info_pair&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unpack_input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;UnpackedInput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unpacked_input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info_pair&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;InputFlags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info_pair&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Record input nodes if tracing&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Initialize backward function (and ctx)&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_executable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_executable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cdata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_next_edges&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next_edges&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;needs_input_grad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;needs_input_grad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_variable_input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_variable_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Prepend ctx to input_tuple, in preparation for static method call&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyTuple_GET_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;THPObjectPtr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx_input_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyTuple_New&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;PyTuple_SET_ITEM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx_input_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx_obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Call forward&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;THPObjectPtr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensor_outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;AutoGradMode&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grad_mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;THPObjectPtr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forward_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyObject_GetAttrString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;forward&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tensor_outputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyObject_CallObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx_input_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor_outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process_outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unpacked_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor_outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                         &lt;span class=&quot;n&quot;&gt;is_executable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;END_HANDLE_TH_ERRORS&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From here, we know that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cls.apply&lt;/code&gt; invokes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cls.forward&lt;/code&gt; and prepares information for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cls.backward&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cls.apply&lt;/code&gt; takes its own class information and all parameters from Python. And those parameters will be applied on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cls.forward&lt;/code&gt;. Noticabily, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ctx&lt;/code&gt; object can carry the information to backward pass.&lt;/p&gt;

&lt;p&gt;Now we can explore how  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataParallel&lt;/code&gt; works.&lt;/p&gt;

&lt;h2 id=&quot;step-1-and-step-2-split-minibatch-on-gpu0-and-move-to-gpu&quot;&gt;Step 1 and Step 2: split minibatch on GPU:0 and move to GPU&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scatter&lt;/code&gt; scatters the input argugments and returns a tuple of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inputs&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kwargs&lt;/code&gt;. The actual definiton is here:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;scatter_kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_gpus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Scatter with support for kwargs dictionary&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;scatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_gpus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;scatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_gpus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scatter&lt;/code&gt; function is a recursive closure unwrap its input tensor(s). But its core is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scatter&lt;/code&gt; class. This is a &lt;a href=&quot;https://pytorch.org/tutorials/beginner/examples_autograd/two_layer_net_custom_function.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Function&lt;/code&gt; class&lt;/a&gt; which will operate differently in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forward&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;backward&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Scatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@staticmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_gpus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk_sizes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# ...
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;outputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;comm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;scatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_gpus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk_sizes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;streams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# Synchronize with the copy stream
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;streams&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_gpus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;main_stream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;current_stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;main_stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;wait_stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;streams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;record_stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main_stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputs&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@staticmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;backward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grad_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Gather&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grad_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s focus on forward path. The backward path should be easier to understand. Thus on a multi-gpu environment, the input tensor will be sent to a PyTorch module for scattering and copying. This process needs synchronization.&lt;/p&gt;

&lt;p&gt;The actual works in done by C++.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IntList&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int64_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk_sizes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional parameter is bad&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CUDAStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;streams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk_sizes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// flatten tensor by size. The default uses the other path&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk_sizes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk_sizes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;AT_CHECK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Chunk size must be positive&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;narrow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk_start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;chunk_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// usually a tensor is seperated into chunks among devices&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;chunks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/*chunks=*/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*dim=*/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OptionalCUDAStreamGuard&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cuda_guard&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// dispatch to different devices&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contiguous&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DeviceType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CUDA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;device_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*non_blocking=*/&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As a matter of fact, tensor would be split which is done by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at::narrow&lt;/code&gt; in the end. Since the operation only happens to strides and sizes, the memory is reused! PyTorch takes zero copy seriously at every level. But an important insight is that tensor is splitted regardless of its shape. You need to align different input tensors by its total size instead of a particular dimension.&lt;/p&gt;

&lt;h2 id=&quot;step-3-copy-models-to-gpu&quot;&gt;Step 3: copy models to GPU&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;replicate&lt;/code&gt; sounds easy! But no. So the module is passed in as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;network&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;replicate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;network&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;detach&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;._functions&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Broadcast&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;num_replicas&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameters&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;network&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;param_indices&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;param_copies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Broadcast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;param_copies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_copies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_copies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffers&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buffers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;network&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;buffers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buffer_indices&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buf&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buffer_copies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;comm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;broadcast_coalesced&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;network&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;module_copies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;device&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;module_indices&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;construrct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;...&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;every&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;submodules&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;...&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;replica&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module_copies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;replica&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module_copies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;their&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameters&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;...&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;replica&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module_copies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;replica&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_copies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;detach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; \
                        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;detach&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_copies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;also&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffers&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buf&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_buffers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;...&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;replica&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module_copies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;replica&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_buffers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffer_copies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module_copies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_replicas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The copying part to GPU is hard to be found. But we know they are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Broadcast&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;comm.broadcast_coalesced(buffers, devices)&lt;/code&gt;.
Until this point, we have the model living in different GPUs.&lt;/p&gt;

&lt;p&gt;Here is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Broadcast&lt;/code&gt;. The invocation starts with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Broadcast.apply(devices, *params)&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Broadcast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@staticmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_gpus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_gpus&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_gpus&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_inputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_device&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get_device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;outputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;comm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;broadcast_coalesced&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_gpus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputs&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@staticmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;backward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grad_outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;return &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ReduceAddCoalesced&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grad_outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And its backward direction &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReduceAddCoalesced&lt;/code&gt; looks similar.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReduceAddCoalesced&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@staticmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;grads&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                 &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;comm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;reduce_add_coalesced&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@staticmethod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;backward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grad_outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;return &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Broadcast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_gpus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grad_outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So the core parts are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;comm.broadcast_coalesced&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;comm.reduce_add_coalesced&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;comm.broadcast_coalesced&lt;/code&gt; is implemented in C++. We have model parameters as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tensors&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tensor_list2d&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;broadcast_coalesced&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TensorList&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IntArrayRef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffer_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                   &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;runtime_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;all tensors must be on devices[0]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;tensor_list2d&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;take_tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffer_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_sparse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flat_tuple&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatten_sparse_tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;broadcast_indices&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flat_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;broadcast_values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flat_tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatten_dense_tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                                              &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is too complicated and perhaps not insightful for our aim. But effecitively NCCL is used to broadcast tensor’s address to multiple GPUs. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reduce_add_coalesced&lt;/code&gt; does the reverse.&lt;/p&gt;

&lt;h2 id=&quot;step-4-forward-pass&quot;&gt;Step 4: Forward pass&lt;/h2&gt;

&lt;p&gt;Finally, this step is obvious. But we need to pay attention to the output tuple because of the next step.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parallel_apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs_tup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Applies each `module` in :attr:`modules` in parallel on arguments
    contained in :attr:`inputs` (positional) and :attr:`kwargs_tup` (keyword)
    on each of :attr:`devices`.

    Args:
        modules (Module): modules to be parallelized
        inputs (tensor): inputs to the modules
        devices (list of int or torch.device): CUDA devices

    :attr:`modules`, :attr:`inputs`, :attr:`kwargs_tup` (if given), and
    :attr:`devices` (if given) should all have same length. Moreover, each
    element of :attr:`inputs` can either be a single object as the only argument
    to a module, or a collection of positional arguments.
    &lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...
&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_worker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# ...
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cuda&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;# this also avoids accidental slicing of `input` if it is a Tensor
&lt;/span&gt;                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
                    &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;threads&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;threading&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_worker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                    &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                   &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt;
                   &lt;span class=&quot;nf&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs_tup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;threads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;threads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;_worker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs_tup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ...
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;results&lt;/code&gt; keeps track of results from every devices. Most cases, it will be a scalar loss tensor.&lt;/p&gt;

&lt;p&gt;Python’s threading library is used to send things to models on different GPUs. This is a little bit expensive than I thought because of the overhead from threading.&lt;/p&gt;

&lt;h2 id=&quot;step-5-compute&quot;&gt;Step 5: Compute&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gather&lt;/code&gt; has a similiar design as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scatter&lt;/code&gt;. The core is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Gather.apply(target_device, dim, *outputs)&lt;/code&gt;.  And its core is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;comm.gather(inputs, ctx.dim, ctx.target_device)&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tensor&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;gather&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TensorList&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;c10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int32_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;destination_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;cp&quot;&gt;# ...
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;AT_CHECK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Expected at least one tensor to gather from&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tensor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;front&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sizes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int64_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expected_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;expected_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;total_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;expected_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Device&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DeviceType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CPU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination_index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination_index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;device&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DeviceType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CUDA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;destination_index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination_index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expected_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

  &lt;span class=&quot;kt&quot;&gt;int64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;narrow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk_start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;copy_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*non_blocking=*/&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;chunk_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s actually hard to find things. This basically compose a final tensor from tensors from devices. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;destination_index&lt;/code&gt; is the index of output device which is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GPU:0&lt;/code&gt; by default (defined as the parameter of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data_parrallel&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;step-6-loss-value&quot;&gt;Step 6: Loss value&lt;/h2&gt;

&lt;p&gt;This is the standard code you will write.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;zero_grad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;backward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In next minibatch, same process will be sent to GPU.&lt;/p&gt;

&lt;h1 id=&quot;discussion&quot;&gt;Discussion&lt;/h1&gt;

&lt;p&gt;PyTorch focuses on abstraction and zero-copy. It’s more intutive to Tensorflow 1.x. It’s indeed an engineering success. Despite its simple interfaces, we need to understand its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tensor&lt;/code&gt; abstraction and those convenient helpers. Since CUDA uses different programming models, the work to hide CUDA details is enormous. PyTorch did this by mixing C++ and Python with &lt;em&gt;pybind11&lt;/em&gt;. And it strives to maintain a similiar language in a large hierarchy that aligns the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tensor&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Function&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Model&lt;/code&gt;. That’s remarkable.&lt;/p&gt;

&lt;p&gt;Though, programming in a mixed languages are difficult. Type checking is always complicated. GIL needs to be remembered. With CUDA, synchronization, memory management and communication expands the scope of engineering work.&lt;/p&gt;

</description>
        <pubDate>Tue, 05 Mar 2019 00:00:00 +0100</pubDate>
        <link>https://erickguan.me/2019/pytorch-parallel-model</link>
        <guid isPermaLink="true">https://erickguan.me/2019/pytorch-parallel-model</guid>
      </item>
    
      <item>
        <title>How to have a data science lab in 13 steps?</title>
        <description>&lt;p&gt;TL;DR. You have to be passionate and insane. I would not recommend doing it.&lt;/p&gt;

&lt;p&gt;Research is an exciting thing. The purpose is to produce knowledge. You have the ultimate freedom because the job is about extending knowledge towards unknown.&lt;/p&gt;

&lt;h2 id=&quot;1-love-computer-science&quot;&gt;1. Love Computer Science&lt;/h2&gt;

&lt;p&gt;You have to believe in what you are doing.&lt;/p&gt;

&lt;h2 id=&quot;2-learning-programming&quot;&gt;2. Learning Programming&lt;/h2&gt;

&lt;p&gt;Programming is a must. You have to write the implementation of your idea. And don’t forget the annoying part! Data processing will take the majority of your time, and there is no open source solution for that.&lt;/p&gt;

&lt;p&gt;In some cases, you will need to use a lot of languages. I used C++/Java/Python/Ruby/Bash. Just learn.&lt;/p&gt;

&lt;h2 id=&quot;3-learning-mathematics&quot;&gt;3. Learning Mathematics&lt;/h2&gt;

&lt;p&gt;Things are useful: Linear Algebra, Probability, and Calculus. It’s for you. You don’t want to cry if you can’t even guess what theory belongs to from the paper. Knowing that you have to learn if you need something otherwise, you have to give up for your own thoughts.&lt;/p&gt;

&lt;h2 id=&quot;4-find-good-peers&quot;&gt;4. Find good peers&lt;/h2&gt;

&lt;p&gt;Unless you have equipment and money. But wait a minute, it’s the least problem. If you don’t have a supervisor, you will have no way of knowing if you are actually thinking. Generally, more experience is better.&lt;/p&gt;

&lt;h2 id=&quot;5-find-awesome-papers&quot;&gt;5. Find awesome papers&lt;/h2&gt;

&lt;p&gt;You are not alone. Papers are written by other miserable researchers. They tried to write it as well as possible. Welcome to this community. But you need to find good papers to start. Learn &lt;em&gt;Scientific Method&lt;/em&gt;. If you failed on this, you can’t define your research problems.&lt;/p&gt;

&lt;h2 id=&quot;6-learn-everything-you-need&quot;&gt;6. Learn everything you need&lt;/h2&gt;

&lt;p&gt;Let’s read this paper in a day. Sorry, I mean it will usually be a week if you are not familiar with all the terms. Machine learning or deep learning, it doesn’t matter. Learn.&lt;/p&gt;

&lt;h2 id=&quot;7-be-passionate-and-have-some-fun&quot;&gt;7. Be passionate and have some fun&lt;/h2&gt;

&lt;p&gt;Research is a lonely job. It’s one of the hardest jobs. Nobody can help you when you are creating. It requires hard work. And good motivation is from your position. And You need to rest. You need to get some good feelings from creation. Your brain is just not that good when it.&lt;/p&gt;

&lt;h2 id=&quot;8-believe-it-just-takes-time-a-lot-of-time&quot;&gt;8. Believe it just takes time. A lot of time.&lt;/h2&gt;

&lt;p&gt;Learning takes time depending on how smart you are. I’m really dumb at getting all of that new knowledge. Programming takes time depending on how annoying the problem is. And your trials are part of the game. That takes weeks until you build a new mental schema.&lt;/p&gt;

&lt;h2 id=&quot;9-design-your-strategy-and-scientific-problem&quot;&gt;9. Design your strategy and scientific problem&lt;/h2&gt;

&lt;p&gt;You need to focus on a tiny piece so you can work on even your research topic is fantastic. Keep looking until you have a good one.&lt;/p&gt;

&lt;h2 id=&quot;10-accept-your-ideas-are-shit&quot;&gt;10. Accept your ideas are shit&lt;/h2&gt;

&lt;p&gt;The secret is that it will get better if you think about it. Don’t stop.&lt;/p&gt;

&lt;h2 id=&quot;11-make-a-time-plan&quot;&gt;11. Make a time plan&lt;/h2&gt;

&lt;p&gt;It’s not about catching the deadline. It’s for stopping. Can’t you do your research perfectly right? You have less data, limited time, time schedule, your future, and your health because you are exploring alone.&lt;/p&gt;

&lt;h2 id=&quot;12-treat-people-nicely&quot;&gt;12. Treat people nicely&lt;/h2&gt;

&lt;p&gt;There are many researchers in the world working on the same thing. Write something that’s easier to understand so that you can also read a good paper. Reply to inquiries so that you can get a reply from the community.&lt;/p&gt;

&lt;h2 id=&quot;13-find-more-people&quot;&gt;13. Find more people&lt;/h2&gt;

&lt;p&gt;You can’t work alone when it’s starting to emerge with new directions and new ideas.&lt;/p&gt;
</description>
        <pubDate>Thu, 20 Dec 2018 00:00:00 +0100</pubDate>
        <link>https://erickguan.me/2018/how-to-have-a-data-science-lab</link>
        <guid isPermaLink="true">https://erickguan.me/2018/how-to-have-a-data-science-lab</guid>
      </item>
    
      <item>
        <title>3 steps to start Google Summer of Code with Discourse</title>
        <description>&lt;p&gt;Discourse is a wonderful free and open source software for a modern forum. Now it has already powered many projects’ forum. Take a look at &lt;a href=&quot;https://meta.discourse.org/&quot;&gt;where it’s built&lt;/a&gt; and &lt;a href=&quot;https://www.discourse.org/customers&quot;&gt;others&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2018/discourse-meta-forum.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;why-discourse&quot;&gt;Why Discourse?&lt;/h1&gt;

&lt;p&gt;Firstly, you need to know what project you are looking for. For example, what’s Discourse?
Discourse is an evolving project with a client Ember.js app and a Rails backend. It focuses on people and community building. Discourse team is also professional and helpful. You can find them on &lt;a href=&quot;https://meta.discourse.org/&quot;&gt;Discourse Meta&lt;/a&gt;. Meta is the place where the team discusses how and what to develop Discourse. It’s transparent to all contributors.&lt;/p&gt;

&lt;p&gt;They are also casual for your involvement. Remote work is how the team works. It’s a lot of freedom so does GSoC.&lt;/p&gt;

&lt;h1 id=&quot;if-you-are-interested-whats-next&quot;&gt;If you are interested, what’s next?&lt;/h1&gt;

&lt;p&gt;Secondly, how to prepare if you are interested in a project?
There are two steps in this task. Read Google Summer of Code’s manual. Moreover, read how the Discourse team wants you to do. However, since you are reading my post, I’m going to tell you a few secrets. The first secret is &lt;strong&gt;&lt;a href=&quot;https://blog.codinghorror.com/because-reading-is-fundamental-2/&quot;&gt;Reading is # Fundamental&lt;/a&gt;&lt;/strong&gt;. So let’s talk about GSoC manual firstly.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Read &lt;a href=&quot;https://developers.google.com/open-source/gsoc/faq&quot;&gt;FAQ&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Read &lt;a href=&quot;https://google.github.io/gsocguides/student/&quot;&gt;guides&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;(Chinese) If you understand Chinese, there are &lt;a href=&quot;https://github.com/gsoc-cn/gsoc-cn&quot;&gt;more resources&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Then you can ask questions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before you continue on reading, let’s answer a question. Are you interested? GSoC aims to contribute open source community which means the aim is to make you comfortable and want to stay in the future. Hang on to that motivation otherwise. It’s going to be dull. My motivation would be that I hope Discourse becomes the largest platform for online discussion because I believe in the same value from the team. It will be useful if I need an online discussion forum.&lt;/p&gt;

&lt;p&gt;Discourse team will be in favor of students that who &lt;strong&gt;have contributed&lt;/strong&gt; to it. Also, it’s a straightforward process. Just start. &lt;a href=&quot;https://meta.discourse.org/t/discourse-development-contribution-guidelines/3823?u=fantasticfears&quot;&gt;Read contributing guidelines&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;take-the-smallest-bite&quot;&gt;Take the smallest bite&lt;/h2&gt;

&lt;p&gt;It’s natural that feels overwhelming when it comes to a massive project. I stills feel the difficulty when I read the code. However, you should be able to find what is most interested. Find that smallest interests part. Analyze it. Write a plan. Also, execute your plan. If there’s a lion on the way, you can ask questions, and most likely you will get a reply quickly. As long as you know what you are trying to do, people understand you.&lt;/p&gt;

&lt;h1 id=&quot;when-it-comes-to-proposal&quot;&gt;When it comes to proposal&lt;/h1&gt;

&lt;p&gt;Lastly, you need to apply.
When you need to write a proposal, you feel it’s real now. That’s true. It would be better if you already have your plans and tried some ideas. As previously said, the team is helpful if you know them. Discourse team usually has a lot on their hands. If they know you, they can, of course, give you some tasks that you might be interested. Alternatively, better, they help you with your ideas.&lt;/p&gt;

&lt;p&gt;Also, more importantly, consider your proposal as a guideline/todo list &lt;strong&gt;for yourself&lt;/strong&gt;. So you don’t get lost.&lt;/p&gt;

&lt;p&gt;Good luck for the incoming Google Summer of Code. Happy hacking!&lt;/p&gt;
</description>
        <pubDate>Sun, 02 Dec 2018 00:00:00 +0100</pubDate>
        <link>https://erickguan.me/2018/how-you-start-gsoc-with-discourse</link>
        <guid isPermaLink="true">https://erickguan.me/2018/how-you-start-gsoc-with-discourse</guid>
      </item>
    
      <item>
        <title>Take it slow in life</title>
        <description>&lt;p&gt;Internet profoundly changes human life. I read a magazine when I was a kid. It says “Everything at your fingertip.” This refers to the internet. It finally becomes truth however terrifying reality.
People start to live in the matrix and feed on their own biases. Nobody
sells happiness. It can’t be traded anyway.&lt;/p&gt;

&lt;h1 id=&quot;social-app&quot;&gt;Social app&lt;/h1&gt;

&lt;p&gt;Being social is a fundamental need for a human. We used to work together for food
and raise children. It’s hard-wired to our brain and defines feelings. But we are
also mammals. Mammals look for variety. Internet and social apps give us this unbelieve variety. Without working on it, we get choices. Dating apps are a great
example, swiping gives you dominating feelings and infinite choices. It works, and
it works like a mirage. Entrepreneurs and engineers are working so hard to provide
this options to us. People design the giant machine clusters running on their algorithm which made by few’s minds. They made it &lt;strong&gt;easy and fun&lt;/strong&gt;. It’s great gamification. It’s highly addictive too.
Though, this is detrimental too. Tinder uses ELO algorithm to ensure you are
not going to see people outside your range (score). But life isn’t like this.
Life has surprises. Meeting people brings enjoyment. Flirting requires
skills and practices. And someone at the door might have the answer you are looking for your development. The habit swiping destroy the joy. It’s fake.&lt;/p&gt;

&lt;h1 id=&quot;people-dont-read&quot;&gt;People don’t read&lt;/h1&gt;

&lt;p&gt;We are a species feed on information. We even have thinking on computer engineering that thinks information + context = knowledge. Knowledge is also written on language. We are incredible because we read. We learn from our greatest so that we don’t make the same mistakes. In fact, all technology comes with profound researches. Those are written over the years. We would die much easier without penicillin. We wouldn’t be able to predict weather without air balloon and mathematics. We wouldn’t be able to watch Netflix without decades of
technological development. Yet people don’t read. We are starting to transit from
learning from text to learning from images and videoes. &lt;strong&gt;Reading builds knowledge structure, but videoes only conveys feelings.&lt;/strong&gt; Reading is fundamental.
No matter who you are.&lt;/p&gt;

&lt;h2 id=&quot;why-people-dont-read&quot;&gt;Why people don’t read?&lt;/h2&gt;

&lt;p&gt;II think learning is always a complicated process. Because you have to put long hours reading a subject which you don’t know. That feels uncomfortable. Maybe many people
don’t have the epiphany moment. That brings you all the joy of learning. It’s
generally true that you can learn whatever you want on the internet. Knowledge
is accessisble than ever, but people are lack of motivation. Yes, learning might not lead you to a perfect job. It doesn’t give you a better income. But,&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Difficulty is a process of mastering your craft. – Qunicy&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We might have two different perspectives in looking of the world. Let’s start with hardest one.&lt;/p&gt;

&lt;h2 id=&quot;developing-world&quot;&gt;Developing world&lt;/h2&gt;

&lt;p&gt;If people don’t have accessible internet, our assumption doesn’t make sense. People probably live based on their instincts or follow social codes. Try to imagine people living in the 1960s.&lt;/p&gt;

&lt;p&gt;Then comes the Chinese. Rapid growth drives technological advancement and the internet.
It builds a gigantic gap between rich and poor but internet puts them together.
Widely accessible information without a privacy filter is terrible. Your need grows
exponentially with the new information. But not your financials. Comparison between real life and life on
photos draw pain and desire. No wonder Chinese are greedy in their relationships.
The idea of better life requiring money is a &lt;strong&gt;illusion&lt;/strong&gt; of not acknowledge time and development.&lt;/p&gt;

&lt;h2 id=&quot;first-world-problem&quot;&gt;First World problem&lt;/h2&gt;

&lt;p&gt;Living in a developed world means knowledge and books are accessible. So do
the internet and smartphones. It’s much more comfortable to live in bubbles. You only
need to react when your life is at stake. Thanks to widely accessible higher
education and good life quality. Living in the 20s are fun. Endless choices among other young people and the internet are always fun. It also develops comfortable numb. Being able to push yourself is the way to grow. And the only way to become
is to work through the pain. Many people don’t go to find that drive. They are not living.&lt;/p&gt;

&lt;h1 id=&quot;happiness-needs-work&quot;&gt;Happiness needs work&lt;/h1&gt;

&lt;p&gt;I love Yuval’s choice of Buddhist view.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If I identify happiness with fleeting pleasant sensations and crave to
experience more and more of them, I have no choice but to pursue them constantly. When I finally get them, they quickly disappear, and because the
mere memory of past pleasures will not satisfy me, I have to start all over
again. Even if I continue this pursuit for decades, it will never bring me
any lasting achievement; on the contrary, the more I crave these pleasant
sensations, the more stressed and dissatisfied I will become. To attain real
happiness, humans need to slow down the pursuit of pleasant sensations, not
accelerate it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just like concrete work, it requires constant tweaking and coping. Life applies.&lt;/p&gt;
</description>
        <pubDate>Mon, 19 Nov 2018 00:00:00 +0100</pubDate>
        <link>https://erickguan.me/2018/take-it-slow-in-life</link>
        <guid isPermaLink="true">https://erickguan.me/2018/take-it-slow-in-life</guid>
      </item>
    
      <item>
        <title>Digging in Python iterator and enumerate</title>
        <description>&lt;p&gt;When a PyTorch DataLoader repeat its data? Why it’s so magical and impossible to see in its code. It is implemented as an iterator in Python. Pythonic but implicit.&lt;/p&gt;

&lt;h1 id=&quot;use-case&quot;&gt;Use case&lt;/h1&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i_batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sample_batched&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data_loader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i_batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sample_batched&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enumerate&lt;/code&gt; is not hard to understand which only &lt;a href=&quot;https://docs.python.org/3/library/functions.html#enumerate&quot;&gt;returns the sequence and iterator’s content.&lt;/a&gt;
So what iterator does is the key to the puzzle.&lt;/p&gt;

&lt;h1 id=&quot;iterator&quot;&gt;Iterator&lt;/h1&gt;

&lt;p&gt;We can find Python’s &lt;a href=&quot;https://docs.python.org/3/glossary.html#term-iterator&quot;&gt;document&lt;/a&gt; about the iterator:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;An object representing a stream of data. Repeated calls to the iterator’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__next__()&lt;/code&gt; method (or passing it to the built-in function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next()&lt;/code&gt;) return successive items in the stream. When no more data are available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__next__()&lt;/code&gt; method just raise StopIteration again. Iterators are required to have an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__iter__() &lt;/code&gt;method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. One notable exception is code which attempts multiple iteration passes. A container object (such as a list) produces a fresh new iterator each time you pass it to the iter() function or use it in a for loop. Attempting this with an iterator will just return the same exhausted iterator object used in the previous iteration pass, making it appear like an empty container.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The document says a lot. When you use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next(data_loader)&lt;/code&gt;, it gives you a new item.
And &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StopIteration&lt;/code&gt; will be raised when it’s exhausted. When we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iter()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; loop with the iterator, a container object is built and as a fresh new iterator.&lt;/p&gt;

&lt;p&gt;That sounds complicated. How does it allocate? Who manages the resources? What about processes? GIL?&lt;/p&gt;

&lt;p&gt;And more puzzles come. The document points to &lt;a href=&quot;https://docs.python.org/3/library/stdtypes.html#typeiter&quot;&gt;itertor types&lt;/a&gt;. It didn’t explain the puzzles but introduced a new concept. A container can be used as an iterator if it supports &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__iter__()&lt;/code&gt;. Plus &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__next__()&lt;/code&gt;, it’ll form the iterator protocol.&lt;/p&gt;

&lt;p&gt;But okay, it doesn’t explain anything. From my experience from Ruby (MRI),
the implementation of Python should be similar to Ruby. Let’s dig in  CPython.&lt;/p&gt;

&lt;h1 id=&quot;cpythons-iterator-support&quot;&gt;CPython’s iterator support&lt;/h1&gt;

&lt;p&gt;CPython supports &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tp_iter&lt;/code&gt; as API. That’s a good start. If you need to support an API, you have to implement it. The search comes to &lt;a href=&quot;https://docs.python.org/3/c-api/typeobj.html&quot;&gt;Type Objects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;CPython seems to have a regular type object for every type. That’s good to find stuff. Maybe it’s also scary to have that long type definition if you have to define a new custom object. Loot at Asian’s work, Ruby (MRI) has a surprisingly &lt;a href=&quot;https://silverhammermba.github.io/emberb/c/#data&quot;&gt;clean interface&lt;/a&gt; since it’s managed in the object inheritance. We are too responsible for doing other’s work.
Though, the document doesn’t explain how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tp_iter&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tp_iternext&lt;/code&gt; were expected to use.&lt;/p&gt;

&lt;p&gt;They are two places defined them. One is included in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;typeobject.h&lt;/code&gt; and the other one is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;object.h&lt;/code&gt;. Everything is objected in Python, so this is more relevant for now.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_typeobject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/* Iterators */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;getiterfunc&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tp_iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iternextfunc&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tp_iternext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyTypeObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But it doesn’t explain how different type implements it. A list is a common sense for Python programmer so let’s look at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;listobject.c&lt;/code&gt;. CPython uses reference counting GC. So heap
space is used for object allocation. The other pairs of functions are reference counting.&lt;/p&gt;

&lt;h2 id=&quot;list-iterator-object&quot;&gt;List iterator object&lt;/h2&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;PyObject_HEAD&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Py_ssize_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;PyListObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it_seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Set to NULL when iterator is exhausted */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;listiterobject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;list_iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;listiterobject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyList_Check&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;PyErr_BadInternalCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyObject_GC_New&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;listiterobject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyListIter_Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it_index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Py_INCREF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it_seq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyListObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_PyObject_GC_TRACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This finally explains how container objects get its allocator. A new struct and new object are used to get iterator in Python. Then we can come to an iterator object.&lt;/p&gt;

&lt;h2 id=&quot;iterator-object&quot;&gt;Iterator object&lt;/h2&gt;

&lt;p&gt;The funny thing is that you can’t construct an iterator in Python (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iterator()&lt;/code&gt;). According to another document says:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;An iterable object is an object that implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__iter__&lt;/code&gt;, which is expected to return an iterator object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the source code, you find similarity.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;PyObject_HEAD&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Py_ssize_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it_seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exhausted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*/&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seqiterobject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;PySeqIter_New&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;seqiterobject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nf&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;PySequence_Check&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;PyErr_BadInternalCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PyObject_GC_New&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seqiterobject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PySeqIter_Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it_index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Py_INCREF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it_seq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;_PyObject_GC_TRACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;return &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;iter_iternext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;bp&quot;&gt;...&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PySequence_GetItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;bp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s not much different except here it expects an iterable object. It also
builds the iterator object. So the last thing would be where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; allocates
iterator.&lt;/p&gt;

&lt;h2 id=&quot;how-for-allocates-the-iterator&quot;&gt;How &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; allocates the iterator?&lt;/h2&gt;

&lt;p&gt;Let’s go back to the example &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for i_batch, sample_batched in enumerate(data_loader):&lt;/code&gt;.
When &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; statements get evaluated, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;testlist&lt;/code&gt; which is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data_loader&lt;/code&gt; object if not consider &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enumerate&lt;/code&gt; will be evaluated. It’s evaluated by executing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__iter__()&lt;/code&gt;
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__next__()&lt;/code&gt;. And an implicit generator will get allocated!&lt;/p&gt;

&lt;p&gt;Until now, we know how CPython allocates the iterator as well as who manages the resource.&lt;/p&gt;

&lt;h1 id=&quot;process-management-and-gil&quot;&gt;Process management and GIL?&lt;/h1&gt;

&lt;p&gt;It’s a wrong question as of now. If CPython manages the resource, it’s
always going to be local and constrained by GIL.&lt;/p&gt;
</description>
        <pubDate>Sun, 04 Nov 2018 00:00:00 +0100</pubDate>
        <link>https://erickguan.me/2018/python-iterator</link>
        <guid isPermaLink="true">https://erickguan.me/2018/python-iterator</guid>
      </item>
    
  </channel>
</rss>
