<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title></title>
      <link>https://www.narendasan.com</link>
      <description></description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://www.narendasan.com/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Sat, 11 Apr 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Do We Still Need Agile?</title>
          <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/drafts/agile-in-the-age-of-ai/</link>
          <guid>https://www.narendasan.com/drafts/agile-in-the-age-of-ai/</guid>
          <description xml:base="https://www.narendasan.com/drafts/agile-in-the-age-of-ai/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Agile_software_development&quot;&gt;Agile&lt;&#x2F;a&gt; was invented to solve a specific problem: software development was slow, expensive, and wrong. The waterfall process — full requirements, full design, full implementation, then test and discover you built the wrong thing — routinely produced systems that were over budget, late, and didn&#x27;t match what users actually needed. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;agilemanifesto.org&#x2F;&quot;&gt;The Agile Manifesto&lt;&#x2F;a&gt; in 2001 was a corrective: working software over comprehensive documentation, responding to change over following a plan, customer collaboration over contract negotiation. The core insight was that you could not know what was right in advance, so the process should be optimized for learning fast and adapting constantly.&lt;&#x2F;p&gt;
&lt;p&gt;That insight was correct, for its time. But the underlying assumption — that implementation is expensive and slow, so you must minimize rework by keeping cycles tight — is being aggressively eroded by AI-assisted development. Which raises a question: if the cost of implementation is approaching zero, does the logic of Agile still hold? And if it doesn&#x27;t — what replaces it?&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;p&gt;To understand what we might be giving up, it&#x27;s worth remembering what Agile replaced and why.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Waterfall_model&quot;&gt;Waterfall&lt;&#x2F;a&gt; was not invented by sadists. It came from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Waterfall_model#History&quot;&gt;Winston Royce&#x27;s 1970 paper&lt;&#x2F;a&gt; on managing large software projects, and it reflected how large engineering projects actually worked: you designed the bridge fully before you started pouring concrete, because once you started pouring you could not cheaply change the design. Software seemed to follow the same logic. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Big_design_up_front&quot;&gt;BDUF&lt;&#x2F;a&gt; — Big Design Up Front — tradition was not irrational. If implementation takes months and you can only do it once, you had better be sure about what you&#x27;re implementing.&lt;&#x2F;p&gt;
&lt;p&gt;The problem was that software is not concrete. Requirements change. Users don&#x27;t know what they want until they see what they don&#x27;t want. The feedback loops in waterfall were months or years long, which meant you could spend enormous effort building something entirely wrong.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Extreme_programming&quot;&gt;Extreme Programming&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scrum_(software_development)&quot;&gt;Scrum&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kanban_(software_development)&quot;&gt;Kanban&lt;&#x2F;a&gt; — these were all attempts to shorten those feedback loops by treating implementation as cheap and repeatable. Write the test before the code. Ship every two weeks. Keep the backlog small and reprioritize constantly. The ritual of the sprint exists specifically because someone calculated that two weeks was short enough to catch mistakes before they became catastrophic.&lt;&#x2F;p&gt;
&lt;p&gt;But &quot;short enough&quot; was a function of how long implementation actually took.&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;p&gt;Here is the shift. Agile&#x27;s unit of work was always calibrated to implementation cost. One sprint equals two weeks equals roughly one feature, or one meaningful slice of a feature. That ratio was not arbitrary — it was set by how long implementation actually took. The sprint length, the story point system, the definition of &quot;done,&quot; the shape of the backlog: all of it was tuned to a world where a feature cost a week of engineering time.&lt;&#x2F;p&gt;
&lt;p&gt;With AI-assisted development, that ratio has broken. A competent engineer can now implement in an afternoon what used to take a sprint. Which means the unit of work per sprint is no longer one feature — it is closer to a full product version. A prototype that used to require a sprint can be standing up the same afternoon. An MVP that used to require a quarter can exist by the end of the week.&lt;&#x2F;p&gt;
&lt;p&gt;Agile does not scale to this. The ceremonies — sprint planning, backlog grooming, story points, velocity tracking — were designed to manage the flow of work when work moved slowly. When work moves fast enough that you could ship a full product version before the sprint planning meeting is over, the management overhead of Agile is no longer a small fraction of the work. It &lt;em&gt;is&lt;&#x2F;em&gt; the work. You spend more time in the process ritual than doing the thing the process was supposed to organize.&lt;&#x2F;p&gt;
&lt;p&gt;The constraint has moved. It is no longer &quot;how do we avoid wasting implementation effort.&quot; It becomes &quot;how do we make sure we are building the right thing at all.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;This is, ironically, the exact problem that BDUF was designed to solve.&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;p&gt;The older methodologies that Agile displaced — waterfall, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rational_unified_process&quot;&gt;RUP&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Spiral_model&quot;&gt;spiral development&lt;&#x2F;a&gt; — had long design phases not because they were bureaucratic for its own sake, but because design was cheaper than implementation. Thinking was cheaper than building. You could iterate through many possible designs on paper — or in diagrams, or in formal specifications — at a fraction of the cost of implementing each one.&lt;&#x2F;p&gt;
&lt;p&gt;Spiral development in particular is worth revisiting. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Barry_Boehm&quot;&gt;Barry Boehm&lt;&#x2F;a&gt; proposed it in 1986 as an iterative process that put risk analysis at the center of each cycle: identify the biggest risks, build a prototype to resolve those risks, evaluate, then plan the next spiral. It was explicitly not &quot;design everything upfront&quot; — it was &quot;resolve the hardest unknowns first, repeatedly, before committing to full implementation.&quot; That is a remarkably sane framework, and it got abandoned because the prototypes and evaluations still took a long time.&lt;&#x2F;p&gt;
&lt;p&gt;What if they didn&#x27;t anymore? What if an afternoon of work with AI could resolve the risk that used to require a two-week spike?&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;p&gt;The specific problem with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kanban_(software_development)&quot;&gt;Kanban&lt;&#x2F;a&gt; and Agile in a world of cheap implementation is that they are optimized for &lt;em&gt;reactivity&lt;&#x2F;em&gt; — responding to new information quickly. But reactivity is only valuable relative to how long reactions used to take. Kanban&#x27;s pull system, Scrum&#x27;s sprint cadence, the constant backlog reprioritization — these were designed for a world where the cost of a wrong decision was measured in weeks of engineering time, and the best you could do was catch it at the next sprint review.&lt;&#x2F;p&gt;
&lt;p&gt;If you can just &lt;em&gt;try the thing&lt;&#x2F;em&gt; in an afternoon, you already have faster feedback than any sprint ceremony provides. The overhead of managing the process — standups, planning, grooming, retrospectives, velocity tracking — was justified when it was a small fraction of total engineering time. When a full product version fits in a sprint, it is no longer a small fraction. The process overhead &lt;em&gt;dominates&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Kanban in particular assumes a steady flow of discrete work items of roughly consistent size moving through defined stages. That model made sense when the unit of work was a feature or a task. It breaks when the unit of work is a product version — because you can&#x27;t pull a &quot;full product version&quot; off a board and have it flow through QA in the same way a bug fix does. The work items are not consistent anymore. Some are hours, some are a day, some are a full product. The pipeline model does not fit.&lt;&#x2F;p&gt;
&lt;p&gt;There is also a subtler issue. Kanban and Agile were explicitly designed to keep teams in a state of &lt;em&gt;perpetual reaction&lt;&#x2F;em&gt;: what does the customer need right now, what is blocking us right now, what did we learn last sprint. This is the right posture when implementation is slow and costly. But it systematically underweights &lt;em&gt;long-horizon thinking&lt;&#x2F;em&gt;. When you are always reacting, you are rarely designing. The backlog replaces the architecture. The sprint replaces the vision. You end up with software that works for the next two weeks but has no coherent shape.&lt;&#x2F;p&gt;
&lt;p&gt;This was always a critique of Agile — that it produced working software that was &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Technical_debt&quot;&gt;difficult to evolve&lt;&#x2F;a&gt; because nobody had ever sat down to think about it whole. AI-assisted implementation makes this worse, not better, because it lowers the cost of adding features without lowering the cost of having no coherent architecture.&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;p&gt;So what might a better methodology look like in a world of cheap implementation?&lt;&#x2F;p&gt;
&lt;p&gt;A few hypotheses:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Longer design phases, shorter implementation phases.&lt;&#x2F;strong&gt; If implementation is fast, the bottleneck is knowing what to build. Invest more time in the design phase — not BDUF in the sense of specifying every detail upfront, but genuine exploratory design: competing approaches, user research, prototype evaluation, architectural thinking. Then implement quickly once you know what you&#x27;re doing.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Multiple competing prototypes.&lt;&#x2F;strong&gt; If building a prototype costs an afternoon instead of a sprint, you can build three and compare them. This is standard practice in hardware design and industrial design — it was prohibitively expensive in software. It may not be anymore. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Design_sprint&quot;&gt;Design sprints&lt;&#x2F;a&gt; pointed in this direction but were still constrained by implementation cost.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Risk-first sequencing à la Boehm.&lt;&#x2F;strong&gt; Before committing to an implementation direction, explicitly identify the riskiest assumptions — the things that would invalidate the design if they turned out to be wrong — and resolve those first. With cheap implementation, you can spike each risk quickly.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Less ceremony, more thinking.&lt;&#x2F;strong&gt; The standups, story points, and sprint planning were process overhead justified by the need to coordinate expensive implementation work. If implementation is cheap and fast, the coordination overhead may not be worth it. A smaller team with a clearer shared vision and a longer planning horizon may outperform a larger Agile team running process for its own sake.&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;p&gt;None of this means Agile is simply wrong. The core values — working software over documentation, customer collaboration, responding to change — remain sound. But the &lt;em&gt;practices&lt;&#x2F;em&gt; that were derived from those values assumed a world where implementation was the expensive constraint. That world is changing faster than the practices are.&lt;&#x2F;p&gt;
&lt;p&gt;The irony is that we may be heading back toward something that looks more like the methodologies Agile displaced — not because those methodologies were right all along, but because the conditions that made them wrong are being removed. Waterfall failed because feedback loops were too slow. AI is compressing those loops. The question is whether we are thoughtful enough about &lt;em&gt;which&lt;&#x2F;em&gt; loops to compress, and whether we preserve the parts of the process that were not about speed at all — the parts about thinking clearly, designing coherently, and building something that will still make sense in two years.&lt;&#x2F;p&gt;
&lt;p&gt;The sprint was a workaround for expensive implementation. The workaround may be expiring. It&#x27;s worth asking what we actually want to do with the time we&#x27;re getting back.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Humanities in SV</title>
          <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/drafts/humanities-in-sv/</link>
          <guid>https://www.narendasan.com/drafts/humanities-in-sv/</guid>
          <description xml:base="https://www.narendasan.com/drafts/humanities-in-sv/">&lt;p&gt;In 2024 Apple released &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;ntjkwIXWtrc&quot;&gt;an ad for the iPad Pro&lt;&#x2F;a&gt;. A hydraulic press slowly destroys a grand piano, paint cans, cameras, books, guitars, trumpets, record players — physical manifestations of human creative expression — as they are compressed into a thin slab of aluminum and glass. They intended to communicate that all you need is an iPad to access all these art forms, that the iPad was the ultimate window to access creativity.&lt;&#x2F;p&gt;
&lt;p&gt;However, people did not take the ad this way. Instead it became a symbol of a general discontent with technology. Instead of all these physical, specific, intentionally designed tools and mediums, we get a blank featureless slab that doesn&#x27;t do anything particularly well and mostly turns into an endless consumption device. The backlash was severe enough that Apple issued a public apology. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hugh_Grant&quot;&gt;Hugh Grant&lt;&#x2F;a&gt; called it &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;x.com&#x2F;HackedOffHugh&#x2F;status&#x2F;1788183871504204257&quot;&gt;&quot;the destruction of the human experience.&quot;&lt;&#x2F;a&gt; Apple pulled it from TV.&lt;&#x2F;p&gt;
&lt;p&gt;The company that set itself the goal of creating &quot;the bicycle of the mind&quot; has lost its way to the point where it now is putting out messaging visualizing how they crushed and compressed the human experience into a box. This is not just an Apple story. It is the story of Silicon Valley over the last three decades — a slow forgetting of what technology was originally for: not to shortcut human activity, but to empower humans to do things that had never been done, to build mediums that had never existed.&lt;&#x2F;p&gt;
&lt;p&gt;Many people love to throw the criticism that tech bros missed their humanities classes in college. But that misses the point. Reading Kant or Heidegger, or taking an art appreciation class — which most of these people have probably done — does not teach you what actually got lost. It is something more basic: the belief that the most valuable thing technology can do is not remove effort from existing activities, but enable entirely new ones. That the goal is not shortcutting the human, but empowering them. That efficiency is not the only axis worth optimizing on, and may not even be the important one.&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;p&gt;There is a specific post-60s cultural cocktail that produced the best of early tech. Countercultural utopianism. New Age metaphysics. A real engagement with art, music, and literature. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Stewart_Brand&quot;&gt;Stewart Brand&lt;&#x2F;a&gt; and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Whole_Earth_Catalog&quot;&gt;Whole Earth Catalog&lt;&#x2F;a&gt;. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Grateful_Dead&quot;&gt;The Grateful Dead&lt;&#x2F;a&gt; as early adopters of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_WELL&quot;&gt;the WELL&lt;&#x2F;a&gt;. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;John_Perry_Barlow&quot;&gt;John Perry Barlow&#x27;s&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.eff.org&#x2F;cyberspace-independence&quot;&gt;Declaration of Independence of Cyberspace&lt;&#x2F;a&gt;, which reads as naive now but was animated by a genuine belief that the network could be a space for human liberation rather than corporate extraction and efficency gains.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Technology is a tool for expanding human capability and consciousness, not replacing it.&lt;&#x2F;em&gt; And crucially — the act of using the tool was supposed to make you more of a person, not less of one. The destination and the journey were both the point. Apple under Steve Jobs centered itself in this philosophy. The Mac&#x27;s proportional fonts came directly from a calligraphy class he auditied. His obsession with industrial design wasn&#x27;t aesthetic vanity; it came from a belief that how an object feels in your hand is part of what it communicates. He described the computer as a &quot;bicycle for the mind&quot; — a tool that makes the human more powerful, not a substitute for the human. The metaphor is precise. A bicycle doesn&#x27;t choose your destination or walk for you. It applies leverage to the effort you were going to spend anyway. Jobs cited a study he&#x27;d read as a child: scientists measured energy per unit of distance across animals, and the condor won — most efficient locomotion on Earth. The human, without tools, was mediocre by comparison. But put a human on a bicycle and they blow past the condor by a factor of three. The computer was that, for the mind — not intelligence replacing yours, but a multiplier on the intelligence you bring to it. The person still has to pedal. The person still navigates. The agency stays human; the reach extends.&lt;&#x2F;p&gt;
&lt;p&gt;More concretely, Jobs understood that some of the most interesting territory in tech was where technology met artistic production. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;SgWdjvRgouk?si=pFHJUC-6Iw5OvZFf&quot;&gt;1996 Charlie Rose interview with Jobs and John Lasseter&lt;&#x2F;a&gt; is worth watching in full. Charlie Rose asks the question you&#x27;d expect: does this make movies faster? Cheaper? &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;John_Lasseter&quot;&gt;Lasseter&lt;&#x2F;a&gt; reframes it completely.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;We don&#x27;t look at it as a way to replace any of the creativity or any of the real art of film making. We look at it as these are just a great new expensive pencils. It&#x27;s artists using these computers as though an artist at Disney uses a piece of paper and a pencil.&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;He then goes further. &quot;It&#x27;s a very common belief that when computers come into a new artistic medium, it&#x27;s either less expensive, takes less time, or it&#x27;s going to replace something. It reminds me a lot of when photography was invented — everybody thought that painting was going to get replaced.&quot; The computers aren&#x27;t cheaper. They aren&#x27;t faster. They&#x27;re a different medium that lets you tell different stories.&lt;&#x2F;p&gt;
&lt;p&gt;Lasseter is describing a pattern that recurs with every new medium. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Roland_TR-808&quot;&gt;Roland TR-808&lt;&#x2F;a&gt; drum machine was a commercial failure when it launched in 1980 — it didn&#x27;t sound like real drums — and was discontinued after two years. Then hip-hop and electronic music got hold of it, and the 808&#x27;s synthetic kick became the sonic foundation of an entire half-century of popular music. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;MIDI&quot;&gt;MIDI&lt;&#x2F;a&gt; was supposed to make musicians obsolete; instead it gave composers direct access to the full palette of orchestral sound from a bedroom. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Desktop_publishing&quot;&gt;Desktop publishing&lt;&#x2F;a&gt; — PageMaker, Quark, a laser printer — was going to destroy graphic design by letting anyone make a layout; instead it produced entirely new visual aesthetics and democratized a craft that had been locked behind expensive typesetting equipment. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Digital_audio_workstation&quot;&gt;Digital audio workstations&lt;&#x2F;a&gt; and cheap recording interfaces collapsed the cost of a studio to near zero, and rather than flooding the world with garbage music, they enabled genres — lo-fi, vaporwave, bedroom pop — that could only have come from individuals making things alone at odd hours with inexpensive tools. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Digital_photography&quot;&gt;Digital photography&lt;&#x2F;a&gt; was not real photography — no grain, no chemical process, no darkroom. Every time, the argument runs the same way: the new thing will either replace the old thing or cheapen it. Every time, the new thing becomes its own medium with its own masters, its own aesthetic vocabulary, and a body of work that could not have existed any other way. Jobs, who got into &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pixar&quot;&gt;Pixar&lt;&#x2F;a&gt; initially because the technology &quot;blew him away,&quot; lands in the same place after a decade alongside Lasseter: &quot;all this technology really is just in the service of the storytelling. The computers don&#x27;t do the animation — they do the drawing.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;That distinction matters enormously. Pixar&#x27;s technology — and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Industrial_Light_%26_Magic&quot;&gt;ILM&#x27;s&lt;&#x2F;a&gt; before it — was developed &lt;em&gt;in service of&lt;&#x2F;em&gt; a creative vision. The renderer existed because Lasseter had something he wanted to show that no existing medium could show. The technology was downstream of the art.&lt;&#x2F;p&gt;
&lt;p&gt;The proof of this is in the specific things Pixar chose to build. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;theasc.com&#x2F;articles&#x2F;toy-story-4-creating-a-virtual-cooke-look&quot;&gt;&lt;em&gt;Toy Story 4&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, the cinematography team implemented &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Split_diopter&quot;&gt;split diopter shots&lt;&#x2F;a&gt; — a technique from live-action filmmaking where a split lens holds two subjects at very different distances in simultaneous sharp focus, used by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Brian_De_Palma&quot;&gt;De Palma&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Steven_Spielberg&quot;&gt;Spielberg&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gordon_Willis&quot;&gt;Gordon Willis&lt;&#x2F;a&gt;. In CG you have no optical physics forcing your hand. You could just render everything sharp. Pixar implemented split diopter shots &lt;em&gt;on purpose&lt;&#x2F;em&gt;, because they were thinking like filmmakers, not like computer scientists. They were asking: what does this scene need cinematographically?&lt;&#x2F;p&gt;
&lt;!-- INSERT: screenshot of Toy Story 4 split diopter shot (Gabby Gabby &#x2F; Forky scene) --&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_Good_Dinosaur&quot;&gt;&lt;em&gt;The Good Dinosaur&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; did similarly demanding work on crowd and herd animation — not because the technology required it but because the story required convincing scale, mass, living ecosystems of creatures. The question was always what the scene needed, and the technology answered.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;-wpXOIPl0wo?si=RNvSoxuXEOQLRaBE&quot;&gt;WETA FX today&lt;&#x2F;a&gt; still operates this way: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Joe_Letteri&quot;&gt;Joe Letteri&lt;&#x2F;a&gt; and his team build tools because directors like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;James_Cameron&quot;&gt;James Cameron&lt;&#x2F;a&gt; have specific things they need to express. The tech doesn&#x27;t drive the story; the story drives the tech.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;GarageBand&quot;&gt;GarageBand&lt;&#x2F;a&gt; is another example. When &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;9MRDDJjTwTw?si=tBAay-iy9C7f8_jA&quot;&gt;Jobs introduced it at Macworld 2004 with John Mayer on stage&lt;&#x2F;a&gt;, the demo was a musician using a tool to make music. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;John_Mayer&quot;&gt;Mayer&lt;&#x2F;a&gt; plugged in his guitar and played — but that was the demo, not the point. The point is that anyone with something musical in their head could now get it out. You didn&#x27;t need to play. You could build loop by loop, note by note. What you needed was intent. The software removed the barrier between the idea and the listener — it did not remove the human with the idea.&lt;&#x2F;p&gt;
&lt;p&gt;This is what it looks like when technology is genuinely human-centered. The tool amplifies the human. It does not replace them. And the &lt;em&gt;process&lt;&#x2F;em&gt; — Mayer practicing, the Pixar animator studying light, the engineer and the artist arguing about what a scene needs — is not inefficiency to be removed. It is the work. It is what produces people who know what they&#x27;re doing.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Silliwood&quot;&gt;Silliwood&lt;&#x2F;a&gt; — the 90s portmanteau for the convergence of Silicon Valley and Hollywood — was a brief, mostly failed attempt to formalize this intersection. Most of those companies were, as Jobs put it, places that existed &quot;so they can raise investment, but they never produced any products.&quot; Pixar was, in his view, the only enterprise where the meeting of Silicon Valley and Hollywood had actually produced something. The reason Pixar worked and Silliwood didn&#x27;t is the same reason: Pixar had Lasseter, and Lasseter had something to say. The technology followed the vision, not the other way around.&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;p&gt;Somewhere in the 2000s-2010s, this tradition died quietly.&lt;&#x2F;p&gt;
&lt;p&gt;The dominant culture of Silicon Valley stopped growing out of art. It grew out of B2B SaaS. The founding mythology shifted from &quot;bicycles for the mind&quot; to &quot;growth hacking,&quot; &quot;enterprise ARR,&quot; and &quot;product-market fit.&quot; The countercultural aesthetic got replaced with the aesthetic of the McKinsey deck: clean sans-serif fonts, white space, and an earnest belief that every human problem was an optimization problem.&lt;&#x2F;p&gt;
&lt;p&gt;Part of what drove this shift was structural. Venture capital developed a playbook good at evaluating one kind of bet: a measurable improvement on something that already exists. X% faster, Y% cheaper, growth rate, annual recurring revenue. These are legible — you can model them, defend them in a partners meeting, show them to LPs. The kind of bet Lasseter represented is much harder: a new medium whose economics cannot be modeled because the audience does not yet exist, whose value will only be evident after years of making things in it. Jobs funded Pixar personally for nearly a decade before it produced anything — close to $60 million of his own money, in a company with no revenue and no proof of concept for the medium it was trying to build. That kind of patience, and that tolerance for illegible upside, is structurally incompatible with the incentives of a modern venture fund. What gets funded is what fits on a pitch deck: productivity gains, market size, churn reduction. New mediums don&#x27;t fit on pitch decks. They require an investor to imagine something that doesn&#x27;t exist yet and believe, without evidence, that people will want to inhabit it once it does. That takes a different kind of bravery — and the industry optimized it out.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s a version of this story that keeps repeating in computing specifically. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;VisiCalc&quot;&gt;VisiCalc&lt;&#x2F;a&gt; — the first spreadsheet, 1979 — automated the work of bookkeepers and accountants who spent careers doing by hand what a computer could now do in seconds. Word processors eliminated the professional typist. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Computer-aided_design&quot;&gt;CAD software&lt;&#x2F;a&gt; eliminated the draftsman. Desktop publishing eliminated the typesetter. Each time, the argument from the technology side was pure efficiency: the computer does this faster and cheaper, therefore the human who used to do it is no longer needed. And each time, that was partially true and wholly incomplete — because the people being displaced weren&#x27;t just doing the mechanical task, they were holding craft knowledge, judgment, and aesthetic sensibility that the software could not encode. When you fire all the typesetters and let the marketing team do layout in PageMaker, you save money and you lose something harder to name.&lt;&#x2F;p&gt;
&lt;p&gt;More than aesthetics: the fundamental question changed. It used to be &lt;em&gt;what does this enable a person to do and become?&lt;&#x2F;em&gt; It became &lt;em&gt;what friction does this remove?&lt;&#x2F;em&gt; Technology stopped being an end — a thing worth engaging with because of what it does to you — and became purely a means. A pipe. The output is what matters; the human in the middle is a cost to be minimized.&lt;&#x2F;p&gt;
&lt;p&gt;This logic does not stay in enterprise software. It leaks into every consumer product built by the same culture. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;DoorDash&quot;&gt;DoorDash&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Uber_Eats&quot;&gt;Uber Eats&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Instacart&quot;&gt;Instacart&lt;&#x2F;a&gt; — the pitch is pure friction removal: food appears, you did not have to cook, you did not have to go anywhere, you did not have to talk to anyone. The convenience is real. But cooking is not just calorie acquisition. It is a skill, a ritual, a way of caring for people, a form of creativity with immediate sensory feedback. The process of going to a restaurant is social, spatial, cultural — you are somewhere, with someone, the meal is an event. What gets optimized away is not just effort. It is the texture of daily life, the practices through which people develop competence and connection. The app does not ask what cooking does for you. It asks how fast you want it gone.&lt;&#x2F;p&gt;
&lt;p&gt;The same logic governs attention. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;TikTok&quot;&gt;TikTok&lt;&#x2F;a&gt; removes the friction of choosing what to watch. The algorithm decides; content arrives; you never have to seek, discover, or exercise taste. But finding things — building a sense of what you like and why, following a thread of curiosity until you&#x27;ve learned something, being bored enough to go looking — is not inefficiency. It is how you develop taste. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Instagram&quot;&gt;Instagram&lt;&#x2F;a&gt; removes the friction of staying in touch, and replaces actual connection with broadcast. The friction of calling someone, having a meal, being present — gone. What&#x27;s also gone is intimacy. More broadly, social media removes the friction of boredom. Idle moments used to be spaces for thought, daydreaming, conversation. Now the phone fills them instantly. The space in which ideas form gets optimized away. The For You Page does not ask what watching does for you. It asks how long it can keep you there.&lt;&#x2F;p&gt;
&lt;p&gt;The trajectory of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Nest_Labs&quot;&gt;Nest&lt;&#x2F;a&gt; captures something sharper: the efficiency-first culture doesn&#x27;t just produce this kind of product — it absorbs even companies that started elsewhere. Tony Fadell — who had led the iPod team at Apple — founded Nest in 2010 to build a thermostat. The original &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Nest_Learning_Thermostat&quot;&gt;Nest Learning Thermostat&lt;&#x2F;a&gt; was a round, beautifully machined object with a satisfying physical dial. But the meaningful design decision was behavioral: it didn&#x27;t ask you to program a schedule. It watched you for a week and learned your patterns. The human&#x27;s life, habits, and comfort remained the point; the thermostat served them without demanding you become an HVAC programmer to use it. That is the bicycle — leverage applied to what you were already doing.&lt;&#x2F;p&gt;
&lt;p&gt;Google acquired Nest in 2014 for $3.2 billion. The thermostat became a node in an ambient home intelligence system: a data point integrated into Google&#x27;s identity and advertising infrastructure, eventually absorbed into Google Home. The pitch shifted to &quot;set it and forget it.&quot; But &quot;forget it&quot; is the tell. The goal became to remove you from the loop entirely — stop thinking about your home, stop interacting with it, stop being present in it. The friction being removed was also awareness. The tool stopped amplifying your preferences and started making decisions on your behalf, invisibly, in service of a platform whose actual customers were advertisers. Fadell left Google in 2016.&lt;&#x2F;p&gt;
&lt;p&gt;This is the culture that produced the Crush ad. The team that made it had a mental model where compression = good, efficiency = good, doing more with less = good. The hydraulic press was not violence — it was elegance. They had lost the ability to see what they were destroying, because the things being destroyed — the &lt;em&gt;process&lt;&#x2F;em&gt; of playing piano, of developing your eye with a camera, of writing something difficult and slow — had already stopped mattering to them.&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;p&gt;Now we have LLMs, and the confusion has deepened.&lt;&#x2F;p&gt;
&lt;p&gt;The pitch is: &quot;everyone is a creator now.&quot; Everyone can generate images. Everyone can write. Everyone can compose music. The technology &lt;em&gt;democratizes&lt;&#x2F;em&gt; creative production. This is not subtext — it is the explicit framing from the people building these systems. Jensen Huang at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cnbc.com&#x2F;2023&#x2F;05&#x2F;30&#x2F;everyone-is-a-programmer-with-generative-ai-nvidia-ceo-.html&quot;&gt;2024 World Government Summit&lt;&#x2F;a&gt;: &quot;It is our job to create computing technology such that nobody has to program. And that the programming language is human. Everybody in the world is now a programmer.&quot; Sam Altman has said &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;futurism.com&#x2F;sam-altman-openai-wipe-out-categories-human-jobs&quot;&gt;entire job categories will be &quot;totally, totally gone&quot;&lt;&#x2F;a&gt; as AI agents join the workforce. Dario Amodei has warned that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.marketingaiinstitute.com&#x2F;blog&#x2F;dario-amodei-ai-entry-level-jobs&quot;&gt;AI could eliminate half of entry-level white-collar roles&lt;&#x2F;a&gt; within five years. The framing is not &quot;here are superpowers for humans.&quot; The framing is &quot;here is a replacement for humans, and the efficiency gains justify it.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;These are metrics that make sense on a spreadsheet. Efficiency. Headcount reduction. Cost per task automated away. What they don&#x27;t capture is what humans actually care about: whether the work means something, whether they&#x27;re growing, whether they made something true and got it into the world. The countercultural tradition that produced the best of early tech cared about those things because it came from people for whom those things mattered personally. The B2B SaaS tradition that replaced it optimizes for the former because that&#x27;s what closes enterprise deals. This is not malice. It is a profound mismatch between what the tool-builders are measuring and what the people using the tools are actually living.&lt;&#x2F;p&gt;
&lt;p&gt;The consequence of this framing is not just philosophical — it is actively shaping the products. Every AI interface designed under the efficiency logic is answering the same question: what existing task can I make cheaper or faster? The chat box is a support ticket. The AI coding tool is a faster typist. The image generator is a cheaper illustrator. These framings treat AI as a shortcut inside existing workflows, not as a new medium with its own vocabulary and demands. The question Lasseter was asking in 1996 — what new thing can a person do with this that they could not do before? what new medium does this enable? — is not being asked, because it does not close enterprise deals. The result is a genuinely transformative technology being built, sold, and understood primarily as a cost-reduction tool. Which is roughly like Pixar deciding the main value of their renderer was that it made animators faster.&lt;&#x2F;p&gt;
&lt;p&gt;The interface is the most legible symptom of this. The way we interact with AI is through a chat box: text in, text out. The nearest analogy is SMS. This is not an interface metaphor — it is the &lt;em&gt;absence&lt;&#x2F;em&gt; of one. The humanist tradition in computing always cared deeply about interface. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_Mother_of_All_Demos&quot;&gt;Engelbart&#x27;s 1968 Mother of All Demos&lt;&#x2F;a&gt; was fundamentally about inventing metaphors for thought. The Mac&#x27;s desktop metaphor was a genuine intellectual achievement: it made the file system legible to non-engineers by grounding it in physical space. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;HyperCard&quot;&gt;HyperCard&lt;&#x2F;a&gt;. VR as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Jaron_Lanier&quot;&gt;Jaron Lanier&lt;&#x2F;a&gt; conceived it — not entertainment but &lt;em&gt;empathy machine&lt;&#x2F;em&gt;, a way to inhabit other perspectives and expand what it means to be a person. These were hard-won insights about how humans think and how technology could meet them where they are. They came from people who read philosophy, who thought about phenomenology and perception, who asked: what is this &lt;em&gt;for&lt;&#x2F;em&gt;, in the deepest sense? The chat interface for AI does not come from that tradition. It comes from: &quot;you know how to text, so text the computer.&quot; It is skeuomorphism in the worst sense — dressed in the clothes of text messaging because the people building it never asked whether text messaging was the right metaphor for what this technology actually does.&lt;&#x2F;p&gt;
&lt;p&gt;This is the Syndrome problem. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_Incredibles&quot;&gt;&lt;em&gt;The Incredibles&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, the villain&#x27;s plan is to sell superpowers to everyone — because &quot;when everyone can be super, no one will be.&quot; The goal is not to celebrate human capability. The goal is to make human capability irrelevant. The Silicon Valley version: when everyone can generate a painting without learning to paint, the painting is worth nothing, and — more importantly — &lt;em&gt;you have learned nothing&lt;&#x2F;em&gt;. The capacity for judgment, for seeing, for knowing what&#x27;s good and why, does not develop without practice. Automating out the practice automates out the person.&lt;&#x2F;p&gt;
&lt;p&gt;The process is not a bug. The struggle of learning to draw, to write, to play an instrument — that is not inefficiency waiting to be removed. It is how you become someone with something to say. Philosopher &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thegradientpub.substack.com&#x2F;p&#x2F;c-thi-nguyen-values-legibility-games&quot;&gt;C. Thi Nguyen&lt;&#x2F;a&gt; calls this &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;academic.oup.com&#x2F;book&#x2F;32137&quot;&gt;striving play&lt;&#x2F;a&gt;&quot; — the idea that we sometimes choose ends specifically because the means are what we actually want. The summit is an excuse to climb. The painting is an excuse to see. Skip the process and you get the output without the person behind it. You get aesthetics without interiority. Gram-worthy, soulless.&lt;&#x2F;p&gt;
&lt;p&gt;Nguyen&#x27;s work on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;philpapers.org&#x2F;rec&#x2F;NGUGAV&quot;&gt;gamification and value capture&lt;&#x2F;a&gt; is equally relevant here: when you reduce a rich activity to a score or metric, people stop doing the activity and start optimizing the metric. The Instagram camera doesn&#x27;t just skip the process of learning to see — it installs a new goal (engagement, likes, the gram-worthy image) that actively competes with the old one (making something true). Once the metric is in place, the underlying value gets crowded out.&lt;&#x2F;p&gt;
&lt;p&gt;There is a growing body of research on exactly this — &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.media.mit.edu&#x2F;publications&#x2F;your-brain-on-chatgpt&#x2F;&quot;&gt;cognitive debt&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;html&#x2F;2510.16019v1&quot;&gt;skill atrophy&lt;&#x2F;a&gt;, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;html&#x2F;2604.03501&quot;&gt;augmentation trap&lt;&#x2F;a&gt; — and the findings are roughly what you&#x27;d expect: offload the thinking and the thinking weakens. But the more interesting question is not whether LLMs cause atrophy. It is &lt;em&gt;which skills&lt;&#x2F;em&gt; are being offloaded, and whether those are the ones that mattered.&lt;&#x2F;p&gt;
&lt;p&gt;GUIs made computers accessible to everyone and in doing so made most people unable to use a command line. That is a real loss. It is also, probably, the right tradeoff — most people did not need the command line, and what they gained was worth what they gave up. The question with LLMs is whether the same logic holds. If what gets offloaded is syntax recall, boilerplate, and the mechanical parts of writing — and what remains is design decisions, API and interface choices, abstractions, the judgment calls that actually determine whether something is good — then LLMs could make people &lt;em&gt;better&lt;&#x2F;em&gt; designers in the same way GUIs made computers accessible, while atrophying skills that were always more means than end. You stop thinking about where the semicolons go and start thinking harder about what the system should do and why.&lt;&#x2F;p&gt;
&lt;p&gt;Whether that is actually what happens depends entirely on how you use them. Use them as a crutch and you get the cognitive debt. Use them as a focusing lens — offload the stuff that doesn&#x27;t require your judgment so your judgment can go where it matters — and you might end up somewhere genuinely interesting. The tool isn&#x27;t the problem. The orientation toward the tool is.&lt;&#x2F;p&gt;
&lt;p&gt;Agentic AI interfaces push this further in an interesting direction. Complex one-off infrastructure tasks — spinning up a multi-node training cluster, configuring a distributed system, wiring together a pipeline that crosses four different services — used to require either deep specialist knowledge or a specialist to hire. The task was tractable only if you already knew the terrain. Agentic tools make the navigational complexity manageable for someone who knows what they want but not every step required to get there. The human judgment that matters — what am I building, what scale do I need, what tradeoffs am I making — stays with the human. The part that was always just terrain navigation gets handled. This is squarely in the GUI tradition: lower the floor, preserve the decisions that require a person.&lt;&#x2F;p&gt;
&lt;p&gt;The tools Jobs, Lasseter, and Letteri built held to one principle: raise the ceiling on what a human could express while keeping the human as the one doing the expressing. The floor was never technique. It was intent — something to say.&lt;&#x2F;p&gt;
&lt;p&gt;The current generation of AI tools is pitched differently. They are not &quot;here is a more powerful brush.&quot; They are &quot;here, let the machine make the creative decisions.&quot; The iPhone camera that automatically adjusts your composition, boosts the colors, removes the blemishes — it produces something that looks &lt;em&gt;gram-worthy&lt;&#x2F;em&gt; while systematically removing every decision that would require you to develop taste. Does this save money? Are you more efficient? Does it matter, as long as the output looks good?&lt;&#x2F;p&gt;
&lt;p&gt;Lasseter&#x27;s framing from 1996 is still the right one. The question is not whether the technology is cheaper or faster. The question is what kind of medium it is, and what it demands of the person using it. Pixar&#x27;s expensive pencils still required you to be an animator. They raised the ceiling on what an animator could do, but the floor was still: &lt;em&gt;you have to be an animator&lt;&#x2F;em&gt;. The AI camera does not require you to learn to see.&lt;&#x2F;p&gt;
&lt;p&gt;The distinction matters even within AI tools themselves. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;X8yRlA7jqEQ?si=LGScLeUOQUqO5c1j&quot;&gt;Gaussian Splats&lt;&#x2F;a&gt; — a new medium for capturing and rendering reality as navigable 3D scenes — use machine learning at their core. The reconstruction is trained. But the human creative experience is not removed because there is &quot;AI&quot; in it. The artist still decides what to capture, how to frame it, what to do with it afterward: relight it, add depth of field, composite 3D objects into it, bend the geometry. When Corridor Crew&#x27;s Wren used a Gaussian Splat to capture &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Inspiration_Point,_Angeles_National_Forest&quot;&gt;Inspiration Point&lt;&#x2F;a&gt; — a mountain landmark that burned in the LA wildfires — the AI did the reconstruction. The human decided it was worth preserving. That impulse, and everything that flows from it, is irreducibly human. The tool served it. As Wren puts it: &quot;I&#x27;m a visual effects artist and my job is to bend reality.&quot; The AI is infrastructure. The bending is still his.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vibe_coding&quot;&gt;Vibe coding&lt;&#x2F;a&gt; — directing an AI to write and iterate on code through natural language — is getting the same dismissal every new medium gets: not real programming, a shortcut that bypasses the work. But the argument applies the wrong floor. The floor of traditional programming was syntax, library APIs, debugging mechanics — terrain navigation. Vibe coding removes that floor the same way GUIs removed the command line. What it does not remove is the judgment that actually makes software good: what are you building and why, what constitutes a correct solution, where are the edge cases that matter, what does acceptable performance look like, when is the AI confidently wrong. These are not syntax problems. They are what separates engineers who understand systems from engineers who can write code. The medium is new. The demands are not gone — they are exposed, because the mechanical layer is no longer there to hide behind. A programmer who cannot articulate what &quot;correct&quot; means, who cannot recognize a plausible-looking solution that fails on the case that matters, who has no taste for what a well-designed system feels like — that programmer is worse off with vibe coding, not better. The one who can do all of that has a new and more powerful pencil.&lt;&#x2F;p&gt;
&lt;p&gt;Critics of AI are mostly reacting against the efficiency discourse — and they are right to. When the loudest voices in tech are promising to eliminate jobs and automate away expertise, the fear is earned. But the critique goes wrong in two ways. The first: it attacks the technology for what the efficiency culture has decided to do with it. AI-as-replacement-engine is a product choice, not a property of the technology — dismissing AI because of how SV pitches it is like dismissing CG animation because Hollywood used it to cut headcount. The second: the argument that AI-generated work is inherently inauthentic — that using AI is cheating, that the human must suffer through the process for the output to count — confuses the tool for the artist. Both errors mistake the medium for the business model of the people currently exploiting it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hip_hop_music&quot;&gt;Hip-hop&lt;&#x2F;a&gt; built its entire sonic vocabulary on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sampling_(music)&quot;&gt;sampling&lt;&#x2F;a&gt; — lifting pieces of existing recordings and recombining them into something new using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Drum_machine&quot;&gt;drum machines&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sampler_(musical_instrument)&quot;&gt;samplers&lt;&#x2F;a&gt;. It was called theft, literally: the copyright lawsuits that followed &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Grand_Upright_Music,_Ltd._v._Warner_Bros._Records_Inc.&quot;&gt;Grand Upright v. Warner&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Campbell_v._Acuff-Rose_Music,_Inc.&quot;&gt;Campbell v. Acuff-Rose&lt;&#x2F;a&gt; reshaped intellectual property law because the industry could not accept that recombining existing recordings was a creative act. It was. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;DJ_Kool_Herc&quot;&gt;DJ Kool Herc&lt;&#x2F;a&gt; isolating the break in a funk record to loop it indefinitely — using two turntables as an instrument — was not stealing. It was inventing a new medium with two pieces of consumer electronics and a good ear.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Demoscene&quot;&gt;demoscene&lt;&#x2F;a&gt; — programmers and artists making real-time audiovisual art within extreme hardware constraints on early PCs and home computers — was not considered &quot;real&quot; art by the mainstream. It was kids messing around with computers. But the demoscene produced a genuine aesthetic tradition, a competitive community of practice, and a generation of people who understood computation as a creative medium in a way that pure engineers never did. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Chiptune&quot;&gt;Chiptune&lt;&#x2F;a&gt; artists making music from the sound chips of Game Boys and Commodore 64s were not making real music. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vaporwave&quot;&gt;Vaporwave&lt;&#x2F;a&gt; — built almost entirely from samples, pitch-shifted and time-stretched, assembled in DAWs by anonymous internet users — was not real music. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Adobe_Flash#Flash_animation&quot;&gt;Flash animation&lt;&#x2F;a&gt; on early internet was not real animation. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Auto-Tune&quot;&gt;Autotune&lt;&#x2F;a&gt;, introduced as an imperceptible pitch-correction tool, became an expressive instrument in its own right: T-Pain, Bon Iver, Kanye each made it do things its inventor never imagined, and those are real songs. Every one of these was dismissed as cheating, as not serious, as a shortcut that bypassed the real work. Every one of them produced genuine art made by humans with something to say. The argument &quot;this is cheating&quot; or &quot;this is not real&quot; has been applied to every new computing and electronic tool in the history of making things. It has been wrong every time for the same reason: it mistakes the process for the point, the medium for the message, the tool for the artist.&lt;&#x2F;p&gt;
&lt;p&gt;Gaussian Splats use machine learning. A GarageBand track built loop by loop without touching an instrument is still a song if someone had something to say in making it. Photography was not painting and the critics who said so were wrong. The question is not whether AI was involved. It is whether a human was present as an agent with something to express, making decisions that mattered. That can be true with AI. It can also be absent without it. The hydraulic press that crushed the grand piano contained no AI at all.&lt;&#x2F;p&gt;
&lt;p&gt;Both sides of this argument forget the same thing: culture is always mediated by technology. There has never been a golden age of unmediated human creativity — no pure state of artistic expression that preceded tools. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Marshall_McLuhan&quot;&gt;Marshall McLuhan&#x27;s&lt;&#x2F;a&gt; insight was that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_medium_is_the_message&quot;&gt;the medium is the message&lt;&#x2F;a&gt;: every technology doesn&#x27;t just transmit expression, it reshapes what can be expressed and thought at all. Writing didn&#x27;t just record speech — it changed how humans reasoned. The printing press didn&#x27;t just copy manuscripts — it restructured knowledge and power. The internet didn&#x27;t just transmit information — it reorganized attention, memory, and identity. DJ Kool Herc&#x27;s two turntables were not a neutral conduit for pre-existing music; they were a new instrument that produced a new culture. The tools are never neutral. They are never outside the culture. They are part of how the culture thinks.&lt;&#x2F;p&gt;
&lt;p&gt;This means the question is never &lt;em&gt;technology vs. pure human expression&lt;&#x2F;em&gt;. It is always: &lt;em&gt;which technology, designed with what values, serving whose vision?&lt;&#x2F;em&gt; The pro-efficiency builders have answered that question — efficiency, automation, headcount reduction — and called it inevitability. The anti-AI critics have refused to engage with it, by pretending the question doesn&#x27;t arise if you just reject the tool. But rejecting the tool is not preserving the culture. The culture was always already being shaped by tools. The only real choice is whether you shape the tools back.&lt;&#x2F;p&gt;
&lt;p&gt;The question worth asking of each new tool is still Lasseter&#x27;s: is this a new expensive pencil in the hands of an artist, or is this the hydraulic press?&lt;&#x2F;p&gt;
&lt;p&gt;There are still companies building cameras that answer this question the right way. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fujifilm&quot;&gt;Fujifilm&lt;&#x2F;a&gt; is the obvious example. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.dpreview.com&#x2F;articles&#x2F;0386546479&#x2F;display-duality-the-fujifilm-x-pro-3-in-california-wine-country&quot;&gt;X-Pro3&lt;&#x2F;a&gt; has a hidden LCD — it flips inward, invisible by default, so the natural state of the camera is: no screen. You shoot. You don&#x27;t chimp. You commit to the frame. This is a design opinion so aggressive that reviewers complained about it. Fujifilm shipped it anyway. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.fujifilm-x.com&#x2F;global&#x2F;products&#x2F;cameras&#x2F;gfx100rf&#x2F;&quot;&gt;GFX 100RF&lt;&#x2F;a&gt; goes further: 102 megapixels of medium format sensor in a rangefinder body with a single fixed lens. No zoom. No interchangeable glass. There&#x27;s a dedicated toggle that steps through a small set of crop-based focal lengths — discrete, deliberate choices, not a continuous zoom you drift through. And then there are the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fujifilm-x.com&#x2F;global&#x2F;products&#x2F;software&#x2F;film-simulation&#x2F;&quot;&gt;film simulations&lt;&#x2F;a&gt; — Velvia, Classic Chrome, Acros, Eterna — color science decisions you make before you shoot, the way you used to choose which roll of film to load. Not &quot;capture everything flat and decide in post.&quot; Not &quot;let the AI pick a look.&quot; &lt;em&gt;You choose, now, before you press the shutter.&lt;&#x2F;em&gt; The camera is opinionated and it wants you to be opinionated too.&lt;&#x2F;p&gt;
&lt;p&gt;This is the exact opposite of the direction Sony, Apple, Google, and Samsung are all moving. Their cameras maximize optionality: shoot RAW, bracket everything, let &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Computational_photography&quot;&gt;computational stacking&lt;&#x2F;a&gt; extend the dynamic range, run the subject through a neural network, decide the look later. The implicit philosophy is that creative decisions are a form of risk to be deferred. Fujifilm&#x27;s implicit philosophy is that creative decisions are the whole point, and deferring them is just procrastination. One approach treats the human as the liability. The other treats the human as the tool&#x27;s reason for existing.&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;p&gt;The early internet humanists — &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;John_Perry_Barlow&quot;&gt;Barlow&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Stewart_Brand&quot;&gt;Brand&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Jaron_Lanier&quot;&gt;Lanier&lt;&#x2F;a&gt; — were utopians but they were also critics. They held the technology accountable to a standard: does this make people more free? More expressive? More truthful to themselves? Does it expand the range of what a human can be?&lt;&#x2F;p&gt;
&lt;p&gt;That critical tradition is what Silicon Valley abandoned. Not because the people there are bad, but because the culture stopped being accountable to it. The question &quot;is this good for human flourishing?&quot; became &quot;does this have product-market fit?&quot; Technology was supposed to be in service of the human process — the messy, slow, necessary work of people making things and becoming, through that making, more themselves. Now the human process is the inefficiency. The friction. The part being optimized away.&lt;&#x2F;p&gt;
&lt;p&gt;The Crush ad is the monument. The bicycle-of-the-mind company made an ad where the hydraulic press is the hero and the grand piano is the problem being solved.&lt;&#x2F;p&gt;
&lt;p&gt;When nobody in the room said &quot;wait&quot; — that is when you know the process has stopped mattering.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Jujutsu is the GOAT but I have no idea how to teach people about it</title>
          <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/drafts/teaching-jj/</link>
          <guid>https://www.narendasan.com/drafts/teaching-jj/</guid>
          <description xml:base="https://www.narendasan.com/drafts/teaching-jj/">&lt;p&gt;Oh look another nerd deciding to waste more internet bandwidth on all the wonderful virtues of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jj-vcs&#x2F;jj&quot;&gt;Jujutsu VCS&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not the first and I won&#x27;t be the last. Here&#x27;s a sampling of the discourse:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;steveklabnik.github.io&#x2F;jujutsu-tutorial&#x2F;&quot;&gt;Steve Klabnik&#x27;s Jujutsu Tutorial&lt;&#x2F;a&gt; — probably the most comprehensive community tutorial&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jj-for-everyone.github.io&#x2F;&quot;&gt;Jujutsu for Everyone&lt;&#x2F;a&gt; — structured for people with zero VCS experience, which is very relevant to what I&#x27;m thinking about&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arne.me&#x2F;blog&#x2F;jj-in-practice&quot;&gt;Jujutsu in Practice&lt;&#x2F;a&gt; — practical patterns for day-to-day use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.stavros.io&#x2F;posts&#x2F;switch-to-jujutsu-already-a-tutorial&#x2F;&quot;&gt;Switch to Jujutsu Already&lt;&#x2F;a&gt; — a good intro focused on making the mental model click&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;neugierig.org&#x2F;software&#x2F;blog&#x2F;2024&#x2F;12&#x2F;jujutsu.html&quot;&gt;Tech Notes: The Jujutsu VCS&lt;&#x2F;a&gt; — first-principles introduction&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kubamartin.com&#x2F;posts&#x2F;introduction-to-the-jujutsu-vcs&#x2F;&quot;&gt;Jujutsu VCS Introduction and Patterns&lt;&#x2F;a&gt; — covers design consistency and practical patterns&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;JJ is worth the hype however, it modernizes one of the most critical components of software engineering, bringing it into the 2020s. The developer experience scales naturally across many axes: small project just starting out &amp;lt;-&amp;gt; large project with tons of developers, local only development &amp;lt;-&amp;gt; multiple remotes moving independently, one user using JJ in a Git world &amp;lt;-&amp;gt; everyone being fully JJ pilled. It saves you from yourself. You can be much more brave about complex VCS operations like rebasing, squashing and cherry picking and the intermediate state tracking allows you to undo and redo operations to recover otherwise lost work. Bookmarks and commit ranges I believe are a superior abstraction to branches. My main complaint is conflict resolution is difficult to do by hand but nothing is perfect out of the box.&lt;&#x2F;p&gt;
&lt;p&gt;I think JJ is good enough that I&#x27;d love to introduce it to the students I teach. Maybe it might save them from the classic fresh developer issues like forgetting to push after committing or forgetting to stage commits before commiting or forgetting to pull or forgetting to switch branches, not pushing to master etc. etc. Git is great, in my day as an undergrad schools still used SVN, we clammored to use Git to avoid SVN&#x27;s problems. The issue with Git is to use it right you need to have a strong mental model confidently navigate common operations and constant vigilance is required to make sure the repository doesn&#x27;t spiral out of hand.&lt;&#x2F;p&gt;
&lt;p&gt;To use Git properly you need to hold this in your head at all times:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Working Directory          Staging Area            Local Repo             Remote Repo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (your files on disk)       (the index)             (.git&#x2F;objects)         (GitHub etc.)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       │                          │                       │                      │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       │──── git add ────────────&amp;gt;│                       │                      │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       │                          │──── git commit ──────&amp;gt;│                      │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       │                          │                       │──── git push ───────&amp;gt;│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       │                                                  │&amp;lt;─── git fetch ───────│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       │&amp;lt;─────────────────── git checkout &#x2F; restore ──────│                      │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       │&amp;lt;─────────────────────────────── git pull ────────────────────────────── │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Four distinct zones, eight commands to move between them, and the mental overhead of always knowing where your changes currently live. Miss a step anywhere — forget to &lt;code&gt;git add&lt;&#x2F;code&gt;, forget to &lt;code&gt;git push&lt;&#x2F;code&gt;, commit to the wrong branch — and you&#x27;re debugging your VCS instead of writing code. For experienced developers this becomes muscle memory. For students who are simultaneously learning to code, it&#x27;s a constant source of friction.&lt;&#x2F;p&gt;
&lt;p&gt;So that motivates the question: &quot;What would it take to have students skip Git and go straight to JJ?&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-jj-simplifies&quot;&gt;What JJ Simplifies&lt;&#x2F;h2&gt;
&lt;p&gt;The staging area is gone. The working copy &lt;em&gt;is&lt;&#x2F;em&gt; a commit — JJ automatically tracks every change you make as part of an ongoing, amendable commit. This collapses the four-zone model above into two: your working copy and the repo. The common newbie mistake of &quot;I forgot to &lt;code&gt;git add&lt;&#x2F;code&gt;&quot; simply does not exist.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;jj undo&lt;&#x2F;code&gt; and &lt;code&gt;jj op log&lt;&#x2F;code&gt; mean mistakes are recoverable. This is huge for beginners. In Git, &quot;I accidentally reset my branch&quot; or &quot;I rebased wrong&quot; can mean real data loss unless you know about the reflog. In JJ, the operation log tracks every action and you can undo them linearly. Students can be brave.&lt;&#x2F;p&gt;
&lt;p&gt;Revsets are a powerful query language for talking about commits. Instead of memorizing cryptic ref syntax (&lt;code&gt;HEAD~3&lt;&#x2F;code&gt;, &lt;code&gt;origin&#x2F;main..HEAD&lt;&#x2F;code&gt;), you write readable expressions. This is a nice on-ramp to thinking about commit history as data you can query.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;jj describe&lt;&#x2F;code&gt; decouples writing your commit message from the act of snapshotting. You can work, then describe what you did. This maps more naturally to how beginners actually work — code first, explain later.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-jj-doesn-t-simplify&quot;&gt;What JJ Doesn&#x27;t Simplify&lt;&#x2F;h2&gt;
&lt;p&gt;Because most code forges (GitHub, GitLab, Bitbucket) are Git-first, students still need to understand enough Git to operate in that world.&lt;&#x2F;p&gt;
&lt;p&gt;At minimum, a JJ-first curriculum still needs to cover:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Concept&lt;&#x2F;th&gt;&lt;th&gt;Why It Can&#x27;t Be Skipped&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Commits&lt;&#x2F;td&gt;&lt;td&gt;The fundamental unit — same in both&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Remotes&lt;&#x2F;td&gt;&lt;td&gt;GitHub is a remote, this doesn&#x27;t go away&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;fetch&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;push&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Still how you sync with the forge&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Bookmarks vs. Branches&lt;&#x2F;td&gt;&lt;td&gt;PRs on GitHub are branch-based; JJ&#x27;s bookmarks map onto this but the translation isn&#x27;t obvious and confuses many people new to JJ&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The bookmarks-to-branches translation is the hardest part. When a student wants to open a pull request on GitHub, they need to understand that their JJ bookmark becomes a Git branch becomes a PR. That&#x27;s three layers of abstraction for someone who just wants to submit their homework. Also without the common &lt;code&gt;tug&lt;&#x2F;code&gt; alias, remembering to move your bookmarks and the exact way to do that can be tedious and easy to get incorrect, potentially poluting the upstream repo&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-a-jj-first-curriculum-might-look-like&quot;&gt;What a JJ-First Curriculum Might Look Like&lt;&#x2F;h2&gt;
&lt;p&gt;Level 0 — &lt;em&gt;Just track changes locally&lt;&#x2F;em&gt;: &lt;code&gt;jj init&lt;&#x2F;code&gt;, &lt;code&gt;jj status&lt;&#x2F;code&gt;, &lt;code&gt;jj describe&lt;&#x2F;code&gt;, &lt;code&gt;jj log&lt;&#x2F;code&gt;. No remotes, no branches, no pushing. Get comfortable with the idea that every save is being tracked and you can always go back.&lt;&#x2F;p&gt;
&lt;p&gt;Level 1 — &lt;em&gt;Work with a remote&lt;&#x2F;em&gt;: &lt;code&gt;jj git clone&lt;&#x2F;code&gt;, &lt;code&gt;jj git fetch&lt;&#x2F;code&gt;, &lt;code&gt;jj git push&lt;&#x2F;code&gt;. Introduce the concept of a remote as a mirror. Still no branches.&lt;&#x2F;p&gt;
&lt;p&gt;Level 2 — &lt;em&gt;Collaborate&lt;&#x2F;em&gt;: Bookmarks, how they map to Git branches, opening a PR. This is where the Git-forge translation layer gets introduced explicitly — &quot;the rest of the world uses Git, here&#x27;s how JJ talks to it.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Level 3 — &lt;em&gt;Power tools&lt;&#x2F;em&gt;: Revsets, &lt;code&gt;jj rebase&lt;&#x2F;code&gt;, &lt;code&gt;jj split&lt;&#x2F;code&gt;, &lt;code&gt;jj absorb&lt;&#x2F;code&gt;, &lt;code&gt;jj op undo&lt;&#x2F;code&gt;. The stuff that makes JJ genuinely better than Git for anyone doing non-trivial history management.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jj-for-everyone.github.io&#x2F;&quot;&gt;Jujutsu for Everyone&lt;&#x2F;a&gt; guide is structured similarly and is worth reading if you&#x27;re thinking about this problem — they&#x27;re actively building out exactly this kind of zero-prior-experience curriculum.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;open-questions&quot;&gt;Open Questions&lt;&#x2F;h2&gt;
&lt;p&gt;I don&#x27;t have a clean answer yet. JJ&#x27;s core model should be simpler than git if you didnt need to think about git and I believe it is more forgiving for new developers. But the forge ecosystem means you cannot fully escape Git concepts. The question is whether you&#x27;re better off teaching Git as the foundation and JJ as an upgrade, or teaching JJ as the foundation and Git as a compatibility layer you&#x27;ll sometimes need to think about.&lt;&#x2F;p&gt;
&lt;p&gt;My instinct is the latter. The mental model of &quot;your working copy is always a commit, and you can always undo&quot; is a healthier foundation than &quot;here are four zones and eight commands.&quot;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>We Need Societal Scaling Laws</title>
          <pubDate>Sat, 07 Mar 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/societal-scaling-laws/</link>
          <guid>https://www.narendasan.com/blog/societal-scaling-laws/</guid>
          <description xml:base="https://www.narendasan.com/blog/societal-scaling-laws/">&lt;p&gt;In AI research, scaling laws are gospel. Put in $X$ more compute, get $Y$ improvement in capability. The Chinchilla paper, the GPT-4 technical report, every major lab&#x27;s internal planning documents—they all revolve around trying to develop these predictable relationships between resources and outcomes. Scaling laws are what is used to justify billion-dollar investments. They&#x27;re why datacenters are being built at unprecedented scale.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;ericjmichaud.com&#x2F;quanta&#x2F;assets&#x2F;kaplan-scaling.png&quot; alt=&quot;Figure 1 from Kaplan et al. (2020): neural language model performance scales as a power-law with compute, data, and parameters across seven orders of magnitude.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We have scaling laws for the returns on investment in terms of capability yet we do not have similar normative models for how we believe widespread application of these technologies will change society. We are not running instructive small scale experiments on what a society with LLMs deeply woven in will look like.&lt;&#x2F;p&gt;
&lt;p&gt;To be clear from the outset: this is not an argument to slow down. It&#x27;s that capability research has billion-dollar investment guided by predictive curves. Societal preparation has none of that. The argument here is for foresight, not restraint.&lt;&#x2F;p&gt;
&lt;p&gt;LLMs at scale could make institutions more contextually sensitive than they have ever been: capable of seeing people as individuals rather than averages, catching bad-faith exploitation that formal rules can never reach, delivering the judgment that scarcity of cognition forced us to compress into crude metrics. Or it could make them more totalizing and less escapable than anything that came before. Perfect enforcement, crystallized bias, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Panopticon&quot;&gt;Foucault&#x27;s Panopticon&lt;&#x2F;a&gt; fully realized, autonomy eroded not by malice but by optimization. LLMs could allow you to be seen as an individual. It also could mean you can never not be seen. Both outcomes are technically possible. This is with LLMs as they are now, imperfect inverse &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mechanical_Turk&quot;&gt;mechanical turks&lt;&#x2F;a&gt; masquerading as oracles. Layers of probabilistic modeling stacked on top of each other. Superintelligence is not required for society to change drastically around this technology. This essay is not arguing that we are saved or we are doomed. It&#x27;s arguing that we are deploying LLMs into institutions without the instruments to know which trajectory we&#x27;re actually on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;society-is-built-on-scarcity&quot;&gt;Society is Built on Scarcity&lt;&#x2F;h2&gt;
&lt;p&gt;Before the industrial revolution, physical labor was the scarce resource that organized everything—where people lived, how families worked, what children did, how authority was justified. The steam engine dissolved that scarcity, and the consequences weren&#x27;t mainly economic: it forced into existence the modern city, compulsory education, the 8-hour workday, labor law, the welfare state. Not automatically—through generations of conflict and experiment. The disruption wasn&#x27;t primarily about wages; it was about what kind of life was possible and what society was obligated to protect.&lt;&#x2F;p&gt;
&lt;p&gt;LLMs threaten to do the same to cognitive labor. Every institution we have is downstream of the assumption that cognitive work is scarce and therefore has to be rationed. Tax authorities audit a sample of returns because they can&#x27;t audit all of them. Food safety inspectors sample products. Financial regulators examine a fraction of transactions. Courts process a fraction of disputes. The entire architecture of governance, markets, law, and expertise is built around one constraint: you cannot check everything, so you check enough to maintain trust. LLMs have the potential to eliminate that constraint.&lt;&#x2F;p&gt;
&lt;p&gt;The industry&#x27;s boldest response is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Universal_basic_income&quot;&gt;Universal Basic Income&lt;&#x2F;a&gt;: a stipend. UBI is a pure economic answer to what is not just an economic problem. It asks &quot;how do people afford things&quot; and ignores every harder question underneath: what do people &lt;em&gt;do&lt;&#x2F;em&gt;? What gives their lives structure? How do communities cohere? These are moral questions, not monetary ones—the same questions the industrial revolution forced into the open over decades of conflict, which we seem determined to defer again. If you can audit every tax return, what does the IRS look like? If cognitive expertise is no longer scarce, what do the institutions built around rationing it look like? Those aren&#x27;t economic questions. They&#x27;re questions about what governance is &lt;em&gt;for&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;More broadly, ordinary life has always depended on the practical limits of what can be known, tracked, or enforced. Society isn&#x27;t just built around what rules say; it&#x27;s built around what rules can reach. A family builds a deck without pulling permits because the permit process is expensive and their neighborhood isn&#x27;t regularly inspected. A landlord &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;boulderreportinglab.org&#x2F;2023&#x2F;03&#x2F;09&#x2F;in-an-effort-to-combat-boulders-housing-crisis-city-councilmembers-want-to-allow-more-people-to-live-together&#x2F;&quot;&gt;rents a basement bedroom without an egress window&lt;&#x2F;a&gt; in a city with a severe housing shortage because inspectors only respond to complaints, and nobody complains because the tenant needs the housing. Someone moves to a new city and quietly leaves a bad chapter behind them, because records didn&#x27;t follow people the way they do now. A person asks a friend who happens to be a doctor for informal advice they couldn&#x27;t afford to pay for officially. A small business owner asks a favor from someone they&#x27;ve known for years rather than going through a formal procurement process that would disadvantage them. None of these are heroic. They&#x27;re just how life works when the cost of full compliance is high and the probability of being checked is low.&lt;&#x2F;p&gt;
&lt;p&gt;The same logic applies beyond individual choices. Communities develop informal economies around what official systems can&#x27;t or won&#x27;t serve: the neighbor who fixes cars, the informal childcare network, the loans between members of a family that doesn&#x27;t involve a bank. Privacy itself has historically been less a right than a byproduct of practical obscurity: your medical history, your spending habits, your location throughout the day weren&#x27;t tracked not because tracking was forbidden but because it was expensive. The gaps in visibility weren&#x27;t accidental; they were structural, and people built lives inside them.&lt;&#x2F;p&gt;
&lt;p&gt;The intuition is that this is all a failure to be corrected. That if we could just enforce everything uniformly, things would be fairer and better. Sometimes that&#x27;s true: selective enforcement often falls hardest on people with the least power to push back. But the gaps also do work that&#x27;s hard to see until it&#x27;s gone. They&#x27;re how rules that don&#x27;t quite fit get quietly negotiated. How communities absorb people who can&#x27;t meet formal requirements but have nowhere else to go. How ordinary life remains livable under systems that were designed for an average case that doesn&#x27;t describe everyone. LLMs don&#x27;t just change enforcement; they change the underlying structure of what can be known and tracked. The question isn&#x27;t only what laws will be applied more uniformly. It&#x27;s what kind of life is possible when practical obscurity disappears. Discord&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;techcrunch.com&#x2F;2026&#x2F;02&#x2F;09&#x2F;discord-to-roll-out-age-verification-next-month-for-full-access-to-its-platform&#x2F;&quot;&gt;2026 age verification rollout&lt;&#x2F;a&gt; is a mundane but clarifying example: a platform used by hundreds of millions of people decided that to access its full features, users would need to submit to a facial scan or upload a government ID to a third-party vendor. This happened six months after a breach &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.eff.org&#x2F;deeplinks&#x2F;2026&#x2F;02&#x2F;discord-voluntarily-pushes-mandatory-age-verification-despite-recent-data-breach&quot;&gt;exposed 70,000 users&#x27; government IDs and selfies&lt;&#x2F;a&gt; from a previous verification vendor. The logic is not malicious. The platform has genuine obligations around age-gated content. But the infrastructure being built (verified identity required for full platform participation) is the same infrastructure that makes practical obscurity structurally impossible.&lt;&#x2F;p&gt;
&lt;p&gt;What LLMs offer looks like comprehensive uniform governance but it&#x27;s a black box that trades acknowledged incompleteness for hidden inconsistency. Training data biases, RL artifacts, distributional shift: these produce failures that aren&#x27;t random and visible like under-sampling, but systematic and opaque, baked into weights no one can fully read. You&#x27;ve swapped a system that knew what it was missing for one that doesn&#x27;t know what it&#x27;s getting wrong. There is no avoiding the LLM audit when the LLM audit costs a few hundred dollars of compute. There is a subtler change here: a move from retrospective to live accountability. Every major institution of accountability we have built is fundamentally backward-looking. Courts reconstruct what happened. Regulators investigate past conduct. Auditors review historical records. Trials are an elaborate technology for producing a credible account of the past. The entire architecture of law assumes that what institutions can do is hold people accountable for what they have done: after the fact, episodically, at the cost of enormous effort. That retrospective character is a feature as much as a limitation: it means people live their lives forward, without continuous institutional observation, and face judgment only when someone decides to look.&lt;&#x2F;p&gt;
&lt;p&gt;LLMs at scale changes that architecture. Not to the Minority Report style predicting of future crimes, but to something potentially as pervasive: live observation of the present. When every transaction, communication, and movement is processable in real time, institutions don&#x27;t have to reconstruct what happened; they can watch it happening. This is the shift from episodic accountability to continuous monitoring. It has versions in both directions. The contextualizing version: harm gets caught as it compounds, not years later after a pattern has solidified beyond remedy. The totalizing version: people no longer have the slack of practical obscurity (the room to fail, recover, and move on that an episodic accountability architecture quietly provides). A juvenile record that a judge might have sealed gets embedded in a risk score. A period of financial difficulty that a loan officer might have contextualized becomes a permanent feature of a profile. The difference between those two versions isn&#x27;t the technology. It&#x27;s whether the governance layer is designed with the retrospective virtues in mind: that some forgetting is a feature, not a bug.&lt;&#x2F;p&gt;
&lt;p&gt;These aren&#x27;t questions about who gets paid. They&#x27;re questions about what institutions are &lt;em&gt;for&lt;&#x2F;em&gt; once the scarcity they were built to manage no longer exists. Jeremy Rifkin anticipated part of this in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_Zero_Marginal_Cost_Society&quot;&gt;&lt;em&gt;The Zero Marginal Cost Society&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; (2014), arguing that near-zero marginal cost production would erode capitalism and give rise to a collaborative commons. His focus was economic: markets, ownership, profit. The institutional argument is deeper: it&#x27;s not just that capitalism struggles when things become free, it&#x27;s that &lt;em&gt;governance itself&lt;&#x2F;em&gt; was designed for a world where you couldn&#x27;t check everything. James C. Scott&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Seeing_Like_a_State&quot;&gt;&lt;em&gt;Seeing Like a State&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; (1998) documents this exhaustively: states make society &quot;legible&quot; through simplification (standardized names, censuses, uniform measurement) because &quot;no administrative system is capable of representing any existing social community except through a heroic and greatly schematized process of abstraction and simplification.&quot; Hayek made the point in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_Use_of_Knowledge_in_Society&quot;&gt;&lt;em&gt;The Use of Knowledge in Society&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; (1945): knowledge is irreducibly dispersed, and no central authority can ever aggregate enough of it to fully govern. Decentralized, spot-check institutions aren&#x27;t a design failure; they&#x27;re a rational response to the impossibility of complete information. C. Thi Nguyen&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.penguinrandomhouse.com&#x2F;books&#x2F;735252&#x2F;the-score-by-c-thi-nguyen&#x2F;&quot;&gt;&lt;em&gt;The Score&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; (2025) identifies the tension with decontextualization via quantification. Numbers travel, institutions are built around stripped metrics of society because this is the best we could do to run society in a uniform (&quot;just&quot;) way. A credit score can be processed by a thousand different loan officers in a thousand different cities; a nuanced assessment of someone&#x27;s full financial situation or repayment habits cannot. Metrics strip context so that judgment can scale; however, Nguyen documents what is left behind when this happens—all the nuance dropped, the consequences of centralizing standardized metrics in your life. The technology to change this now exists. Society necessarily changes in a world where the marginal cost of analysis approaches zero. Yet we are operating as if 20th-century institutions smoothly adopt 21st-century capability.&lt;&#x2F;p&gt;
&lt;p&gt;&quot;Scalable contextual judgment&quot; is a capability, not a value, and capabilities go in any direction. Replace the credit score with an AI that actually understands someone&#x27;s financial situation: that could mean fairer lending, or it could mean lenders now have perfect information about every part of your life and no way to improve your credit score. The same dissolution of cognitive scarcity that makes individual judgment richer could make institutional reach total. Which one we build is not a technical question. It&#x27;s a governance one.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data-as-law&quot;&gt;Data As Law&lt;&#x2F;h2&gt;
&lt;p&gt;In 1999, Lawrence Lessig argued in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Code_and_Other_Laws_of_Cyberspace&quot;&gt;&lt;em&gt;Code and Other Laws of Cyberspace&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; that behavior online is regulated by four forces: law, norms, markets, and architecture. His warning was that code—the architecture of cyberspace—was becoming the most powerful of the four, and that unlike law, code has no appeals process. It just executes.&lt;&#x2F;p&gt;
&lt;p&gt;Law is fuzzy by design. It has context, interpretation, precedent, exceptions. A judge can decide that the letter of a statute doesn&#x27;t apply to an unusual case. A jury can acquit on conscience. These aren&#x27;t bugs—they&#x27;re features, the accumulated wisdom that rigid rules applied without judgment produce injustice. Fuzziness is how law accommodates the infinite complexity of human situations.&lt;&#x2F;p&gt;
&lt;p&gt;Code is absolute. An if-statement doesn&#x27;t care about context. A smart contract executes whether or not execution is fair. Bitcoin doesn&#x27;t make exceptions. This is precisely what &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cypherpunk&quot;&gt;cypherpunks&lt;&#x2F;a&gt; found appealing: rules that couldn&#x27;t be bent by the powerful, enforced by math rather than men. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sazmining.com&#x2F;blog&#x2F;code-is-law&quot;&gt;Code as a replacement for trust in institutions&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The ideological throughline from Bitcoin to AI alignment is not accidental. Many of the same people, or at least the same type of people—&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rationalist_community&quot;&gt;rationalists&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.effectivealtruism.org&#x2F;posts&#x2F;opCxiPwxFcaaayyMB&#x2F;relationship-between-ea-community-and-ai-safety&quot;&gt;effective altruists&lt;&#x2F;a&gt;, believers in formal systems over human judgment—migrated from crypto to AI safety carrying the same core intuition: that you can encode ethics into a system, that values can be specified precisely enough to be executed reliably. The dream is a Platonic one: a reasoning agent that receives principles and derives correct behavior from them the way a philosopher derives conclusions from premises. Write the right constitution, and the model applies it. The world&#x27;s best virtue ethicist.&lt;&#x2F;p&gt;
&lt;p&gt;Anthropic&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2212.08073&quot;&gt;Constitutional AI&lt;&#x2F;a&gt; is the most legible attempt at this. They literally wrote a constitution for Claude, a list of principles drawn from documents like the UN Declaration of Human Rights, and trained the model to critique and revise its own outputs against those principles. The name is deliberate: here are the values, encoded in text, now reason from them.&lt;&#x2F;p&gt;
&lt;p&gt;The problem is the model isn&#x27;t doing what the framing implies. A constitution binds a reasoning agent that interprets and applies its principles. What Constitutional AI actually produced is a statistical model fine-tuned to generate outputs consistent with how constitutionally-flavored reasoning appears in text. Those are different things. The model doesn&#x27;t derive behavior from the constitution the way a judge derives rulings from precedent. It produces outputs that pattern-match to what applying-this-constitution looked like in training data. In distribution, that can look indistinguishable from principled reasoning. Out of distribution, at genuine edge cases, novel cultural contexts, situations the rater pool never encountered, there is no logical guarantee. This is what &quot;prompt injection&quot; is. Its an input that forces the model into a regime where the statistically consitent response violates the governance layer laied on top. The constitution didn&#x27;t bind the model. It shaped the weights. That gap is where the failure modes live.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Three_Laws_of_Robotics&quot;&gt;Three Laws of Robotics&lt;&#x2F;a&gt; are the most famous fictional attempt at the same program, and the entire corpus of robot stories is a catalog of their failure modes. Not because the laws are badly written, but because the fuzziness they tried to eliminate keeps reasserting itself: every story finds a situation the laws didn&#x27;t anticipate. Asimov demonstrates that you cannot specify human values precisely enough to execute them reliably, that a reasoning agent genuinely applying rigid principles will eventually encounter a case where the principles conflict or don&#x27;t reach. LLMs aren&#x27;t true reasoning agents encountering edge cases in the laws. They do not build conceptual abstractions and manipulate them according to rules in the same way humans might. They&#x27;re statistical models producing outputs that looked like reasoning in training, which is a subtler and harder-to-diagnose failure mode.&lt;&#x2F;p&gt;
&lt;p&gt;The public debate about AI is structured around a question that turns out not to matter: is this thing actually reasoning, or just predicting tokens? The popular conception—the one animating both techno-utopian and extinction-risk discourse—is of a mechanistic human: an agent with goals, values, something like intent. LLMs are not that. But the societal consequences don&#x27;t hinge on whether it is or not. A statistical parrot deployed at institutional scale, trained on whoever&#x27;s data, shaped by whoever&#x27;s rater pool, still makes decisions that govern people&#x27;s lives.&lt;&#x2F;p&gt;
&lt;p&gt;This points to something Lessig&#x27;s framework didn&#x27;t anticipate: in a world of LLM-informed governance, data is law. The training corpus is the actual constitution. Whatever was overrepresented in the pretraining data, whatever the rater preferred during finetuning, whatever got filtered in or out—those are the binding documents. They were never written down, have no preamble, nobody voted on them, and you cannot look them up. Constitutional AI wrote a visible constitution on top of a data constitution that already existed and was already shaping every output. The written one is the legible governance layer. The real one is hundreds of billions of tokens of human text, with all its biases and distributional skews baked into weights no interpretability technique can fully read.&lt;&#x2F;p&gt;
&lt;p&gt;Data-as-law has different properties from both of Lessig&#x27;s categories, with distinct failure modes. Code is deterministic and auditable: you can read the contract, find the bug. Law is fuzzy and has appeals: the written text can be challenged, the edge case can go to court. Data-as-law is statistical and opaque: the outputs appear contextual, but the context-sensitivity isn&#x27;t deliberate like a judge&#x27;s, it&#x27;s distributional, a reflection of what the training data happened to contain. The biases aren&#x27;t in a rule you can find and argue against. They&#x27;re in the shape of the distribution, invisible until they produce an outcome someone bothered to measure.&lt;&#x2F;p&gt;
&lt;p&gt;The approach for encoding ethics varies across labs; the shape is always the same: someone decides what the values are, encodes them through whatever mechanism they&#x27;ve chosen, and deploys the result without the public deliberation or democratic mandate that would be required of any analogous human institution.&lt;&#x2F;p&gt;
&lt;p&gt;This is their best attempt at governing AI&#x27;s societal trajectory, and it operates entirely from the model out, not from society in. It does not ask whether LLMs are pushing institutions toward the contextualizing attractor or the totalizing one. It asks only whether the model behaves. Those are not the same question. And when LLMs with the capability to apply contextual judgment at institutional scale get deployed, the question of whose context it&#x27;s applying doesn&#x27;t get answered by writing a better constitution. It gets answered by whoever controlled the training pipeline. The capability to scale judgment is value-neutral. What gets scaled is the data.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-unintentional-regulator&quot;&gt;The Unintentional Regulator&lt;&#x2F;h2&gt;
&lt;p&gt;The tech industry operates in a perpetual race. Capture the market before someone else does. Ship the feature before it&#x27;s commoditized. Train the model before your competitor. Move fast and break things—the motto that defined an era and never really went away, they just have a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Effective_accelerationism&quot;&gt;different slogan&lt;&#x2F;a&gt; now. This isn&#x27;t a moral failing of individuals; it&#x27;s game theory. If you don&#x27;t capture the value, someone else will.&lt;&#x2F;p&gt;
&lt;p&gt;The most revealing case is Anthropic. They are, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.anthropic.com&#x2F;company&quot;&gt;by their own account&lt;&#x2F;a&gt;, the lab most convinced that they might be building one of the most dangerous technologies in human history. They built an entire &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.anthropic.com&#x2F;news&#x2F;announcing-our-updated-responsible-scaling-policy&quot;&gt;Responsible Scaling Policy&lt;&#x2F;a&gt; around the premise of not deploying models unless adequate safeguards exist. And then, under competitive pressure, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;time.com&#x2F;7380854&#x2F;exclusive-anthropic-drops-flagship-safety-pledge&#x2F;&quot;&gt;they dropped the flagship pledge&lt;&#x2F;a&gt; that was supposedly the whole point of the company. They operate in a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;G._W._F._Hegel#Philosophy_of_history&quot;&gt;Hegelian&lt;&#x2F;a&gt; sense: the technology is inevitable, history has already decided, so the only meaningful choice is whether the people who take the risks seriously get there first. Existential concern about AI is now an &lt;em&gt;argument for&lt;&#x2F;em&gt; building faster, not slower.&lt;&#x2F;p&gt;
&lt;p&gt;Ironically, despite tens of thousands of words in think pieces on the implications of AI and entire research fields devoted to alignment and safety, the most effective governor on AI development turned out to be &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tomshardware.com&#x2F;tech-industry&#x2F;artificial-intelligence&#x2F;nvidias-rubin-gpu-and-vera-cpu-data-center-ai-platforms-begin-tape-out-both-chips-in-fab-and-on-track-for-2026&quot;&gt;TSMC&#x27;s N3 process yield rates&lt;&#x2F;a&gt;. Not a law. Not a treaty. Not a democratically mandated pause. A semiconductor fabrication bottleneck and a lack of cheap electricity.&lt;&#x2F;p&gt;
&lt;p&gt;NVIDIA&#x27;s Blackwell architecture &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wccftech.com&#x2F;nvidia-ship-150k-200k-blackwell-gb200-ai-servers-q4-2024-500-550k-units-q1-2025&#x2F;&quot;&gt;shipped roughly 1.5 to 2 million units in 2025&lt;&#x2F;a&gt; not because anyone deliberated about whether society was ready, but because of the limitations of lithography throughput, DDR5 yields at Micron, how many generators you can buy. The most consequential &quot;AI governance&quot; decision of 2026 was made in a fab in Hsinchu and city council meetings about substation lead times. Physical reality is doing what policy couldn&#x27;t.&lt;&#x2F;p&gt;
&lt;p&gt;That bottleneck is being engineered away on both sides of the geopolitical divide as aggressively as possible. The export controls that weaponize this bottleneck in order to slow China down are &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.brookings.edu&#x2F;articles&#x2F;deepseek-shows-the-limits-of-us-export-controls-on-ai-chips&#x2F;&quot;&gt;demonstrably not working&lt;&#x2F;a&gt;: DeepSeek built frontier-competitive models on restricted chips by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fourweekmba.com&#x2F;deepseeks-chip-workaround-how-china-is-innovating-despite-us-export-controls&#x2F;&quot;&gt;programming around their bandwidth limitations at a lower level than CUDA&lt;&#x2F;a&gt;; the controls didn&#x27;t slow them down, they forced an efficiency breakthrough. Huawei is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bloomberg.com&#x2F;news&#x2F;articles&#x2F;2025-09-29&#x2F;huawei-to-double-output-of-top-ai-chip-as-nvidia-wavers-in-china&quot;&gt;planning to double Ascend AI chip output in 2026&lt;&#x2F;a&gt;. When those constraints loosen, we&#x27;ll discover that we never actually built a governance system. We just got lucky that the supply chain was the bottleneck first. When compute costs drop by a factor of ten, and despite &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dennard_scaling&quot;&gt;the end of Dennard scaling&lt;&#x2F;a&gt;, they likely will, what required a hyperscaler becomes feasible for a startup, then a hobbyist.&lt;&#x2F;p&gt;
&lt;p&gt;Crucially, supply chain physics don&#x27;t resolve the tension; they only control the speed at which we approach it. Whether LLMs in institutions converge on the contextualizing attractor or the totalizing one is not a question wafer yields can answer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-laziness-of-extinction-discourse&quot;&gt;The Laziness of Extinction Discourse&lt;&#x2F;h2&gt;
&lt;p&gt;The community that should be asking &#x27;which future are we building?&#x27; is asking a different question entirely. The popular public discussions about AI safety began with a focus on extinction risk: will superintelligent AI decide to eliminate humanity? Will we lose control of systems more capable than ourselves?&lt;&#x2F;p&gt;
&lt;p&gt;The focus on extinction is a failure mode disguised as rigor. It has the aesthetic of serious thinking (philosophical depth, civilizational stakes) while actually functioning as an escape hatch from the harder, messier, more tractable questions about the society we&#x27;re building right now. Extinction is the one scenario where you don&#x27;t have to do the institutional work, because if it happens there are no institutions left to fix. It&#x27;s the most intellectually convenient possible framing.&lt;&#x2F;p&gt;
&lt;p&gt;Extinction is binary. We survive or we don&#x27;t. It lets you skip the infinite gradations between &quot;everything is fine&quot; and &quot;everyone is dead&quot;: where the actual future will lie. A world where AI works but democracy doesn&#x27;t isn&#x27;t an extinction scenario. Neither is a world of abundance and spiritual emptiness, where we solved AGI but not meaning. Neither is a world where the people building these systems made choices about whose values to encode without any democratic mandate, and we only noticed after the fact. These aren&#x27;t edge cases. They&#x27;re the likeliest futures. And extinction discourse has nothing useful to say about any of them.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s also a practical problem: it&#x27;s been a decade of serious public investment in x-risk as a framing, and the main thing it has produced is a community with a strong aesthetic identity and a negligible effect on actual deployment decisions. The labs that take existential risk most seriously, Anthropic, have sped up not slowed down. The framing has not generated the institutional responses or the governance infrastructure that would constitute taking it seriously. It has generated a lot of essays, a lot of funding for capability research disguised as safety research, and a career path for people who want to think about AI without thinking about any specific deployment or variant of &quot;AI&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;The deep questions about an AI-native society go unasked because they&#x27;re hard and ultimately human-centered, not technological. Consider: the personal computer has existed for roughly 45 years, the internet has been mainstream for 30, and we&#x27;re still working out their second and third-order effects: cybersecurity, mass data collection, algorithmically mediated media. The speculation was extensive at the time about what the cyber-future will hold and how we should manage cyberspace: Alvin Toffler&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_Third_Wave_(Toffler)&quot;&gt;&lt;em&gt;The Third Wave&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; (1980) anticipated the information society before the PC was widespread; Nicholas Negroponte&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Being_Digital&quot;&gt;&lt;em&gt;Being Digital&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; (1995) predicted digital convergence with remarkable accuracy; Howard Rheingold&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_Virtual_Community&quot;&gt;&lt;em&gt;The Virtual Community&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; (1993) mapped online social life before most people had experienced it; John Perry Barlow&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.eff.org&#x2F;cyberspace-independence&quot;&gt;&quot;A Declaration of the Independence of Cyberspace&quot;&lt;&#x2F;a&gt; (1996) staked out the libertarian governance vision that still shapes platform policy today. We did not lack for vision. Yet there were still deeply disturbing unforeseen outcomes. And we are even blinder now in the era of LLMs.&lt;&#x2F;p&gt;
&lt;p&gt;LLMs at institutional scale could move society toward institutions that are finally able to hold contextual complexity, or toward institutions that are more totalizing and less escapable than anything we have built before. Extinction discourse has nothing useful to say about which of those we&#x27;re headed toward, because both of them involve humans surviving.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-moral-machine&quot;&gt;The Moral Machine &lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#moral-machine&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;h2&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;moral-machine&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;The term borrows from MIT&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.moralmachine.net&#x2F;&quot;&gt;Moral Machine&lt;&#x2F;a&gt; experiment (Awad et al., &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nature.com&#x2F;articles&#x2F;s41586-018-0637-6&quot;&gt;&lt;em&gt;Nature&lt;&#x2F;em&gt;, 2018&lt;&#x2F;a&gt;), which crowdsourced human moral judgments about autonomous vehicle decisions across millions of participants in 233 countries. The experiment revealed substantial cross-cultural variation in moral intuitions (who to spare in a trolley-problem-style crash) and is a systematic attempt to empirically map the terrain of human moral judgment at scale. Its lesson was not that moral consensus exists and can be extracted; it was that moral intuitions are culturally contingent, contested, and resistant to simple aggregation. Any &quot;moral machine&quot; faces that problem first.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Philip K. Dick&#x27;s &lt;em&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_Minority_Report&quot;&gt;The Minority Report&lt;&#x2F;a&gt;&lt;&#x2F;em&gt; is an illustration of what algorithmic governance looks like at institutional scale: a pre-crime system that arrests people for murders they haven&#x27;t committed yet, based on probabilistic prediction. The horror isn&#x27;t that it&#x27;s wrong; the predictions are largely accurate. The horror is what it means to live in a society organized around algorithmic certainty rather than demonstrated action. Guilt becomes statistical. Justice becomes actuarial. The system is more accurate than human judgment and also more inhuman.&lt;&#x2F;p&gt;
&lt;p&gt;Take a real judge. Today, judicial discretion is a feature, not a bug. Sentencing guidelines exist, but judges can depart from them. A first-time offender with extenuating circumstances gets treated differently than a repeat one. A prosecutor can decline to pursue a case they consider unjust. The system is leaky by design, because the alternative (rigid rule application without context) produces outcomes so obviously wrong that every legal tradition across history has built in escape valves. The same tension applies when LLMs allocate jobs, admit students, set insurance rates, and decide parole, it could eliminate the nepotism and bias that currently shape these decisions. It could also calcify whatever assumptions were baked into training data, producing a more rigorous version of the same discrimination with less recourse. When a human rejects you, you can argue, appeal, find another human. When a system does, the decision feels categorical, produced by something that doesn&#x27;t negotiate.&lt;&#x2F;p&gt;
&lt;p&gt;Less discriminatory hiring, more consistent sentencing: these could all be genuine improvements. But we would be arriving at them without the governance infrastructure to make them legitimate.&lt;&#x2F;p&gt;
&lt;p&gt;The problem Lessig identified used to cut both ways. Yes, encoding ethics into hard rules strips out the fuzziness that makes law humane. But fuzziness also has a cost: it was expensive to apply. Judgment takes time and expertise. You can&#x27;t hire enough judges, regulators, or compliance officers to apply contextual reasoning at the scale that modern systems operate. So we defaulted to rules. Not because rules are better, but because rules are cheap.&lt;&#x2F;p&gt;
&lt;p&gt;That tradeoff is now shifting. We&#x27;ve had mechanisms for fuzzy judgment before. The jury is one. A group of peers, drawn from the community, asked not to apply a rule but to reach a verdict: to decide what a reasonable person would find. Lessig also points to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;deliberation.stanford.edu&#x2F;what-deliberative-polling&quot;&gt;deliberative polls&lt;&#x2F;a&gt;: randomly sampled citizens given balanced information and time to discuss, whose considered opinions turn out to look quite different from snap poll responses. Both are attempts to extract something like collective moral judgment without reducing it to a rule. Both are expensive, slow, and impossible to scale. A jury deliberates for days over a single case. A deliberative poll costs millions and takes months. They work, in their domain. But you can&#x27;t run a jury on every financial transaction or a deliberative poll on every norm violation.&lt;&#x2F;p&gt;
&lt;p&gt;However, Nguyen&#x27;s diagnosis points directly at what&#x27;s new here. The gap Lessig identified (between what law says and what norms expect) exists precisely because enforcing norms requires context, and context doesn&#x27;t travel. The moment you formalize &quot;exploiting the spirit of the rule,&quot; clever actors find a new way to comply with the letter of your formalization while violating its spirit. Every attempt to encode a norm into a rule just moves the gap. The underlying problem is that norms are about &lt;em&gt;the whole situation&lt;&#x2F;em&gt; (intent, pattern, effect, social meaning) and rules can only address &lt;em&gt;specified features&lt;&#x2F;em&gt; of situations.&lt;&#x2F;p&gt;
&lt;p&gt;What LLMs offer is a system that might hold context without collapsing it into a score. Not a metric, but something closer to the judgment that generates metrics: pattern recognition across entire situations, including the parts that didn&#x27;t fit neatly into the rule. Norms are implicit, contextual, and hard to articulate, but not to an LLM trained on billions of examples of human communication about what&#x27;s fair and what isn&#x27;t. How do you write a regulation that catches someone acting in bad faith? You might not need to write it. You might be able to describe the situation and ask.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;It&#x27;s also worth being clear that the system described in the rest of this section (a moral machine capable of reliable contextual norm enforcement) does not currently exist but is easy to imagine from current techniques and in no way requires general superintelligence to be convincing enough to deploy at scale.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Consider what this looks like in practice. High-frequency trading firms spend enormous resources finding strategies that are technically legal but structurally extractive; they don&#x27;t buy and sell based on economic fundamentals, they arbitrage market microstructure in ways that impose costs on other participants without creating value. No specific rule is broken. Every individual transaction is legal. But the aggregate behavior is a kind of predation that most market participants would recognize as wrong if they could see it clearly. Rules-based regulation can&#x27;t catch it because catching it requires reasoning about &lt;em&gt;intent&lt;&#x2F;em&gt; and &lt;em&gt;effect&lt;&#x2F;em&gt; across a pattern of behavior, not just checking whether individual transactions conform to specified constraints. The SEC issues guidance, adds new rules, watches the strategies mutate. It&#x27;s an arms race that the regulators are structurally losing.&lt;&#x2F;p&gt;
&lt;p&gt;An LLM-based system asked to evaluate whether a trading strategy is &lt;em&gt;fair&lt;&#x2F;em&gt; (not whether it&#x27;s &lt;em&gt;legal&lt;&#x2F;em&gt;) can reason about the question the way a thoughtful senior regulator would. Is this adding liquidity or extracting it? Is this participant providing a service to the market or imposing costs on it? Does the pattern, taken as a whole, serve or undermine the purpose markets are supposed to serve? These aren&#x27;t algorithmic questions. They require the kind of contextual reasoning that formal systems have never been able to automate. Until now.&lt;&#x2F;p&gt;
&lt;p&gt;This opens something genuinely new: the possibility of identifying violations of norms rather than just laws. A &quot;moral machine&quot; that doesn&#x27;t ask &quot;did this actor violate rule 47(b)(2)?&quot; but &quot;did this actor behave in a way the community would recognize as wrong?&quot; The difference is enormous. You could catch the tax lawyer who finds every loophole without breaking any rule. The company that technically complies with environmental regulations while deliberately undermining their intent. The landlord who never explicitly discriminates but systematically makes certain applicants&#x27; experience unpleasant enough to withdraw. These are norm violations that current law cannot reach: not because no one has tried to write the rules, but because the behavior is defined by context and intent that formal specification cannot capture.&lt;&#x2F;p&gt;
&lt;p&gt;This is not a simple good. Enforcing norms at scale means someone decides whose norms. The informal non-enforcement that allows communities to signal that a law is outdated, that makes space for civil disobedience, that permits the kind of friction where moral progress actually happens: that gets foreclosed too. A moral machine powerful enough to catch bad-faith exploitation is powerful enough to enforce consensus morality uniformly, without appeal, without exception. The same capacity that could fix high-frequency trading abuse could enforce social conformity. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Panopticon&quot;&gt;Foucault&#x27;s Panopticon&lt;&#x2F;a&gt; again, but now it&#x27;s watching for spirit-of-the-rule violations, not just rule violations.&lt;&#x2F;p&gt;
&lt;p&gt;China&#x27;s social credit system is the preview everyone points to. But what makes it troubling isn&#x27;t really the LLMs; it&#x27;s the values encoded in the system and the absence of any check on those values. An AI-mediated society with strong civil liberties, democratic oversight, and genuine recourse mechanisms could look different. The problem isn&#x27;t LLMs in institutions. The problem is arriving at AI in institutions without considering the oversight layer that makes it legitimate.&lt;&#x2F;p&gt;
&lt;p&gt;What the oversight layer would actually look like is worth speculating about concretely, because the abstract version (&quot;democratic oversight,&quot; &quot;civil liberties&quot;) doesn&#x27;t do the work. Consider a different model: a standing deliberative body, convened not to pass a law but to build a model. Citizens, drawn like jurors from the community that will live under its decisions, spend weeks deliberating over the values they want encoded in the AI systems that govern them. What counts as fair hiring in this jurisdiction? What level of past conduct should stop counting against someone? When does pattern-of-behavior monitoring become surveillance? The outputs aren&#x27;t statutes. They&#x27;re preferences: training data, principles expressed in the form that AI systems can actually consume.&lt;&#x2F;p&gt;
&lt;p&gt;Deliberative polls have extracted considered judgments on contested issues across dozens of countries. The missing piece, if AI is going to be deployed broadly through society, isn&#x27;t any single technology or institution; it is a process with democratic legitimacy, subject to ongoing audit and revision by the community that created them. None of that is technically impossible. What it requires is deciding that the legitimacy problem is real: that the question &quot;whose values are encoded?&quot; deserves a democratic answer rather than being settled by whichever research team&#x27;s cultural assumptions happened to shape the reward model.&lt;&#x2F;p&gt;
&lt;p&gt;Meanwhile, the panopticon isn&#x27;t a hypothetical—it&#x27;s being assembled now, not through any deliberate plan but through a thousand independent procurement decisions nobody is watching. Automated systems determine benefits eligibility, flag suspected fraud, set insurance rates. Courts use risk assessment tools in bail hearings and sentencing. Facial recognition runs in transit systems and public spaces. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.vice.com&#x2F;en&#x2F;article&#x2F;revealed-this-is-palantirs-top-secret-user-manual-for-cops&#x2F;&quot;&gt;Palantir&#x27;s Gotham platform&lt;&#x2F;a&gt;, deployed across hundreds of law enforcement agencies, lets an officer start from a single name or license plate and retrieve email addresses, phone numbers, bank accounts, Social Security numbers, and family relationships, then auto-track every person in the resulting network. In 2025, ICE awarded Palantir a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.americanimmigrationcouncil.org&#x2F;blog&#x2F;ice-immigrationos-palantir-ai-track-immigrants&#x2F;&quot;&gt;$30 million contract to build ImmigrationOS&lt;&#x2F;a&gt;, integrating travel histories, biometrics, social media, Medicaid records, IRS data, and license-plate readers into unified AI-driven profiles on individuals, drawing on data from agencies with no legal mandate to share it for immigration enforcement. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.flocksafety.com&#x2F;&quot;&gt;Flock Safety&lt;&#x2F;a&gt;, now deployed across more than 5,000 communities, operates a national network of license-plate readers that passively logs every vehicle&#x27;s movements—data pooled across jurisdictions and queryable by any participating law enforcement agency with no warrant required. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Real-time_crime_center&quot;&gt;Real-time crime centers&lt;&#x2F;a&gt;, now operational in dozens of major cities, aggregate these feeds alongside gunshot-detection sensors, surveillance camera networks, and social media monitoring into unified analyst dashboards, converting what were once separate procurement decisions into something approaching continuous observation of public space. Each piece was someone solving their own problem: the agency wanted better tools, the vendor had a product, the contract got signed. Most people living under it have no idea it&#x27;s there. The totalizing attractor doesn&#x27;t need a master plan. It just needs everyone to keep optimizing locally while no one asks what they&#x27;re building together.&lt;&#x2F;p&gt;
&lt;p&gt;There is a version of this that resolves toward the contextualizing attractor, not the totalizing one. The failure mode of metric-based institutions is that they treat people from different contexts as if context didn&#x27;t exist: the same credit score formula applied everywhere, the same sentencing guideline regardless of circumstance, the same test score as the measure of a student. This produces a particular kind of injustice: technically consistent, contextually blind. The promise of AI-native institutions, properly governed, is something different: systems that can see context and still aspire to consistency. A sentencing model that can hold the full circumstances of a case and still be &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ai.equineteurope.org&#x2F;system&#x2F;files&#x2F;2022-02&#x2F;ICA2014-Sandvig.pdf&quot;&gt;audited for disparate outcomes&lt;&#x2F;a&gt; across race or class (the kind of structured algorithmic audit that Sandvig, Hamilton, Karahalios, and Langbort developed as a research methodology precisely for detecting discrimination in opaque systems). An admissions system that can evaluate a student&#x27;s actual trajectory rather than their GPA, without the nepotism that currently fills the gap when human &quot;holistic review&quot; becomes cover for preference. These aren&#x27;t guaranteed improvements. But they describe a real possibility that metric-based systems, by design, can never achieve: judgment that travels &lt;em&gt;with&lt;&#x2F;em&gt; its context rather than by stripping it away.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;The accidental regulator (TSMC&#x27;s yield rates, grid interconnection queues, the fact that 3nm lithography is hard) bought us time. We didn&#x27;t earn it. Every efficiency breakthrough DeepSeek finds, every fab TSMC opens, every GPU off the production line is time running out on a clock we never started.&lt;&#x2F;p&gt;
&lt;p&gt;The public discourse about what to do with that time has been captured by the AGI question: will it be conscious? Will it take over? Will it kill us? These are the wrong questions. Every institution that deploys an AI-based system is already operating under data-as-law, whether or not anyone named it that. The training corpus is already the constitution. The rater pool already encoded preferences.&lt;&#x2F;p&gt;
&lt;p&gt;This is the thing the extinction discourse spent a decade not asking. It isn&#x27;t about superintelligence. It doesn&#x27;t require AGI. It&#x27;s happening with the systems that exist right now, at the scale they&#x27;re deployed right now, in the institutions that are quietly replacing spot-checks with models nobody voted to build. The facade of the AGI debate makes it easy to defer: we&#x27;ll govern this once it gets serious. It&#x27;s already serious. The governance gap isn&#x27;t ahead of us. It opened the moment the first procurement decision was made.&lt;&#x2F;p&gt;
&lt;p&gt;The new rules aren&#x27;t written down anywhere. That&#x27;s the point. Data is law, and unlike every previous form of law, you cannot read it, cannot cite it, cannot challenge it in court. It has no preamble stating its purpose. It has no amendment process. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.theguardian.com&#x2F;technology&#x2F;2026&#x2F;mar&#x2F;01&#x2F;claude-anthropic-iran-strikes-us-military&quot;&gt;US military used Claude to select over 1,000 targets in the first 24 hours of strikes on Iran&lt;&#x2F;a&gt;—all run through weights shaped by a rater pool nobody voted to convene, applying values nobody publicly deliberated, with no written record of what was decided or why. It does not know what it got wrong. The cognitive scarcity that forced institutions to strip context out of judgment is dissolving, and the thing replacing it could finally restore that context or it could be the most complete instrument of control ever assembled, enforcing not just rules but norms, not just laws but the full shape of whoever&#x27;s training data happened to dominate.&lt;&#x2F;p&gt;
&lt;p&gt;Scaling laws for capabilities exist because someone decided to run the experiments: vary the compute, measure the loss, find the curve. We don&#x27;t have societal scaling laws because we haven&#x27;t run the equivalent experiments. Some of them are obvious enough to start. LLMs are not inscrutable technology. Even if we don&#x27;t know how it works, we know how to make it. We can develop societal practices around it. What happens when RLHF is treated like a vote — with franchise requirements, transparency, and an auditable record of what was decided? What does training data look like when it goes through a deliberative assembly instead of a contractor&#x27;s annotation queue? What if democratic AI weren&#x27;t a slogan but a methodology: citizens&#x27; assemblies that produce preference specifications, small-scale pilots in low-stakes institutions, iterated and measured? The point isn&#x27;t that any of these would work. The point is that we don&#x27;t know, because nobody is trying. The labs run thousands of ablations to understand what changes a model&#x27;s capabilities. Nobody is running ablations to understand what changes a society&#x27;s trajectory. That asymmetry isn&#x27;t inevitable. It&#x27;s just where we chose to put the resources.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Lots of different LLM based tools were used in the writing and research for this essay&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
      <item>
          <title>SWE Automation Is the Killer App</title>
          <pubDate>Sun, 08 Feb 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/swe-automation-killer-app/</link>
          <guid>https://www.narendasan.com/blog/swe-automation-killer-app/</guid>
          <description xml:base="https://www.narendasan.com/blog/swe-automation-killer-app/">&lt;h1 id=&quot;the-ui-moment-again&quot;&gt;The UI Moment, Again&lt;&#x2F;h1&gt;
&lt;p&gt;In November 2022, &lt;a href=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;chatgpt-web&#x2F;&quot;&gt;ChatGPT&#x27;s launch felt like a paradigm shift&lt;&#x2F;a&gt;. Suddenly, everyone was talking about AI. The technology press couldn&#x27;t stop writing about it. Your relatives asked you about it at Thanksgiving. It seemed to appear overnight.&lt;&#x2F;p&gt;
&lt;p&gt;But it didn&#x27;t appear overnight. Large language models had existed for years. GPT-3 launched in 2020. BERT came out in 2018. The transformer architecture that powers all of this dates back to 2017. Researchers had been steadily improving these systems, publishing papers, iterating on architectures, scaling up training runs.&lt;&#x2F;p&gt;
&lt;p&gt;What changed in November 2022 wasn&#x27;t the underlying technology. It was the &lt;strong&gt;interface&lt;&#x2F;strong&gt;. ChatGPT put a language model behind a chat interface and let anyone use it for free. No API keys, no Python notebooks, no papers to read. Just a text box and a conversation.&lt;&#x2F;p&gt;
&lt;p&gt;That interface unlocked something. It made the capability legible to non-researchers. People could &lt;em&gt;feel&lt;&#x2F;em&gt; what the model could do by talking to it. The chat format was familiar—everyone texts, everyone uses messaging apps. Within that familiar frame, the AI&#x27;s capabilities became visible. It could write, reason, explain, code, analyze. The technology had been there, but the interface made it undeniable.&lt;&#x2F;p&gt;
&lt;p&gt;This is how technologies break out of research labs. Not through incremental improvements to benchmarks, but through interfaces that make capabilities viscerally obvious to normal humans.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-industry-is-stumbling-around-in-the-dark&quot;&gt;The Industry Is Stumbling Around in the Dark&lt;&#x2F;h2&gt;
&lt;p&gt;Since ChatGPT&#x27;s launch, we&#x27;ve seen an explosion of AI applications. Every software category has been AI-ified:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Search&lt;&#x2F;strong&gt;: Perplexity, ChatGPT search, Bing Chat&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Writing assistants&lt;&#x2F;strong&gt;: Notion AI, Google Docs AI, Grammarly&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Image generation&lt;&#x2F;strong&gt;: Midjourney, DALL-E, Stable Diffusion&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Video generation&lt;&#x2F;strong&gt;: Sora, Runway, Pika&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Voice&lt;&#x2F;strong&gt;: ElevenLabs, voice cloning, AI podcasts&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Music&lt;&#x2F;strong&gt;: Suno, Udio, AI-generated soundtracks&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Customer service&lt;&#x2F;strong&gt;: AI chatbots on every website&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Personal assistants&lt;&#x2F;strong&gt;: Replika, Character.AI, custom GPTs&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Education&lt;&#x2F;strong&gt;: Khan Academy&#x27;s Khanmigo, Duolingo Max&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Design&lt;&#x2F;strong&gt;: Figma AI, Canva AI, Adobe Firefly&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Productivity&lt;&#x2F;strong&gt;: Mem, Notion AI, meeting transcription&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Code&lt;&#x2F;strong&gt;: GitHub Copilot, Cursor, Claude Code, Devin&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The list goes on. There&#x27;s an AI tool for everything. Venture funding has flooded into AI startups. Every company is adding &quot;AI-powered&quot; to their feature list. We&#x27;re in the hype phase.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-sticks&quot;&gt;What Sticks?&lt;&#x2F;h2&gt;
&lt;p&gt;But hype cycles pass. The question isn&#x27;t what&#x27;s hot right now, but what remains when the novelty wears off. What application of LLMs is so fundamentally valuable that it becomes infrastructure? What&#x27;s the killer app that justifies all this investment and attention?&lt;&#x2F;p&gt;
&lt;p&gt;The answer is &lt;strong&gt;software engineering automation&lt;&#x2F;strong&gt; because it&#x27;s the one where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The value is measurable&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The users are willing to pay&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The technology is good enough&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The feedback loops are strong enough that the tech doesn&#x27;t need to be perfect&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;It compounds: better tools make better tools&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-value-is-measurable&quot;&gt;The Value Is Measurable&lt;&#x2F;h3&gt;
&lt;p&gt;Most AI applications exist in fuzzy value territory. Is an AI-generated image &quot;better&quot; than one you&#x27;d commission from an artist? Depends on your taste. Does an AI writing assistant make you a better writer? Hard to say, maybe you&#x27;d have written something better yourself given time. They maybe faster to make on the surface but they are still distingushable from human images and text enough that you may spend as much time fixing them up as it took to make it from scratch.&lt;&#x2F;p&gt;
&lt;p&gt;Software engineering is different. The value is concrete:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Did the code work?&lt;&#x2F;strong&gt; Yes or no. It either compiles, passes tests, and does what it&#x27;s supposed to, or it doesn&#x27;t.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;How fast was it delivered?&lt;&#x2F;strong&gt; You can measure velocity—features shipped per sprint, time from spec to deployment.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;How many bugs were caught?&lt;&#x2F;strong&gt; Fewer production incidents, faster debugging cycles—these are trackable metrics.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There&#x27;s no subjectivity. If an AI coding assistant lets you ship twice as fast and produce the same results, that&#x27;s not a matter of taste. It&#x27;s a measurable business outcome.&lt;&#x2F;p&gt;
&lt;p&gt;And the business outcomes are enormous. Software engineering is expensive. Senior engineers at tech companies make &lt;code&gt;$300K–500K+&lt;&#x2F;code&gt; total comp. At scale, even modest productivity gains are worth millions. If an AI tool makes a 100-person engineering team 20% more productive, that&#x27;s like adding 20 engineers—&lt;code&gt;$6–10M&lt;&#x2F;code&gt;year in value.&lt;&#x2F;p&gt;
&lt;p&gt;Companies will pay for that. They already are.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;users-who-are-willing-to-pay&quot;&gt;Users Who Are Willing to Pay&lt;&#x2F;h3&gt;
&lt;p&gt;Consumer AI applications face a harsh reality: users expect AI to be free. In the long term, &lt;strong&gt;it will be &quot;free&quot;&lt;&#x2F;strong&gt; . Costs for power, maybe some hardware, but you won&#x27;t subscribe to some service. Fundamentally, there are few moats in AI. The data is largely publicly available (give or take discussions of fair use). The model architectures for LLMs are publicly disclosed. The fundamental gatekeeper is access to compute. Even then, through techniques like model distillation and quantization, the vast majority of capability can be captured and run on very limited hardware. The current barriers for self-hosted consumer AI come down to ease of setup, use, and maintenance (another UI revolution yet to come). But as many who have instituted paywalls (newspapers, apps, etc.) have found, even charging one cent for your service causes a drastic reduction in your userbase. I fully expect that in the long term, consumer AI will be serviced by something akin to a personal AI computer, a device you&#x27;d buy from a manufacturer like Apple that gives you a simple interface to a local model that feels no worse than the trillion-parameter Opus-class models running in datacenters.&lt;&#x2F;p&gt;
&lt;p&gt;Businesses have a different value calculus and are far less cost-sensitive. Time and human capital are as important as dollars. Being able to move faster with fewer resources is worth the extra monetary cost. SaaS as a business model has demonstrated this. Workday, Justworks, JIRA, Slack, Tableau, all companies that automate common business functions, allowing companies to have less support staff, move faster, and coordinate better. This doesn&#x27;t mean you don&#x27;t have HR specialists or project managers or accountants or data analysts, but you certainly don&#x27;t need as many.&lt;&#x2F;p&gt;
&lt;p&gt;For a long time, software engineering was an exception. It was a high-skill job, and for the most part you could never have enough great engineers. But with tools like Claude Code, one senior engineer with clear intention can implement a feature that used to take a month and a few junior implementers. A &lt;code&gt;$20&lt;&#x2F;code&gt;&#x2F;month AI coding assistant that saves even an hour per week is worth 10x its cost for an engineer making &lt;code&gt;$150K&lt;&#x2F;code&gt;&#x2F;year. There&#x27;s also a management aspect: regulating access to codebases and infrastructure, enforcing best practices. Having a company-wide provider of AI services allows some semblance of control and guarantees about how employees conduct their work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-technology-is-good-enough&quot;&gt;The Technology Is Good Enough&lt;&#x2F;h3&gt;
&lt;p&gt;Many AI applications are still in the &quot;impressive demo, rough product&quot; phase. AI-generated video is stunning for 10 seconds, then the physics break. AI music sounds plausible until you listen carefully. AI search is great until it confidently hallucinates.&lt;&#x2F;p&gt;
&lt;p&gt;Code generation has crossed a threshold. It&#x27;s not perfect, but it&#x27;s &lt;strong&gt;useful right now&lt;&#x2F;strong&gt;. Why is code different? A few reasons:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Verification loops&lt;&#x2F;strong&gt;: Code either runs or it doesn&#x27;t. Tests pass or fail. The compiler catches type errors. There&#x27;s immediate, deterministic feedback that lets the AI iterate toward correctness. This is unlike creative tasks where &quot;correctness&quot; is subjective and subtly encoded into the product.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Massive training data&lt;&#x2F;strong&gt;: Code is public (GitHub, Stack Overflow), structured, and abundant. LLMs have seen millions of repositories and billions of lines of code. They&#x27;ve learned patterns deeply.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Clear intent from context&lt;&#x2F;strong&gt;: When writing code, the surrounding context—existing functions, type signatures, comments, variable names—provides strong signal about what should come next. The AI isn&#x27;t generating from a blank slate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Tolerance for iteration&lt;&#x2F;strong&gt;: Developers already iterate. Writing code is revising code. An AI that generates something 80% right that you refine is still a massive win. You don&#x27;t need perfection, just a good starting point.&lt;&#x2F;p&gt;
&lt;p&gt;This combination means code generation is past the toy phase. It&#x27;s delivering real value in production workflows today.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;feedback-loops-provide-leniency-to-imperfect-systems&quot;&gt;Feedback Loops Provide Leniency to Imperfect Systems&lt;&#x2F;h3&gt;
&lt;p&gt;This might be the most important factor. AI coding assistants achieve tasks via feedback. Where there&#x27;s a strong pass-or-fail signal, with enough iteration an AI agent can solve the problem to some degree.&lt;&#x2F;p&gt;
&lt;p&gt;Compare this to other AI applications:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AI art&lt;&#x2F;strong&gt;: Users either like an image or they don&#x27;t. Taste is subjective. Hard to use that to improve the model systematically.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;AI writing&lt;&#x2F;strong&gt;: Did this make the writing &quot;better&quot;? Hard to measure. Most users can&#x27;t articulate why they prefer one version over another.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;AI search&lt;&#x2F;strong&gt;: Did the answer satisfy the user? Maybe they closed the tab because they found what they needed, or maybe because the answer was wrong. Ambiguous signal.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Even when users have preferences, you end up with what we see in consumer-facing chat interfaces: degenerate behavior like sycophancy gets reinforced even when humans know it&#x27;s suboptimal. People love having their egos stroked, and due to how models trained against human feedback this behavior gets reinforced.&lt;&#x2F;p&gt;
&lt;p&gt;Code has ground truth. The compiler and tests are the judge. This lets AI coding tools improve faster than other applications.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, the code generation task aligns with LLM strengths. LLMs are pattern-matching engines trained on vast amounts of text. Code is structured, pattern-rich, and well-represented in training data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;it-compounds-better-tools-make-better-tools&quot;&gt;It Compounds—Better Tools Make Better Tools&lt;&#x2F;h3&gt;
&lt;p&gt;AI coding assistants make themselves better.&lt;&#x2F;p&gt;
&lt;p&gt;The teams building Cursor, Claude Code, and GitHub Copilot use their own tools. This use case is being dogfooded more than any other at the companies developing LLMs. As people say in product design, the best products are the ones you make for yourself.&lt;&#x2F;p&gt;
&lt;p&gt;This is a compounding loop that doesn&#x27;t exist for most AI applications. AI-generated art doesn&#x27;t help you build better art generators—it probably makes them worse. AI writing assistants don&#x27;t make it easier to train better writing models. But AI code generation directly accelerates AI research and development.&lt;&#x2F;p&gt;
&lt;p&gt;This suggests a future where AI-powered software development accelerates—not because models get bigger (though they will), but because the tools for building models get more targeted on this use case, where the feedback signals are most observable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-staying-power&quot;&gt;The Staying Power&lt;&#x2F;h2&gt;
&lt;p&gt;When the current AI hype cycle cools, what remains?&lt;&#x2F;p&gt;
&lt;p&gt;Some consumer AI apps may stick. Chat-mediated research probably survives. AI-generated art may become a standard tool for certain creative workflows, particularly in marketing where art is commodified. Voice AI for transcription and customer service likely becomes commodity infrastructure.&lt;&#x2F;p&gt;
&lt;p&gt;But I think the most durable, highest-value application is software engineering automation. This doesn&#x27;t mean programmers disappear. It means programming changes. The job shifts from writing every line by hand to directing AI systems, reviewing their output, and focusing on architecture and intent. The cognitive load moves up the stack.&lt;&#x2F;p&gt;
&lt;p&gt;But unlike other AI applications that might be fads, coding automation has staying power because it&#x27;s embedded in the critical path of building everything else. Every software company, every tech product, every digital service—they all need code. Making that code faster and cheaper to write is valuable to everyone.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-interface-moment-for-coding-agents&quot;&gt;The Interface Moment for Coding Agents&lt;&#x2F;h2&gt;
&lt;p&gt;Just like ChatGPT made LLMs legible to the general public through a simple chat interface, we&#x27;re approaching an interface moment for coding agents.&lt;&#x2F;p&gt;
&lt;p&gt;Until recently, AI coding tools were mostly autocomplete-plus. Copilot suggests the next line. Cursor helps you edit faster. These are powerful, but they&#x27;re incremental improvements to existing workflows.&lt;&#x2F;p&gt;
&lt;p&gt;The interface moment is here: the abstraction level is shifting. Instead of writing code and having AI assist, you &lt;strong&gt;describe intent and AI generates working systems&lt;&#x2F;strong&gt;. The unit of work isn&#x27;t &quot;write this function&quot; but &quot;build this feature&quot; or &quot;refactor this architecture.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;When this interface matures, when the abstraction is natural and the reliability is high enough that you trust it, that&#x27;s when coding automation becomes truly sticky. Not just for early adopters and AI enthusiasts, but for every engineer, every team, every company, &lt;strong&gt;normal people&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;ChatGPT&#x27;s launch wasn&#x27;t about new technology. It was about making existing technology legible through the right interface. The chat box made LLM capabilities undeniable to millions of people.&lt;&#x2F;p&gt;
&lt;p&gt;Coding agents follow the same pattern. The technology isn&#x27;t new or novel. What&#x27;s coming is the interface refinement that makes software engineering automation natural and reliable. It will also expose software engineering to people who have no clue how to write a single line of code or what a command line is.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s no longer a novelty or a power-user tool. It will be infrastructure—the default way software gets built.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s the killer app. The one that remains when the hype fades. The one that justifies the investment, the attention, and the transformation.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>The Definition of Good Software Ergonomics Has Changed</title>
          <pubDate>Thu, 05 Feb 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/software-ergonomics/</link>
          <guid>https://www.narendasan.com/blog/software-ergonomics/</guid>
          <description xml:base="https://www.narendasan.com/blog/software-ergonomics/">&lt;h1 id=&quot;the-vibe-coding-automated-programming-revolution&quot;&gt;The &lt;del&gt;Vibe Coding&lt;&#x2F;del&gt; Automated Programming Revolution&lt;&#x2F;h1&gt;
&lt;p&gt;Software engineering is fundamentally changing. AI coding agents like Claude Code have put the vision of just telling a computer to do something in natural language and it just working out of the box in sight - the kind of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=6CDhEwhOm44&quot;&gt;natural language computer interface&lt;&#x2F;a&gt; that Star Trek: The Next Generation and other science fictionpromised decades ago. This approach emphasizes directness and velocity over precision. You describe what you want, the AI generates something close, you iterate until it feels right.&lt;&#x2F;p&gt;
&lt;p&gt;However, as we embrace more stochastic, probabilistic code generation, the need for deterministic, pedantic verification systems has become more critical, not less. The definition of good ergonomics in software tools has fundamentally changed. &lt;strong&gt;&quot;Annoying and verbose&quot; type systems that once felt overly burdensome are now precisely what makes automated programming viable for production systems.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-old-ergonomics-flexibility-vs-safety&quot;&gt;The Old Ergonomics: Flexibility vs. Safety&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;python-js-maximal-expressiveness&quot;&gt;Python&#x2F;JS: Maximal Expressiveness&lt;&#x2F;h3&gt;
&lt;p&gt;For decades, languages like Python, Ruby, and JavaScript defined &quot;ergonomic&quot; programming. They clearly made design decisions prioritizing:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rapid prototyping&lt;&#x2F;strong&gt;: Write code without upfront type declarations or boilerplate&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Low friction&lt;&#x2F;strong&gt;: No compiler to satisfy, just run your code and see what happens&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Expressiveness&lt;&#x2F;strong&gt;: Duck typing lets you write generic code without ceremony&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Approachability&lt;&#x2F;strong&gt;: New developers could be productive quickly&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The goal a lot of programmers have is &quot;what is the shortest path to getting something running&quot;. And Python and JavaScript are great choices for this because of their flexibility.&lt;&#x2F;p&gt;
&lt;p&gt;This made perfect sense when humans were the primary authors. We have the full context of what we just wrote and over time this knowledge grows, so we can make informed decisions about additions or subtractions from the programs. We intuitively understand types from variable names and usage patterns. We catch obvious mistakes as we go. The cognitive overhead of static types felt like friction against our natural workflow. Python became the language of ML precisely because of these properties. When you&#x27;re iterating on model architectures or experimenting with data transformations, you want to think about the problem, not satisfy a type checker.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-deal-we-made-with-the-devil&quot;&gt;The Deal We Made with the Devil&lt;&#x2F;h4&gt;
&lt;p&gt;But this flexibility came with costs that we grudgingly accepted:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Runtime surprises&lt;&#x2F;strong&gt;: &lt;code&gt;AttributeError&lt;&#x2F;code&gt;, &lt;code&gt;TypeError&lt;&#x2F;code&gt;, &lt;code&gt;KeyError&lt;&#x2F;code&gt; appearing in production&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Refactoring anxiety&lt;&#x2F;strong&gt;: Changing a function signature requires manually hunting down all call sites&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Integration fragility&lt;&#x2F;strong&gt;: Connecting components means carefully reading documentation and hoping you followed the library and language right&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Testing burden&lt;&#x2F;strong&gt;: You need comprehensive test coverage just to catch new bugs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We built elaborate defensive strategies: extensive unit tests, runtime assertions, careful code reviews, gradual typing systems like TypeScript and mypy. But fundamentally, we relied on human vigilance to catch what the language wouldn&#x27;t.&lt;&#x2F;p&gt;
&lt;p&gt;This was manageable when humans wrote all the code. We could be careful. We understood our codebases. We had context.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rust-maximal-safety&quot;&gt;Rust: Maximal Safety&lt;&#x2F;h3&gt;
&lt;p&gt;Consider the common complaints about Rust today. Developers constantly cite &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;viralinstruction.com&#x2F;posts&#x2F;borrowchecker&#x2F;&quot;&gt;&quot;fighting the borrow checker&quot;&lt;&#x2F;a&gt; as a major pain point. Lifetime annotations are confusing. The compiler is pedantic about ownership and mutability in ways that feel unnecessarily restrictive. You write what seems like perfectly reasonable code and the compiler rejects it with cryptic error messages about borrowed values not living long enough. Simple tasks that take five minutes in Python require 30 minutes of appeasing the type system. The learning curve is brutal.&lt;&#x2F;p&gt;
&lt;p&gt;All of this is true when a human is writing Rust character by character. The cognitive overhead of tracking ownership, satisfying lifetime requirements, and structuring code to make the borrow checker happy is immense. You&#x27;re trying to solve a problem while simultaneously managing low-level memory safety invariants.&lt;&#x2F;p&gt;
&lt;p&gt;But with AI-assisted development, this dynamic inverts completely. The LLM doesn&#x27;t experience cognitive overhead from the borrow checker. It will happily try 20 different lifetime annotations until one works (provided youre willing to pay for the tokens). It doesn&#x27;t get frustrated when the compiler complains about moving a value that&#x27;s still borrowed. It just generates a new version. The &quot;fighting the borrow checker&quot; experience - which exhausts humans - is exactly what LLMs are built for: rapid iteration against deterministic feedback.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; You: &amp;quot;create a user service that fetches users and validates email&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; AI generates, borrow checker complains, AI regenerates, repeat 15 times...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; You see only the final result:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; get_user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; UserId&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;User&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; ... implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; validate_email&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; User&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; ... implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; process_user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; UserId&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;lt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; get_user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; AI accidentally tries:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    validate_email&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;email&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; &#x2F;&#x2F; COMPILE ERROR: expected User, got String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; AI immediately fixes:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    validate_email&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; &#x2F;&#x2F; ✓ compiles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The compiler catches that the agent initially mixed up &lt;code&gt;user.email&lt;&#x2F;code&gt; and &lt;code&gt;user&lt;&#x2F;code&gt;. No runtime error in production, no unit test needed for this specific case. The type system caught it mechanically, the AI fixed it automatically, and you never saw the 15 iterations it took to satisfy the borrow checker.&lt;&#x2F;p&gt;
&lt;p&gt;The complaints about Rust&#x27;s difficulty are really complaints about the human experience of satisfying its strict requirements. But those strict requirements are precisely what make it ideal for AI-generated code. The pain points for humans become verification points for AI.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;declarative-infrastructure-the-nix-example&quot;&gt;Declarative Infrastructure: The Nix Example&lt;&#x2F;h3&gt;
&lt;p&gt;The same pattern extends beyond code to systems management. Declarative, reproducible infrastructure tools like Nix represent another case where what seemed like excessive rigor for human operators becomes ideal for AI agents.&lt;&#x2F;p&gt;
&lt;p&gt;Traditional imperative systems administration - running sequences of &lt;code&gt;apt install&lt;&#x2F;code&gt;, &lt;code&gt;systemctl enable&lt;&#x2F;code&gt;, editing config files, hoping everything works - is error-prone and fragile. It works when experienced sysadmins carefully maintain mental models of system state and manually verify each step. But it&#x27;s a nightmare to automate reliably because there&#x27;s no verification that the system ended up in the desired state. Tools like Ansible improved on raw shell scripts by adding idempotency and a declarative veneer, but they still operate imperatively under the hood - checking current state, computing diffs, applying changes. When an Ansible playbook fails halfway through, you&#x27;re left with partial state and have to reason about what succeeded and what didn&#x27;t.&lt;&#x2F;p&gt;
&lt;p&gt;Nix flips this model. You declare what you want: &lt;em&gt;Python 3.11, PostgreSQL 15, these exact library versions, with these configuration files&lt;&#x2F;em&gt;, and Nix handles the how. More importantly, Nix provides strong guarantees: builds are reproducible, rollbacks are atomic, different configurations can coexist without conflict. The system either successfully reaches the declared state or fails clearly, with no partial success states. However, many decry Nix&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=38657786&quot;&gt;obtuse syntax&lt;&#x2F;a&gt; and steep learning curve. Many developers take one look at Nix and decide &lt;code&gt;apt install&lt;&#x2F;code&gt; is good enough. They want to think imperatively not wrestle with recursive attribute sets and &lt;code&gt;mkDerivation&lt;&#x2F;code&gt; functions.&lt;&#x2F;p&gt;
&lt;p&gt;Consider asking an AI to write a bash script that installs dependencies, configures services, and sets up an environment. The AI has to reason about: What packages are already installed? What version? Will this conflict with something else? Did the previous step succeed? Is the service already running? Every system is unique. The AI generates plausible commands that might work, but verification requires actually running them and seeing what breaks.&lt;&#x2F;p&gt;
&lt;p&gt;With Nix, the AI writes a declarative configuration. The Nix evaluator immediately catches errors. When you build it, you get exactly what was declared, reproducibly, every time. The AI handles the ceremony of Nix syntax and package resolution while the human specifies intent. The declarative substrate provides verification that what gets built matches what was intended.&lt;&#x2F;p&gt;
&lt;p&gt;With AI agents, you can have it both ways. You express your intent imperatively and naturally: &quot;Install PostgreSQL 15, create a database called &#x27;myapp&#x27;, set up connection pooling with 20 max connections, and configure it to start on boot.&quot; The AI translates this into proper Nix configuration handling the syntax, looking up the right package attributes, structuring the configuration options correctly, managing the boilerplate. You think imperatively, the AI writes declaratively, and Nix verifies the result.&lt;&#x2F;p&gt;
&lt;p&gt;This inverts the traditional adoption barrier. Instead of having to learn Nix before you can use it, you can use Nix from day one by expressing what you want in plain language. The weird syntax and verbose boilerplate become the AI&#x27;s problem, not yours. You get the benefits of declarative, reproducible infrastructure without having to master the tool itself.&lt;&#x2F;p&gt;
&lt;p&gt;The same applies to all the declarative tools that have better properties but worse ergonomics: Terraform&#x27;s HCL, Kubernetes manifests, etc. They&#x27;re all better than imperative alternatives for reproducibility and verification, but they&#x27;re harder to learn and more verbose to write. AI bridges this gap: you work imperatively, the AI generates declaratively, and the declarative substrate provides verification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-this-matters-now-enter-stochastic-code-generation&quot;&gt;Why This Matters Now: Enter Stochastic Code Generation&lt;&#x2F;h2&gt;
&lt;p&gt;Now instead of writing code character by character, we describe what we want and receive entire functions, classes, or modules. This is incredible for productivity, but it introduces new failure modes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Plausible but wrong&lt;&#x2F;strong&gt;: AI generates code that looks right but has subtle bugs&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Inconsistent assumptions&lt;&#x2F;strong&gt;: Different sections of AI-generated code may make incompatible assumptions about data types&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Naming mismatches&lt;&#x2F;strong&gt;: Field names, parameter names, method names might be close but not quite right&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Silent type mismatches&lt;&#x2F;strong&gt;: Passing &lt;code&gt;string&lt;&#x2F;code&gt; where &lt;code&gt;int&lt;&#x2F;code&gt; was expected, or vice versa&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Lost context&lt;&#x2F;strong&gt;: AI doesn&#x27;t always maintain type consistency across the codebase&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;When a human writes &lt;code&gt;user.email&lt;&#x2F;code&gt;, they remember that &lt;code&gt;user&lt;&#x2F;code&gt; came from a database query two lines ago and has specific fields. When AI generates it, it&#x27;s making a probabilistic guess based on prior context for that particular session. That guess is often right, but not always.&lt;&#x2F;p&gt;
&lt;p&gt;The same flexibility that made Python ergonomic for human-written code becomes treacherous for AI-generated code. The AI can&#x27;t &quot;just know&quot; the types the way a human author might, just the same way a fresh new grad being thrown a codebase needs time to understand its subtle behavior, the nuances of the language that the codebase exploits &#x2F; abuses. Agents without that long form persistent experience do the best they can, sample from a distribution of valid completions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;typescript-s-evolution&quot;&gt;TypeScript&#x27;s Evolution&lt;&#x2F;h3&gt;
&lt;p&gt;TypeScript&#x27;s adoption trajectory shows us a preview of this future. When it launched in 2012, many JavaScript developers saw it as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;javascript-scene&#x2F;you-might-not-need-typescript-or-static-types-aa7cb670a77b&quot;&gt;&quot;unnecessary&quot;&lt;&#x2F;a&gt; ceremony. JavaScript was already working fine,why add all this type annotation boilerplate? The tooling was immature. The type definitions for popular libraries were incomplete or wrong. Developers complained about having to write &lt;code&gt;interface&lt;&#x2F;code&gt; declarations for every data structure and explicitly type every function parameter.&lt;&#x2F;p&gt;
&lt;p&gt;The turning point came as codebases scaled. When teams grew beyond five people, when code lived longer than six months, when people joined and left organizations, the lack of static checking and other mechanistic verification became a liability. You couldn&#x27;t rely on humans having perfect context about all the nuances of the codebase. A new hire looks at a function that returns &lt;code&gt;data&lt;&#x2F;code&gt;, has no idea what shape that data has, and makes an incorrect assumption that ships a catastrophic bug into production.&lt;&#x2F;p&gt;
&lt;p&gt;TypeScript solved this by making the implicit explicit. Types serve as documentation that the compiler enforces. When someone changes a function signature, every call site gets flagged. When you hover over a variable in your editor, you see exactly what it is. The &quot;unnecessary ceremony&quot; turned out to be essential scaffolding for teams and time scales.&lt;&#x2F;p&gt;
&lt;p&gt;Now with AI coding assistants, TypeScript&#x27;s value proposition has intensified. LLMs generate more accurate code when they have type information to guide them, using types as contracts to ensure correctness. The types that made human collaboration scalable now make human-AI collaboration reliable.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-runtime-errors-are-worse-for-ai-generated-code&quot;&gt;Why Runtime Errors Are Worse for AI-Generated Code&lt;&#x2F;h3&gt;
&lt;p&gt;Running code to discover errors is orders of magnitude slower than compile-time checking. When an LLM generates code, waits for it to run, encounters a &lt;code&gt;TypeError&lt;&#x2F;code&gt; on line 47, and has to regenerate. Compile errors return in milliseconds. Runtime errors require executing code, potentially setting up test environments, databases, or external dependencies. The AI might need to generate and run code multiple times to catch all the runtime errors that static analysis would have caught immediately. In AI development in particular, runs can be on the order of months. So either you must spend a lot of effort verifying each AI generated piece of code, or you pray that in 2 weeks you wont have a crashed training run. Runtime errors also leave your system in an unknown state. Did the database transaction commit? Did the file get written? Did the message get sent? The AI has no memory of what side effects occurred before the error, making it hard to reason about what needs to be cleaned up or retried. Runtime errors can depend on execution paths, data, and timing. The same AI-generated code might work with one set of inputs and fail with another. It might work in development and fail in production. The LLM might successfully generate code that passes initial tests but contains latent bugs that only appear under specific conditions. Type systems catch these categories of errors unconditionally. In dynamically typed languages, one type error can cascade into many runtime errors. The AI fixes the first error, runs again, hits a second error caused by the same underlying type confusion, fixes that, runs again, hits a third error. With static types, all related errors are caught simultaneously, and fixing the type definition fixes all of them at once. AI coding assistants amplify both the productivity gains of flexible languages and their risks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-new-ergonomics-flexibility-safety&quot;&gt;The New Ergonomics: Flexibility + Safety&lt;&#x2F;h2&gt;
&lt;p&gt;This is where formally verified and compiler-verified systems become essential. Languages like Rust, OCaml, Haskell, and even modern TypeScript provide something critical: &lt;strong&gt;automated, mechanical verification that generated code is internally consistent&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The new ergonomic ideal is this: be loose and viby with &lt;strong&gt;intent&lt;&#x2F;strong&gt;: ideas, features, specifications, but strict and pedantic with &lt;strong&gt;verification&lt;&#x2F;strong&gt;. This is where previously &quot;annoying&quot; tools like static analyzers, linters, and type checkers play a crucial role. Good software software written with these agentic tools needs to be self-verifying. Ideally in addition to using a programming language with strong type checking, the codebase itself should be imposing additional contract layers to ensure that new code integrates as expected.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-pedantic-systems-are-perfect-for-ai-assisted-coding&quot;&gt;Why Pedantic Systems Are Perfect for AI-Assisted Coding&lt;&#x2F;h3&gt;
&lt;p&gt;The pairing of AI code generation with strong type systems exploits a fundamental asymmetry in capabilities. LLMs are remarkably good at iterating rapidly through compiler errors without fatigue, pattern matching against type signatures to generate syntactically valid code, and exploring large search spaces of possible implementations. They maintain perfect patience through dozens of compile-fix cycles, never getting frustrated or bored. An LLM will happily regenerate code 20 times to satisfy the borrow checker or fix a type mismatch.&lt;&#x2F;p&gt;
&lt;p&gt;But LLMs are comparatively poor at catching subtle semantic bugs that compile correctly, understanding deep business logic and domain invariants, reasoning comprehensively about edge cases and error conditions, or maintaining consistency in intent across a large codebase. These require contextual understanding and judgment that current models lack.&lt;&#x2F;p&gt;
&lt;p&gt;This creates a clear division of labor. Strong type systems and compiler verification provide quick, theoretical guarantees about structural correctness, exactly the kind of mechanical feedback that LLMs can iterate against efficiently. The compiler provides immediate, precise feedback that guides the generative process toward valid implementations. The LLM fights through the pedantic mechanical details that would exhaust a human developer.&lt;&#x2F;p&gt;
&lt;p&gt;Meanwhile, those same type systems won&#x27;t catch that you&#x27;re calculating the discount incorrectly, that you forgot to handle the case where a user account is suspended, or that your algorithm has the wrong complexity for the scale you need. These subtle implementation issues require human review and domain knowledge. This points to what next-generation programming interfaces must solve: surfacing business logic and domain invariants clearly and explicitly, rather than allowing them to be scattered implicitly throughout the codebase. When the critical logic is concentrated and visible, humans can effectively review what matters. The type system details, the mechanical plumbing, the syntactic correctness become increasingly hidden from the human developer, the same way most people don&#x27;t read the assembly for their programs. Its main role now is as feedback for the LLM during implementing a new set of business logic. Part of this work will also be implementing higher order contract verfication into the codebase so that as new additions are made, conflicts can be surfaced prior to deployement.&lt;&#x2F;p&gt;
&lt;p&gt;This suggests a future where programming interfaces have two distinct layers: a dense, type-rich substrate that the LLM interacts with directly, and a higher-level interface where humans specify intent, business rules, and constraints. The human never sees the 40 iterations the LLM took to satisfy the borrow checker. They see the business logic they specified, and tools that help them verify it does what they intended. The type system becomes infrastructure - essential, but largely invisible to the human operator.&lt;&#x2F;p&gt;
&lt;p&gt;This isn&#x27;t just speculation - this pattern is already being deployed in production systems where correctness is life-or-death critical.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;real-deployments-stochastic-generation-deterministic-verification-today&quot;&gt;Real Deployments: Stochastic Generation + Deterministic Verification Today&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;dual-verification-in-safety-critical-systems&quot;&gt;Dual Verification in Safety-Critical Systems&lt;&#x2F;h3&gt;
&lt;p&gt;This pattern of dual-system verification isn&#x27;t hypothetical, it&#x27;s already deployed in autonomous vehicles. NVIDIA&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blogs.nvidia.com&#x2F;blog&#x2F;halos-safety-system-autonomous-vehicles&#x2F;&quot;&gt;DRIVE platform for autonomous vehicles&lt;&#x2F;a&gt; exemplifies this architecture. The system runs two parallel stacks: an end-to-end AI-based autonomous driving system (increasingly powered by models like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.nvidia.com&#x2F;blog&#x2F;building-autonomous-vehicles-that-reason-with-nvidia-alpamayo&#x2F;&quot;&gt;Alpamayo&lt;&#x2F;a&gt;, which uses vision-language-action models to reason about complex driving scenarios) and a traditional safety verification system.&lt;&#x2F;p&gt;
&lt;p&gt;The AI system is generative and stochastic, making probabilistic decisions about steering, acceleration, and navigation based on sensor inputs. It can handle novel situations and reason through edge cases like navigating a traffic light outage, but its decision-making process is fundamentally opaque. The safety system, in contrast, uses traditional formal verification methods that check whether the AI&#x27;s proposed actions violate safety constraints.&lt;&#x2F;p&gt;
&lt;p&gt;The result is exactly the pattern we&#x27;ve been discussing: a stochastic generative system (the AI driver) paired with deterministic verification (the safety stack). The AI explores the solution space creatively, making real-time decisions. The formal verification system checks those decisions against hard constraints such as occupancy, speed limits, and traffic rules. The AI can propose novel solutions to complex problems, but only actions that pass formal verification get executed.&lt;&#x2F;p&gt;
&lt;p&gt;This is the template for AI-assisted development writ large. The generative system proposes, the verification system validates, and humans review the semantic correctness at a high level. When your car&#x27;s autonomy stack makes a decision, you want the same confidence you get from a type-checked program: the mechanical details have been verified, so you can focus on whether the high-level behavior matches your intent.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;formal-methods-and-theorem-proving&quot;&gt;Formal Methods and Theorem Proving&lt;&#x2F;h3&gt;
&lt;p&gt;For critical systems, we&#x27;re seeing interest in even stronger verification: formal methods like dependent types (Idris, Agda), proof assistants (Coq, Lean), and specification languages (TLA+, Alloy).&lt;&#x2F;p&gt;
&lt;p&gt;These tools let you specify invariants and properties that must hold, and mechanically verify that your code satisfies them. This was previously seen as too expensive for most software, but when AI can help generate both code and proofs, the cost-benefit calculation changes.&lt;&#x2F;p&gt;
&lt;p&gt;The recent breakthroughs in AI-assisted theorem proving demonstrate this isn&#x27;t hypothetical. Google DeepMind&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;deepmind.google&#x2F;discover&#x2F;blog&#x2F;ai-solves-imo-problems-at-silver-medal-level&#x2F;&quot;&gt;AlphaProof achieved silver-medal performance at the 2024 International Mathematical Olympiad&lt;&#x2F;a&gt; by proving mathematical statements in Lean. More recently, they achieved &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;deepmind.google&#x2F;discover&#x2F;blog&#x2F;advanced-version-of-gemini-with-deep-think-officially-achieves-gold-medal-standard-at-the-international-mathematical-olympiad&#x2F;&quot;&gt;gold-medal performance in 2025&lt;&#x2F;a&gt;. These systems train by proving millions of problems, learning from each verified proof to tackle increasingly difficult challenges.&lt;&#x2F;p&gt;
&lt;p&gt;Tools like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;leandojo.org&#x2F;&quot;&gt;LeanDojo&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lean-dojo&#x2F;LeanCopilot&quot;&gt;Lean Copilot&lt;&#x2F;a&gt; now make this accessible for developers. They provide AI-assisted theorem proving that integrates directly into the Lean workflow, with over 210,000 theorems already formalized in mathlib as of 2025. The AI generates proof candidates, the Lean proof assistant verifies them mechanically, and the process iterates until a valid proof is found.&lt;&#x2F;p&gt;
&lt;p&gt;This is the same pattern: you specify what properties your system should have (the theorem statement), AI explores the solution space (generating proof candidates), and formal verification ensures correctness (Lean checking each proof). The difference is that instead of catching type errors, you&#x27;re proving algorithmic correctness, data structure invariants, or protocol safety properties.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine: you vibe out the high-level requirements and properties your system must satisfy, AI generates an implementation and proofs that it satisfies those properties, and a proof checker verifies everything mechanically. You get the velocity of vibe coding with the confidence of formal verification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-cognitive-load-shift&quot;&gt;The Cognitive Load Shift&lt;&#x2F;h2&gt;
&lt;p&gt;The old model:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Writing code&lt;&#x2F;strong&gt;: Low cognitive load (flexible, forgiving)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifying code&lt;&#x2F;strong&gt;: High cognitive load (manual review, testing, debugging)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;-- or --&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Writing code&lt;&#x2F;strong&gt;: High cognitive load (fighting to satisfy the compiler, very slow iteration time)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifying code&lt;&#x2F;strong&gt;: Low(er) cognitive load (compiler does much of it automatically, but still some manual review, testing, debugging)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The new model:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Writing code&lt;&#x2F;strong&gt;: Medium cognitive load (express intent clearly, but let AI handle details)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifying code&lt;&#x2F;strong&gt;: Low(er) cognitive load (compiler does much of it automatically but still some manual review)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is a fundamental shift in what programming ergonomics means.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-ergonomic-means-now&quot;&gt;What &quot;Ergonomic&quot; Means Now&lt;&#x2F;h3&gt;
&lt;p&gt;Good software ergonomics used to mean:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Minimal ceremony&lt;&#x2F;li&gt;
&lt;li&gt;Flexibility&lt;&#x2F;li&gt;
&lt;li&gt;Freedom to experiment&lt;&#x2F;li&gt;
&lt;li&gt;Low friction for small changes&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Good software ergonomics now means:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Minimal ceremony &lt;strong&gt;for expressing intent&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Flexibility &lt;strong&gt;in approach&lt;&#x2F;strong&gt;, rigidity &lt;strong&gt;in contracts&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Freedom to experiment &lt;strong&gt;with implementation&lt;&#x2F;strong&gt;, strictness &lt;strong&gt;in interfaces&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Low friction for small changes &lt;strong&gt;with automated verification&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The key insight is that we can have both velocity and safety by separating the stochastic layer (AI generation) from the deterministic layer (type checking and formal verification). Each does what it&#x27;s good at.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implications-for-existing-languages&quot;&gt;Implications for Existing Languages&lt;&#x2F;h2&gt;
&lt;p&gt;Today, the choice of tools should be guided by the principles of choosing systems which can enforce correctness and safety, letting LLMs be the interface between the creative high level design decisions (e.g. model architecture choices in a machine learning system) and a deterministic self verifiying implementation. The complaint about Nix flake being too hard to write doesn&#x27;t make as much sense when the LLM will do it for you and Nix will verify it and all you have to say is &quot;add postgres to my environment&quot;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;python-s-potential&quot;&gt;Python&#x27;s Potential&lt;&#x2F;h3&gt;
&lt;p&gt;Python is in an interesting position. It&#x27;s the language of AI development, but it&#x27;s poorly suited to AI-assisted application development in its default form. The solution could be more disciplined use of type hints and tools like mypy, Pydantic, and dataclasses. But this only goes so far and requires significant discipline and effort from developers &lt;strong&gt;and the LLMs&lt;&#x2F;strong&gt; to verify through those tools.&lt;&#x2F;p&gt;
&lt;p&gt;Projects like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.modular.com&#x2F;mojo&quot;&gt;Mojo&lt;&#x2F;a&gt; and efforts to improve Python&#x27;s performance also point toward a future where Python gets stricter, not looser, because strictness enables better tooling and verification.&lt;&#x2F;p&gt;
&lt;p&gt;But what if we didn&#x27;t retrofit existing languages? What if we designed a language from scratch for this new paradigm?&lt;&#x2F;p&gt;
&lt;!--## What would an AI-Native Programming Language Look Like?

What would a programming language designed from the ground up for AI-assisted development look like? Not a language retrofitted with type hints or gradual typing, but one built around the two-layer architecture this new paradigm demands.

### The User Layer: Declarative Intent

At the surface, the human programmer works with a highly declarative interface focused on business logic and invariants:

```
service UserManagement {
  invariant: suspended_users_cannot_login
  invariant: email_addresses_are_unique

  type User {
    email: Email  &#x2F;&#x2F; validated format
    status: Active | Suspended | Deleted
    created: Timestamp
  }

  constraint discount_calculation {
    &#x2F;&#x2F; Human-readable business rules
    if user.lifetime_value &gt; $10000 then discount = 20%
    else if user.tenure &gt; 2.years then discount = 15%
    else discount = 10%

    ensure: discount &gt;= 0% and discount &lt;= 25%
    ensure: vip_users_get_at_least(15%)
  }

  behavior authenticate(email: Email, password: Password) -&gt; Session {
    requires: user.status == Active
    ensures: session.user.email == email
    ensures: session.expires_at &gt; now()

    &#x2F;&#x2F; Natural language intent
    &quot;Verify the password hash matches stored hash using constant-time comparison.
     Generate a session token with 24-hour expiry.
     Log the successful authentication event.&quot;
  }
}
```

Notice what the human specifies:

- **Invariants** that must always hold across the system
- **Constraints** with explicit business logic in near-natural language
- **Types** that encode domain concepts, not implementation details
- **Contracts** (requires&#x2F;ensures) that specify behavior precisely
- **Intent** in natural language for implementation details

Notice what the human doesn&#x27;t specify:

- How to hash passwords
- What data structure to use for session storage
- Memory management or lifetimes
- Error handling boilerplate
- Threading or concurrency primitives

### The Substrate Layer: Rich Type System for Verification

Under the hood, the AI generates code in a target language with strong verification properties - something like a fusion of Rust&#x27;s ownership system, Haskell&#x27;s type system, and Coq&#x27;s theorem proving:

```rust
&#x2F;&#x2F; Generated by AI, hidden from user
struct User&lt;&#x27;lifetime&gt; {
    email: Verified&lt;Email, UniqueConstraint&lt;UserTable&gt;&gt;,
    status: UserStatus,
    created: Timestamp,
    _phantom: PhantomData&lt;&amp;&#x27;lifetime ()&gt;
}

impl&lt;&#x27;db&gt; UserService&lt;&#x27;db&gt; {
    fn authenticate(
        &amp;self,
        email: Verified&lt;Email, FormatValid&gt;,
        password: Password&lt;Unverified&gt;
    ) -&gt; Result&lt;Session&lt;&#x27;db&gt;, AuthError&gt;
    where
        &#x27;db: &#x27;static,
    {
        &#x2F;&#x2F; Type system ensures:
        &#x2F;&#x2F; - Email format is valid (checked at boundary)
        &#x2F;&#x2F; - Password will be constant-time compared
        &#x2F;&#x2F; - Session lifetime tied to database connection
        &#x2F;&#x2F; - All invariants preserved through types

        let user = self.repo.find_by_email(email)
            .ok_or(AuthError::UserNotFound)?;

        &#x2F;&#x2F; Verify status through type system
        let active_user: Active&lt;User&gt; = user.try_into()
            .map_err(|_| AuthError::UserSuspended)?;

        verify_password_constant_time(password, active_user.password_hash)?;

        let session = Session::new(active_user, Duration::hours(24));
        self.audit_log.record(AuthEvent::Success { user_id: session.user.id });

        Ok(session)
    }
}
```

The generated code is densely typed:

- `Verified&lt;Email, UniqueConstraint&lt;UserTable&gt;&gt;` ensures emails are both valid format and unique in the database
- `Active&lt;User&gt;` is a type-level proof that the user&#x27;s status is Active
- Lifetimes ensure sessions can&#x27;t outlive their database connections
- Phantom types carry invariants through the type system
- The constant-time comparison is enforced by types--&gt;
&lt;h3 id=&quot;the-compiler-s-job-verification-and-translation&quot;&gt;The Compiler&#x27;s Job: Verification and Translation&lt;&#x2F;h3&gt;
&lt;p&gt;The AI compiler should do several things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Translates intent to implementation&lt;&#x2F;strong&gt;: Natural language becomes properly structured code&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Generates verification artifacts&lt;&#x2F;strong&gt;: Adds phantom types, lifetime annotations, proofs&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Enforces contracts&lt;&#x2F;strong&gt;: Ensures all &lt;code&gt;requires&lt;&#x2F;code&gt; and &lt;code&gt;ensures&lt;&#x2F;code&gt; clauses are satisfied&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Iterates on errors&lt;&#x2F;strong&gt;: When the verification layer rejects code, the AI regenerates until it passes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Optimizes silently&lt;&#x2F;strong&gt;: Chooses efficient data structures and algorithms within the constraints&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Builds internal verification tooling&lt;&#x2F;strong&gt;: Adds progressively more verification to the application to test against new additions that validate the semantic correctness the type system can&#x27;t guarantee&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This last point is crucial. Good LLM-assisted design doesn&#x27;t just generate code that satisfies a type checker - it also generates the verification infrastructure to check semantic properties. When you specify &lt;code&gt;ensure: vip_users_get_at_least(15%)&lt;&#x2F;code&gt; in your discount calculation constraint, the system should generate property-based tests that verify this holds across thousands of randomized inputs. When you declare &lt;code&gt;invariant: suspended_users_cannot_login&lt;&#x2F;code&gt;, the system should generate integration tests that attempt to authenticate suspended users and verify they&#x27;re rejected.&lt;&#x2F;p&gt;
&lt;p&gt;The LLM can generate both the implementation and the verification tooling in parallel, using the same declarative specifications. Your business logic constraints become executable tests. Your invariants become runtime assertions in debug builds and fuzzing targets. The type system catches structural errors, and the generated verification tooling catches semantic errors.&lt;&#x2F;p&gt;
&lt;p&gt;This is another advantage of working at the right abstraction level. When humans write tests, we often skip edge cases or forget to test invariants we assume are obvious. When an LLM generates verification tooling from explicit invariant declarations, it can be exhaustive. It doesn&#x27;t get bored writing the hundredth property test. It will happily generate comprehensive test suites that check every stated constraint from every angle, because constraints are just another kind of specification to translate into code.&lt;&#x2F;p&gt;
&lt;p&gt;The human never sees most compiler errors. The AI iterates in the background until the generated code satisfies all the invariants and type constraints. What the human sees is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;✓ Constraint discount_calculation verified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;✓ Invariant suspended_users_cannot_login enforced at type level&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;✓ Session lifetime safety proven&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;✓ All authentication paths preserve invariants&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or, if there&#x27;s a semantic issue the type system can&#x27;t catch:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;⚠ Warning: discount_calculation may overflow for lifetime_value &amp;gt; $9,999,999,999&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Suggest: Add explicit bounds to user.lifetime_value type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;⚠ Potential performance issue: authenticate() performs O(n) scan on user table&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Suggestion: Add index on email column (migrations&#x2F;add_email_index.sql)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;properties-of-ai-native-languages&quot;&gt;Properties of AI-Native Languages&lt;&#x2F;h3&gt;
&lt;p&gt;This two-layer architecture enables several key properties:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;For humans:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Write mostly declarative specifications&lt;&#x2F;li&gt;
&lt;li&gt;See business logic clearly concentrated&lt;&#x2F;li&gt;
&lt;li&gt;Get semantic feedback about domain issues&lt;&#x2F;li&gt;
&lt;li&gt;The compiler is not your problem&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;For LLMs:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Clear contracts to satisfy through types&lt;&#x2F;li&gt;
&lt;li&gt;Rich type system to iterate against&lt;&#x2F;li&gt;
&lt;li&gt;Mechanical verification of correctness&lt;&#x2F;li&gt;
&lt;li&gt;Freedom to explore implementation space&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;For the system:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Provably correct by construction&lt;&#x2F;li&gt;
&lt;li&gt;Performance optimizations without sacrificing safety&lt;&#x2F;li&gt;
&lt;li&gt;Refactoring is automated - change a constraint, AI updates all implementations&lt;&#x2F;li&gt;
&lt;li&gt;Testing focuses on business logic, not mechanical correctness&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-gap-today&quot;&gt;The Gap Today&lt;&#x2F;h3&gt;
&lt;p&gt;We&#x27;re not there yet. Current AI coding tools work with languages designed for humans writing code character by character. But the bones of this vision exist: Rust&#x27;s type system, Liquid Haskell&#x27;s refinement types, Dafny&#x27;s verification, even SQL&#x27;s declarative nature. What&#x27;s missing is the integration - a language where the human interface is intent and contracts, the machine interface is rich types and proofs, and AI bridges the gap.&lt;&#x2F;p&gt;
&lt;p&gt;Early evidence suggests this approach is viable. Anthropic&#x27;s experience &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.anthropic.com&#x2F;engineering&#x2F;building-c-compiler&quot;&gt;building a C compiler in Rust with Claude&lt;&#x2F;a&gt; demonstrated exactly this dynamic: the LLM patiently iterated through Rust&#x27;s strict type system and borrow checker, generating code until it satisfied all the constraints. The compiler&#x27;s mechanical feedback guided the AI toward correct implementations, catching entire classes of bugs that would have been subtle runtime errors in C. The developers focused on architectural decisions and correctness of the parsing logic, while Claude fought the borrow checker.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion-embracing-the-pedantic&quot;&gt;Conclusion: Embracing the Pedantic&lt;&#x2F;h2&gt;
&lt;p&gt;This isn&#x27;t a compromise or a trade-off. It&#x27;s a synthesis. We get the benefits of flexible, natural-language-driven development without sacrificing correctness or maintainability. We (humans) write less boilerplate than ever, but the underlying code is verified to be consistent.&lt;&#x2F;p&gt;
&lt;p&gt;The definition of ergonomic software development has changed. Languages and tools that felt heavyweight in the era of human-only coding &lt;strong&gt;are the lightweight choice&lt;&#x2F;strong&gt; in the era of AI-assisted coding. When you didn&#x27;t write the code yourself, you want as many guarantees as possible. Hoping that an agent writes perfect Python every time is a gamble. The future of programming isn&#x27;t choosing between velocity and safety - it&#x27;s using formal systems to verify stochastic processes, and that combination is more ergonomic than either approach alone.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;an-aside-llms-as-an-abstraction-layer-2-9-26&quot;&gt;An aside: LLMs as an abstraction layer (2&#x2F;9&#x2F;26)&lt;&#x2F;h2&gt;
&lt;p&gt;Writing assembly is an enlightening experience. Anything is possible, but it&#x27;s tedious, hard to reason about system state, and errors are easy to make, severe, and difficult to debug (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;courses.grainger.illinois.edu&#x2F;ece391&#x2F;sp2025&#x2F;&quot;&gt;as anyone who has taken ECE 391 at UIUC can attest&lt;&#x2F;a&gt;). The burden of reasoning about system state falls entirely on the programmer. Yet assembly is far preferable to writing raw machine code or having to build an ASIC by hand.&lt;&#x2F;p&gt;
&lt;p&gt;The stack machine abstraction built on assembly enables code reuse through strict conventions (like the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;X86_calling_conventions&quot;&gt;C calling convention&lt;&#x2F;a&gt;). By imposing limitations through contract—register usage, stack management—two disjoint codebases can be merged to create more complex systems. C adds another abstraction layer with its type system, memory management, and abstract system definition, meaning many developers never need to think about how many bits are in an integer or where a local variable is stored in memory. Objects, methods, and interfaces introduce further contracts that make systems easier to reason about. The operating system provides a common virtual environment for multiple userland programs to interact with hardware concurrently. The GUI offers a graphical language for managing operating system state, creating a more intuitive interface.&lt;&#x2F;p&gt;
&lt;p&gt;Each abstraction layer imposes rigid rules on what is allowed that may at first feel limiting, while providing a solid foundation for building higher-order applications. The abstraction layer enforces these rules, ensuring the system remains consistent and predictable. What&#x27;s missing now is a composable contract system that allows LLMs to expose a higher level of abstraction to developers with the same strong guarantees that existing abstraction layers provide.&lt;&#x2F;p&gt;
&lt;p&gt;(Relevant discussion: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;oxide-and-friends.transistor.fm&#x2F;episodes&#x2F;software-engineering-past-present-and-future-with-grady-booch&quot;&gt;Software Engineering Past, Present, and Future with Grady Booch&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Understanding the Waypoint Transformer</title>
          <pubDate>Sun, 27 Oct 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/waypoint-transformer/</link>
          <guid>https://www.narendasan.com/blog/waypoint-transformer/</guid>
          <description xml:base="https://www.narendasan.com/blog/waypoint-transformer/">&lt;h1 id=&quot;waypoint-transformer&quot;&gt;Waypoint Transformer&lt;&#x2F;h1&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;openreview.net&#x2F;pdf?id=BYywOFbRFz&quot;&gt;Waypoint Transformer&lt;&#x2F;a&gt; was published at NeuRIPS 2023 by Badrinath et. al. and is a new method for Reinforcement learning via supervised learning (RvS) that builds on the prior &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2106.01345&quot;&gt;Decision Transformer&lt;&#x2F;a&gt; and is conditioned on automatically generated waypoints.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;online-vs-offline-reinforcement-learning&quot;&gt;Online vs Offline Reinforcement Learning&lt;&#x2F;h3&gt;
&lt;p&gt;In reinforcement learning, the agent learns to interact with an environment by taking actions and observing the results. The agent&#x27;s goal is to maximize the cumulative reward it receives over time. The agent learns by trial and error, exploring the environment and learning from its experiences. There are two large classes of approach to reinforcement learning: online and offline. Online reinforcement learning interacts with the environment in real-time, while offline reinforcement learning learns from collected prior experiences interacting with the environment.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;supervised-reinforcement-learning-rvs&quot;&gt;Supervised Reinforcement Learning (RvS)&lt;&#x2F;h3&gt;
&lt;p&gt;Value-based offline methods tend to attempt to learn a pessimistic value estimate for different states in the state space or state action pairs. This is used to estimate the expected return of a policy. Alternatively, model-based offline RL methods estimate the dynamics of the environment and use it to plan. Typically, complex hyperparameter tuning is required to achieve stable learning.&lt;&#x2F;p&gt;
&lt;p&gt;Reinforcement learning via supervised learning (RvS), builds off behavioral cloning as a simple alternative to traditional offline RL. This removes the need for Temporal Difference (TD) learning and value functions and allows offline RL to reuse methods from supervised learning. Typically, the conditioning variable for the policy is based off the return, goal-conditioning, or inverse reinforcement learning,&lt;&#x2F;p&gt;
&lt;p&gt;RvS has historically struggled in tasks where the agent must combine multiple sub-optimal training trajectories to achieve a goal. The Waypoint Transformer paper points to two notable examples: reaching specific locations in AntMaze and completing a series of tasks in FrankaKitchen. Here, prior TD methods such as Implicit Q-learning outperform RvS methods.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;waypoint-transformer-1&quot;&gt;Waypoint Transformer&lt;&#x2F;h2&gt;
&lt;p&gt;The Waypoint Transformer introduces a method for generating intermediate goals and more stable proxy rewards that guide the policy towards objectives. Then they use a transformer based RvS method on the generated sub-goals to obtain a policy that learns to follow the waypoints improving performance and stability vs other offline RL methods.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setting&quot;&gt;Setting&lt;&#x2F;h3&gt;
&lt;p&gt;Using the Markov Decision Process (MDP) setting, with states $s_t \in \mathcal{S}$, $a_t \in \mathcal{A}$, unknown dynamics $p(s_{t+1} | s_t, a_t)$ and initial state distribution $p(s_0)$, the agent chooses an action $a_t \sim \pi_{\theta}(a_t | s_{t-k..t}, \Phi_{t-k..t})$, parameterized by $\theta$ and conditioned on a known history of states $s_{t-k..t}$ and a conditioning variable $\Phi_{t-k..t}$ that could encode goals or rewards based on a target global outcome $\omega$.&lt;&#x2F;p&gt;
&lt;p&gt;This is distinct from the traditional RL setting where the policy is modeled on $\pi(a_t | s_t)$, as the policy is modeled using a transformer which accepts the past states in a fixed sized context window $k$. The choice of $\omega$ during training is sampled from data. At test time, it is assumed that $\omega$ can be generated or provided by global goal information for a goal-conditioned variant or simply a target reward in the reward-conditioned variant.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;waypoints&quot;&gt;Waypoints&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;waypoint-transformer&#x2F;imgs&#x2F;basic_mdp.png&quot; alt=&quot;basic_mdp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In offline RL, data typically does not encompass all possible cases that an agent may want to achieve in testing. Consider a infinite dataset $\mathcal{D}$ that is collected by a random behavior policy $\pi_{b}(a_t|s_t)$. When looking to achieve a goal $\omega = s^{(H)}$, the random policy will be suboptimal since actions are selected at random. Then when using a goal conditioned policy $\pi_{G}(a_t|s_t,\omega)$ that is trained using demonstrations from $\mathcal{D}$, the policy will also be suboptimal since $\omega$ is fixed, so $\forall s \in \mathcal{S},$ $\pi_{G}(a_t|s_t,\omega) = \pi_{b}(a_t|s_t)$. So a global goal-conditioned policy cannot be any better than the random behavior policy it was trained on.&lt;&#x2F;p&gt;
&lt;p&gt;Instead consider a policy that uses intermediate goals $\pi_{W}(a_t|s_t, \Phi_t)$, $\Phi_t = s_{t+k}$. The paper shows that the probability of choosing an optimal action is higher compared to the longer-horizon goal conditioned policy. $\Phi_t$ also serves as a guide as it guides the policy towards strong intermediate targets to reach the global goal. As long as the selected waypoints are strong ones that lead towards the goal $\omega$, the expectation on policy will be more optimal than behavior cloning.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;stitching-waypoints&quot;&gt;Stitching Waypoints&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;waypoint-transformer&#x2F;imgs&#x2F;region_crossing.png&quot; alt=&quot;region_crossing&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The ability to compose sequences of otherwise suboptimal trajectories requires finding experiences that are more relevant to achieving subgoals vs the overall goal. The paper uses AntMaze to demonstrate this. They find that only 5% of trajectories using a &lt;em&gt;random policy&lt;&#x2F;em&gt; (this is unclear in the paper) would demonstrate how to cross between a start region and the target region. It is therefore very unlikely to find a trajectory that goes from the start state to the goal state. The policy must stitch together trajectories that start at the start state with trajectories that end at the goal state. By providing waypoints in the stitching regions the policy can be guided to connect the relevant sub-sequences together.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;generating-waypoints-goal-conditioned-rvs&quot;&gt;Generating Waypoints (Goal-conditioned RvS)&lt;&#x2F;h3&gt;
&lt;p&gt;The paper uses a waypoint generator that makes $k$ step ahead predictions of future observations conditioned on $s_t$ and $\omega$. This is parameterized as a neural network that is trained on the same offline dataset $\mathcal{D}$ as the policy using MSE loss.&lt;&#x2F;p&gt;
&lt;p&gt;$$
arg\min_{\phi} \sum_{(s_t, \omega) \in \mathcal{D}} || W_{\phi}(s_t, \omega) - s_{t+k} ||^2_2
$$&lt;&#x2F;p&gt;
&lt;p&gt;By doing this you are learning which states $k$ steps ahead you want to visit to reach a goal $\omega$ and then use this to guide the policy. The assumption is that you will have a strong demonstration of the policies to cross $k$ steps from any particular state to other states $k$ steps away.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;generating-proxy-rewards-reward-conditioned-rvs&quot;&gt;Generating Proxy Rewards (Reward-conditioned RvS)&lt;&#x2F;h3&gt;
&lt;p&gt;Prior methods use cumulative reward to-go (CRTG) - a dynamic estimate of the reward to go or average reward-to-go (ARTG) - a static estimate of the reward to go as proxy rewards for the policy. However, using these conditioning variables has drawbacks: the variance of cumulative reward-to-go is high and the bias of the average reward-to-go is high. Instead of using a learned value function like in TD methods, this paper adds a reward waypoint network to estimate both cumulative and average reward-to-go conditioned on $s_t$ and $\omega$ using $\mathcal{D}$. They claim that modeling both CRTG and ARTG addresses the high bias of ARTG and the high variance of CRTG in the same way that prior methods like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;article&#x2F;10.1007&#x2F;BF00992696&quot;&gt;REINFORCE&lt;&#x2F;a&gt; do.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;policy-transformer&quot;&gt;Policy Transformer&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;waypoint-transformer&#x2F;imgs&#x2F;wt.png&quot; alt=&quot;policy_transformer&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The architecture for the waypoint transformer is based on GPT-2. The policy is conditioned on the past $k$ states and the waypoints (either the goals or rewards) $\Phi_{t - k..t}$ which are generated by the waypoint network. The policy transformer is trained using negative log likelihood loss based on data sampled from $\mathcal{D}$. During this process, the waypoint network is fixed. Unlike decision transformers, the waypoint transformer is not conditioned on past actions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experiments&quot;&gt;Experiments&lt;&#x2F;h2&gt;
&lt;p&gt;The proposed method is evaluated on two environments that come with many suboptimal demonstrations in the goal-conditioned case: AntMaze and FrankaKitchen. FrankaKitchen specifically has no end to end demonstrations available. For each of these environments, the paper uses goal conditioning where $\omega = s_{target}$ and constructs intermediate waypoints using the goal waypoint network. For reward-conditioned tasks they use Gym-MuJoCo. For a plurality of evaluated tasks, waypoint transformers outperform decision transformers and other offline RL methods. However there are some cases where TD still outperforms the waypoint transformer or that waypoint transformer simply matches the performance of behavior cloning.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;waypoint-transformer&#x2F;imgs&#x2F;wps.png&quot; alt=&quot;wps&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The authors analyze the behavior of the waypoint transformer on AntMaze, they find that WT is much more effective at reaching the goal state than a globally conditioned policy and completes the task faster. When using $k = 30$ vs. $k = 0$, the performance is 2.2x worse.&lt;&#x2F;p&gt;
&lt;p&gt;On reward conditioned tasks the authors analyze the behavior of the waypoint transformer on Hopper-v2. They find that the standard deviation of CRTG grows slower than other methods. WT is also more robust to the choice of seed than other methods.&lt;&#x2F;p&gt;
&lt;p&gt;Interestingly in the appendix, they evaluated using manually selected waypoints and found that WT outperforms manual waypoints. However the manual waypoints are still better than no waypoints and the difference seems to come down to the density of waypoints selected. The manual waypoints are much coarser than the waypoints selected by the waypoint network.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-this-matters&quot;&gt;Why This Matters&lt;&#x2F;h3&gt;
&lt;p&gt;The real usefulness of this method is to be able to collect a lot of partial demonstrations of relevant trajectories, then allow the waypoint network guide the policy to compose them together to achieve a goal in an environment with sparse rewards where traditional RL methods would struggle or would require much higher quality data. RvS is a compelling method for RL since it does not require learning a value function which is incredibly sensitive to initialization and requires a lot of data to learn. The issue with prior RvS methods is that they rely on the quality of the demonstrations to be able to learn a good policy. Behavior cloning and imitation learning methods alone are unable to utilize partial demonstrations as well, requiring demonstrations that fully explain how to achieve a goal. This makes data collection incredibly expensive and time consuming particularly when goal and start states are not fixed. Waypoint transformers demonstrate a method to learn from partial demonstrations and compose them together to achieve a goal. However, waypoint transformers are a method designed to handle degenerate cases. In cases where demonstrations are complete, waypoint transformers are not necessary and their performance will be similar to behavior cloning or decision transformers. This paper focuses on spatial composability and reward interpolation, it is unclear how well waypoint transformers are able to compose over other dimensions such as skill chaining.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Building CLIP from Scratch to Classify Pokemon</title>
          <pubDate>Mon, 07 Oct 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/pokemon-clip/</link>
          <guid>https://www.narendasan.com/blog/pokemon-clip/</guid>
          <description xml:base="https://www.narendasan.com/blog/pokemon-clip/">&lt;h1 id=&quot;building-clip-from-scratch-to-classify-pokemon&quot;&gt;Building CLIP from Scratch to Classify Pokemon&lt;&#x2F;h1&gt;
&lt;p&gt;Prior deep learning approaches to performing image classification frame the problem as given a
dataset of image, label pairs, learn a mapping between the image space and the label space using
a neural network (MLP, CNN, etc.). Here the image space is typically a CxHxW dimensional space
where C is the number of channels, H and W are the height and width of the input image. Labels
may have semantic meaning to us as humans, but are presented to the model simply as one-hot
encoded vectors in a fixed sized N-D space where N is the number of possible different labels
that can be seen in the dataset. Each dimension of the label space is assigned a distinct
possible label, and the models output in that any particular dimension represents the models
confidence that the image is of that class. Extremely good performance on classification tasks
can be achieved using this problem framing and a good choice of model architecture. However,
this framing has drawbacks when trying to move out of narrow independent and identically
distributed settings, such as classification of images that are of a class not seen before
or dealing with slightly differently formed labels. In such cases, the model is unaware of
the existence of anything other than the N classes it was designed to decide between. Even
if it was, it would not be able to represent a novel class due to its fixed sized output and
the assigned semantic meanings to each dimension.&lt;&#x2F;p&gt;
&lt;p&gt;More recently, self-supervised methods have emerged which use simple scalable training tasks
to create models that can easily be repurposed for a number of different tasks. Many of these
methods avoid the use fixed sized label spaces instead looking to embed representations of
different modalities of data in a common embedding space. Distance in this embedding space
represents “sameness”. These models look to therefore project tuples of related data into the
same area in embedding space. Unseen labels or classes can be projected into this embedding
space just as easily as seen data, so even if the model has not seen that exact label before,
it its embedding should be close to similar seen labels and consequently their corresponding images.&lt;&#x2F;p&gt;
&lt;p&gt;One of these methods is Contrastive Language-Image Pre-training (CLIP). CLIP looks to take image
and text pairs such as captions for an image or alt-text and estimate how related they are by
this projection into a common embedding space. As opposed to “traditional” classification approaches,
CLIP is not attempting to solve the classification problem directly. It instead looks to maximize
the cosine similarity between correct image text pairs in the joint embedding space and minimize
the similarity between incorrect pairs. CLIP can then be repurposed for classification by giving
the model the choice between a number of potential captions (or labels) for an unseen image. The
caption with the highest cosine similarity can be considered the class, leading to what is known
“open world” object recognition. In this tutorial, we will learn how to create our own CLIP model
and use it to classify images of Pokemon.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-clip-model&quot;&gt;The CLIP Model&lt;&#x2F;h2&gt;
&lt;p&gt;The CLIP model consists of a text encoder and an image encoder. Since the ultimate goal is to be
able pair image embeddings with their corresponding text embeddings, these two models are trained
together to maximize the pairwise cosine similarities between corresponding image and text embeddings
and conversely minimize the cosine similarity between image and text embeddings from different pairs.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; CLIP&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; emb_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; vit_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; img_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; n_channels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; vit_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; vit_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; vocab_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; text_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; text_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; text_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span&gt;__init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;image_encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; ImageEncoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;vit_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; img_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; n_channels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vit_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vit_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; emb_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;text_encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; TextEncoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;vocab_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; emb_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;temperature&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Parameter&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ones&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; np&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0.07&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;cuda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;cuda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;is_available&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        I_e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;image_encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        T_e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;text_encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # scaled pairwise cosine similarities [n, n]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        logits&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;I_e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; @&lt;&#x2F;span&gt;&lt;span&gt; T_e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;transpose&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;temperature&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # symmetric loss function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;arange&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;logits&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        loss_i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;functional&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cross_entropy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;logits&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;transpose&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        loss_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;functional&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cross_entropy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;logits&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;loss_i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; loss_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; loss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you don’t know what text or image encoders are, you might want to follow a more bottom-up CLIP
tutorial that first develops these concepts: https:&#x2F;&#x2F;medium.com&#x2F;correll-lab&#x2F;building-clip-from-scratch-68f6e42d35f4&lt;&#x2F;p&gt;
&lt;h3 id=&quot;text-encoder&quot;&gt;Text Encoder&lt;&#x2F;h3&gt;
&lt;p&gt;For the text encoder in CLIP we use the standard transformer architecture. However we want to embed
features in the joint vision-text embedding space. Therefore we have an extra set of parameters
&lt;code&gt;nn.Parameter(torch.randn(width, emb_dim))&lt;&#x2F;code&gt;. In the forward function, the text features are
embedded in the joint space by getting the dot product of the features and the learned
projection divided by the normalized dot product.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; TextEncoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; vocab_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; n_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; n_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; emb_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span&gt;__init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  # Maximum length of input sequence&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encoder_embedding&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Embedding&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;vocab_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; # Embedding Table&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;positional_embedding&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; PositionalEmbedding&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ModuleList&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;TransformerEncoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;n_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;n_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # learned proj of image to embed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;projection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Parameter&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;randn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; emb_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Text Embedding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;encoder_embedding&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Positional Embedding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;positional_embedding&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Transformer Encoder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; encoder_layer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; encoder_layer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Takes features from the EOT Embedding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;arange&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]),&lt;&#x2F;span&gt;&lt;span&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;sub&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[:,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # joint multimodal embedding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;projection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; is not&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;projection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;norm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; keepdim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;image-encoder&quot;&gt;Image Encoder&lt;&#x2F;h3&gt;
&lt;p&gt;For the image encoder we use the standard vision transformer architecture. Similar to the text encoder,
we have an extra set of parameters &lt;code&gt;nn.Parameter(torch.randn(width, emb_dim))&lt;&#x2F;code&gt;, the forward function
will embed the image features in the joint embedding space by taking the dot product of the features
and the learned projection divided by the normalized dot product.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; ImageEncoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; img_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; n_channels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; n_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; n_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; emb_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span&gt;__init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt; img_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span&gt; patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; img_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span&gt; patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;img_size dimensions must be divisible by patch_size dimensions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt; width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span&gt; n_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;width must be divisible by n_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;n_patches&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;img_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; img_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;n_patches&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Patch Embedding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;linear_project&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Conv2d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;n_channels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; kernel_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; stride&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Classification Token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;cls_token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Parameter&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;randn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;positional_embedding&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; PositionalEmbedding&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ModuleList&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;TransformerEncoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;n_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;n_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # learned proj of image to embed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;projection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Parameter&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;randn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; emb_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Patch Embedding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;linear_project&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;flatten&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;transpose&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Positional Embedding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;cls_token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;expand&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;positional_embedding&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Transformer Encoder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; encoder_layer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; encoder_layer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Takes Class Tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[:,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, :]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # joint multimodal embedding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;projection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; is not&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;projection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;norm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; keepdim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;training&quot;&gt;Training&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;pokemon-clip&#x2F;imgs&#x2F;clip_training.webp&quot; alt=&quot;clip_training&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The training process consists of providing image, caption pairs from the dataset. CLIP uses contrastive
loss to train the model. Since we are looking to maximize the scaled pairwise cosine similarities
between the image and text embeddings along the diagonal where the text and image embeddings are correctly
paired, we can use cross entropy loss across the rows and columns with psuedo-labels corresponding to the
index of the embedding. This is the same as evaluating $n$ distinct text -&amp;gt; image estimates
and $n$ image -&amp;gt; text estimates concurrently. The model loss is the mean loss between the text and
image cross entropy loss.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;arange&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;logits&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Label for row&#x2F;column i is i (i.e. the index of the correct other half of the pair)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;loss_i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;functional&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cross_entropy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;logits&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;transpose&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;loss_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;functional&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cross_entropy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;logits&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;loss_i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; loss_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;dataset&quot;&gt;Dataset&lt;&#x2F;h3&gt;
&lt;p&gt;For this tutorial we will use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;huggingface.co&#x2F;fcakyon&quot;&gt;Faith Aykon&lt;&#x2F;a&gt;&#x27;s
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;huggingface.co&#x2F;datasets&#x2F;fcakyon&#x2F;pokemon-classification&quot;&gt;Mini-Pokemon dataset&lt;&#x2F;a&gt;, hosted on HuggingFace
(this requires &lt;code&gt;datasets==2.21.0&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;This dataset consists of 280 examples in a 210&#x2F;70 train&#x2F;test split. The full dataset has 7000 images but as
such takes much longer to train, though the code can be trivially modified to use the full dataset&lt;&#x2F;p&gt;
&lt;p&gt;We will perform a number of modifications to this dataset to make it more suitable to training for CLIP.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; torchvision&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;transforms&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Pokemon&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;Dataset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; train&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Download the dataset from HuggingFace, use the mini split (change &amp;quot;mini&amp;quot; to &amp;quot;full&amp;quot; for the full dataset)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;dataset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; load_dataset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;fcakyon&#x2F;pokemon-classification&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;mini&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; trust_remote_code&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        # Image preprocessing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;transform&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; v2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Compose&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;            v2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Resize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;128&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 128&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;            v2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ToTensor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        ])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; train&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;train&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;label_names&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;dataset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;].&lt;&#x2F;span&gt;&lt;span&gt;features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;].&lt;&#x2F;span&gt;&lt;span&gt;names&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;caption_options&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; [&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;An image of &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;A photo of &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; in a photo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;A picture of &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;captions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;quot;An image of a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;label_names&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;label_names&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __len__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;dataset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;num_rows&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __getitem__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;dataset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;transform&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        caption_template&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;random&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;choice&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;caption_options&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        caption_text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; caption_template&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;dataset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;]])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; tokenizer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;caption_text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;repeat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt; img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;caption&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt; cap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt; caption_text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;label&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;dataset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;]}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;image-preprocessing&quot;&gt;Image Preprocessing&lt;&#x2F;h4&gt;
&lt;p&gt;We define a transformation pipeline which gets applied to each image using&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;transform&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; v2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Compose&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;    v2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Resize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;128&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 128&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;    v2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ToTensor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is not too much data augmentation needed for simple cases, therefore we just resize the input image to a reasonable size.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;text-preprocessing&quot;&gt;Text Preprocessing&lt;&#x2F;h4&gt;
&lt;p&gt;The original dataset is set up for more traditional classification approaches, i.e. some class label for each image which is an &lt;code&gt;int&lt;&#x2F;code&gt;
representing the index of the 1 in a one-hot encoded form of the label. Since CLIP uses text and not one-hot encoded vectors for the
“labels”, we need to generate them. The critical information is the type of Pokemon in the image. However, there are many ways in
natural language to convey the same information and we want to be robust to phrasing as it will help our classifier be more
robust later on.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore, we include a number of caption templates that phrase the label in many semantically similar ways. When retrieving
a new image, a label pair is pulled from the dataset, this code will choose one of the caption templates to create a caption
containing the label text.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Pokemon&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __init&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;caption_options&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; [&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;An image of &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;A photo of &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; in a photo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;A picture of &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{0}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __getitem__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    caption_template&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; rng&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;choice&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;caption_options&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    caption_text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; caption_template&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;dataset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;]])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;tokenization&quot;&gt;Tokenization&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;pokemon-clip&#x2F;imgs&#x2F;tokenizing.webp&quot; alt=&quot;tokenizing&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Transformer models do not work directly on text, instead they use a numerical representation of characters (tokens). In this example
we use a trivial tokenization scheme UTF-8.&lt;&#x2F;p&gt;
&lt;p&gt;With the UTF-8 encoding the max vocabulary size is 256 since we are direct mapping from characters. For larger desired context sizes,
other tokenization schemes with greater vocabulary sizes may be desired.&lt;&#x2F;p&gt;
&lt;p&gt;The tokenizer delimits the input string with start and end tokens, reserved values that denote the limits of the input. Since the
input to the transformer is fixed size, the input tensor is padded to the full width of the input. Finally a mask is created to denote
that padded inputs should be ignored.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; tokenizer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; encode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; encode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; chr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; chr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; # Adding SOT and EOT tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&amp;quot;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;join&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;chr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; # Adding Padding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;IntTensor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;utf-8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; # Encoding Text&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ones&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;nonzero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;zeros&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)))).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;IntTensor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;chr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;nonzero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&amp;quot;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;join&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; mask&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These tokenzied forms of the captions are pre-calculated as part of the dataset.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; tokenizer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;caption_text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since the mask will be applied to the attention scores ($max_seq_len x max_seq_len$), it needs to be repeated to be applied to each row.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;repeat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Therefore for each entry in the dataset we have the following information&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt; img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;caption&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt; cap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt; caption_text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;label&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;dataset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;]}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;example&quot;&gt;Example&lt;&#x2F;h5&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;pokemon-clip&#x2F;imgs&#x2F;abra.webp&quot; alt=&quot;abra&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;shape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 128&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 128&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;caption&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;shape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;shape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;A Alakazam image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;caption&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;tokenized&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; tensor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 65&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 112&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 104&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 111&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 116&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 111&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 111&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 102&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 65&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 108&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;97&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 107&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 97&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 122&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 97&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 109&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; dtype&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;int32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; tensor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; …&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; …&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; …&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;…&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; …&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; …&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; …&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; dtype&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;int32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;hyperparameters&quot;&gt;Hyperparameters&lt;&#x2F;h4&gt;
&lt;p&gt;These are the parameters I used for training on a 3080Ti. The notebook contains these parameters and the seed I used.
Some modifications to the batch size might be needed if training on smaller GPUs.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;emb_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vit_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;img_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;128&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;128&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;n_channels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vit_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vit_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vocab_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;text_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;text_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;text_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1e-3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;epochs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1500&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;batch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1024&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;training-loop&quot;&gt;Training Loop&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;cuda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;cuda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;is_available&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Using device: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;quot;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;cuda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;get_device_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;)&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;cuda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;is_available&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; CLIP&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;emb_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vit_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; img_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; n_channels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vit_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vit_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vocab_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;optimizer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; optim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Adam&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;parameters&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; lr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;lr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;best_loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;inf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; epoch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;epochs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;train_loader&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; cap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;caption&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;cap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        optimizer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;zero_grad&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;backward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        optimizer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    # Saves model if it performed better than the previous best&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;quot;Epoch [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;epoch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;epochs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;], Batch Loss: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;item&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;:.3f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;item&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; best_loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        best_loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;item&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;save&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;state_dict&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(), &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;clip_pokemon4.pt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Model Saved.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;testing-performance&quot;&gt;Testing Performance&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;pokemon-clip&#x2F;imgs&#x2F;clip_inference.webp&quot; alt=&quot;clip_inference&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can evaluate how well our model is at associating image text pairs. We start by creating a spanning set of captions
for the different possible labels using one a slightly different caption form from those seen in training (ex. ”An
image of a Pikachu”). This was actually done as part of the dataset construction:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;captions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;quot;An image of a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;label_names&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each of these potential captions is tokenzied using the tokenizer and fed to the text encoder and a batch of images from the
test set are fed into the image encoder.&lt;&#x2F;p&gt;
&lt;p&gt;We then calculate the cosine similarity between the text and image embeddings and run softmax to get probabilities that any
particular label is the best pairing for a particular image.&lt;&#x2F;p&gt;
&lt;p&gt;We can then match these predicted captions with the true label to determine if the model was correct or not.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Loading Best Model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; CLIP&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;emb_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vit_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; img_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; n_channels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vit_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vit_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vocab_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;load_state_dict&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;load&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;clip_pokemon4.pt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; map_location&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Getting dataset captions to compare images to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;tokenizer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; test_set&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;captions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;values&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()]).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;tokenizer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; test_set&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;captions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;values&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;repeat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;reshape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;correct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; total&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;no_grad&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; test_loader&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        images&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;label&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        image_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;image_encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;images&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        text_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;text_encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        image_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &#x2F;=&lt;&#x2F;span&gt;&lt;span&gt; image_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;norm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; keepdim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        text_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &#x2F;=&lt;&#x2F;span&gt;&lt;span&gt; text_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;norm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; keepdim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        similarity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;100.0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;image_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; @&lt;&#x2F;span&gt;&lt;span&gt; text_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;T&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;softmax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; indices&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;similarity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        correct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;indices&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        total&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Model Accuracy: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{100&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; correct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; total&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; %&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using my training settings and seed, I was able to achieve 87% accuracy on the Pokemon-mini dataset. This is not really representative for C
LIP’s power, as the dataset we have used for training here is very small. Using a CNN would actually be the preferred approach
here. Yet, for very large datasets CLIP has outperformed previous CNN model.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;zero-shot-classification&quot;&gt;Zero-shot Classification&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;pokemon-clip&#x2F;imgs&#x2F;result.webp&quot; alt=&quot;result&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can reuse our CLIP model to perform the classification task now. First we generate a list of possible labels. These will just be names of
different types of Pokemon found in the dataset (ex. ”Pikachu”). We then tokenize each potential label and feed them to the text encoder. We
also feed an unlabeled image to the image label. The CLIP model will return the similarities between each potential label and the image based
on the training it had seen before. Note that we never just provide the label alone as a text pairing during training, but we do provide
various different captions which all share the label word within them. This demonstrates how, because of our pre-training, we are robust to
unseen label forms and yet can correctly associate the image with the correct label.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Loading Best Model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; CLIP&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;emb_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vit_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; img_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; patch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; n_channels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vit_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vit_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; vocab_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; max_seq_length&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_heads&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; text_layers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;load_state_dict&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;load&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;clip_pokemon4.pt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; map_location&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Captions to compare images to&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;class_names&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; test_set&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;label_names&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;class_text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; class_names&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;tokenizer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; class_text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;tokenizer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; class_text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;repeat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;reshape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;idx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; test_set&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;idx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,:]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;plt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;imshow&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;  img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;permute&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;plt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;title&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;test_set&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;idx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;plt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;show&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;no_grad&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  image_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;image_encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  text_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;text_encoder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;text&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;image_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &#x2F;=&lt;&#x2F;span&gt;&lt;span&gt; image_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;norm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; keepdim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;text_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &#x2F;=&lt;&#x2F;span&gt;&lt;span&gt; text_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;norm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; keepdim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;similarity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;100.0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; image_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; @&lt;&#x2F;span&gt;&lt;span&gt; text_features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;T&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;softmax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;values&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; indices&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; similarity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;topk&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Print the result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Top predictions:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; index&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; zip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;values&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; indices&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;class_names&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;index&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;:&amp;gt;16s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;{100&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;item&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;:.2f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;%&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can find a notebook with the code from this tutorial &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;colab.research.google.com&#x2F;drive&#x2F;1tOJDnSeScGTDATwWXxCF9jL8X_V9m9B2&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>All Recommendation Engines Should Follow Twitter&#x27;s Example on Transparency</title>
          <pubDate>Sat, 01 Apr 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/twitter-algo/</link>
          <guid>https://www.narendasan.com/blog/twitter-algo/</guid>
          <description xml:base="https://www.narendasan.com/blog/twitter-algo/">&lt;p&gt;This week has been weird to say the least. We have fringe figures in the artificial intelligence community publishing opinions in Time Magazine on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;time.com&#x2F;6266923&#x2F;ai-eliezer-yudkowsky-open-letter-not-enough&#x2F;&quot;&gt;the need to take violent action to stop the propagation of large language models&lt;&#x2F;a&gt;, but I thought the most important story was &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.twitter.com&#x2F;engineering&#x2F;en_us&#x2F;topics&#x2F;open-source&#x2F;2023&#x2F;twitter-recommendation-algorithm&quot;&gt;Elon Musk and Twitter releasing the source code for their Tweet recommendation system&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;details&gt;
I&#x27;m going to keep referring to this thing as a system or engine. I refuse to call it an algorithm. There are no strong guarantees associated with these systems, they mostly boil down to a collection of heuristics. Calling them an algorithm bastardizes the meaning of the term.
&lt;&#x2F;details&gt;
&lt;br&gt;
&lt;p&gt;There&#x27;s a lot of reasons to be tired of hearing about Twitter and Elon Musk. Twitter is a navel-gazy self important subculture full of &quot;niche internet celebrities&quot; being toxic to each other in one way or another. And Elon oscillates from being out of touch to down right unhinged depending on the hour. However, Twitter and other social media platforms for many, and particularly many who occupy other places of influence in society, serves as their primary lens on the state of the world. Many measure importance of issues, people, ideas etc. based on the traction they garner on these platforms. Therefore, it matters how and why some things are widely promoted and somethings are suppressed.&lt;&#x2F;p&gt;
&lt;p&gt;When Twitter released the source, Elon put out the following Tweet.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Most of the recommendation algorithm will be made open source today. The rest will follow.&lt;br&gt;&lt;br&gt;Acid test is that independent third parties should be able to determine, with reasonable accuracy, what will probably be shown to users.&lt;br&gt;&lt;br&gt;No doubt, many embarrassing issues will be… &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;41U4oexIev&quot;&gt;https:&#x2F;&#x2F;t.co&#x2F;41U4oexIev&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; Elon Musk (@elonmusk) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;elonmusk&#x2F;status&#x2F;1641874582473695246?ref_src=twsrc%5Etfw&quot;&gt;March 31, 2023&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;I do not care what your opinion of him or his actions were, the stated goal &lt;em&gt;&quot;[T]hat independent third parties should be able to determine, with reasonable accuracy, what will probably be shown to users&quot;&lt;&#x2F;em&gt; is a great one and should become the industry standard if not required by law to operate a walled (more on this caveat later) hosted consumer internet service.&lt;&#x2F;p&gt;
&lt;p&gt;The choices these systems make deeply influence society. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Social_media_and_the_Arab_Spring&quot;&gt;Revolutions&lt;&#x2F;a&gt;, political movements, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iiasa.ac.at&#x2F;news&#x2F;oct-2022&#x2F;why-do-covid-19-conspiracy-theories-persist-on-social-media&quot;&gt;conspiracy theories&lt;&#x2F;a&gt; all have been amplified or suppressed based on the opaque decisions of private actors and have effected billions of people with their actions. We do not know to what extent the Arab Spring, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pewresearch.org&#x2F;internet&#x2F;2016&#x2F;08&#x2F;15&#x2F;the-hashtag-blacklivesmatter-emerges-social-activism-on-twitter&#x2F;&quot;&gt;Black Lives Matter&lt;&#x2F;a&gt;, various COVID-19 related conspiracies have been enabled and &quot;unnaturally&quot; propagated or suppressed due to the operation of these recommendation systems. How would &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nytimes.com&#x2F;2018&#x2F;04&#x2F;21&#x2F;world&#x2F;asia&#x2F;facebook-sri-lanka-riots.html&quot;&gt;ethinic relations in South Asia&lt;&#x2F;a&gt; look without content recommendation systems mediating what people see? We have no idea if the stated values of platforms match what they recommend, all we get is little boxes on hot-button issues and handed down judgments from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;techcrunch.com&#x2F;2019&#x2F;01&#x2F;28&#x2F;facebook-drafts-a-proposal-describing-how-its-new-content-review-board-will-work&#x2F;&quot;&gt;unaccountable panels&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This issue applies past the realm of social media. Models control &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nclc.org&#x2F;resources&#x2F;past-imperfect-how-credit-scores-and-other-analyticsbake-in-and-perpetuate-past-discrimination&#x2F;&quot;&gt;access to credit&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.science.org&#x2F;doi&#x2F;10.1126&#x2F;science.aax2342&quot;&gt;access to health care&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hirevue.com&#x2F;blog&#x2F;train-validate-re-train-how-we-build-hirevue-assessments-models&quot;&gt;hiring decisions&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.brookings.edu&#x2F;research&#x2F;enrollment-algorithms-are-contributing-to-the-crises-of-higher-education&#x2F;&quot;&gt;entrance into elite institutions&lt;&#x2F;a&gt;. Most of these systems are entirely black-box. The source data is not available and the modeling is not available. Yet we let these things make meaningful decisions in society.&lt;&#x2F;p&gt;
&lt;p&gt;We get some information from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;about.instagram.com&#x2F;blog&#x2F;announcements&#x2F;shedding-more-light-on-how-instagram-works&quot;&gt;company blog posts&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.washingtonpost.com&#x2F;technology&#x2F;interactive&#x2F;2021&#x2F;how-facebook-algorithm-works&#x2F;&quot;&gt;leaks&lt;&#x2F;a&gt;. But, many try to divine the incentives these models encode in a way reminiscent of a priest trying to divine the will of the Gods. Some say all that matters is engagement - just things that make you feel a strong emotion. Others say that these models try to recommend things that are easy to advertise against. People&#x27;s livelihoods are tied to trying to figure out what will be most favored by the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=ogzsDTBh1T0&quot;&gt;&quot;Algorithm&quot;&lt;&#x2F;a&gt;. However, code is code, and with the release people have taken to searching through and trying to glean insights.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Twitter revealed its algorithm to the world. &lt;br&gt;&lt;br&gt;But what does it mean for you?&lt;br&gt;&lt;br&gt;I spent the evening analyzing it.&lt;br&gt;&lt;br&gt;Here’s what you need to know:&lt;&#x2F;p&gt;&amp;mdash; Aakash Gupta 🚀 Product Growth Guy (@aakashg0) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;aakashg0&#x2F;status&#x2F;1641976869460275201?ref_src=twsrc%5Etfw&quot;&gt;April 1, 2023&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Twitter just open-sourced their algorithm.&lt;br&gt;&lt;br&gt;Some initial takeaways:&lt;br&gt;◆ Your following to follower ratio matters.&lt;br&gt;◆ &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;TwitterBlue?ref_src=twsrc%5Etfw&quot;&gt;@TwitterBlue&lt;&#x2F;a&gt; subscribers do get a boost in the algorithm.&lt;br&gt;&lt;br&gt;Will keep adding more to this thread 👇&lt;&#x2F;p&gt;&amp;mdash; Steven Tey (@steventey) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;steventey&#x2F;status&#x2F;1641892386564640768?ref_src=twsrc%5Etfw&quot;&gt;March 31, 2023&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;So, Twitter open-sourced The Algorithm...&lt;br&gt;&lt;br&gt;I was so close (at least for the toxicity&#x2F;abuse&#x2F;nsfw detection models) &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;I4aiSkkcHm&quot;&gt;https:&#x2F;&#x2F;t.co&#x2F;I4aiSkkcHm&lt;&#x2F;a&gt; &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;5DJUCvUbov&quot;&gt;pic.twitter.com&#x2F;5DJUCvUbov&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; François Chollet (@fchollet) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;fchollet&#x2F;status&#x2F;1641902708297981958?ref_src=twsrc%5Etfw&quot;&gt;March 31, 2023&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;And most hilariously:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twitter-algo&#x2F;imgs&#x2F;users.jpg&quot; alt=&quot;users&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;What people found is that some types of engagement (likes) are preferable to others. Some types of content (multimedia) are better than others (links). And it really matters if you are Elon Musk. These rules encode biases (in the ML sense) that have far reaching effects. Likes being preferable to replies or retweets incentivize quippy one liners over substantive back and froths or long threads. Promoting multimedia embeds and penalizing links is a way to keep people on twitter.com and not constantly leaving the site. And it&#x27;s easy to make your boss feel like the most important person in the world if his tweets get sent to everyone.&lt;&#x2F;p&gt;
&lt;p&gt;People have figured out some of this without the source code but having the source, potentially having researchers try to set up model systems and experimentally discover emergent properties is another level. Work like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.science.org&#x2F;doi&#x2F;10.1126&#x2F;science.aax2342&quot;&gt;Obermeyer et. al.&lt;&#x2F;a&gt; serves as a model of what should be performed on all these sort of systems. They try to find evidence of racial bias in UnitedHealth&#x27;s models used to recommend additional care to patients. They get access to the training dataset and objective function used by UnitedHealth and notably find &lt;strong&gt;race is not an explicit factor&lt;&#x2F;strong&gt; considered by the model. However, the model uses &quot;total medical expenditures&quot; as a proxy for the &quot;prediction on health needs&quot;. I.e. an encoded assumption of the system is that people who spend more on healthcare need more healthcare. They find that when considering this, &lt;strong&gt;there is no bias w.r.t race&lt;&#x2F;strong&gt; in UnitedHealth&#x27;s model. However the fact of the matter is that African Americans spend less on average than Caucasian Americans on health care, so while the model itself does not discriminate, UnitedHealth neglects folks who could use additional care because larger demographic trends confound the proxy they use to assess need.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;These results suggest that the driving force behind the bias we detect is that Black patients generate lesser medical expenses, conditional on health, even when we account  for specific comorbidities. As a result, accurate prediction of costs  necessarily means being racially biased on health. First, poor patients face substantial barriers to accessing health care, even when enrolled in insurance plans. Although the population we study is entirely insured, there are many other mechanisms by which poverty  can lead to disparities in use of health care: geography and  differential access to transportation, competing demands from jobs or  child care, or knowledge of reasons to seek care. To the extent that race and socioeconomic status are correlated, these  factors will differentially affect Black patients.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The authors conclude &quot;On the one hand, the algorithm manufacturer’s choice to predict future  costs is reasonable: The program’s goal, at least in part, is to reduce  costs, and it stands to reason that patients with the greatest future  costs could have the greatest benefit from the program.&quot; But there is now much greater clarity on UnitedHealth&#x27;s objectives, some possible design flaws have been exposed and hopefully this work has helped UnitedHealth improve their model to provide better service.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-objections&quot;&gt;The Objections&lt;&#x2F;h3&gt;
&lt;p&gt;Why might these companies push back against being transparent about how they
recommend content to users?&lt;&#x2F;p&gt;
&lt;h4 id=&quot;objection-1-exploiting-the-system&quot;&gt;Objection 1: Exploiting the System&lt;&#x2F;h4&gt;
&lt;p&gt;The first thing some black box system advocates might say is that obfuscating the mechanisms used to select content to promote and demote is necessary to prevent spam and gaming the system. I think this argument fails on the same principles that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Security_through_obscurity&quot;&gt;security through obscurity&lt;&#x2F;a&gt; fails. The fact that a system is not inspectable does not prevent this from being exploited. And folks operating recommendation systems have seen this &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mcrc.journalism.wisc.edu&#x2F;files&#x2F;2018&#x2F;05&#x2F;TwitterExploit.pdf&quot;&gt;first hand&lt;&#x2F;a&gt;. As has been learned in infosec, more eyes and more pentesters makes systems more solid. And the easiest way to do that is to make the system open and transparent. We could have better, more fair, more exploitative proof systems if we do the work in the open.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;objection-2-value-proposition-and-the-caveat-data-monopolies&quot;&gt;Objection 2: Value Proposition and The Caveat - Data Monopolies&lt;&#x2F;h4&gt;
&lt;p&gt;Likely, the next thing you might hear from an industry lobbyist regarding some sort of legislation requiring recommendation engine transparency would be &quot;This harms our competitive advantage&quot; i.e. that the reason a user or advertiser may choose Twitter over Mastodon is their recommendation system. This fundamentally mischaracterizes the value proposition of these services. An adequate recommendation system is required to be able to use these systems at scale, as not all posts or content are relevant or interesting to all people.&lt;&#x2F;p&gt;
&lt;p&gt;However, the reason why these platforms are valuable is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;online.hbs.edu&#x2F;blog&#x2F;post&#x2F;what-are-network-effects&quot;&gt;network effects&lt;&#x2F;a&gt; and data exclusivity of these platforms. They tend to be the one or two places on the internet to find particular types of content. On Instagram this might be your friends or influencers photos, on Twitter this may be some public figure&#x27;s musings. Fundamentally, you use Twitter and not Mastodon because XYZ person is here and not there.&lt;&#x2F;p&gt;
&lt;p&gt;For advertisers this is similar. The vast &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.visualcapitalist.com&#x2F;the-50-most-visited-websites-in-the-world&#x2F;&quot;&gt;majority of people&#x27;s time&lt;&#x2F;a&gt; is spent on one of a few websites. The value proposition to advertisers is, if you want eyeballs this is the best place on the web to find them. A recommendation system is one way to keep people on for longer per person, but this is marginal gains compared to acquiring a massive user base. As such these companies have realized that one of the most important things they can do is regulate access to this content for maximum leverage. I.e. in order to see your friends posts on Instagram, you must sign up, sign the EULA giving permission for whatever tracking the service provider wants to do, and log in. More and more these platforms are preventing their content from being indexed publicly or explored anonymously.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twitter-algo&#x2F;imgs&#x2F;login_page.png&quot; alt=&quot;login_page&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is all in contrast to services like Google where all the content is public and the value proposition of the service is to find the most relevant results. For Google, their differentiation is in their recommendation engines performance because anyone can set up a web server and start ranking results. Therefore, if you think Google is unfair, use a different option. There is no alternative for Twitter or Facebook.&lt;&#x2F;p&gt;
&lt;p&gt;So social media companies control the data and control what data is shown. I argue that you should be able to have one or the other. Either your recommendation system can be private because your source data is public thus allowing competition in recommendations and the ability to audit the data or you can hoard data but you must be transparent on what you collect and how it is promoted or suppressed, thus clarifying the encoded values of the platform (like how Obermeyer et. al. clarifies what is valued in UnitedHealth&#x27;s model). People can then make an informed decision on whether they agree or if the content available is worth the trade off. If someone is going to be the sole mediator of access to a particular type of data, I want to know what incentives are at play for deciding what is show and what is hidden.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;objection-3-embarrassment&quot;&gt;Objection 3: Embarrassment&lt;&#x2F;h4&gt;
&lt;p&gt;A ridiculous argument, yet honestly the most deeply held one. It&#x27;s easier to not be transparent and not expose your dirty laundry, all the hacks and tricks used to recommend one piece of content over another (e.g. Elon, Democrat and Republican specific filters). But this seems like an unacceptable reason for people who&#x27;s ambitions include being the main source of news and media for &lt;strong&gt;billions&lt;&#x2F;strong&gt; of people to not be transparent. Either reduce the scope of the product or be more open.&lt;&#x2F;p&gt;
&lt;p&gt;More and more content is being mediated. The days of the web being fully open are over and it &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;narendasan.com&#x2F;posts&#x2F;chatgpt-web.html&quot;&gt;seems like this trend will get worse&lt;&#x2F;a&gt;. As this happens, platform owners take a more central role in deciding what is shown and what is suppressed. It therefore matters what the encoded values of these systems are. Letting people make these decisions behind closed doors without disclosing how they decide recommendations leaves us vulnerable. We would be relying on them to be strong moral arbiters, making ethical decisions and policy unilaterally that spans the whole world&#x27;s political and cultural spectrum, a level of institutional power and responsibility that seems almost unrivaled and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nbcnews.com&#x2F;video&#x2F;zuckerberg-struggles-to-answer-if-facebook-is-a-neutral-public-forum-1207652931674&quot;&gt;a position that they themselves would rather not be in&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Open recommendation systems allow people to be informed on platform values and incentives. Barring the alternative of forcing the data these companies hoard to be openly accessible (a radical yet, not terrible idea) so competitor recommendation systems can exist, being transparent benefits everyone. Users are more informed on why they are seeing this post and not that post or why their post has not garnered a lot of perceived interest, something which does &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;social.cs.uiuc.edu&#x2F;papers&#x2F;pdfs&#x2F;Eslami_Algorithms_CHI15.pdf&quot;&gt;cause people stress and anguish&lt;&#x2F;a&gt;. Advertisers have more clarity on how their ads fit into the system. And, the companies can benefit from the insights of the greater open source community and are able to point to explicit code to explain their decisions.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>ChatGPT&#x27;s Plugin System Poses an Existential Risk to the Open Web</title>
          <pubDate>Thu, 23 Mar 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/chatgpt-web/</link>
          <guid>https://www.narendasan.com/blog/chatgpt-web/</guid>
          <description xml:base="https://www.narendasan.com/blog/chatgpt-web/">&lt;h5 id=&quot;sections-1-and-2-are-motivation-and-background-if-you-care-section-3-is-the-real-meat-of-the-essay&quot;&gt;Sections 1 and 2 are motivation and background if you care, Section 3 is the real meat of the essay.&lt;&#x2F;h5&gt;
&lt;h2 id=&quot;chatgpt-is-more-information-retrieval-ui-than-artificial-intelligence&quot;&gt;ChatGPT is more Information Retrieval UI than Artificial Intelligence&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;(In the AGI sense)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Generative AI is having its moment right now and OpenAI&#x27;s ChatGPT is at the center of it. The &quot;humanness&quot; of the conversations one has with these chatbots have many pundits busy wondering if this is the dawn of the end of humanity or a break down in the economy is imminent. Meanwhile, many in the research community have pointed out the fundamentally iterative improvements in underlying ML technology behind the system and are hesitant to ascribe too much to these systems (yet). Personally, I lean towards the iterative improvement camp when viewing these systems in the artificial intelligence context.&lt;&#x2F;p&gt;
&lt;p&gt;However, I believe (and many others have pointed this out in one way or another) that the fundamental contribution of systems like ChatGPT is a step-change difference in the performance and particularly the usability of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Information_retrieval&quot;&gt;&lt;em&gt;information retrieval systems&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. Chatbot systems based on LLMs bring us as close as we have come to the realization of science fiction inspired technology where a user can converse with a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=1ZXugicgn6U&quot;&gt;system using natural language to parse, extract and manipulate information&lt;&#x2F;a&gt;. Examples like code being written on the fly, articles being summarized and essays being generated, can be thought of as a form of &lt;em&gt;artificial intelligence&lt;&#x2F;em&gt; but I argue that they should be more thought of as an alternative to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ncbi.nlm.nih.gov&#x2F;pmc&#x2F;articles&#x2F;PMC1068946&#x2F;&quot;&gt;existing information synthesis workflows&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Abstractly, lots of knowledge work: programming, research, writing, art, can be thought of as a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;library.suu.edu&#x2F;LibraryResearch&#x2F;information-synthesis&quot;&gt;loop&lt;&#x2F;a&gt; of searching a knowledge base, evaluating results, identifying the key ideas, synthesizing new ones and repeating. The primary difficulty is the searching step. 70 years ago, this required going to physical repositories of information like libraries, museums, reading a lot of books and papers, listening to talks, performances etc. 40 years ago, people started making queryable and traversable repositories (e.g. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hypertext&quot;&gt;hypertext&lt;&#x2F;a&gt; and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;World_Wide_Web&quot;&gt;&quot;World Wide Web&quot;&lt;&#x2F;a&gt;) and until yesterday tools like Google would be used to search through them, finding relevant information &#x2F; inspiration. Today and tomorrow it seems more and more likely that this role (and part of the synthesis role as well – a topic for another essay) will be replaced by systems like ChatGPT.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chatbots-are-a-better-ui-for-information-retrieval&quot;&gt;Chatbots are a Better UI For Information Retrieval&lt;&#x2F;h2&gt;
&lt;p&gt;Systems like ChatGPT wrap up the open web in a neat box. You can &quot;speak&quot; directly to them, you don&#x27;t need to reformat your question into a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;support.google.com&#x2F;websearch&#x2F;answer&#x2F;2466433?hl=en&quot;&gt;pseudo-natural query language&lt;&#x2F;a&gt; that many of us have learned to speak fluently. And, because it understands context, it is easy to refine your questions to tune the results. Language models both encode a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aclanthology.org&#x2F;D19-1250&#x2F;&quot;&gt;compressed knowledge base&lt;&#x2F;a&gt; (provided by training on the open web) and have the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;openai.com&#x2F;research&#x2F;webgpt&quot;&gt;capability to leverage other knowledge bases&lt;&#x2F;a&gt; to provide results. Of course, due to the nature of language models the issue of &quot;hallucination&quot; is an issue but any competent and principled knowledge worker can easily check the results and refine if necessary. Information retrieval is hard to do but easy to verify. To this end, these systems seem like a wonderful step forward in the accessibility of using the web.&lt;&#x2F;p&gt;
&lt;p&gt;User Interfaces, I&#x27;d argue, are one if of not &lt;strong&gt;the&lt;&#x2F;strong&gt; most important factor for technology adoption at any level. I cannot be convinced that computers would be as prevalent a tool as they are without the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Graphical_user_interface&quot;&gt;Graphical User Interface&lt;&#x2F;a&gt; and more recently Multi-Touch. Anyone who has used a command line can explain the cognitive load required to operate a system at that level. There is for sure more control at a lower level, but it requires users to have a strong mental model of the state of the system. GUIs require very little of that. Adoption of the web itself has been mediated by UI step changes as well, first the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mosaic_(web_browser)&quot;&gt;Graphical Web Browser&lt;&#x2F;a&gt;, then &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Search_engine&quot;&gt;Search Engines&lt;&#x2F;a&gt;. Systems like ChatGPT are the next step in that lineage for the web and just like how GUIs abstract much of the operating system from the user, ChatGPT can abstract much of the web.&lt;&#x2F;p&gt;
&lt;p&gt;Previous versions of the web in a box have failed precisely because the UIs were not capable enough. Voice assistants like Alexa, Ok Google, Siri and Duplex struggle firstly because voice is likely not the ideal modality for these sort of UIs, speech varies in so many ways e.g. timbre, accents, background noise. Language models solve this by using text. Text is uniform, discrete, there are fewer sources of confusion. Second voice assistants &quot;don&#x27;t work&quot;; it is a frustrating experience trying to get one of these things to do anything of slight complexity correctly. Even if the assistant heard you correctly, it does not understand what to do or how to do it. Without explicit developer integrations, voice assistants are next to useless. Critically, language models have proven their ability to provide meaningful and interesting results on their own without external resources and more importantly, also have been shown to have the ability to traverse the web to find new information. LM-based chatbots provide a smooth onramp from the open HTML web to the chatbot world. Much like how Facebook created a MySpace bridge to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;locusmag.com&#x2F;2023&#x2F;01&#x2F;commentary-cory-doctorow-social-quitting&#x2F;&quot;&gt;make it easier to switch&lt;&#x2F;a&gt;, LM-based chatbots do not need to wait for developers to integrate with them to be useful.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;openai-vs-the-open-web&quot;&gt;&quot;OpenAI&quot; vs. the Open Web&lt;&#x2F;h2&gt;
&lt;p&gt;The recent announcement of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;openai.com&#x2F;blog&#x2F;chatgpt-plugins&quot;&gt;&quot;plugins&quot; for ChatGPT&lt;&#x2F;a&gt; has me concerned. Not about any sort of existential risk due to runaway AGI in the near to mid-term, but about the prospects for the open web as we know it. In the past 30 years the &quot;World Wide Web&quot; has become the near complete repository of human knowledge and it is the reason why systems like ChatGPT even have a chance to exist. But some of its most valuable qualities are not foundational to its job as a knowledge base, namely the fact it is human readable&#x2F;browsable, open and (provided you are connected) equally accessible to all. Some corners of the knowledge base may be more curated, organized and searchable than others (e.g. Wikipedia, StackOverflow, Reddit) and some parsing and retrieval tools may be better than others (e.g. Google - until 3-5 years ago) but whenever anyone anywhere in the world opens a web browser, they for the most part have the same access as anyone else to any part of the knowledge base.&lt;&#x2F;p&gt;
&lt;p&gt;The fact that it feels like LM-based chatbots are the next step in interacting with the internet creates a forcing function to be a first class member in that world and plugins seem like it will be the mechanism to do so. Will people find you or your service if you&#x27;re not integrated into ChatGPT? Google already has been criticized for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.documentcloud.org&#x2F;documents&#x2F;7273448-DOC.html&quot;&gt;centralizing and arbitrating traffic on the web&lt;&#x2F;a&gt; and many actors have taken to optimizing their content to best fit Google. The implications of this new UI takes that world a step further. Ultimately, what backstopped Google&#x27;s information was human readable, openly accessible content. Google fundamentally prefers HTML, the interconnections between HTML pages serve at the foundation of its approach to extracting knowledge. Therefore, to an extent Google encourages the open human readable web (perhaps not in its ideal form) and as a sideffect there remains the ability to push through or go around Google and still get to some sort of readable content. Language models (especially hosted ones) themselves are absolutely not human readable, and with plugins the need for an open human-readable raw corpus becomes optional once people have transitioned to using LM-based systems. Even additional training data can be captured monitoring human input and by querying plugins, things OpenAI can include as conditions of being part of their ecosystem. Content can more easily be centralized in privately maintained, heavily accessed controlled repositories and mediated through primarily web APIs with no requirement for an open readable option.&lt;&#x2F;p&gt;
&lt;p&gt;If this is indeed what happens, what happens to the large corpus of human readable and browsable content? Will it just atrophy over time? What happens when not just information retrieval but information insertion into the knowledge base is moderated through systems like ChatGPT? Society already has an incredibly strained relationship with content middlemen, e.g. Google, Meta, Twitter. It is not clear what these actors&#x27; responsibilities are, or if they should have these responsibilities in the first place. The move to Chatbot UIs pushes us even more towards companies mediating discourse and access to knowledge in society. This raises the questions: how does ChatGPT (really how does OpenAI) decide who gets to service your question and what information gets added to knowledge bases, how does OpenAI get compensated for this middle man service and what incentives does that produce? It feels incredibly uncomfortable that we seem to be careening towards an uncertain future without considering the values we might be leaving behind.&lt;&#x2F;p&gt;
&lt;p&gt;To get an idea of what some potential futures may be look to existing integrated platforms and previous iterations of recommender systems. For example, how &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jingdaily.com&#x2F;wechat-ecosystem&#x2F;&quot;&gt;applications integrate into WeChat&lt;&#x2F;a&gt;. WeChat mediates the interface and access users have to applications and applications to users. This middle man position provides a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;citizenlab.ca&#x2F;2020&#x2F;05&#x2F;wechat-surveillance-explained&#x2F;&quot;&gt;convenient gateway for censorship&lt;&#x2F;a&gt;. We can see shades of this already in systems like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;SamuelBickett&#x2F;status&#x2F;1639737947707547657&quot;&gt;Bing AI&lt;&#x2F;a&gt;. Look at how YouTube creators try to divine the whims of the &quot;YouTube Algorithm&quot; and more importantly look at all the content left by the wayside, inaccessible to anyone because &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=ogzsDTBh1T0&quot;&gt;YouTube decided its not &quot;relevant&quot;&lt;&#x2F;a&gt;. Also look at social media in general. Social media platforms - Facebook, Instagram, etc. have over the last decade pulled the individual off the &lt;strong&gt;open&lt;&#x2F;strong&gt; web. Where as in the late 90s and early 00s, it may be common to see people maintaining a website for themselves or a perhaps a business or hobby, these sites for the most part have been subsumed by simply an Instagram page. For many these accounts are their sole personal presence on the web. Behind these walled gardens owners mediate what you and others can see, how you see it, what is permissable and what the incentives of the platform are. Access to the information in these closed parts of the web are set via negotiations between large actors or by signing an opaque end user license.&lt;&#x2F;p&gt;
&lt;p&gt;Without the UI of the web continuing to incentivize HTML, one could imagine this format going the way of books, mostly replaced by databases hooked up to Chatbots where users can retrieve information, do key actions and insert new information to improve the knowledge base without needing to find, read, then create or edit a website. For knowledge work perhaps this looks like hooking up an S3 bucket to ChatGPT, asking it to browse the information, extract some key information, and help you compose a new document which is stored in the bucket. For the individual currently using closed social media apps, perhaps in the future you would ask ChatGPT &quot;What are my friends up to?&quot; or to post a status update. Both for generic knowledge work and many of the common things individuals do on the web, this feels like it will be an easier information synthesis workflow than the current paradigm. However, it sacrifices a lot of the benefits that the open web brought with it, like those discussed above namely being decentralized, open and human traversable and readable. Unfortunately, as we have seen time and time again, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.npr.org&#x2F;sections&#x2F;therecord&#x2F;2011&#x2F;03&#x2F;18&#x2F;134598010&#x2F;for-better-or-worse-mp3s-are-the-format-of-choice&quot;&gt;people will sacrifice a lot for better user experiences&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There is this notion of an approaching fissure in the web splitting it into a web for robots and a web for humans. Many discussions of this idea focus on the ability to tell real from fake, generated from handcrafted. But I do not think this discourse focuses enough on the notions of control and freedom. How will the web change when its UI changes so fundamentally? What formats do we incentivize and what values do those formats encode? Who manages and owns the web when its UI is chatbots and what are the incentives of actors? Where do individuals fit in? Is there still space for an open, readable web? And most crucially: What are we giving up when this change happens? Recommendation systems which in many ways are the precursors to chatbots have been blamed for everything from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;healthcare.utah.edu&#x2F;healthfeed&#x2F;2022&#x2F;09&#x2F;impact-of-social-media-teens-mental-health&quot;&gt;increasing depression&lt;&#x2F;a&gt; to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thediplomat.com&#x2F;2020&#x2F;05&#x2F;facebooks-apology-for-its-role-in-sri-lankas-anti-muslim-riots-should-spark-change&quot;&gt;inciting atrocities&lt;&#x2F;a&gt;. We would be fools to blindly make this transition without thinking through what we would like the future to look like, and what values we would like to preserve.&lt;&#x2F;p&gt;
&lt;p&gt;The worst case scenario is extreme but I think the likelihood of significant negative externalities relating to information access, mediation and the health of the human readable web from a transition to LM-Based IR systems is non-zero (and much larger than the likelihood of malicious AGI in the coming years). It took 30 years for the open web to take the form it has today and it seems like there is no guarantee now that it will continue on the trajectory it has been on. For the first time in a long time, the human readable web has real competition and I do not think it is clear who is going to win.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;This essay was handwritten without the aid of large language models&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Update 3&#x2F;26&#x2F;23:
I thought this thread speaks well to of some the ideas presented here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;peternixey&#x2F;status&#x2F;1640002493630369792&quot;&gt;https:&#x2F;&#x2F;twitter.com&#x2F;peternixey&#x2F;status&#x2F;1640002493630369792&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
      <item>
          <title>procgen-terrain: A Procedurally Generated Mountain Town</title>
          <pubDate>Fri, 10 Dec 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/procgen-terrain/</link>
          <guid>https://www.narendasan.com/blog/procgen-terrain/</guid>
          <description xml:base="https://www.narendasan.com/blog/procgen-terrain/">&lt;h3 id=&quot;a-procedurally-generated-mountain-town&quot;&gt;A Procedurally Generated Mountain Town&lt;&#x2F;h3&gt;
&lt;p&gt;I spent the fall learning about computer graphics and OpenGL, a topic which I didn&#x27;t get to cover in my undergrad. OpenGL is now a 30 year old standard which is primarily written in C&#x2F;C++. It is a nice way to start since a lot of the common components needed in a graphics stack are baked in. But its usage patterns and APIs are showing their age so I wanted to see what next generation tools like Rust and Vulkan can allow me to do and to see what the differences are between the two stacks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;github.com&#x2F;narendasan&#x2F;procgen-terrain&#x2F;raw&#x2F;0464e203bce1b5bfb2319ae0876c78b722aafbfc&#x2F;example_images&#x2F;village.gif&quot; alt=&quot;procgen-terrain&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;approach&quot;&gt;Approach&lt;&#x2F;h2&gt;
&lt;p&gt;Vulkan is a new low level graphics API that is intended as the next generation OpenGL. OpenGL being created in 1992 was designed for very different hardware paradigms. Over the last 3 decades the architecture and roles of the graphics card, driver and APIs have changed and Vulkan is intended to address these changes.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, when OpenGL was created C and C++ were the primary languages used to develop graphics applications. While they remain to be wildly popular, a new generation of programing languages are reaching maturity. These languages offer many modern convinces not reflected in C&#x2F;C++ programming like a language specific build system and package manager, modules, and many compiler features to catch errors. One of the most exciting next generation programming languages is Rust which is a C-Like low level systems programming language with guaranteed memory and thready safety. Features that are of particular interest in graphics programming.&lt;&#x2F;p&gt;
&lt;p&gt;To try these new tools out I implemented a procedurally generated scene, where the terrain is generated from perlin noise. I then place models of trees and houses on to the terrain, randomly placed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;vulkan-pipeline-setup&quot;&gt;Vulkan Pipeline Setup&lt;&#x2F;h3&gt;
&lt;p&gt;There is a lot to do to setup a Vulkan Rendering Pipeline. In Rust there are a few choices for Vulkan API implementations. Some like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;MaikKlein&#x2F;ash&quot;&gt;ash&lt;&#x2F;a&gt; are very lightweight and close to the original C++ implementation. However, these sort of APIs are &quot;unsafe&quot; meaning you lose many of the benefits of using Rust in terms of memory
and thread safety in exchange for a very familiar interface. I chose &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;vulkano-rs&#x2F;vulkano&quot;&gt;vulkano&lt;&#x2F;a&gt;. Vulkano is a &quot;Rusty&quot; implementation of Vulkan in that the coding paradigms used are native to Rust and it is fully compliant with &quot;safe&quot; Rust.&lt;&#x2F;p&gt;
&lt;p&gt;To actually set up a Vulkan renderer you need to construct all the parts of the OpenGL state machine which existed globally in OpenGL. This starts with the Vulkan Instance. The instance manages the version of the Vulkan spec we are using and any extensions to Vulkan we need to use. Window drawing is in fact not part of the core Vulkan spec, so this is one of the extensions we need to include.&lt;&#x2F;p&gt;
&lt;p&gt;In Rust the render loop is encapsulated in an EventLoop which defines enums for different events that can happen like key presses or window resizes. The actual render loop logic is defined in closure provided to the event loop.&lt;&#x2F;p&gt;
&lt;p&gt;The render image is called a surface. I actually use a different package &lt;code&gt;winit&lt;&#x2F;code&gt; to create this surface since its not a core part of Vulkan.&lt;&#x2F;p&gt;
&lt;p&gt;Next, we need to set up the device to render on. This starts by defining the set of extensions our device needs to support. All we need is a device that supports swapchains so we can draw onto the surface. Then we need to find a compatible device. Vulkano lets you list all available Vulkan capable devices (including software based Vulkan devices) and query if they support the necessary extensions. In my code there is logic to prefer the dGPU over the iGPU in the case there both.&lt;&#x2F;p&gt;
&lt;p&gt;After selecting the physical device (in my case my RTX 3050Ti) we need to create a Vulkan device. We base it off the physical device selected and provide a list of the features we need to have support for. In this case just swapchain support is needed. As a result of this process, queues are creates as well. Vulkan can support multiple queues but I only use one.&lt;&#x2F;p&gt;
&lt;p&gt;Next we actually create the swapchain which manages the image buffers. Swapchains allow you to construct the next frame while the current frame is being shown. The swap chain buffer size is window size dependent so the swap chain must be recreated if the window is resized.&lt;&#x2F;p&gt;
&lt;p&gt;We then create the render pass. Vulkan lets you have more than one render pass which can be used to apply multiple sets of vertex and fragment shaders. This is useful to isolate effects like lighting in their own passes. Passes can also multiple sub passes. In my application I only use a single pass similar to OpenGL code. The render pass defines as well the where the output of the graphics pipeline will go, the layout of the images and where the depth, color and stencil information will go.&lt;&#x2F;p&gt;
&lt;p&gt;From there we create the graphics pipeline. This is similar to the OpenGL program but contained and it provides more control. You provide the pipeline builder the layout of your input. the input shader, the format of the buffer, the viewport, the fragment shader and the render pass. This part is where Rust starts the shine. Macros in Rust are much more powerful than in C&#x2F;C++. They let you execute code at compile time as well as create new code. This lets you do all sorts of powerful things. For example I can write my shaders and provide them to a rust macro. This macro can compile my shader at compile time and create a rust struct which corresponds to the input layout of my shader. This means I can set uniform buffers by just setting fields in a struct. I can also use another macro which takes my definition of a vertex and automatically structures the buffer to interface properly with my shader. Therefore I can just provide a vector of vertex structs and have Rust generate the code to lay it out. The compile will also throw errors if you improperly populate the buffers.&lt;&#x2F;p&gt;
&lt;p&gt;The last step is to allocate the framebuffers for the swapchain. We launch the event loop to start the rendering.&lt;&#x2F;p&gt;
&lt;p&gt;The closure in the event loop defines the render logic. Rust enforces that all cases be handled, so you need to define a way to handle each event. Most will fall into a default case. In this default case, the first thing to do is clean the last frame so that memory does not leak. Then it is important to check if the swap chain needs to be rebuilt. This can be due to the window being resized or Vulkan can tell you when the swapchain is not optimal.&lt;&#x2F;p&gt;
&lt;p&gt;The next step is to get the next framebuffer we can draw on which we clear. From this point the pipeline is similar to OpenGL. You carry out a series of draw commands to render components of the scene. However in Vulkano this is done via a command builder. The command builder allows you to sequence a list of operations to run during the render pass. This is where pipelines and vertex buffers are bound and draw commands are issued. Once the pass is closed the command is built and then executed returning a &quot;Future&quot;. Futures are a placeholder of something to happen in the future. It lets the main program continue executing and checking later for a result. This future will tell the program if the frame rendered successfully.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;scene-pipeline&quot;&gt;Scene Pipeline&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;procgen-terrain&#x2F;imgs&#x2F;scene_pipeline.png&quot; alt=&quot;scene_pipeline&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The graphics pipeline to generate terrain and then place models&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;When the application starts the user can provide the following settings:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;procgen-terrain 0.1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;USAGE:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    procgen-terrain.exe [OPTIONS]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FLAGS:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        --help       Prints help information&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -V, --version    Prints version information&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OPTIONS:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -b, --bounds &amp;lt;bounds&amp;gt;         [default: 30]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -g, --gridsize &amp;lt;gridsize&amp;gt;     [default: 256]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -h, --houses &amp;lt;houses&amp;gt;         [default: 10]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -m, --map &amp;lt;map&amp;gt;               [default: 128.0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -n, --noise &amp;lt;noise&amp;gt;           [default: 512]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -s, --seed &amp;lt;seed&amp;gt;             [default: 100]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -t, --trees &amp;lt;trees&amp;gt;           [default: 200]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;noise&lt;&#x2F;code&gt;: Control the size of the noise map ($N \times N$) that is generated. This allows you to control the resolution of the noise&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;map&lt;&#x2F;code&gt;: Size ($M \times M$) of the terrain mesh generated in world coordinates&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;gridsize&lt;&#x2F;code&gt;: The resolution ($G \times G$) of the terrain mesh. Higher numbers mean more vertices in the mesh&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;seed&lt;&#x2F;code&gt;: The seed for the noise generator. Giving the same seed generates the same noise map&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;bounds&lt;&#x2F;code&gt;: The distance from the center that modeled geometry can spawn. Prevents unnecessary rendering for models that can&#x27;t be seen&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;trees&lt;&#x2F;code&gt;: Number of trees to spawn. Trees are spawned in random positions on the terrain within the bounds&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;houses&lt;&#x2F;code&gt;: Number of houses to spawn. Like trees houses are spawned in random positions within the bounds&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Using the noise seed, a perlin noise map is generated. A flat surface of $S \times S$ vertices is created spanning the space $M \times M$ in world coordinates. Using the noise map the intensity of a pixel in the map is used to set the $y$ coordinate by mapping each vertex from grid space into the dimensions of the noise map. Now the geometry of the terrain is set. In order to set the colors, bands of elevation are mapped to each material (Grass, Rock, Snow). At this point the terrain is complete. At the terrain creation stage, a $G \times G \times 3$ elevation map is created which stores the position of each vertex for later.&lt;&#x2F;p&gt;
&lt;p&gt;The bounds argument defines a $B \times B$ area in the scene centered on the origin where models can be rendered. This is done since far off parts of the terrain mesh will never have enough resolution to see the models. The scene pipeline samples $T$ locations for trees and $H$ locations for houses without replacement. The geometry and textures for the tree model and house models are loaded and initially scaled. Only one copy of the tree and house geometry are on the GPU but $T$ and $H$ copies of the model matrix are created to define the transformation for each tree to be rendered. Using the sampled locations to index the elevation map to get the $xyz$ position of the vertex that the model will be rendered on. The model is then translated to that position which makes it seem like the model is rendered on the surface of the terrain. During draw calls only the model matrix is changed between models, the model vertices never change.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rust-vulkan-vs-c-opengl&quot;&gt;Rust&#x2F;Vulkan vs C++&#x2F;OpenGL&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-performance-of-vulkan&quot;&gt;The performance of Vulkan&lt;&#x2F;h3&gt;
&lt;p&gt;I profiled my application using NVIDIA NSight Graphics which can profile both the CPU and GPU usage as well as the latency for each draw call and bottlenecks in shader execution.&lt;&#x2F;p&gt;
&lt;p&gt;In my profiling I found there is negligible CPU overhead once rendering begins on the order of &amp;lt; 0.1 ms. Since this was a design goal of Vulkan in improving over OpenGL and its heavy driver this is cool to see.&lt;&#x2F;p&gt;
&lt;p&gt;Using default settings I found that the terrain draw call took 9.41ms to draw. Default settings produce a 393216 vertex terrain model and is by far the most complex piece of geometry in the scene. The tree and house models each take 0.2ms and 0.1ms respectively per model to draw. They are 930 and 534 vertex models respectively.&lt;&#x2F;p&gt;
&lt;p&gt;With default settings I get a frame rate of on average 64 FPS on an RTX 3050 Ti. There are 211 draw calls per render pass. I also found that the frame rate fluctuates due to the complexity of the terrain in frame more an any number of models that get spawned.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;procgen-terrain&#x2F;imgs&#x2F;verts.png&quot; alt=&quot;verts&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In profiling the terrain rendering system you see linear scaling in the time to render the terrain model with the number of vertices in th the model which is to be expected.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;procgen-terrain&#x2F;imgs&#x2F;num_trees.png&quot; alt=&quot;num_trees&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the measure of the impact of the number of models in the scene I found initially, up to 500, there is not a huge impact in frame times, the long pole is the terrain rendering. but there is a cross over point around 600 trees where the number of models becomes the main contributor to additional frame latency.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;performance-improvements&quot;&gt;Performance Improvements&lt;&#x2F;h4&gt;
&lt;p&gt;I currently only keep one copy of the models, Terrain, Tree and House on the GPU and just swap out the uniform buffers for the draw calls. I could try to find a way to reduce the upload time, maybe through pipelining or a swap buffer. This would reduce GPU memory bandwidth consumption and latency. I think that rendering gets held up on terrain for reasonable amounts of models. One of the new things Vulkan enables is multi-threaded rendering. So while the terrain is being drawn, I can draw the other geometry. Rust is also known for its thread safety so this seems like a good pair.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-vulkan-and-rust-compare-to-opengl-and-c&quot;&gt;How Vulkan and Rust compare to OpenGL and C++&lt;&#x2F;h3&gt;
&lt;p&gt;There are stark differences between Vulkan and OpenGL. Vulkan gives you control over &lt;em&gt;everything&lt;&#x2F;em&gt;. This is both good and bad. The good is that you fully understand all aspects of the system and can customize it to the exact render architecture you would like. The bad is that there is a lot of set up. Vulkan also is not a &quot;batteries included&quot; Graphics API. Functionality other stacks deem core like windowing are extensions in Vulkan. Vulkan also still has some confusing and incomplete support in the ecosystem as it is still pretty new. Sometimes you get odd features being reported as unsupported.&lt;&#x2F;p&gt;
&lt;p&gt;All this being said, I think the way to look at Vulkan in contrast to OpenGL is that OpenGL is a framework for graphics applications. The majority of the effort is in formatting your data in a way that is consumable by OpenGL. Vulkan is a toolkit. The expectation is that you use the components in Vulkan to create something tuned to your specific application. You have direct control of the state of the graphics pipeline vs. managing a global state machine and all state modifications are in a self contained environment allowing you to manage more than one. This also enables multi-threaded rendering. Overall, this means you need to spend the time up front setting up a renderer but you can make sure that it fits the data you have ideally.&lt;&#x2F;p&gt;
&lt;p&gt;Vulkan is also more lightweight and has much better performance than OpenGL which is a clear decision maker in graphics. It allows you finer tuned control of the memory management to make resource management more efficient. Multi-threading is possible and commands take less time with less CPU overhead.&lt;&#x2F;p&gt;
&lt;p&gt;I also think that a strong positive or Vulkan is just that it is modern. OpenGL being written in the 90s lacks the last 20 years of evolution in programming paradigms. Functional programming, closures, advanced compiler support, types, descriptive error messaging and more are nonexistent in OpenGL where as in Vulkan through Vulkano, all these concepts are included and leveraged to help you develop applications.&lt;&#x2F;p&gt;
&lt;p&gt;This leads into the benefits of Rust. Where as I would be more tempered in my recommendation of Vulkan as a tool to use if you know what you want. I 100% recommend Rust over C++. The developer velocity during this project in contrast to the previous assignments is an order of magnitude greater. It is much easier to leverage the community who have put work into mesh file loaders, noise generators, ndarray implementations and graphics math libraries. Code is portable out of the box with little to no setup. It took me 5 mins on Windows to setup an environment to build the project which I built in Linux and it worked on the first try.&lt;&#x2F;p&gt;
&lt;p&gt;The community work and tooling alone is a strong enough reason to use Rust. But really what sets it apart are the language features and compiler. Macros in Rust remove 90% of boilerplate code. They let you generate linkages between shaders, CPUAccessibleBuffers and Structs in 5 lines of code, not to mention auto derived print formatting for debugging and copy constructors. Rust as a through its syntax gives you the freedom to solve problems in the way that feels most natural. In some cases functional map, filter, reduce pipelines make a lot of sense, like processing a lot of vertices in a vector. Other times for loops make sense. Tagged enums make it easy to encode information and create state machines which get enforced by the compiler. The intelligence of the compiler, the rules the language imposes and how strictly they are enforced also means that you get the performance of C with the memory safety of Java. If your code compiles, likely it will work in a safe manner. You pay the cost in terms of time to get code compiling but you spend far less time battling runtime bugs which are far harder to debug. The biggest concern of many beginning Rust programmers, the borrow checker gets addressed by Rust&#x27;s wonderful compiler which unlike GCC not only provides relevant error messages but also suggests useful solutions. Many times the only thing needed to solve the borrow checker is just paste in the code that the compiler tells you to.&lt;&#x2F;p&gt;
&lt;p&gt;There are drawbacks for Rust though that I found. The main one is that there are 10 different alpha stability solutions for each problem which do 80% of what you need. Each dependency uses a different approach. So in my application I have 3 different glm like libraries which are good at slightly different things. This is just due to the ecosystem not solidifying common solutions like Python did with NumPy or PyTorch. I believe this is just a matter of time.&lt;&#x2F;p&gt;
&lt;p&gt;Overall, I had a really positive experience switching from OpenGL and C++ to Vulkan and Rust. I think that Vulkan is a little too low level for most small hobbyist scale projects but as soon as you move to build a real world system it is the clear choice. I think that there is space for something to provide a batteries included version of Vulkan. In Rust, the wgpu project might be this solution. I think that Rust on the otherhand enables developers to do more faster and provided the foundational dependencies needed for a project exist, there are very few reasons to use C&#x2F;C++ over Rust.&lt;&#x2F;p&gt;
&lt;p&gt;You can find the implementation of this pipeline at: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;narendasan&#x2F;procgen-terrain&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;narendasan&#x2F;procgen-terrain&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>TRTorch: A compiler for TorchScript Targeting NVIDIA GPUs</title>
          <pubDate>Fri, 20 Mar 2020 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/trtorch/</link>
          <guid>https://www.narendasan.com/blog/trtorch/</guid>
          <description xml:base="https://www.narendasan.com/blog/trtorch/">&lt;p&gt;In the practice of developing machine learning models, there are few tools as approachable as PyTorch for developing and experimenting in designing machine learning models. The power of PyTorch comes from its deep integration into Python, its flexibility and its approach to automatic differentiation and execution (eager execution). However, when moving from research into production, the requirements change and we may no longer want that deep Python integration and we want optimization to get the best performance we can on our deployment platform. In PyTorch 1.0, TorchScript was introduced as a method to separate your PyTorch model from Python, make it portable and optimizable. TorchScript uses PyTorch&#x27;s JIT compiler to transform your normal PyTorch code which gets interpreted by the Python interpreter to an intermediate representation (IR) which can have optimizations run on it and at runtime can get interpreted by the PyTorch JIT interpreter. For PyTorch this has opened up a whole new world of possibilities, including deployment in other languages like C++. It also introduces a structured graph based format that we can use to do down to the kernel level optimization of models for inference.&lt;&#x2F;p&gt;
&lt;p&gt;When deploying on NVIDIA GPUs TensorRT, NVIDIA&#x27;s Deep Learning Optimization SDK and Runtime is able to take models from any major framework and specifically tune them to perform better on specific target hardware in the NVIDIA family be it an A100, TITAN V, Jetson Xavier or NVIDIA&#x27;s Deep Learning Accelerator. TensorRT performs a couple sets of optimizations to achieve this. TensorRT fuses layers and tensors in the model graph, it then uses a large kernel library to select implementations that perform best on the target GPU. TensorRT also has strong support for reduced operating precision execution which allows users to leverage the Tensor Cores on Volta and newer GPUs as well as reducing memory and computation footprints on device.&lt;&#x2F;p&gt;
&lt;p&gt;TRTorch is a compiler that uses TensorRT to optimize TorchScript code, compiling standard TorchScript modules into ones that internally run with TensorRT optimizations. This enables you to continue to remain in the PyTorch ecosystem, using all the great features PyTorch has such as module composability, its flexible tensor implementation, data loaders and more. TRTorch is available to use with both PyTorch and LibTorch. Here is a quick example on how to use it.
Creating a TorchScript Module&lt;&#x2F;p&gt;
&lt;p&gt;When developing models in PyTorch, modules are the unit of composition, you create or use subclasses of &lt;code&gt;torch.nn.module&lt;&#x2F;code&gt; which are composed into a super module representing your model.  Here is a simple LeNet implementation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; LeNetFeatExtractor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;LeNetFeatExtractor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span&gt;__init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;conv1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Conv2d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;conv2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Conv2d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;max_pool2d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;F&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;relu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;conv1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)), (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;max_pool2d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;F&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;relu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;conv2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; LeNetClassifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;LeNetClassifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span&gt;__init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;fc1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Linear&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 120&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;fc2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Linear&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;120&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 84&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;fc3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Linear&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;84&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;flatten&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;relu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;fc1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;relu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;fc2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;fc3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; LeNet&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;LeNet&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span&gt;__init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;feat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; LeNetFeatExtractor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;classifer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; LeNetClassifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;feat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;classifer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here we create two submodules for a feature extractor and a classifier and stitch them together in a single LeNet module. In this case this is overkill but modules give us granular control over our program including where we decide to optimize and where we don&#x27;t. It is also the unit that the TorchScript compiler operates on. So you can decide to only convert&#x2F;optimize the feature extractor and leave the classifier in standard PyTorch or you can convert the whole thing. When compiling your module to TorchScript, there are two paths: Tracing and Scripting.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;tracing&quot;&gt;Tracing&lt;&#x2F;h4&gt;
&lt;p&gt;Tracing follows the path of execution when the module is called and records what happens. This recording is what the TorchScript IR will describe. To trace an instance of our LeNet module, we can call &lt;code&gt;torch.jit.trace&lt;&#x2F;code&gt;  with an example input.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; LeNet&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;traced_model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;jit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;trace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;empty&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;scripting&quot;&gt;Scripting&lt;&#x2F;h4&gt;
&lt;p&gt;Scripting actually inspects your code with a compiler and  generates an equivalent TorchScript program. The difference is that since tracing simply follows the execution of your module, it cannot pick up control flow for instance, it will only follow the code path that a particular input triggers. By working from the Python code, the compiler can include these components. We can run the script compiler on our LeNet  module by calling &lt;code&gt;torch.jit.script&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; LeNet&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;script_model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;jit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There are reasons to use one path or another, the PyTorch documentation has information on how to choose and more information on TorchScript &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pytorch.org&#x2F;tutorials&#x2F;beginner&#x2F;Intro_to_TorchScript_tutorial.html&quot;&gt;https:&#x2F;&#x2F;pytorch.org&#x2F;tutorials&#x2F;beginner&#x2F;Intro_to_TorchScript_tutorial.html&lt;&#x2F;a&gt;. From a TRTorch perspective, there is better support (i.e your module is more likely to compile) for traced modules because it doesn’t include all the complexities of a complete programming language, though both paths are supported.&lt;&#x2F;p&gt;
&lt;p&gt;After scripting or tracing your module, you are given back a TorchScript Module. This contains the code and parameters used to run the module stored in an intermediate representation. Here is what the LeNet traced module IR looks like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graph(%self.1 : __torch__.___torch_mangle_10.LeNet,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %input.1 : Float(1, 1, 32, 32)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %129 : __torch__.___torch_mangle_9.LeNetClassifier = prim::GetAttr[name=&amp;quot;classifer&amp;quot;](%self.1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %119 : __torch__.___torch_mangle_5.LeNetFeatExtractor = prim::GetAttr[name=&amp;quot;feat&amp;quot;](%self.1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %137 : Tensor = prim::CallMethod[name=&amp;quot;forward&amp;quot;](%119, %input.1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %138 : Tensor = prim::CallMethod[name=&amp;quot;forward&amp;quot;](%129, %137)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return (%138)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and the LeNet scripted module IR:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graph(%self : __torch__.LeNet,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %x.1 : Tensor):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %2 : __torch__.LeNetFeatExtractor = prim::GetAttr[name=&amp;quot;feat&amp;quot;](%self)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %x.3 : Tensor = prim::CallMethod[name=&amp;quot;forward&amp;quot;](%2, %x.1) # x.py:38:12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %5 : __torch__.LeNetClassifier = prim::GetAttr[name=&amp;quot;classifer&amp;quot;](%self)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %x.5 : Tensor = prim::CallMethod[name=&amp;quot;forward&amp;quot;](%5, %x.3) # x.py:39:12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return (%x.5)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can see that the IR preserves the module structure we have in our python code.&lt;&#x2F;p&gt;
&lt;p&gt;From the user perspective it behaves like a normal PyTorch module. You can run the forward pass using the forward method or just calling the module &lt;code&gt;torch_script_module(in_tensor).&lt;&#x2F;code&gt; The JIT interpreter will run the module and return the results. From here we are in a position to compile our module further to run more efficiently on GPUs with TRTorch.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;compiling-with-trtorch-in-python&quot;&gt;Compiling with TRTorch in Python&lt;&#x2F;h2&gt;
&lt;p&gt;To compile your TorchScript module with TRTorch, all you need to do is provide the module and some compiler settings to TRTorch and you will be returned an optimized TorchScript module to run or add into another PyTorch module. The only required setting is the input size for applications which will have a static input size which is defined as a list of either list types like lists, tuples or PyTorch size objects. If your application needs to support a range of sizes, entries in the list should be dictionaries of minimum, optimal and maximum sizes which describe the range of dimensions that the auto-tuner should use for optimization. The auto-tuner will select kernels which have the lowest runtime for the optimal size but are valid through the range of dimensions specified. You can also specify settings such as operating precision for the engine or target device.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; trtorch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;compile_settings&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;input_shapes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;min&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 224&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 224&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;opt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 512&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 512&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1024&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1024&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        },&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; # For static size [1, 3, 224, 224]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;op_precision&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;half&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; # Run with FP16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;trt_ts_module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;torch_script_module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; compile_settings&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;input_data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; input_data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;half&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; trt_ts_module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;input_data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;working-with-torchscript-in-c&quot;&gt;Working with TorchScript in C++&lt;&#x2F;h2&gt;
&lt;p&gt;After converting a PyTorch module to TorchScript our dependency on Python ends. We can just save our TorchScript module using &lt;code&gt;torch.jit.save&lt;&#x2F;code&gt; which will serialize the TorchScript code, weights and other information into a package and load it in a C++ application.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;torch&#x2F;script.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; &#x2F;&#x2F; One-stop header.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;iostream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; argc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; const char*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; argv&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;jit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Deserialize the ScriptModule from a file using torch::jit::load().&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;jit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;load&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;lt;PATH TO SAVED TS MOD&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    catch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; c10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;        std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;cerr &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;error loading the model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;cout &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;ok&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can do full training and inference in C++ with LibTorch if you would like, you can even define your modules in C++ and have access to the same powerful tensor library that backs PyTorch. (For more information: https:&#x2F;&#x2F;pytorch.org&#x2F;cppdocs&#x2F;). For instance we can run inference with our module like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;eval&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Tensor in &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;randn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;auto&lt;&#x2F;span&gt;&lt;span&gt; out &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and to run on the GPU:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;eval&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kCUDA&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Tensor in &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;randn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kCUDA&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;auto&lt;&#x2F;span&gt;&lt;span&gt; out &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see it is pretty similar to the Python API. When you call the forward method, you again invoke the JIT interpreter in the same way running a PyTorch module in Python would to run the TorchScript code and return back the results.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;compiling-with-trtorch-in-c&quot;&gt;Compiling with TRTorch in C++&lt;&#x2F;h2&gt;
&lt;p&gt;We are also at the point where we can compile and optimize our module with TRTorch in C++. With our module loaded, we can feed it into the TRTorch compiler. When we do so, we must provide a similar set of additional information on the expected input size and also configure any settings when we do.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;torch&#x2F;script.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;trtorch&#x2F;trtorch.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;at&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kCUDA&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;eval&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; in &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;randn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kCUDA}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; trt_mod &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;CompileGraph&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;ExtraInfo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;InputRange&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;{{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sizes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span&gt;}}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; out &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; trt_mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{in}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That’s it! Now the graph runs a TensorRT optimized version of the module through the JIT interpreter.&lt;&#x2F;p&gt;
&lt;p&gt;We can also set settings like operating precision to run in FP16.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;torch&#x2F;script.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;trtorch&#x2F;trtorch.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;at&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kCUDA&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;eval&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; in &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;randn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kCUDA}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kHALF&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; input_sizes &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;ExtraInfo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;InputRange&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sizes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;ExtraInfo info&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;input_sizes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    info&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;op_precision&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kHALF&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; trt_mod &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;CompileGraph&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; info&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; out &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; trt_mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{in}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now we are running the module in FP16 precision.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to save the engine produced by TRTorch to use in a TensorRT application, you can use the &lt;code&gt;ConvertGraphToTRTEngine&lt;&#x2F;code&gt; API (this API is available in Python as well and is compatible with the TensorRT Python API to deploy).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;torch&#x2F;script.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;trtorch&#x2F;trtorch.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;at&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kCUDA&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;eval&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; in &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;randn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kCUDA}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kHALF&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; input_sizes &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;ExtraInfo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;InputRange&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sizes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;ExtraInfo info&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;input_sizes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    info&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;op_precision&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kHALF&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; trt_mod &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;ConvertGraphToTRTEngine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span&gt; info&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;ofstream out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&#x2F;tmp&#x2F;engine_converted_from_jit.trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    out &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    out&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;close&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;compiler-internals&quot;&gt;Compiler Internals&lt;&#x2F;h2&gt;
&lt;p&gt;When a module is provided to TRTorch, it goes through three main phases, lowering, compilation, and execution.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lowering-phase&quot;&gt;Lowering Phase&lt;&#x2F;h3&gt;
&lt;p&gt;The lowering is made up of a set of passes (some from PyTorch and some specific to TRTorch) run over the graph IR to map the large PyTorch opset to a reduced opset that is easier to convert to TensorRT.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graph(%input.2 : Tensor):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %2 : Float(84, 10) = prim::Constant[value=&amp;lt;Tensor&amp;gt;]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %3 : Float(120, 84) = prim::Constant[value=&amp;lt;Tensor&amp;gt;]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %4 : Float(576, 120) = prim::Constant[value=&amp;lt;Tensor&amp;gt;]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %5 : int = prim::Constant[value=-1]() # x.py:25:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %6 : int[] = prim::Constant[value=annotate(List[int], [])]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %7 : int[] = prim::Constant[value=[2, 2]]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %8 : int[] = prim::Constant[value=[0, 0]]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %9 : int[] = prim::Constant[value=[1, 1]]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %10 : bool = prim::Constant[value=1]() # ~&#x2F;.local&#x2F;lib&#x2F;python3.6&#x2F;site-packages&#x2F;torch&#x2F;nn&#x2F;modules&#x2F;conv.py:346:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %11 : int = prim::Constant[value=1]() # ~&#x2F;.local&#x2F;lib&#x2F;python3.6&#x2F;site-packages&#x2F;torch&#x2F;nn&#x2F;functional.py:539:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %12 : bool = prim::Constant[value=0]() # ~&#x2F;.local&#x2F;lib&#x2F;python3.6&#x2F;site-packages&#x2F;torch&#x2F;nn&#x2F;functional.py:539:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %self.classifer.fc3.bias : Float(10) = prim::Constant[value= 0.0464  0.0383  0.0678  0.0932  0.1045 -0.0805 -0.0435 -0.0818  0.0208 -0.0358 [ CUDAFloatType{10} ]]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %self.classifer.fc2.bias : Float(84) = prim::Constant[value=&amp;lt;Tensor&amp;gt;]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %self.classifer.fc1.bias : Float(120) = prim::Constant[value=&amp;lt;Tensor&amp;gt;]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %self.feat.conv2.weight : Float(16, 6, 3, 3) = prim::Constant[value=&amp;lt;Tensor&amp;gt;]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %self.feat.conv2.bias : Float(16) = prim::Constant[value=&amp;lt;Tensor&amp;gt;]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %self.feat.conv1.weight : Float(6, 1, 3, 3) = prim::Constant[value=&amp;lt;Tensor&amp;gt;]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %self.feat.conv1.bias : Float(6) = prim::Constant[value= 0.0530 -0.1691  0.2802  0.1502  0.1056 -0.1549 [ CUDAFloatType{6} ]]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %input0.4 : Tensor = aten::_convolution(%input.2, %self.feat.conv1.weight, %self.feat.conv1.bias, %9, %8, %9, %12, %8, %11, %12, %12, %10) # ~&#x2F;.local&#x2F;lib&#x2F;python3.6&#x2F;site-packages&#x2F;torch&#x2F;nn&#x2F;modules&#x2F;conv.py:346:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %input0.5 : Tensor = aten::relu(%input0.4) # ~&#x2F;.local&#x2F;lib&#x2F;python3.6&#x2F;site-packages&#x2F;torch&#x2F;nn&#x2F;functional.py:1063:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %input1.2 : Tensor = aten::max_pool2d(%input0.5, %7, %6, %8, %9, %12) # ~&#x2F;.local&#x2F;lib&#x2F;python3.6&#x2F;site-packages&#x2F;torch&#x2F;nn&#x2F;functional.py:539:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %input0.6 : Tensor = aten::_convolution(%input1.2, %self.feat.conv2.weight, %self.feat.conv2.bias, %9, %8, %9, %12, %8, %11, %12, %12, %10) # ~&#x2F;.local&#x2F;lib&#x2F;python3.6&#x2F;site-packages&#x2F;torch&#x2F;nn&#x2F;modules&#x2F;conv.py:346:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %input2.1 : Tensor = aten::relu(%input0.6) # ~&#x2F;.local&#x2F;lib&#x2F;python3.6&#x2F;site-packages&#x2F;torch&#x2F;nn&#x2F;functional.py:1063:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %x.1 : Tensor = aten::max_pool2d(%input2.1, %7, %6, %8, %9, %12) # ~&#x2F;.local&#x2F;lib&#x2F;python3.6&#x2F;site-packages&#x2F;torch&#x2F;nn&#x2F;functional.py:539:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %input.1 : Tensor = aten::flatten(%x.1, %11, %5) # x.py:25:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %27 : Tensor = aten::matmul(%input.1, %4)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %28 : Tensor = trt::const(%self.classifer.fc1.bias)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %29 : Tensor = aten::add_(%28, %27, %11)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %input0.2 : Tensor = aten::relu(%29) # ~&#x2F;.local&#x2F;lib&#x2F;python3.6&#x2F;site-packages&#x2F;torch&#x2F;nn&#x2F;functional.py:1063:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %31 : Tensor = aten::matmul(%input0.2, %3)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %32 : Tensor = trt::const(%self.classifer.fc2.bias)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %33 : Tensor = aten::add_(%32, %31, %11)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %input1.1 : Tensor = aten::relu(%33) # ~&#x2F;.local&#x2F;lib&#x2F;python3.6&#x2F;site-packages&#x2F;torch&#x2F;nn&#x2F;functional.py:1063:0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %35 : Tensor = aten::matmul(%input1.1, %2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %36 : Tensor = trt::const(%self.classifer.fc3.bias)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %37 : Tensor = aten::add_(%36, %35, %11)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return (%37)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(CompileGraph)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The graph has now been transformed from a collection of modules, each managing their own parameters into a single graph with the  parameters inlined into the graph and all of the operations laid out. TRTorch has also executed a number of optimizations and mappings to make the graph easier to translate to TensorRT and produces more efficient TensorRT engines. From here the compiler can assemble the TensorRT engine by following the dataflow through the graph.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;conversion-phase&quot;&gt;Conversion Phase&lt;&#x2F;h3&gt;
&lt;p&gt;In the conversion phase we traverse the lowered graph and construct an equivalent TensorRT graph. The conversion phase is made up of three main components, a context to manage compile time data, a evaluator library which will execute operations that can be resolved at compile time and a converter library which maps an op from JIT to TensorRT. Operations are mapped to TensorRT through the use of modular converters, functions that take a node from a the JIT graph and produce an equivalent layer or subgraph in TensorRT. TRTorch ships with a library of these converters stored in a registry, that will be executed depending on the node being analyzed. For instance an &lt;code&gt;aten::relu(%input0.4)&lt;&#x2F;code&gt; instruction will trigger the ReLU converter to be run on it, producing an activation layer in the TensorRT graph.&lt;&#x2F;p&gt;
&lt;p&gt;For example, if we try to compile a graph with a build of TRTorch that doesn’t support the flatten operation (&lt;code&gt;aten::flatten&lt;&#x2F;code&gt;) you may see this error:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;terminate called after throwing an instance of &amp;#39;trtorch::Error&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;what():  [enforce fail at core&#x2F;conversion&#x2F;conversion.cpp:109] Expected converter to be true but got false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Unable to convert node: %input.1 : Tensor = aten::flatten(%x.1, %11, %5) # x.py:25:0 (conversion.AddLayer)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Schema: aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -&amp;gt; (Tensor)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Converter for aten::flatten requested, but no such converter was found.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;If you need a converter for this operator, you can try implementing one yourself&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;or request a converter: https:&#x2F;&#x2F;www.github.com&#x2F;NVIDIA&#x2F;TRTorch&#x2F;issues&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We register converters in the global converter registry, associating a function schema like &lt;code&gt;aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -&amp;gt; (Tensor)&lt;&#x2F;code&gt; with a lambda that will take the state of the conversion, the node&#x2F;operation in question to convert and all of the inputs to the node and produces as a side effect a new layer in the TensorRT network. Arguments are passed as a vector of inspectable unions of TensorRT &lt;code&gt;ITensors&lt;&#x2F;code&gt; and Torch &lt;code&gt;IValues&lt;&#x2F;code&gt; (PyTorch data such as Tensors, ints, lists, etc.) in the order arguments are listed in the schema.&lt;&#x2F;p&gt;
&lt;p&gt;Below is an implementation of an &lt;code&gt;aten::flatten&lt;&#x2F;code&gt; converter.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;torch&#x2F;script.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;trtorch&#x2F;trtorch.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;trtorch&#x2F;core&#x2F;conversion&#x2F;converters&#x2F;converters.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;static auto&lt;&#x2F;span&gt;&lt;span&gt; flatten_converter &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;core&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;conversion&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;converters&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;RegisterNodeConversionPatterns&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;pattern&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -&amp;gt; (Tensor)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        [](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;core&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;conversion&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;ConversionCtx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; ctx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;jit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;Node&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;            trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;core&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;conversion&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;converters&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            auto&lt;&#x2F;span&gt;&lt;span&gt; in &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;ITensor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            auto&lt;&#x2F;span&gt;&lt;span&gt; start_dim &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;unwrapToInt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            auto&lt;&#x2F;span&gt;&lt;span&gt; end_dim &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;unwrapToInt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            auto&lt;&#x2F;span&gt;&lt;span&gt; in_shape &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;core&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;util&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;toVec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;getDimensions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            auto&lt;&#x2F;span&gt;&lt;span&gt; out_shape &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;flatten&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;torch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;rand&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;in_shape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span&gt; start_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; end_dim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sizes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            auto&lt;&#x2F;span&gt;&lt;span&gt; shuffle &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; ctx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;net&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;addShuffle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            shuffle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;setReshapeDimensions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;core&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;util&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;toDims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;out_shape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            shuffle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;setName&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;trtorch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;core&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;util&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;node_info&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;c_str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            auto&lt;&#x2F;span&gt;&lt;span&gt; out_tensor &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; ctx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;AssociateValueAndTensor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; shuffle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;getOutput&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;writing-converters&quot;&gt;Writing Converters&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;converter-contract&quot;&gt;Converter Contract&lt;&#x2F;h5&gt;
&lt;p&gt;What is guaranteed to converters&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;In the args there will be an entry for each node input value, either a ITensor or IValue&lt;&#x2F;li&gt;
&lt;li&gt;Inputs will be provided in order according to the function schema&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Responsibilities of a converter&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Args must be guaranteed to be a type to unwrap the Arg union without checking, typically input tensor arguments can be expected to be ITensors&lt;&#x2F;li&gt;
&lt;li&gt;Any weights or static values must guaranteed to be valid until the end of conversion time&lt;&#x2F;li&gt;
&lt;li&gt;Converters are expected to produce an &lt;code&gt;IValue&lt;&#x2F;code&gt; or &lt;code&gt;ITensor &lt;&#x2F;code&gt;for each output of a node. The compiler will check this and produce warnings if there are Values that don’t have associated ITensors or IValues.&lt;&#x2F;li&gt;
&lt;li&gt;Outputs must be annotated. There must be an association between a JIT nodes output values and the new TRT layers output tensors in the value_tensor_map in the conversion context&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h5 id=&quot;conversion-context&quot;&gt;Conversion Context&lt;&#x2F;h5&gt;
&lt;p&gt;The conversion context maintains the state of conversion, it manages the Network Definition, two maps one that stores associations between &lt;code&gt;Values&lt;&#x2F;code&gt; and &lt;code&gt;IValues&lt;&#x2F;code&gt; (the evaluated_value_map) and one that stores associations between &lt;code&gt;Values&lt;&#x2F;code&gt; and &lt;code&gt;ITensors&lt;&#x2F;code&gt;, and any sort of memory that needs to live until the end of conversion. The main apis that you will interface with in converters is directly accessing the network definition to add layers ctx-&amp;gt;net and data association functions &lt;code&gt;ctx-&amp;gt;AssociateValueAndTensor()&lt;&#x2F;code&gt; and &lt;code&gt;ctx-&amp;gt;AssociateValueAndIValue()&lt;&#x2F;code&gt;, which you will use to add layers to the TRT layers and log pairs of node outputs and static values or TensorRT layer outputs.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;args&quot;&gt;Args&lt;&#x2F;h5&gt;
&lt;p&gt;Arguments provided to the converter are inspectable unions of nvinfer1::ITensors and torch::jit::IValues (i.e. abstract dataflow in the TensorRT graph and static values). You are guaranteed that you will have some argument for each input value for the node. They are provided in the order of the function schema. It can be expected that inputs (meaning the parameters that would be passed into the forward function of a module in PyTorch) will be ITensors but the Arg class also has mechanisms to inspect arguments safely before unwrapping if you are unsure. Args also have deep unwrap methods that let you get straight to the underlying data in an IValue if you know it’s safe. You can also pass in a fallback value if there is a chance the IValue is None. IValues have been extended to be able to hold a wrapper around ITensors only in the case of TensorLists. You can get an ITensor from an IValue by a pattern similar to this: ivalue.toCustomClass&lt;TensorContainer&gt;()-&amp;gt;tensor() . You can tell if an IValue contains a Tensor or an ITensor by using ivalue.isTensor() or ivalue.isCustomClass() .&lt;&#x2F;p&gt;
&lt;h5 id=&quot;weights&quot;&gt;Weights&lt;&#x2F;h5&gt;
&lt;p&gt;Weights are used during build time, so any weights need to be guaranteed to live until the end of the conversion phase. TensorRT also uses its own weights structure to hold the weights. There is a wrapper around this class available to converts which abstracts a lot of this.&lt;&#x2F;p&gt;
&lt;p&gt;The weights wrapper class can accept either at::Tensors or singular values (right now). You also need to pass the conversion context when constructing these weights because internally the weights class will allocate memory managed by the conversion context to store a copy of the tensor data. This data gets freed when the conversion context destructor gets destroyed so converters don’t really need to think about it.&lt;&#x2F;p&gt;
&lt;p&gt;There is metadata generated from the shape of the input data which becomes useful in interfacing with TensorRT, such as number of input maps, number of output maps and kernel shape.&lt;&#x2F;p&gt;
&lt;p&gt;The complier will topologically traverse the graph from the lowering phase and then iteratively construct the TensorRT graph. Once it is complete, the graph is optimized for the target hardware using TensorRT&#x27;s library of tuned kernel implementations. Here TRTorch creates a JIT Module to execute the TensorRT engine which will be  instantiated and managed by the TRTorch runtime.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the graph that you get back after compilation is complete:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graph(%self.1 : __torch__.___torch_mangle_10.LeNet_trt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %2 : Tensor):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %1 : int = prim::Constant[value=94106001690080]()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    %3 : Tensor = trt::execute_engine(%1, %2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    return (%3)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(AddEngineToGraph)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can see the call where the engine is executed, based on a constant which is the ID of the engine, telling JIT how to find the engine and the input tensor which will be fed to TensorRT.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;runtime-phase&quot;&gt;Runtime Phase&lt;&#x2F;h3&gt;
&lt;p&gt;After the graph is provided to the user, it is now a fully compliant TorchScript module. You can seralize and deserialize it the same way and all that is required is to have the TRTorch runtime loaded in memory.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;getting-trtorch&quot;&gt;Getting TRTorch&lt;&#x2F;h3&gt;
&lt;p&gt;TRTorch 0.1.0 precompiled binaries are available on GitHub &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;NVIDIA&#x2F;TRTorch&#x2F;releases&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;NVIDIA&#x2F;TRTorch&#x2F;releases&lt;&#x2F;a&gt; You can get a tarball distribution of the C++ API (either pre-CXX11 ABI or CXX11 ABI builds) and wheel files for the Python package, which is installable via pip. To get the latest and greatest, you can compile the library and&#x2F;or the Python package from source following these instructions: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nvidia.github.io&#x2F;TRTorch&#x2F;tutorials&#x2F;installation.html&quot;&gt;https:&#x2F;&#x2F;nvidia.github.io&#x2F;TRTorch&#x2F;tutorials&#x2F;installation.html&lt;&#x2F;a&gt;. Compilation on embedded platforms like Jetson is possible via minor modifications to the build system.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;more-information&quot;&gt;More Information&lt;&#x2F;h3&gt;
&lt;p&gt;I gave two talks on TRTorch at the GPU Technology Conference:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nvidia.com&#x2F;en-us&#x2F;gtc&#x2F;session-catalog&#x2F;?search.language=1594320459782001LCjF&amp;amp;tab.catalogtabfields=1600209910618002Tlxt&amp;amp;search=TRTorch#&#x2F;session&#x2F;15985554695910019Knc&quot;&gt;TRTorch: A PyTorch&#x2F;TorchScript Compiler Targeting NVIDIA GPUs Using TensorRT&lt;&#x2F;a&gt; - GTC 2020 October&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.nvidia.com&#x2F;gtc&#x2F;2020&#x2F;video&#x2F;s21671-vid&quot;&gt;PyTorch-TensorRT: Accelerating Inference in PyTorch with TensorRT&lt;&#x2F;a&gt; - GTC 2020&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Github: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;NVIDIA&#x2F;TRTorch&#x2F;&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;NVIDIA&#x2F;TRTorch&#x2F;&lt;&#x2F;a&gt;
Project Page: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nvidia.github.io&#x2F;TRTorch&#x2F;&quot;&gt;https:&#x2F;&#x2F;nvidia.github.io&#x2F;TRTorch&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
      <item>
          <title>Naren&#x27;s Web Directory</title>
          <pubDate>Sun, 17 Nov 2019 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/web-directory/</link>
          <guid>https://www.narendasan.com/blog/web-directory/</guid>
          <description xml:base="https://www.narendasan.com/blog/web-directory/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;web-directory&#x2F;imgs&#x2F;zuck-header.jpg&quot; alt=&quot;zuck-header&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dumping-facebook&quot;&gt;Dumping Facebook&lt;&#x2F;h2&gt;
&lt;p&gt;Sophomore year of college I started becoming more aware of the all the data I was posting online, mostly because I realized how much time I was spending on Facebook in the first place. Before it was on the first page of my home screen on my phone and always opened in a browser tab. Whenever I had a free moment on the bus or an empty URL bar in the browser I would find myself moving to hit the &#x27;f&#x27; icon, or typing &#x27;f&#x27; in to the URL bar without thinking and end up aimlessly scrolling Facebook.  Once I realized it, I started to consider why I used Facebook, what was I getting out of it and also what was the true cost of using the service? In middle and high school I did things like backfilling all the places I&#x27;ve been, where I worked, what my interests were and more out of some sense of completion. But, now I was wondering, why does everyone (and Facebook) need to know that I went to Botswana and really like the All Blacks and Bill Nye the Science Guy?&lt;&#x2F;p&gt;
&lt;p&gt;At this time skepticism regarding Facebook was increasing, I was starting to notice reports about tracking pixels, reports of experimentation on users without consent, the addition of the M assistant in Messenger and some of the dark patterns associated with the like button (obviously this sort of criticism really took off after the election of Trump). I was also looking more into &quot;Big Data&quot; as they referred to what Facebook was doing then as I was diving deeper into my work on Computer Vision and Machine Learning.  As I learned more about what is required to develop effective systems like the ones Facebook was making and especially the incentives that Facebook has to design systems in particular ways, I grew a lot more wary of them and similar services on the internet (Instagram, TicTok, etc.). The straw that broke the camels back was this paper from Prof. Karahalios group at UIUC &lt;em&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;social.cs.uiuc.edu&#x2F;papers&#x2F;pdfs&#x2F;Eslami_Algorithms_CHI15.pdf&quot;&gt;“I always assumed that I wasn’t really that close to [her]”:Reasoning about invisible algorithms in the news feed&quot;&lt;&#x2F;a&gt;&lt;&#x2F;em&gt; which poignantly raises questions about the effects these recommendation engines have on us (and if we notice at all).&lt;&#x2F;p&gt;
&lt;p&gt;But Facebook has it&#x27;s uses. First of all its a great &lt;em&gt;facebook&lt;&#x2F;em&gt;, an index of people you know. By extension it&#x27;s a really powerful local organizing tool and messaging platform. These are the features that Facebook touts as it tries to posture itself as a force for good and they are right because it&#x27;s a unique feature of their platform. And this is why I haven&#x27;t &quot;gone off the grid&quot; and deactivated my account, especially while I was in college organizing things. But I have significantly curtailed my use and limit it to the features that truly have the best exchange rate between the utility and the costs.  So I still have Messenger installed on my phone for the random message I need to send &#x2F; receive from someone I talked to last 3 years ago and until Facebook got rid of the Events app (and replaced it with a recommender app for local events) I had that too. But I have a strong preference not to use Messenger and most conversations that go long enough get ported to Wire, Signal, maybe Telegram or if necessary iMessage&#x2F;SMS.&lt;&#x2F;p&gt;
&lt;p&gt;However these aren&#x27;t the core uses of Facebook for many people. The core use is the News Feed. To its credit, it really is an effective discovery method for new content especially about your friends. However, as has become abundantly clear (shown by Prof. Karahalios and others), content is not shown to you purely because it might be relevant or interesting to you. Eslami et al. shows that $&amp;gt; 50% $ of respondents in the study were previously unaware that there was a curation model operating the News Feed. &quot;[They also] found participants often attributed missing stories to their friends’ decisions to exclude them rather than to Facebook News Feed algorithm.&quot; Social media companies like other curators have their own motives for showing or suppressing content. Where these motives align with your interest, you have a healthy symbiosis. For example, if I&#x27;m looking to buy a new bike, seeing potentially paid advertising for a bike might actually be pretty nice. Or a cool story on the EF Education First team was written in Bicycle Magazine that the magazine promoted. Or just making the service useful enough to keep you on the platform consuming ads would be a worthwhile tradeoff. But a lot of times irrelevant or erroneous content is shown because it&#x27;s paid for in the most charitable case, in the more sinister case, its promoted in a faustian bargain to further increase user engagement on the platform, i.e. Facebook looks to illicit a reaction, positive or negative (it doesn&#x27;t matter) over providing relevant or informative content in a bid to get you to keep coming back. After falling for a couple instances of disinformation being promoted on Facebook, it became clear this is not a reasonable way to get news.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alternative-forms-of-curation-on-the-internet&quot;&gt;Alternative forms of curation on the Internet&lt;&#x2F;h3&gt;
&lt;p&gt;So how does one get news without a recommendation engine? Very millennial &#x2F; Gen Z question I know. One can try the newsy subreddits of Reddit. Reddit doesn&#x27;t use an recommender model, it uses the opinions of its users to promote or hide content. I found myself aimlessly scrolling it to waste time on Reddit too, so I uninstalled that app as well. But one again, there are also concerns about if the aggregate opinion of Reddit is an effective way to rank news or content. Similar to how Facebook has an incentive to promote incendiary content because it&#x27;s more engaging, the promotion of content on Reddit is based on a measure of how engaging it is. So again without the pressures of decorum, nuance and factual accuracy enforced in real life, you end up seeing the id of society embodied on reddit. The things that are most popular on Reddit are things that make you super happy (&#x2F;r&#x2F;aww, &#x2F;r&#x2F;wholesomememes, etc.) or make you super angry (&#x2F;r&#x2F;PublicFreakout, &#x2F;r&#x2F;IdiotsInCars and &#x2F;r&#x2F;trashy) (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;redditmetrics.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;redditmetrics.com&#x2F;&lt;&#x2F;a&gt;) or some other strong emotion. Other link aggregators (HackerNews etc.) have the similar problems.&lt;&#x2F;p&gt;
&lt;p&gt;So if you can&#x27;t use a model that you don&#x27;t control and you can&#x27;t use the crowd, what about the old fashioned way - Editorial Boards of reputable publications? After getting rid of Reddit on my phone too, for the next few years I mostly frequented between a couple tech sites and common news sources, essentially websites I committed to muscle
memory or that were on my bookmarks toolbar. However, for whatever journalists say about their moral responsibility, in the end they also publish to satisfy their own ends and the work is curated by a few on the editorial board. By wholly relying on one or a few sources, you are left in the same position you would be using Facebook, albeit at a different scale. Fox News is the most obvious example of this happening, but the same would happen if I only read the Jacobin or CNN or MSNBC. You can try to diversify, but I found that its a lot harder to habit form frequenting a broad range of sites over just going to the first couple sites on your home page or bookmarks bar.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-theory-of-curation-for-the-internet&quot;&gt;A Theory of Curation for the Internet&lt;&#x2F;h2&gt;
&lt;p&gt;So how do you solve this problem? You could demand Facebook, Reddit or the New York Times change, but its&#x27; unclear how successful you&#x27;d be given the things they would be potentially giving up. Is the answer tear down all curation and muddle your way through it all yourself? No. The web needs curation, don&#x27;t take the rejection of managed feeds or editorial boards as a some sign that we don&#x27;t. There are millions of exabytes of data out there, people need help parsing through it. Google is great for when you know what specifically you&#x27;re looking for. But if you have just a vague notion of a topic or no idea and just want compelling content, it&#x27;s much more effective to use someone else&#x27;s expertise as a filter.&lt;&#x2F;p&gt;
&lt;p&gt;The issue with curation as it is right now is that agency has been taken from the user (by their own choice to be clear) and they have become purely a consumer. In exchange for not expending much effort to get a wide variety of selected &quot;interesting and relevant&quot; content, you have little to no recourse when it comes to what you see and how it&#x27;s shown to you. The level of input you have is explicitly declaring your interests to the service (subscribing to subreddits or liking sources), interactions with the site (which are tracked), explicit &quot;like&#x2F;dislike&quot; buttons or complaining to maybe nudge the engine one way or another. A great example of this lack of agency is the anxiety people feel when it comes to clicking on a weird video, not because they aren&#x27;t curious about it but because it might screw up their YouTube recommendations. This seems fundamentally broken.&lt;&#x2F;p&gt;
&lt;p&gt;Aggregators as well whether they are Facebook, Reddit or the New York Times aim to abstract away the content producer from the feed. It&#x27;s beneficial to them if you do not notice the difference between a long form New Yorker piece and a quiz from BuzzFeed or an article from a wire service from one researched for years by the investigative reporting staff. It keeps you on their site, consuming their ads. But in doing that you lose the advantages that come with curators, why you&#x27;d want one in the first place. A good curator, has a consistent voice and a domain of expertise and by extension a context that their arguments are presented in. By using the New York Times, Facebook or Reddit as your &quot;broker&quot; for content from content &quot;wholesalers&quot; you lose context in addition to the loss in agency.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nesting-doll-of-curators&quot;&gt;Nesting Doll of Curators&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;web-directory&#x2F;imgs&#x2F;nesting-doll.jpg&quot; alt=&quot;nesting doll&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The best example of a healthy ecosystem of curation is podcasts. For podcasts, you don&#x27;t have a generic feed of content ordered by a third party, you have a collection of feeds, each curated by one or a few people that end up coalescing into a customized feed for each person. When looking for podcasts we don&#x27;t look for specific episodes we care about from a generic feed, we look for good voices who over time produce interesting and varied content. We are essentially trying to collect a set of curators who in aggregate give you a broad and diverse view of the world, each of them bringing a different experience and expertise to the table. The onus is now on you, the consumer, when it comes to podcasts to construct a feed that represents the breath of topics and perspectives you want to see, not anyone else. If you want to create a close minded eco-chamber, that&#x27;s your prerogative but you chose that feed not anyone else.&lt;&#x2F;p&gt;
&lt;p&gt;Unbeknownst to many, the way podcasts work is based on the open standard RSS. Content producers attach a generic feed to their website which RSS Readers can use to get a list of content published that day. RSS fell out of favor with the death of Google Reader and gradually people adopting Facebook, Twitter and Reddit. But what it did have was a similar curation model to podcasts. People chose what to subscribe to and were delivered all content from those subscriptions. From there they can choose how to filter through that feed.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s easy enough to set up an RSS feed that just shows you the postings of the day or if you&#x27;re ambitious you can take it further. There&#x27;s a whole bunch of clients you can use, I use Reeder4 on my mac and phone (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;reederapp.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;reederapp.com&#x2F;&lt;&#x2F;a&gt;), and I have a shared feed in a discord server I am in using a bot we made which posts the new posts every morning (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;the-round-table&#x2F;trtbot&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;the-round-table&#x2F;trtbot&lt;&#x2F;a&gt;). The beauty of RSS is it gives you a mechanism to diversify the sources you&#x27;re exposed to without the additional cognitive load. The issue you face without RSS is to remember to check out all of those sources. This is not an issue if you automatically poll all the sources you&#x27;ve written down as interesting.  As to my usage patterns issue, which started this journey, it has the benefit of being based around pulls (i.e. you need to ask for more content for more content to show), and inherently limited by the content being published, so you can&#x27;t build the habit of endlessly refreshing the page to get more content.&lt;&#x2F;p&gt;
&lt;p&gt;But both Podcasts and RSS are based around multiple levels of curation, there is curation in the sources and this is done by the user, and there is curation in each source, done by the source themselves. The user has the ability to change the sources they see at their will but will need to go through all the content sources put out. The nice thing is that they get to choose what metrics are used to organize content. It gives the user recourse to change the feed as they like while also benefiting from the value curators provide.&lt;&#x2F;p&gt;
&lt;p&gt;RSS is not a complete solution however. The key flaw (that curated feeds are really good at and is probably why people switched) is the discovery of the new is &lt;em&gt;really&lt;&#x2F;em&gt; hard with RSS by itself. RSS is static with regard to sources. So while some cool new source might appear on Reddit or Facebook because someone else frequents that site, you&#x27;ll never find it if you&#x27;re not looking it. It&#x27;s easy enough to continue to use Reddit, Facebook, Twitter or HackerNews and remain vigilant for new sources which you add to your RSS feed, but these are stochastic events based on Reddit, Facebook etc. catching your interest and may draw you back into the algorithmic or crowd feed fold.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-web-directory&quot;&gt;The Web Directory&lt;&#x2F;h4&gt;
&lt;p&gt;Turns out this too was solved previously, coming from a time before Web 2.0 or even Google. How do you find cool places on the web if you don&#x27;t have a search engine or you don&#x27;t know what you&#x27;re looking for? How do you know what&#x27;s even out there on the Web? With a directory of course! When the internet was small enough that all the important websites could fit on a page or a few, websites like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;19961017235908&#x2F;http:&#x2F;&#x2F;www2.yahoo.com&#x2F;&quot;&gt;yahoo.com&lt;&#x2F;a&gt; served as the phone book of the internet, categorizing cool or interesting sites so that people could find their way around.&lt;&#x2F;p&gt;
&lt;p&gt;So the practice was if I was looking for a website on rugby or just interesting place to go, I&#x27;d go to yahoo.com and just look in the sport section for relevant sounding websites. People also maintained their own &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;werbach.com&#x2F;hotlist.html&quot;&gt;personal lists&lt;&#x2F;a&gt; (called web hotlists) containing their discoveries on the web. So if I&#x27;m looking for interesting places on the web, I can hop to a buddy&#x27;s website and see what they were reading.&lt;&#x2F;p&gt;
&lt;p&gt;I believe this is the missing piece to make self crafted feeds (via RSS or some other protocol) relevant as a method to find and discover new content. There needs to be ways to explore and discover new sources. Podcasts do this in a wide variety of ways; they cross promote themselves, apps have special discovery views, but the best way (in terms of how many podcasts I&#x27;ve liked from this method) I believe has been word of mouth, i.e. the curation of sources from people whose opinions I already respect.  I think this is a practice that needs to comeback (with RSS) as part of the infrastructure to live a recommendation feed free life. In order for people to be able to effectively use RSS to find content on the internet, there needs to easy ways to explore what is out there at the source level. Allowing others to benefit from your exploration through a directory is an easy way to develop this infrastructure. There is a similar old idea I&#x27;ve seen pop up again called Web Rings, which is a group of self referential websites. Members of the ring will link to other members, either to drive traffic towards them or to optimize for SEO. A pretty cool one is this one from XXIIVV &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;webring.xxiivv.com&#x2F;#&quot;&gt;webring.xxiivv.com&lt;&#x2F;a&gt;. Regardless of how you do it though, the support must be out there for people so they can make decisions about what they want to see themselves.&lt;&#x2F;p&gt;
&lt;p&gt;So as a step in this direction, I&#x27;m putting up my own &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;narendasan.com&#x2F;directory.html&quot;&gt;Web Directory&lt;&#x2F;a&gt;. Its pretty plain right now (&lt;del&gt;I may attach a formated OPML file with the entries so its easy to import into a RSS reader later&lt;&#x2F;del&gt; &lt;strong&gt;UPDATE:&lt;&#x2F;strong&gt; You can now find an OPML file with all the sources &lt;a href=&quot;..&#x2F;naren-web-directory.opml&quot;&gt;here&lt;&#x2F;a&gt;), but it includes a list of the websites, youtube channels and podcasts I enjoy. I may add other formats to this, but the rule I&#x27;m keeping to is the source must either be a website or consumable by RSS (or both). I hope that you do the same and if you do you should tweet me or whatever other form of communication you prefer &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.twitter.com&#x2F;narendasan&quot;&gt;@narendasan&lt;&#x2F;a&gt;. I&#x27;d love to see it, I&#x27;m always looking for more content.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;web-directory&#x2F;imgs&#x2F;directory.png&quot; alt=&quot;directory&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;post-script-twitter-youtube&quot;&gt;Post Script (Twitter &amp;amp; YouTube)&lt;&#x2F;h2&gt;
&lt;p&gt;So even though I basically got rid of Facebook as a news feed and I frequent a few specific subreddits, I still have a couple recommendation engines in my life, YouTube and Twitter.&lt;&#x2F;p&gt;
&lt;p&gt;YouTube is an interesting case. Video is not cheap to host, especially compared to a website. And there is no GitHub pages for Video (yet). So there is structural pressure to upload to a service (this centralizes video on a few sites). The additional pressures to actually make a living of content creation, further centralizes video on the one or two services that have that yield the most revenue, for short form video this is YouTube. I don&#x27;t know how to change this. There are some alternatives (PeerTube, FloatPlane etc.) but for now YouTube is the home of video on the internet, and as much as I want to make decisions for myself, I&#x27;d much rather watch the guys at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;channel&#x2F;UCeWaURbVb0kEFTpN2pB38cw&quot;&gt;Mahalo My Dude&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;channel&#x2F;UCu2oaGQ6Dds6g9lqfexUFbQ&quot;&gt;Squidge Rugby&lt;&#x2F;a&gt;. So I resort to trying to use the subscriptions tab when I remember to still maintain as much control over what I&#x27;m seeing as possible. But by default you are given an recommendation feed and so there is cognitive load associated with switching over (you can intentionally make the recommendation feed less helpful to aid in this cognitive load by telling Youtube to not track history and set your region to some where else). But people may not know or may have forgotten that there is actually RSS support for youtube channels, so you may be able to bypass the YouTube recommendation engine that way.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-to-subscribe-to-youtube-channels-over-rss&quot;&gt;How to subscribe to YouTube Channels over RSS&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;get-rss-updates-for-a-single-channel&quot;&gt;Get RSS updates for a single channel&lt;&#x2F;h4&gt;
&lt;p&gt;To get an RSS feed of a single channel’s uploads, paste the channel URL into your RSS reader.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;This seems to only work for channels associated with Users on YouTube (look for &lt;code&gt;&#x2F;user&#x2F;&lt;&#x2F;code&gt; in the url to tell the difference)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;You can subscribe to &quot;channel channels&quot; by finding the external channel id in the URL and using this URL template&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;feeds&#x2F;videos.xml?channel_id=CHANNEL_ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;channel&#x2F;UCWq-qJSudqKrzquTVep9Jwg&quot;&gt;Royal Ocean Film Society&lt;&#x2F;a&gt; who&#x27;s url is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;channel&#x2F;UCWq-qJSudqKrzquTVep9Jwg&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;channel&#x2F;UCWq-qJSudqKrzquTVep9Jwg&lt;&#x2F;a&gt;, the RSS feed would be &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;feeds&#x2F;videos.xml?channel_id=UCWq-qJSudqKrzquTVep9Jwg&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;feeds&#x2F;videos.xml?channel_id=UCWq-qJSudqKrzquTVep9Jwg&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can also subscribe to specific playlist similarly using the following template&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;feeds&#x2F;videos.xml?playlist_id=PLAYLIST_ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So to subscribe to all the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;playlist?list=PLKtIunYVkv_SUyXj_6Fe53okfzM9yVq1F&quot;&gt;&lt;em&gt;It&#x27;s Alive&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;playlist?list=PLKtIunYVkv_SUyXj_6Fe53okfzM9yVq1F&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;playlist?list=PLKtIunYVkv_SUyXj_6Fe53okfzM9yVq1F&lt;&#x2F;a&gt;) videos from Bon Appetit, you would use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;feeds&#x2F;videos.xml?playlist_id=PLKtIunYVkv_SUyXj_6Fe53okfzM9yVq1F&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;feeds&#x2F;videos.xml?playlist_id=PLKtIunYVkv_SUyXj_6Fe53okfzM9yVq1F&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;get-rss-updates-for-all-subscriptions&quot;&gt;Get RSS updates for all subscriptions&lt;&#x2F;h4&gt;
&lt;p&gt;To import all your YouTube subscriptions to your RSS reader, you can use our OPML file download feature:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Download the OPML file by clicking &lt;strong&gt;Export subscriptions&lt;&#x2F;strong&gt; at the bottom of your &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;subscription_manager&quot;&gt;Manage Subscriptions&lt;&#x2F;a&gt; page. This will download a file named &quot;subscription_manager.xml&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;Import the OPML file in your RSS reader.
&lt;ul&gt;
&lt;li&gt;In Feedly, for example, this can be found in Organize in the left panel, then Import OPML.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For Twitter, again I feel the issue is that the format is unique. Not everyone has a blog, but &quot;everyone&quot; has a Twitter account. Especially for academia, I probably would not hear about a good percentage of the work in ML&#x2F;DL that I would be interested in without Twitter. My solution here is to strongly prefer the use of self curated lists as well as setting the main feed to &quot;Latest Tweets show up as they happen&quot;, which avoids the cognitive load you need to deal with on YouTube. I also to avoid the use issues I had with Facebook and Reddit don&#x27;t install the Twitter app on my phone. I manage feeds of accounts for Academia, Tech, Open Source, Sports, Colorado and more. So ultimately I end up treating like I treat my RSS feed, mostly check them about once a day.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-to-set-your-timeline-to-latest-tweets&quot;&gt;How to set your timeline to latest tweets&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Click on the sparkle ✨
&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;web-directory&#x2F;imgs&#x2F;linear-feed-1.png&quot; alt=&quot;linear-feed-1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Select &quot;See latest Tweets instead&quot;
&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;web-directory&#x2F;imgs&#x2F;linear-feed-2.png&quot; alt=&quot;linear-feed-2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Now you should see the feed chronologically
&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;web-directory&#x2F;imgs&#x2F;linear-feed-3.png&quot; alt=&quot;linear-feed-3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Note the fine print though &lt;strong&gt;&quot;You&#x27;ll be switched back to Home after you&#x27;ve been away for a while&quot;&lt;&#x2F;strong&gt; its unclear how this really works and when you will be switched back, here is what Twitter said
&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;web-directory&#x2F;img&#x2F;feed-setting.png&quot; alt=&quot;feed-setting&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
      <item>
          <title>Real Time Autonomous Vehicle Perception on Heterogenous Hardware</title>
          <pubDate>Fri, 12 Apr 2019 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/dl4agx/</link>
          <guid>https://www.narendasan.com/blog/dl4agx/</guid>
          <description xml:base="https://www.narendasan.com/blog/dl4agx/">&lt;p&gt;I wrote a post for the NVIDIA Developer Blog on how we implemented real-time autonomous vehicle perception using the specialized
hardware available on the NVIDIA DRIVE AGX Self Driving Computer. The AGX is powered by Xavier, NVIDIAs in-house ARM SoC which
includes a Volta-based GPU, two programmable vision accelerators (used for tasks like edge detection, epipolar geometry) and two deep learning accelerators
(fixed function neural network accelerator) in a unified memory architecture. We show how you can easily span all of these different types of simultaneously accelerators to make a real time perception pipeline.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;take-a-look-https-developer-nvidia-com-blog-drive-agx-accelerators-object-detection&quot;&gt;Take a look: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.nvidia.com&#x2F;blog&#x2F;drive-agx-accelerators-object-detection&#x2F;&quot;&gt;https:&#x2F;&#x2F;developer.nvidia.com&#x2F;blog&#x2F;drive-agx-accelerators-object-detection&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
</description>
      </item>
      <item>
          <title>Twilight</title>
          <pubDate>Wed, 13 Dec 2017 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/twilight/</link>
          <guid>https://www.narendasan.com/blog/twilight/</guid>
          <description xml:base="https://www.narendasan.com/blog/twilight/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twilight&#x2F;assets&#x2F;install.jpg&quot; alt=&quot;install&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A portion of the Twilight Installation in the office of ACM@UIUC&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Twilight is a concept for self organizing office lighting based on similar ideas to my work on
the &lt;a href=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twilight&#x2F;amorphous-facade&quot;&gt;Amorphous Facade&lt;&#x2F;a&gt;. I did this work for my Undergraduate Senior Project
with Rauhul Varma and advised by Rebecca Chen and Prof. Can Bayram.&lt;&#x2F;p&gt;
&lt;p&gt;Phillips Hue and similar lighting systems are really popular and they actually can have health
benefits for their users as well as be a useful display of information. Having the correct color temperature
at certain times of day for example improves peoples&#x27; happiness and their productivity. Since
we spend a majority of our days in the office, it makes sense that we would want similar benefits
at work. Solutions like Hue won&#x27;t work in the office place due to their architecture. They operate
on a hub spoke model where lights will connect to a hub which connects the lights to the network
where they will be controlled by a cloud service, operated by Phillips themselves. Users are therefore
beholden to Phillips to keep the service running in order to access their lights. This immediately
is not acceptable to a business. This architecture also limits scalability and increases network congestion,
where for every $N$ lights you need $M$ hubs. This sort of model is common place across the
range of IoT devices and as a rebuttal to the current industry approach to ubiquitous computing, we present a lighting
platform called Twilight that seeks to demonstrate the potential of intelligent and easy to
use smart devices. Twilight achieves these goals by applying ideas from the field of swarm robotics and developing
a lighting system that is self-organizing and reconfigurable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twilight&#x2F;assets&#x2F;concept.png&quot; alt=&quot;concept&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Concept art for Twilight, lights are designed to be compatible with standard ceiling tiles and magnetically mounted.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Having these properties allows you to infinitely scale out the system, no longer requiring hubs to connect them.
Lights communicate amongst themselves in order to change properties like their colors and having federated control
of the lighting system creates desirable properties like fault tolerance. If key nodes in the system go down,
the lighting system is resilient or in the worst case can partition itself into two separate fully operational systems.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hardware&quot;&gt;Hardware&lt;&#x2F;h3&gt;
&lt;p&gt;Each light is setup as a box, the size of a standard ceiling tile and ringed with magnets for mounting. On the internal
perimeter there is reflective tape and an LED strip as the actual light source. The strip is controlled by a Raspberry Pi
and a custom control board which also connects the light to other lights in the network. Blocks are run off standard $120 VAC$
wall power.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twilight&#x2F;assets&#x2F;hw.png&quot; alt=&quot;hw&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The hardware architecture for Twilight&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twilight&#x2F;assets&#x2F;board.png&quot; alt=&quot;board&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The custom controller for Twilight node&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;software&quot;&gt;Software&lt;&#x2F;h3&gt;
&lt;p&gt;We chose a Raspberry Pi because in addition to building this project for our Senior Design Project we also
made this as an installation for the UIUC Chapter of ACM. It was meant to be installed in their office and
serve as a teaching tool for swarm robotics. Raspberry Pis make Twilight way more accessible than an embedded
programming environment.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twilight&#x2F;assets&#x2F;sw.png&quot; alt=&quot;sw&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The software architecture for Twilight&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;self-organization&quot;&gt;Self-Organization&lt;&#x2F;h4&gt;
&lt;p&gt;The whole point of this system is that we can build a bunch of lights, but they organize themselves to
create smart behavior. The first step is localization. Conveniently, the lights are arranged in a grid on
the ceiling. We therefore start by gossiping between nodes until they elect a leader, the block with the
&quot;lowest MAC address&quot;. This node will also be the &quot;border router&quot; the bridge between the LAN and the Twilight network.
This is dynamic role so if this node is lost then a new border router is elected. This node also serves as the origin of the grid.
From here messages are propagated telling nodes their coordinates until each node knows where it is. Now developers can create
applications which just index nodes in the grid and set states for them or they can send out a global command and let the network
resolve how to implement it. For instance below is a example of a command to set the grid white. Nodes receive and send commands until
all nodes are the right color.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twilight&#x2F;assets&#x2F;sync.gif&quot; alt=&quot;sync&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-installation&quot;&gt;The Installation&lt;&#x2F;h2&gt;
&lt;p&gt;Here are some cool videos and pictures of the system.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twilight&#x2F;assets&#x2F;deploy.gif&quot; alt=&quot;deploy&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Twilight running on the ceiling of the ACM office&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twilight&#x2F;assets&#x2F;installation.jpg&quot; alt=&quot;installation&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Installing a Twilight node&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;twilight&#x2F;assets&#x2F;system.jpg&quot; alt=&quot;system&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Three twilight nodes connected&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;You can find the full thesis here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;narendasan&#x2F;narendasan.com&#x2F;raw&#x2F;master&#x2F;_assets&#x2F;files&#x2F;twilight_reconfigurable_self_organizing%20_office_lighting.pdf&quot;&gt;Twilight: Reconfigurable Self Organizing Office Lighting&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;You can find the source code and schematics can be found here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;acm-uiuc&#x2F;twilight-old&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;acm-uiuc&#x2F;twilight-old&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
      <item>
          <title>ACM@UIUC GPU Cluster</title>
          <pubDate>Sun, 01 Oct 2017 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/acm-gpu-cluster/</link>
          <guid>https://www.narendasan.com/blog/acm-gpu-cluster/</guid>
          <description xml:base="https://www.narendasan.com/blog/acm-gpu-cluster/">&lt;h2 id=&quot;acm-uiuc-gpu-cluster&quot;&gt;ACM@UIUC GPU Cluster&lt;&#x2F;h2&gt;
&lt;p&gt;In order to effectively work with deep learning a GPU is required. When I was an intern at
NVIDIA, this wasn&#x27;t a problem. NVIDIA maintains a massive GPU compute pool which is accessible
to all its engineers (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nvidia.com&#x2F;en-us&#x2F;data-center&#x2F;dgx-saturnv&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.nvidia.com&#x2F;en-us&#x2F;data-center&#x2F;dgx-saturnv&#x2F;&lt;&#x2F;a&gt;). It&#x27;s harder when
you don&#x27;t work for the company who makes all the GPUs for deep learning, let alone a student. Y
ou can try to use cloud providers like AWS or GCP but that costs money and is not as easy as running
something locally. Having a large on site cluster is nice but you need to make sure that people
using the cluster are able to work without interfering with each other.&lt;&#x2F;p&gt;
&lt;p&gt;ACM@UIUC was donated a couple GPUs from NVIDIA for setting up a chapter deep learning cluster.
We then built out a machine which had 16 TB of disk space and these two GPUs installed as the first
node in our cluster. The question was how to give people access in a way that was contained and controlled.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;acm-gpu-cluster&#x2F;imgs&#x2F;system.png&quot; alt=&quot;system&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Vault, root node of the ACM GPU Cluster&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;nvidia-docker-and-ngc&quot;&gt;NVIDIA Docker and NGC&lt;&#x2F;h3&gt;
&lt;p&gt;One of the large investments NVIDIA made in GPU software was adding an integration into docker (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.github.com&#x2F;NVIDIA&#x2F;nvidia-docker&quot;&gt;https:&#x2F;&#x2F;www.github.com&#x2F;NVIDIA&#x2F;nvidia-docker&lt;&#x2F;a&gt;). This
allows docker containers to access GPUs directly giving people a containerized workspace with GPU compute available.
This is a nice way to host many people on one platform and make sure that no one accidentally bricks the system.
Along with this docker extension NVIDIA released the NVIDIA GPU Cloud (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ngc.nvidia.com&quot;&gt;https:&#x2F;&#x2F;ngc.nvidia.com&lt;&#x2F;a&gt;). NVIDIA GPU Cloud is a
registry of docker containers which pre package common deep learning environments and some provisioning software. This lets
users who have Deep Learning Workstation Cards, DGX systems or who want to use NVIDIAs Cloud infrastructure to quickly set up
workspaces and jobs to train their models. Users can upload a job in the form of a container, the data resources to mount and a
command and then the NGC software will find an open GPU and start the run. Artifacts are then uploaded to the cloud service to be consumed.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;acm-gpu-cluster&#x2F;imgs&#x2F;ngc.png&quot; alt=&quot;ngc&quot; &#x2F;&gt;
NVIDIA GPU Cloud, a platform for sharing GPU compute resources amongst a team&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Because NGC is limited to paying customers or owners of $10.000 machines we decided to build a clone which anyone could run.
Just like NGC it is based off of a repository of docker images and some software to launch containers. Unlike NGC which focused
on batch jobs which makes sense for companies who are training massive networks, we wanted to focus on interactive jobs where people
are developing code in the system for quick experiments (if they wanted to run a week long job AWS at that point serves them better).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-gpu-cluster&quot;&gt;The GPU Cluster&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;acm-gpu-cluster&#x2F;imgs&#x2F;menu.png&quot; alt=&quot;menu&quot; &#x2F;&gt;
ACM GPU Cluster interface&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;acm-gpu-cluster&#x2F;imgs&#x2F;select.png&quot; alt=&quot;select&quot; &#x2F;&gt;
PyTorch container environment information&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We run a web server on the root node of the cluster which shows an interface that has a list of different container options for people
to use. When a user selects one they are promoted to login with their ACM@UIUC credentials which lets us restrict users to just members.
Then on the system a container is provisioned that is prebaked with the framework of their choice. This container also has a volume mounted
which maps to the host machines 16TB data partition. There we keep peoples long term workspaces, and common datasets like ImageNet or COCO.
This lets users restart work easily. Finally an open GPU is assigned to the container for the user. If there are no open GPUs then the user is told to come
back later. Once the container is provisioned, the web interface directs users to a Jupyter interface which is running within the container.
Here now users can run and create notebooks in their workspace or they can open up an in-browser bash shell as well.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;acm-gpu-cluster&#x2F;.&#x2F;imgs&#x2F;notebook.png&quot; alt=&quot;notebook&quot; &#x2F;&gt;
Jupyter notebook interface once container has been provisioned&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Integration with the ACM@UIUC infrastructure also allowed us to mediate usage and make sure people don&#x27;t hog the system.
The infra has a credit system which we use to monitor usage, if people run out of credits then jobs cannot be started until they have more.&lt;&#x2F;p&gt;
&lt;p&gt;This system was pretty successful, used for hackathon projects, class work and personal projects amongst many members in ACM.
The GPU Cluster software is open source software and can be found here:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.github.com&#x2F;acm-uiuc&#x2F;gpu-cluster&quot;&gt;https:&#x2F;&#x2F;www.github.com&#x2F;acm-uiuc&#x2F;gpu-cluster&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
      <item>
          <title>TensorRT Python API</title>
          <pubDate>Wed, 27 Sep 2017 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/tensorrt-python-api/</link>
          <guid>https://www.narendasan.com/blog/tensorrt-python-api/</guid>
          <description xml:base="https://www.narendasan.com/blog/tensorrt-python-api/">&lt;p&gt;When one thinks of neural networks, probably the first thing they think of is a deep learning framework like Tensorflow or PyTorch. The creation of deep learning frameworks were crucial to the adoption of deep learning in the products we use every day. Instead of having to write your own CUDA kernels to leverage the parallelization power of a GPU, you can easily structure components together into a graph and managed the training of that graph all in python, letting the frameworks handle all the hard parts. But this is only half of the solution to making deep learning a viable tool to do useful work.&lt;&#x2F;p&gt;
&lt;p&gt;Once the weights have been finalized and the training completed you are left with something that while may be good at its particular task, is far less efficient than it could be. Many people when deploying neural network models, take the extra step to optimize their model before deploying it so as to get the maximum throughput through the network. There are a couple projects that look to be the Tensorflow or PyTorch of this deployment phase (also known as the inference phase). Those include Facebook&#x27;s GLOW compiler, DLVM, ONNC, nGraph, TVM and XLA. NVIDIA creates one specifically for optimizing networks on their GPUs for inference called TensorRT. If you want to know more about the optimizations that TensorRT does, take a look at these blog posts: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devblogs.nvidia.com&#x2F;tag&#x2F;tensorrt&#x2F;&quot;&gt;https:&#x2F;&#x2F;devblogs.nvidia.com&#x2F;tag&#x2F;tensorrt&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In January of 2017 when I joined NVIDIA for a 8 month co-op, TensorRT 2.1 just came out. At the time for a user to optimize a network they had a couple of options, all of which required setting up a large C++ infrastructure around the model ingest.
At the time the only supported &quot;parser&quot; was for Caffe Models, and everyone else would have to manually extract weights and read them into a network definition API. Here was a minimal example from around then:&lt;&#x2F;p&gt;
&lt;p&gt;The user would start by creating an ingest system that would take a Caffe model, parse it then create an engine.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;tensorrt-engine-builder&quot;&gt;TensorRT Engine Builder&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;IBuilder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; builder &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; createInferBuilder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;gLogger&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;​&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; parse the caffe model to populate the network, then set the outputs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;INetworkDefinition&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; network &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;createNetwork&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;​&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CaffeParser parser&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;auto&lt;&#x2F;span&gt;&lt;span&gt; blob_name_to_tensor &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; parser&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;“&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;deploy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;prototxt&lt;&#x2F;span&gt;&lt;span&gt;”&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;​                                        &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;trained_file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;c_str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;​                                        &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;​&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;                                        DataType&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;kFLOAT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;​&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; specify which tensors are outputs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;markOutput&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;blob_name_to_tensor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;find&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;prob&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;​&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; Build the engine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;setMaxBatchSize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;setMaxWorkspaceSize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ICudaEngine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; engine &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;buildCudaEngine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then using the engine they would setup an inference pipeline, that would manage transferring data to the GPU and results back.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;tensorrt-engine-executor&quot;&gt;TensorRT Engine Executor&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; The execution context is responsible for launching the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; compute kernels&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;IExecutionContext &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;context &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;createExecutionContext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; In order to bind the buffers, we need to know the names of the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; input and output tensors.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; inputIndex &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;getBindingIndex&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;INPUT_LAYER_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; outputIndex &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;getBindingIndex&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;OUTPUT_LAYER_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; Allocate GPU memory for Input &#x2F; Output data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; buffers &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; malloc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;getNbBindings&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; * sizeof&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cudaMalloc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;buffers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;inputIndex&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;span&gt; batchSize &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; size_of_single_input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cudaMalloc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;buffers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;outputIndex&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;span&gt; batchSize &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; size_of_single_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; Use CUDA streams to manage the concurrency of copying and executing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cudaStream_t&lt;&#x2F;span&gt;&lt;span&gt; stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cudaStreamCreate&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; Copy Input Data to the GPU&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cudaMemcpyAsync&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;buffers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;inputIndex&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;span&gt; input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;​                batchSize &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; size_of_single_input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;​                cudaMemcpyHostToDevice&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; Launch an instance of the GIE compute kernel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;context&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;enqueue&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;batchSize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; buffers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nullptr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; Copy Output Data to the Host&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cudaMemcpyAsync&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; buffers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;outputIndex&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;​                batchSize &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; size_of_single_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;​                cudaMemcpyDeviceToHost&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; It is possible to have multiple instances of the code above&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; in flight on the GPU in different streams.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; The host can then sync on a given stream and use the results&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cudaStreamSynchronize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For people who had the resources to develop this sort of infrastructure it was entirely worth it to get the performance benefits, but to say the least it was in accessible for prototyping and light applications.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;enter-the-tensorrt-python-api&quot;&gt;Enter the TensorRT Python API&lt;&#x2F;h2&gt;
&lt;p&gt;For actual deployments C++ is fine, if not preferable to Python,  especially in the embedded settings I was working in. However, there is still quite a bit of development work to be done between having a  trained model and putting it out in the world. One example is quantization.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;a-quick-primer-on-quantization&quot;&gt;A Quick Primer on Quantization&lt;&#x2F;h4&gt;
&lt;p&gt;Typically (at least in 2017), neural networks are trained at FP32 precision. This is mostly due to the hardware available at that time specializing in FP32 math. But this precision has a lot more granularity than is necessary and ultimately you can get significant performance improvements by lowering the precision (to FP16 or INT8 or INT9 for example). For INT8 in particular, you need to go through a process called quantization that maps the range of weights onto an 8bit space.&lt;&#x2F;p&gt;
&lt;p&gt;In TensorRT there are APIs that help do this quantization for you in a way that hopefully minimizes the precision lost by using this less granular representation. This and other advanced features are usually what need to be experimented with before deploying a model but having to set up quantization infrastructure in C++ just for experiments is a lot of work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wrapping-a-c-library&quot;&gt;Wrapping a C++ Library&lt;&#x2F;h3&gt;
&lt;p&gt;So instead of having to rewrite a library in Python there are APIs and tools you can use to wrap an existing library and expose a python interface. This is in fact the approach that libraries like PyTorch and Tensorflow use, a C++ core with a Python Frontend. There are couple tools that people use that automate the process of wrapping a library, one is SWIG which is able to auto generate an interface based on a header file and an interface file and PyBind11 a newer library that takes more work to define an interface but is lighter weight. For easy of prototyping and the shear amount of code to wrap I chose to use SWIG in my initial versions of the Python API for TensorRT but in later versions this was ported to PyBind11.&lt;&#x2F;p&gt;
&lt;p&gt;TensorRT also requires directly interfacing with the CUDA Device API to transfer over data to a GPU and manage that memory through inference. There are a few python libraries that provide this capability. The one used officially with the TensorRT API is PyCUDA, but effort was put in to make sure other libraries such as CuPy (or even PyTorch) also work.&lt;&#x2F;p&gt;
&lt;p&gt;If you are going through the trouble to make a nice python API you should also try to abstract out a lot of the boilerplate that comes with a library targeted at C++ which I did in the &lt;code&gt;utils&lt;&#x2F;code&gt; sub package so as to maintain as much similarity between the C++ and Python APIs in the main package but allow for higher level features else where.&lt;&#x2F;p&gt;
&lt;p&gt;At this point I was able to do a lot of the basic work you&#x27;d want to do with TensorRT in Python:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;tensorrt-engine-builder-in-python&quot;&gt;TensorRT Engine Builder in Python&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; tensorrt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; trt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; uff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; tensorrt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;parsers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; caffeparser&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;G_LOGGER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;infer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ConsoleLogger&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;infer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;LogSeverity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;ERROR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;OUTPUT_LAYERS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; [&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;prob&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;MODEL_PROTOTXT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.&#x2F;data&#x2F;mnist&#x2F;mnist.prototxt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;CAFFE_MODEL&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.&#x2F;data&#x2F;mnist&#x2F;mnist.caffemodel&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;utils&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;caffe_to_trt_engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;G_LOGGER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;                                       MODEL_PROTOTXT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;                                       CAFFE_MODEL&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;                                       1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;                                       1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;                                       OUTPUT_LAYERS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;                                       trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;infer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;DataType&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;FLOAT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;tensorrt-engine-executor-in-python&quot;&gt;TensorRT Engine Executor in Python&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;runtime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;infer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;create_infer_runtime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;G_LOGGER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;context&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;create_execution_context&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;astype&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;np&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;float32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;empty&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; dtype&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; np&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;float32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;d_input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cuda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;mem_alloc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;dtype&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;itemsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;d_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cuda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;mem_alloc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;dtype&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;itemsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bindings&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;d_input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;d_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cuda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cuda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;memcpy_htod_async&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;d_input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; img&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;context&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;enqueue&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; bindings&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;handle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cuda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;memcpy_dtoh_async&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; d_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;synchronize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Prediction: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;np&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;argmax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;leveraging-the-python-ecosystem&quot;&gt;Leveraging the Python Ecosystem&lt;&#x2F;h3&gt;
&lt;p&gt;There are some great things about python that make life a lot easier. Data manipulation with NumPy for one is a massive benefit, so is being able to directly interface with other deep learning frameworks and tools. So one of the first things I added as soon as the library was wrapped was NumPy compatibility. This means that you can use NumPy arrays not only for your data, but also to transfer your weights around. This allows people using libraries like PyTorch (&lt;em&gt;note: this was before ONNX came out&lt;&#x2F;em&gt;) to extract their weights into NumPy arrays and then load them into TensorRT all in Python.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;importing-a-pytorch-model-manually&quot;&gt;Importing a PyTorch Model Manually&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Given a net&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Net&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Module&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;Net&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span&gt;__init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;conv1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Conv2d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; kernel_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;conv2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Conv2d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; kernel_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;conv2_drop&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Dropout2d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;fc1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Linear&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;800&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 500&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;fc2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Linear&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;500&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;max_pool2d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;conv1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; kernel_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; stride&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;max_pool2d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;conv2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; kernel_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; stride&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;view&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 800&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;relu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;fc1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;fc2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;log_softmax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; Net&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;weights&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;state_dict&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;G_LOGGER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;infer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ConsoleLogger&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;infer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;LogSeverity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;ERROR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;infer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;create_infer_builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;G_LOGGER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;create_network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#Name for the input layer, data type, tuple for dimension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;add_input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;infer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;DataType&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;FLOAT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#-------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;conv1_w&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; weights&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;conv1.weight&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;numpy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;reshape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;conv1_b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; weights&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;conv1.bias&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;numpy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;reshape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;conv1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;add_convolution&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;  conv1_w&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; conv1_b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;conv1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;conv1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;set_stride&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#-------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pool1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;add_pooling&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;conv1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;get_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;infer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;PoolingType&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;MAX&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;pool1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pool1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;set_stride&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#-------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;conv2_w&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; weights&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;conv2.weight&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;numpy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;reshape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;conv2_b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; weights&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;conv2.bias&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;numpy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;reshape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;conv2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;add_convolution&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;pool1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;get_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; conv2_w&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; conv2_b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;conv2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;conv2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;set_stride&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#-------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pool2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;add_pooling&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;conv2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;get_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;infer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;PoolingType&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;MAX&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;pool2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pool2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;set_stride&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#-------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fc1_w&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; weights&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;fc1.weight&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;numpy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;reshape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fc1_b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; weights&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;fc1.bias&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;numpy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;reshape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fc1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;add_fully_connected&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;pool2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;get_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 500&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; fc1_w&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; fc1_b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;fc1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#-------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;relu1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;add_activation&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;fc1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;get_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; trt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;infer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;ActivationType&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;RELU&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;relu1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#-------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fc2_w&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; weights&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;fc2.weight&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;numpy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;reshape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fc2_b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; weights&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;fc2.bias&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;numpy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;reshape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fc2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;add_fully_connected&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;relu1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;get_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; fc2_w&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; fc2_b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;fc2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fc2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;get_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;set_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;prob&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;mark_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;fc2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;get_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;set_max_batch_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;set_max_workspace_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;build_cuda_engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;destroy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;builder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;destroy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This was a new capability introduced by the Python API because of Python and NumPy.&lt;&#x2F;p&gt;
&lt;p&gt;We can also use NumPy and other tools like SciPy to do some of the data preprocessing required for inference and the quantization pipeline.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;quantization-with-tensorrt-python&quot;&gt;Quantization with TensorRT Python&lt;&#x2F;h4&gt;
&lt;p&gt;This blog post describes using the Python API to do the majority of the work for INT8 Quantization and deploying on a embedded platform:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devblogs.nvidia.com&#x2F;int8-inference-autonomous-vehicles-tensorrt&#x2F;?utm_content=buffer46af6&amp;amp;utm_medium=social&amp;amp;utm_source=twitter.com&amp;amp;utm_campaign=buffer%5D&quot;&gt;https:&#x2F;&#x2F;devblogs.nvidia.com&#x2F;int8-inference-autonomous-vehicles-tensorrt&#x2F;?utm_content=buffer46af6&amp;amp;utm_medium=social&amp;amp;utm_source=twitter.com&amp;amp;utm_campaign=buffer&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;higher-level-apis&quot;&gt;Higher level APIs&lt;&#x2F;h3&gt;
&lt;p&gt;Using Python allows for a lot of abstracted work. One of the things introduced in the Python API is the Lite API a essentially one liner to create an engine and run it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#Post Processing Callback, Should take a 5D Tensor, run post processing and return a single object&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; analyze&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;output_data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    #Results from the engine are returned as a list of 5D numpy arrays:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    #        (Number of Batches x Batch Size x C x H x W)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; output_data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;reshape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;LABELS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    # Get result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    top&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;argmax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    top&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt; LABELS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;top&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    # Get top5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    top5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;argpartition&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; axis&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    top5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; top5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;np&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;argsort&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;top5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;])][::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B16286;&quot;&gt;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    top5_classes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; top5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        top5_classes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;LABELS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;top&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; top5_classes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#Arguments to create lite engine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;framework&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;tf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;                                     #Source framework&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;           &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;DATA&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&#x2F;resnet50&#x2F;resnet50-infer-5.pb&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;          #Path to frozen model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;           &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;input_nodes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:{&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;224&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;224&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)},&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;                  #Dictionary of input nodes and their associated dimensions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;           &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;output_nodes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:[&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;GPU_0&#x2F;tower_0&#x2F;Softmax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;             #List of output nodes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;           &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;logger_severity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt;LogSeverity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;font-weight: bold;&quot;&gt;INFO&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;                   #Debugging info&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;           &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;postprocessors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:{&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;GPU_0&#x2F;tower_0&#x2F;Softmax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;:&lt;&#x2F;span&gt;&lt;span&gt;analyze&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   #Postprocessor function table&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; Engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;**&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;network&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that defines a full pipeline with pre&#x2F;post processing allowing for integration with other apps easily. The lite api also supports a variety of batching formats automatically so its pretty easy to just throw data at it and get results out.&lt;&#x2F;p&gt;
&lt;p&gt;Take a look at the examples in the TensorRT distribution for demonstrations of this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;enabling-other-applications&quot;&gt;Enabling other applications&lt;&#x2F;h2&gt;
&lt;p&gt;Since it&#x27;s now easy to integrate TensorRT its pretty straightforward to include optimized deep learning models in your projects. This enables a lot of cool new applications in spaces such as smart cities, robotics and web applications.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Hackillinois</title>
          <pubDate>Sun, 26 Feb 2017 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/hackillinois2017/</link>
          <guid>https://www.narendasan.com/blog/hackillinois2017/</guid>
          <description xml:base="https://www.narendasan.com/blog/hackillinois2017/">&lt;blockquote&gt;
&lt;p&gt;Thoughts after running Experience for HackIllinois 2016 about growth and direction of HackIllinois and Hackathons in general. This was written in May of 2016 with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;andrewkuz.net&quot;&gt;Andrew Kuznetsov&lt;&#x2F;a&gt; as we were trying to assemble a vision of what HackIllinois could become.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;background&quot;&gt;Background&lt;&#x2F;h2&gt;
&lt;p&gt;HackIllinois was founded in 2014, just one year after the first MHacks, and 5 years after PennApps. For the past 3 years, HackIllinois has been refining the idea of the “College Hackathon”, by focusing on experience at scale; creating a large highly themed whimsical hackathon, which tries to provide as many resources as possible. As a result, HackIllinois has grown year over year to 1500 Hackers in 2016. It has grown to become a top class event in the world of hackathons, alongside MHacks, PennApps, HackMIT and more &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.quora.com&#x2F;What-are-the-best-hackathons&quot;&gt;Quora - What are the best hackathons&lt;&#x2F;a&gt;. HackIllinois traditionally has created an event to evangelize the hacker culture to new students by trying not to look at qualifications before admission (in fact admissions are mostly based around transportation), thereby making an event where people who are new to the world of hackathons can meet the true hackathon hackers.&lt;&#x2F;p&gt;
&lt;p&gt;However it has become apparent from hacker feedback, the submissions and general observation, that HackIllinois is struggling to scale the experience further. Many hackers complain of long lines for food, the inability to get mentorship, not being accepted despite being a student at UIUC, and the event’s inability to handle so many submissions in the competition. The quality of submissions at college hackathons in general has fallen as well. Many of the first hackathon goers have graduated and left behind those who believe in a warped view of what hacking is. This new generation, who are now the organizers and major figures in the hacking community, were inundated by the CS culture during its current boom as they were being introduced to the hackathon community, and created a more concentrated form of the startup centric, founder-glorifying culture in Silicon Valley. This culture focuses more on being able to pitch ideas and imaging wild ways in which they might “change the world” than it does on the journey of hacking and the engineering behind it and now people are starting to reject it. This is clear to see in the submissions to HackIllinois 2016, where not all of the Top 10 hacks in either category had done any significant engineering work, however many make claims such as “ we solved 3rd world sanitation” with a project featuring 3 wires a couple LEDs and a SparkCore. The organizers of these hackathons are just as culpable as the hackers: by putting incentives on using company APIs, current hackathons only encourage this sort of hacking.&lt;&#x2F;p&gt;
&lt;p&gt;It is obvious that HackIllinois needs to change in order to continue delivering the same quality of experience to hackers. However, it must change within the greater context of the culture it represents. Hackathons are no longer growing, especially hackathons that focused on size over experience, (Hackathons that artificially limit the number of students will not see this effect for a year or two). The people who are interested in the college hackathons are not the same type of people that were setting up and attending these events in the past. MHacks is a poignant example - the entire leadership of the MHacks organizing committee did not return. As a consequence, the people who attend MHacks are more and more just Michigan students that want free food as other students are not seeing the value in traveling to Ann Arbor to sit and work on meaningless projects incentivized by API prizes. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;brianchang.info&#x2F;2016&#x2F;02&#x2F;28&#x2F;hackathon-be-gone.html&quot;&gt;Hackathon Be Gone&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-quick-history-of-hackathons&quot;&gt;A Quick History of Hackathons&lt;&#x2F;h2&gt;
&lt;p&gt;There are 2 places of origin for what is now the hackathon; both tied together by the people involved. The first event called a hackathon was in the 1990s, where 10 or so developers of BSD Unix, came together to prototype some ideas for the operating system. This idea transferred to Sun Microsystems as some of the founders of BSD were core engineers at Sun. At Java One, Sun had the first corporate hackathon. Developers were challenged to learn&#x2F;use Java to create new applications for the Palm. These two events set the platform for what hackathons would be. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hackathon&quot;&gt;Wikipedia - Hackathon&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;At their core, Hackathons are events that seek to accomplish several things at a very specific scale, showing what is possible with a technology, but often without pushing the limits of scalability or deployment in real world environment. Hackers either twist technologies to do something it was never supposed to do (think the top hardware hack at Hackillinois 2016 - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devpost.com&#x2F;software&#x2F;catch-me-if-you-can-ga3yxs&quot;&gt;Catch Me if You Can&lt;&#x2F;a&gt;) or develop a prototype for a feature or idea.&lt;&#x2F;p&gt;
&lt;p&gt;During the intervening years, the Hackathon tradition was shared and small groups would organize events to quickly make prototypes or explore new tech (ex: developing mobile apps with javascript - Apache Cordova). However, as Computer Science became more popular (read: sexy) a culture shift became apparent.  As popular culture started idealizing the concept of the startup, the hackathon was appropriated as a concentrated representation of that idea &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.nytimes.com&#x2F;2015&#x2F;04&#x2F;12&#x2F;education&#x2F;edlife&#x2F;the-hackathon-fast-track-from-campus-to-silicon-valley.html?_r=1&quot;&gt;New York Times - The Hackathon&lt;&#x2F;a&gt;. Importance shifted from blowing minds or prototyping a new idea to what food and swag is given out. Projects were expected to be presented as a groundbreaking piece of tech in the form of a startup competition pitch. The effect was immediate; people with very little deep technical knowledge began passing off company APIs, hardcoded backends, and frontend templates as original work in a bid to secure prizes. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.facebook.com&#x2F;1409787509243611&#x2F;posts&#x2F;1539618566260504&quot;&gt;HH - Unsustainable Hackathons&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;problems-facing-hackillinois&quot;&gt;Problems Facing HackIllinois&lt;&#x2F;h2&gt;
&lt;p&gt;There are a bunch of issues that arise from the expectations of hackathons:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Influx of business-minded individuals coming in with a business pitch and a coder believing they are holding the next Facebook™ in their hands.&lt;&#x2F;li&gt;
&lt;li&gt;The Code Evangelism Hackathon vision is no longer relevant.
&lt;ol&gt;
&lt;li&gt;No one learns anything after their first hackathon because the same technologies (and skills) are being used over and over again (Different frameworks don’t count, just as different languages don’t count).&lt;&#x2F;li&gt;
&lt;li&gt;Hackers rely on APIs for major compute power, competition has become geared at best applying an API at a problem.&lt;&#x2F;li&gt;
&lt;li&gt;It’s easier to plan events for beginners, after all you can teach them everything. However, not much thought is dedicated to providing for participants who are not first time programmers or hackathoners?&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Nothing of substance is ever developed in hackathon because most of the heavy lifting is done by the APIs, nor is their incentive to do so. Virtually no projects survive the closing ceremony.&lt;&#x2F;li&gt;
&lt;li&gt;Companies that are not platform based (e.g. Amazon) see very little value in evangelizing their products at current style of hackathon.
&lt;ol&gt;
&lt;li&gt;Other companies put on their own hackathons that are more effective at evangelize their systems.
&lt;ol&gt;
&lt;li&gt;Sun and Java One, Pebble and Pebble Rocks, Github and local hacknights, AT&amp;amp;T and the AT&amp;amp;T Dev Summit and Hackathon&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;The competitive skills that are developed at hackathons are geared toward prototyping, rather than teaching solid engineering.
&lt;ol&gt;
&lt;li&gt;Hackers cannot see a project through, will avoid good engineering for speed (Whatever Works Development). Reinforces the practice of deploying prototypes&lt;&#x2F;li&gt;
&lt;li&gt;Unfortunately, they do not realize that this is poor development and try to apply the same strategy to real life situations&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A thread that mentions all these issues -  &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=9205177&quot;&gt;Hacker News - The Rising &quot;Hackathon Hackers&quot; Culture&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“We hired a dev that&#x27;s very much like you [OP] described. We &quot;knew&quot; he was smart because he did well in some Hackathons. Had built some cool projects on his flashy portfolio. Went to the same university we went to, which is a top university in the world. Had good grades at said University. etc. He had all the markings of being a fantastic intern for us. About half way through his internship we had to fire him. He lacked the attention span for a long term, rigorous software development project. We later hired someone whom we evaluated very differently and it has been incredible. He&#x27;s doing a fantastic job. Constantly questions our opinions about software and pushes the boundaries of our depth of understanding. To add to this, we knew the fired intern went on to another startup to keep doing whatever it is he thinks he&#x27;s doing. The founders of that company ended up telling us the same exact problems were happening with them. Don&#x27;t worry about these &quot;hackers&quot; and what they&#x27;re doing. They&#x27;ll all end up getting a reality check at some point. If they frustrate you, then just remember that the best revenge is living well.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Many of the students who lead the charge for hackathons now distance themselves from the culture because of what it now represents (Large exodus of Hackathon Hackers sub-groups from the HH community&#x2F;brand in early 2016). These original students founded their own hackathons because of what they saw in industry or in the colleges of peers, and are now seeing them becoming calculated competitions for prizes. The system of prizes and especially API prizes reinforces this behavior. We can see this evidence of this trend in project distribution among prizes, and in the dearth of workshop and talk participants (and the subsequent need to incentivize their attendance) (HackMIT 2016).&lt;&#x2F;p&gt;
&lt;p&gt;The ever widening gap between the hacking community (HH, Hackathon goers and Organizers) and the tech community (employers, engineers, members of the FOSS movement, older hackers) is concerning. From the hacker perspective, a collegiate hackathon provides access to other fellow hackers and a handful of recruiters. From the perspective of the greater developer community, collegiate hackathons are prototyping competitions which reinforce a poor competitive mindset (read: faking tech demos), as well as fostering poor engineering practices &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;kevintechnology.com&#x2F;post&#x2F;61323921846&#x2F;preventing-cheating-at-hackathons&quot;&gt;Kevin Techonology - Preventing Cheating at Hackathons&lt;&#x2F;a&gt;, targeting a very homogeneous set of people - 18-21 year olds with 1-5 years of programming experience. Unfortunately, due to the lack of mentorship, the cycle of poor development repeats itself: hackers learn from other hackers (company mentors are typically recruiters, evangelists or older hackathon goers, not engineers) and are then asked to mentor others. It is hard to see such a culture to continue to be a respected part of the CS community if something drastic is not done to change the values and the vicious cycle that has been created.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-main-event&quot;&gt;The Main Event&lt;&#x2F;h2&gt;
&lt;p&gt;The MLH-style “College Hackathon” is dead, or it will be soon. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@folz&#x2F;selling-out-and-the-death-of-hacker-culture-fec1f101b138#.e651zzp1r&quot;&gt;@folz - Selling out and the death of hacker culture&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But as always is the case, less active companies and institutions are still only discovering the basic idea. For the near future, Hackathons (and MLH beside it) will continue to expand to these new territories largely to continue growth. Despite this, the original college hackathon has peaked, and we can see the evidence in MLH’s newfound (2015-2017) focus in Code Evangelism, High School Hackathons, European Hackathons, and untouched colleges.&lt;&#x2F;p&gt;
&lt;p&gt;HackIllinois is now faced with a choice, take the money, drink the kool-aid, and ride it to the end or try and create something new and start the new phase of hackathons. This is the time to do it while there is still some momentum in the community (among quite a few reasons to which we will get to later). It is increasingly harder to justify HackIllinois attendance (over others) as the more we continue along this path, the less unique we become.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;vision&quot;&gt;Vision&lt;&#x2F;h3&gt;
&lt;p&gt;There are entire subsets of students that are not being served by the current MLH infrastructure and it just so happens these are the passionate engineers, the founders of the hacking culture and collaborative minded engineers who understand the prestige of significant contributions to the greater community and growing that community. As an event, we need to focus on these technology and community drivers; people who are passionate about the technology and the journey of creating something new. This group of active community makers and developers define the original values of the hacking community and also are disenfranchised by what it has become. It is this group that HackIllinois needs to attract and impress, if we to change what hackathons represent. We need to examine and question the culture we have created, and advocated for.&lt;&#x2F;p&gt;
&lt;p&gt;That being said, a new idea that will pull in these hackers as well as the greater CS community and solve many of the issues facing hackathons today is the Open Source Initiative created at HackIllinois 2016.&lt;&#x2F;p&gt;
&lt;p&gt;OpenSource@HackIllinois questioned everything about hackathons.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Why can only college students hack?&lt;&#x2F;li&gt;
&lt;li&gt;Why are teams only up to 4 people?&lt;&#x2F;li&gt;
&lt;li&gt;Can we run a hackathon without prizes?&lt;&#x2F;li&gt;
&lt;li&gt;What if people could work on previously existing projects?&lt;&#x2F;li&gt;
&lt;li&gt;Etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;OpenSource@HackIllinois also presented solutions to common problems that faced hackathons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What happens to projects after the hackathon?&lt;&#x2F;li&gt;
&lt;li&gt;How do you make sure that people learn something?&lt;&#x2F;li&gt;
&lt;li&gt;How do you make sure hackers meet new people and develop meaningful connections?&lt;&#x2F;li&gt;
&lt;li&gt;Etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Open Source harkens back to the original meaning of ‘hacker’, and  a hackathon that unifies the two would go a long way to start bringing the culture back to its roots.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Take a look at the free software community (which is incidentally very well-correlated with what the &quot;hacker&quot; community used to be 20-30 years ago, and has much more of a claim to being the intellectual heirs of that group than the hackathon crowd does or even the HN crowd does). There&#x27;s a lot of focus on ethics and civil liberties, and maybe a bit too little focus on effective PR and on shipping, but it&#x27;s very refreshing. As a concrete suggestion, LibrePlanet https:&#x2F;&#x2F;libreplanet.org&#x2F;2015&#x2F; is next weekend at MIT, and free for students. Or see if there&#x27;s a Debian group in your local area.” - Hacker News Poster &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=9205177&quot;&gt;(https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=9205177)&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The way forward for HackIllinois is to recapture the old idea of what a hacker meant through fully embracing FOSS (Free and Open Source Software). In doing so, we may stave off the decline of the College Hackathon Scene, reintroduce a focus on the craft and journey of a hackathon, and on the brand of hacking and community contribution that is exemplified by groups like iOS Jailbreakers and Android ROM community.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;values&quot;&gt;Values&lt;&#x2F;h3&gt;
&lt;p&gt;Pre-MLH, Rutgers student Mike Swift wrote an excellent article on why not to run a hackathon &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;theycallmeswift.com&#x2F;2013&#x2F;10&#x2F;25&#x2F;dont-throw-that-hackathon&#x2F;&quot;&gt;http:&#x2F;&#x2F;theycallmeswift.com&#x2F;2013&#x2F;10&#x2F;25&#x2F;dont-throw-that-hackathon&#x2F;&lt;&#x2F;a&gt; and it exemplifies exactly what should be avoided when throwing such an event. What the author says should be something that should be internalized at HackIllinois: &lt;strong&gt;“Hacks are just that… they are hacks”&lt;&#x2F;strong&gt;. Hacks are just pieces of code cobbled together - just as a writer in the flow spits words onto a page, a hacker wired in spits out code. And just as writers would never submit a first draft for publication, hackers should never presume that their project is done after the hackathon. Like a good writer, the hackathoner should make it stable and share it. No one should be going into a hackathon thinking they are going to change the world because that requires more than 36 hours and working at a scale hackathons cannot provide. That being said, hackathons are wonderful tools for 2 types of projects.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Crank out a prototype
&lt;ul&gt;
&lt;li&gt;If there is an idea that has been itching in your head, a hackathon is a great place to put pen to paper
&lt;ul&gt;
&lt;li&gt;This traces back to the first hackathon at BSD.&lt;&#x2F;li&gt;
&lt;li&gt;Hopefully this turns into something more, a patch to a FOSS project that reaches millions of people or a brand new technology (will require more than 36 hours)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Demonstrate a proof of concept
&lt;ul&gt;
&lt;li&gt;How can you make something do what it was never supposed to do
&lt;ul&gt;
&lt;li&gt;This goes back to the core of the hacking movement,
&lt;ul&gt;
&lt;li&gt;Excellent example is Saurik and the Jailbreaking movement or ROM hackers for Android.&lt;&#x2F;li&gt;
&lt;li&gt;Another good one is the Car controller for Mario Kart  - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devpost.com&#x2F;software&#x2F;catch-me-if-you-can-ga3yxs&quot;&gt;Catch Me if You Can&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Hopefully the hacker puts out a guide or at least the source so other can learn&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;One may see that these two categories are symbiotic. These categories do not presume anything past the restrictions of a hackathon, but focus on sharing the result, which is what hackathons are about.&lt;&#x2F;p&gt;
&lt;p&gt;HackIllinois’ motto should be &lt;strong&gt;“Contribute Something Amazing”&lt;&#x2F;strong&gt;. Hackathons should not be about founding startup or curing cancer. They should be a place to create, contribute, and explore. Contribution could take the form of a discovery or a patch, and we should encourage people not just make something and leave it, they should feel proud and inspired enough to keep working and sharing it with others.&lt;&#x2F;p&gt;
&lt;p&gt;Applications of existing APIs are not strong qualifiers.  A video search engine that glues two external APIs (one to process images and another to process text) with some basic engineering glue is not in the spirit of the ideal of make a contribution, since nothing new was learned. It is extremely important to notice that this protects the event from imminent data science projects that will visualize data provided from leveraging existing analysis on large open datasets.&lt;&#x2F;p&gt;
&lt;p&gt;While the entire event is geared towards open source, that doesn’t mean the elimination of the unique whimsicality HackIllinois is well known for, since that is a major part of the HackIllinois brand and success.&lt;&#x2F;p&gt;
&lt;p&gt;The event should have 3 key values:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Students should be creating legitimate projects, either by contributing to the world of open source, or by developing novel uses of common (open source) technologies or devices and there should be a focus on getting those contributions released to the public (i.e. Open Licensing)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;HackIllinois should attract the most motivated students from around the nation. This can be done by the unique opportunity that is presented by being able to work with key people from the CS community.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;The people who come to HackIllinois should represent various backgrounds i.e young, old, male, female etc.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;And the event should seek to be something&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Whimsical and Fun&lt;&#x2F;li&gt;
&lt;li&gt;A unique experience that sets people on a new path&lt;&#x2F;li&gt;
&lt;li&gt;A place where the FOSS community gets to interacts and mentor students.&lt;&#x2F;li&gt;
&lt;li&gt;A place of mentorship and study at a depth not typical of a hackathon.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;inspiration&quot;&gt;Inspiration&lt;&#x2F;h3&gt;
&lt;p&gt;Our inspirations are not other college hackathons, but rather meetups like Twillo BASH, or Greylock Hackfest.&lt;&#x2F;p&gt;
&lt;p&gt;Twilio BASH is a small event tied to the Signal Conference. It featured a carnival type atmosphere with a bunch of games centered around the CS culture (e.g a virtual boat race where successfully debugging a code snip-it moves your boat ahead, a 4 v 4 person arcade game or a lego building competition). Winners of these games would earn tickets which could be exchanged for prizes like a NES or headphones. This might be a fun way to let people go home with something without the idea of judging and prizes. It would also be a great  way to take a break.&lt;&#x2F;p&gt;
&lt;p&gt;Greylock Hackfest exemplifies the execution goals of HackIllinois: mentorship is plentiful, there is an extremely wide variety of participants, and events like a midnight carnival or a chocolate fountain provided memorable experiences. Submission-wise, this was a very selective hackathon, and as a result, API hacks were rare. Many hacks were full platforms or clean apps, there was even one group trying to recreate Project Soli from a RC car &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;atap.google.com&#x2F;soli&#x2F;&quot;&gt;https:&#x2F;&#x2F;atap.google.com&#x2F;soli&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;These events should serve as inspiration for how to make an event memorable but they don&#x27;t represent the values that HackIllinois should stand for. Ultimately what we should aim for is the vibe of a quirky LAN party: Lots of food, lots of fun, and lots of people having a good time with each other while learning and contributing. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=5302940&quot;&gt;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=5302940&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-hackillinois-2017-looks-like&quot;&gt;What HackIllinois 2017 looks like&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;300-400 external (non-UIUC) hackers, hard max.
&lt;ul&gt;
&lt;li&gt;All UIUC students are accepted to walk in, however swag and food is only promised to those who pre-register.&lt;&#x2F;li&gt;
&lt;li&gt;Target ratio of 1:1 Non-UIUC to UIUC&lt;&#x2F;li&gt;
&lt;li&gt;Admission is partially random and partially via a completely objective merit based system (e.g admissions puzzle)&lt;&#x2F;li&gt;
&lt;li&gt;No cap on project team size.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Registration must be put out in late Nov, early Dec to give us time to react to demand.&lt;&#x2F;li&gt;
&lt;li&gt;All projects made and submitted during HackIllinois 2017 should be open released as open source under a FOSS license (e.g GPL, MIT, UIUC&#x2F;NCSA, CC) to be eligible for judging&lt;&#x2F;li&gt;
&lt;li&gt;A significant portion of the attendees (not counting the 300-400 + UIUC students) should be active developers on Open Source projects&lt;&#x2F;li&gt;
&lt;li&gt;Target 30% active Open Source developers.&lt;&#x2F;li&gt;
&lt;li&gt;Any Open Source project represented must send min 3 mentors but ideally 5-10
&lt;ul&gt;
&lt;li&gt;This should enable a ratio mentor to student ratio of 1:2-3 while keeping groups around 10 to 15.
&lt;ul&gt;
&lt;li&gt;This means personal attention and resiliency from people who dip.&lt;&#x2F;li&gt;
&lt;li&gt;This was learned from attempting the small group size model in 2016 with 1 mentor and 3-4 hackers. Ultimately small issues (hackers leaving, mentor sleeping in etc.) had an outsized impact on the success of the team. Due to some natural reorganization during the event we saw that a low mentor hacker ratio but large group size made it easier to react to these issues&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Sponsors of HackIllinois 2017 should have interest in Open Source and should send 3-5 Engineers to work with students on one of their open source projects&lt;&#x2F;li&gt;
&lt;li&gt;The company showcase should be named a tech showcase, where they alongside the open source projects, present an open source technology  and the problems that need to be solved.
&lt;ul&gt;
&lt;li&gt;This occurs during the team matching phase at the beginning of the hackathon.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Submissions for judging should be of one of 2 categories
&lt;ul&gt;
&lt;li&gt;Patch or Feature to existing Open Source Platform
&lt;ul&gt;
&lt;li&gt;E.g Contribution to Ubuntu 16.10&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;A start of a new Open Source project (could be PoC with future)
&lt;ul&gt;
&lt;li&gt;E.g If ACM wanted to open source &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;acm-uiuc&#x2F;groot&quot;&gt;Groot&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Can be mainly Proof of Concept, but must have clear path forward. The ‘mario in a car’ project from HackIllinois 2016 would only qualify if the team had clearly shown a path toward emulating other key-presses and playing other games, etc.&lt;&#x2F;li&gt;
&lt;li&gt;Condition: There must be a team of min 3 people who worked on this project for it to be eligible&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Logically, Web APIs will not be a part of this hackathon&lt;&#x2F;li&gt;
&lt;li&gt;VIP Speakers and judges should have a hard bent towards open source
&lt;ul&gt;
&lt;li&gt;E.g Chris DiBona, Director of Open Source - Google&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Workshops and Tutorials need to have a strong open source basis and should ideally be put on by the projects not the event. Some should exist specifically to introduce developers to the FOSS flow.
&lt;ul&gt;
&lt;li&gt;How to choose a license&lt;&#x2F;li&gt;
&lt;li&gt;How to submit a patch, Pull Request&lt;&#x2F;li&gt;
&lt;li&gt;Tool chain and build tools&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Prizes should not be monetary
&lt;ul&gt;
&lt;li&gt;Should be items or experiences such as
&lt;ul&gt;
&lt;li&gt;Compute time on Blue Waters&lt;&#x2F;li&gt;
&lt;li&gt;Tickets to DefCon&lt;&#x2F;li&gt;
&lt;li&gt;Etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;A special “Test of Time” prize should be awarded 3-6 months after the event for the group who has made the most progress&lt;&#x2F;li&gt;
&lt;li&gt;HackIllinois should still maintain its whimsicality
&lt;ul&gt;
&lt;li&gt;I.e Strong theming&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;HackIllinois should encourage healthy hacking
&lt;ul&gt;
&lt;li&gt;Places to actually sleep
&lt;ul&gt;
&lt;li&gt;Set up hosts for example.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Have healthy food&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Use the opportunity to showcase Champaign-Urbana
&lt;ul&gt;
&lt;li&gt;Midnight tours&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Try something like Twilio Bash to get people&#x27;s minds off hacking for a bit
&lt;ul&gt;
&lt;li&gt;Allows students to win prizes while not making the hackathon overly competitive&lt;&#x2F;li&gt;
&lt;li&gt;Have games like Debugging Boat Race&lt;&#x2F;li&gt;
&lt;li&gt;4v4 Arcade Battle&lt;&#x2F;li&gt;
&lt;li&gt;Lego Building comp.&lt;&#x2F;li&gt;
&lt;li&gt;Etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Improve event long activities
&lt;ul&gt;
&lt;li&gt;Cluehunt (a favorite amongst hackers)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Make sure that Hardware and Software Open Source Projects are represented
&lt;ul&gt;
&lt;li&gt;Hardware
&lt;ul&gt;
&lt;li&gt;Arduino&lt;&#x2F;li&gt;
&lt;li&gt;Raspberry Pi&lt;&#x2F;li&gt;
&lt;li&gt;RepRap 3D Printers&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Software
&lt;ul&gt;
&lt;li&gt;React&lt;&#x2F;li&gt;
&lt;li&gt;Debian&lt;&#x2F;li&gt;
&lt;li&gt;Python&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;A final part of expo at the end of the event should have the groups (all teams competing + any leftover sponsors) presenting ways to get further involved in their projects&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;what-is-open-source&quot;&gt;What is Open Source?&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;“Open-source software (OSS) is computer software with its source code made available with a license in which the copyright holder provides the rights to study, change, and distribute the software to anyone and for any purpose” -Wikipedia&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;At it’s core, Open Source is little more than providing your project’s source code (read: having it up on github), and attaching a Open Source software license to it, in which you release your ability to sue people for using it. Since we live in an age of github repositories and stackoverflow code snippets, the idea that you can be sued over using a code snippet from the internet is beyond foreign. Many don’t realize that before Open Source won out as the dominant way to develop software, code simply wasn’t shared openly on github: it was hidden and viciously protected by lawyers as proprietary software. The simple idea of releasing your code for free for people to use and play around with was immensely powerful: people began contributing to large projects in their free time, collaboratively creating immensely complex software projects that would become some of the software we know today (Linux, Python, etc..).  Open Source so crushed that we don’t realize there could have a been a completely different historical outcome had everyone stuck to their lawyers and kept their codebases proprietary. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;radar.oreilly.com&#x2F;2012&#x2F;07&#x2F;open-source-won.html&quot;&gt;O&#x27;Reilly - Open Source Won&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The Open Source ideals do not stop at software. The Open Hardware is a growing community as well, featuring the open 3D printing platform RepRap, Arduino, and more. There are efforts and many other disciplines, Biology, Design, Architecture that all are looking to incorporate open source ideals into their workflows. Open Design [IDEO] - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ideo&#x2F;avocado&quot;&gt;Avacado&lt;&#x2F;a&gt;, Open Interaction Design [Facebook] - [Origami](https:&#x2F;&#x2F;github.com&#x2F;facebook&#x2F;origami, Open 3d-printing  [RepRap] http:&#x2F;&#x2F;reprap.org&#x2F;, Open Source Architecture [Emerging] https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Open-source_architecture)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note: Open Source is not a theme like wilderness or space. It is a focus like hardware or software. HackIllinois should still have a separate theme. Which leads to a secondary point, the theme does not need to be interconnected with focus.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-open-source&quot;&gt;Why Open Source&lt;&#x2F;h3&gt;
&lt;p&gt;Embracing the culture of Open Source will gain us access to this community and the people who run it. While it may seem that embracing the FOSS movement is not a major change for our generation, just the shift in terminology will have deep impact on the mindset with which hackers come in with, as the FOSS movement traditionally embodies a spirit of open collaboration and building out software for the greater good.&lt;&#x2F;p&gt;
&lt;p&gt;Open Source also brings these added benefits:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Many great relationships in CS span generations Adve and Latner, Clark and Andreesen.&lt;&#x2F;strong&gt; This is an opportunity unique to HackIllinois where you actually meet developers who are not your age.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;More than just recruiters and hackathoners.&lt;&#x2F;strong&gt; The current Hackathon paradigm focuses on prizes and flair, leaving mentorship to a desperate call for peer mentoring among hackathoners and recruiters who attend the event regardless. It is at the point that no participant (barring first timers) expects to learn anything from the mentorship system, aside from fixing an issue.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Existing strong traction among sponsors and participants&lt;&#x2F;strong&gt; HackIllinois 2016 demonstrated very strong traction among Open Source participants, from both participants and mentors, despite a sideshow execution. Interest is on the rise, with Chris DiBona, Google’s head of open source reaching out after hearing about the initiative. Google’s summer of code annually connects ~200 Open Source organizations with about ~1000 students. This is a big deal.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Solves continuity problem&lt;&#x2F;strong&gt; Hackathons are often looked down as competitions that go nowhere and contribute nothing. Open Source, by it’s nature, counters this trend.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Open Source tends to attract strong developers&lt;&#x2F;strong&gt; It is no secret that legitimate developers at some point are drawn to Open Source, whether of good will or the prestige of contributing. Companies know this. Open Source organizations know this.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Very Unique&lt;&#x2F;strong&gt; No other college hackathon has done anything significant in the Open Source space, the potential to become a groundbreaking and original leader in the hackathon space is wide open. As a result, there is also uniquely additional opportunities for media coverage &#x2F; hype.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Inherently high visibility&lt;&#x2F;strong&gt; By the nature of Open Source, the event proselytizes itself. Participating organizations will broadcast their presence, and the work itself is thrust upon the community.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-the-hybrid-model-does-not-work&quot;&gt;Why the Hybrid Model does not work&lt;&#x2F;h3&gt;
&lt;p&gt;The obvious compromise is to make open source a larger part of the event as it currently stands. However, the hybrid model dilutes the strengths of Open Source and ultimately this means less people benefit from what is been shown to be a superior model, and the software and hardware aspects lose out due to a less resources and time devoted (you end up half assing both parts). This is best exemplified by the feedback given by hackers in the Open Source Program:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“The Open Source program was a great experience for our team, because we finally had time, mentorship, and resources to further an open source project that we had actually started. However, despite HackIllinois&#x27; calling for projects that would outlive the hackathon, most of our team felt like the Open Source program was a sideshow during the event... We really appreciated the intent behind Open Source, but a lot of activities at the event didn&#x27;t back up its goals.“ - Open Source Hacker HackIllinois 2016&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;While the Open Source Program at HackIllinois 2016 was a pilot program, the criticism was warranted. Most people if given the choice will do what feels normal and and that is contrary to the goals of the event.&lt;&#x2F;p&gt;
&lt;p&gt;The battle between breadth and depth harkens back to business models and the battle between horizontal (Google) and vertical integration (Apple). As a champion of horizontal integration, Google tends to get a little involved in each space, being dominate in some and doing woefully poor in others (ehm, Google+). Apple is the opposite, controlling every detail that goes into their products, but as a result can only focus on a handful of products . Neither company’s approach is particularly better in the overall business space as both annually alternate as the “world’s most valuable company”. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;venturebeat.com&#x2F;2010&#x2F;05&#x2F;06&#x2F;vertical-vs-horizontal-silicon-apple-google&#x2F;&quot;&gt;VentureBeat - Vertical vs. Horizontal&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;However, only one of these models truly fits within the context of HackIllinois values. As an organization, we seek to create a hackathon that provides the absolute best experience while advocating for this different style of hacking. By trying to commit to all initiatives, we do not show commitment to any specific values and thereby endorse a mediocre product: the MLH style hackathon.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note: A hackathon becomes legendary when it goes hard in one aspect of their experience. MHacks used to go hard at sheer scale, sacrificing food quality and experience quality, yet consistently making it very well known hackathon. Making the same hackathon as others, with a theme and a couple extra features is not a solid path to that success.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-about-the-newbies&quot;&gt;What about the newbies?&lt;&#x2F;h3&gt;
&lt;p&gt;If the expectation of hackers is to make novel uses of tech or add features to the most popular open source projects, the topic of the fate of beginners naturally arises. There are 2 prongs to the strategy.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Students looking to primarily learn skills such as how to use an API or mobile development will find their needs equally satisfied by the 50+ other collegiate hackathons.&lt;&#x2F;li&gt;
&lt;li&gt;Students looking to contribute to FOSS but don’t have the technical chops yet or the confidence to move at the speed of React or Angular, can contribute to an open source initiative OpenHackathon, an open source effort we are forming that aims to create the technical tools and providing documentation necessary for anyone to create their own hackathon. This includes the software for registration, check-in, mentorship, dashboard, mobile apps, how to approach sponsors, a prototyping board and more. All of this tech and information will be released under GPL and Creative Commons. This gives the opportunity for students can work alongside other developers passionate in the EdTech &#x2F; Hackathon space, while providing a high visibility avenue to contribute, while not having the intensity of a large FOSS project.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;incentives-and-value-proposition&quot;&gt;Incentives and Value Proposition&lt;&#x2F;h3&gt;
&lt;p&gt;There are always the questions of incentives to attend and compete, not to mention sponsoring or mentoring. There are two parts to answering these questions: what is our audience, and what is their motivation.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;hackers&quot;&gt;Hackers&lt;&#x2F;h4&gt;
&lt;p&gt;Hackers broadly fall into three camps: those who enter to win (Competition Hackers), those who enter to spend time with their friends&#x2F;work on a project&#x2F;enjoy the process of hacking (Casual Hackers), and those who enter to join the movement or learn (Curious Hackers).&lt;&#x2F;p&gt;
&lt;p&gt;Attracting competition hackers should never be a focus of HackIllinois. At their core, these participants are competitors who have developed (and are constantly improving) a formula for winning prizes (fairly famous example http:&#x2F;&#x2F;thetech.com&#x2F;2014&#x2F;11&#x2F;14&#x2F;hackmit-v134-n54). They only care about the monetary benefit of their attendance, and will strongly affected by any any changes to prizes. Aside from not creating a sustainable spirit, this does not mesh well with HackIllinois’ or the FOSS movement’s values.&lt;&#x2F;p&gt;
&lt;p&gt;Hackers who are solely entering to learn coding or join the college hackathon movement, should not be our main focus as there already exist  50+ hackathons out there focused on this demographic, though we think that the event would be helpful to them, however it is going to be more demanding that many of the hackathons they are used to.&lt;&#x2F;p&gt;
&lt;p&gt;We need to target  hackers who are looking to contribute to the greater Software Engineering community (the Free and Open Source Software movement) or are looking to work on projects of substance. It may seem exclusive but creating a beginner-oriented hackathon is (at the time of this writing) incredibly redundant throughout the hackathon space.&lt;&#x2F;p&gt;
&lt;p&gt;Our core target group is people who feel disenfranchised by the current hackathon culture, people who understand or seek to understand Free and Open Source Software. As noted previously, these people  are typically great engineers looking for a push to contribute to the things they have used or seen. Initially, these hackers will be skewed toward a certain profile, but provided they have great experiences (good food, good fun and good people) they will spread the word and bring more and more of the other two groups next year and the year after. These participants will also understand that good work never goes unnoticed, and see that they can potentially get an employee referral based on their work. By bringing Open Source to the hackathon scene, we stand to make a significant change in Open Source involvement at the college level.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;incentives&quot;&gt;Incentives&lt;&#x2F;h5&gt;
&lt;p&gt;That being said, in order to increase the probability of people attending, several significant incentives must be available. The first should be an incredible event in and of itself, and we are able to leverage the tremendous reputation of HackIllinois in this respect. . The next incentive is a  form of travel compensation. From our experience during HackIllinois 2016, we know that it is important that well defined and clear-cut qualification criteria should be put in place. As a potential qualification for a  target of 300-400 non UIUC attendees, is the following offer of acceptance to the event:  hackers more than 350 miles (Ann Arbor) to 500 miles (Pittsburgh) away will be given reimbursements but will in summation not make up more than ⅓ of the accepted hackers. Criteria for reimbursements could be determined from a variety of factors, from just distance to prior contributions to FOSS or other hacker-related criteria (e.g. demographic representation).&lt;&#x2F;p&gt;
&lt;p&gt;As many people will be traveling, another possible incentive is the ability to stay in a UIUC students dorm, HackMIT style. This creates an opportunity to forge a connection with someone at UIUC, someone who could showcase UIUC and make sure to take care of their guest and others visiting, ensuring there is always a place to sleep and safely store belongings. It also encourages healthy hacking (a key point often brought up by critics of the college hackathon scene), and insures that each participant has someone to ask when they need something or have a problem. This is key to making new and old hackers alike feel welcome.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;prizes&quot;&gt;Prizes&lt;&#x2F;h5&gt;
&lt;p&gt;In this new pivoted event, prizes are somewhat obvious but need to be overhauled from previous years. There should no longer be a 1st, 2nd, 3rd place hack because frankly it makes no sense - deciding priority between the top several hacks has always been difficult and very subjective and only creates division and salt.&lt;&#x2F;p&gt;
&lt;p&gt;One possible method of allocating prizes is a vote of all participants. Participants would vote for: “Best Contribution to a FOSS Project” (like if someone added a new graphics driver to Ubuntu), and “Most Interesting New FOSS Project”. Particularly, one “Test of Time” prize should be given 3-6 months after the end of HackIllinois and given to the team that has been the most productive after the end of HackIllinois. The endorsement it gives the winner, that huge members of the FOSS and hacking community liked their submission the best is something truly special.&lt;&#x2F;p&gt;
&lt;p&gt;The prizes would take the form of items that will provide new experiences or resources, not just money. Good examples are items like tickets to conferences such as DefCon, SXSW, WWDC, Google I&#x2F;O, and O’Reilly OSCON, items such as a GTX 1080 (great for CUDA and Deep Learning)  or very unique prizes such as a couple hours on Blue Waters.&lt;&#x2F;p&gt;
&lt;p&gt;Since HackIllinois is only giving out about 3 top prizes (we do want to avoid sponsor prizes since that doesn’t really jive with the FOSS mentality) a prize giving event such as Twilio Bash, carnival type atmosphere, and CS-related minigames with prizes that can be bought with won tickets (e.g. NES, flash drives, HackIllinois swag and company swag) may provide the same thrill of having something to take home (while not just being something you queue in line for upon registration and leave with).&lt;&#x2F;p&gt;
&lt;h5 id=&quot;the-question-of-initiatives&quot;&gt;The Question of Initiatives&lt;&#x2F;h5&gt;
&lt;p&gt;From data gathered from 3 prevalent hackathons (HackIllinois, MHacks, BoilerMake). The idea of separating segments of the hacking population into initiatives adds a lot of complexity for very little added benefit.&lt;&#x2F;p&gt;
&lt;p&gt;We saw in 2016, 20% of submissions were hardware projects (16% if you don&#x27;t include VR and smart watches) , 21% in 2015 (10% if you don&#x27;t include VR and smart watches) , and 16% in 2014 (11% is you don&#x27;t count VR and smart watches) for HackIllinois. We had 216, 180, and 135 submissions total for 2016, 2015, and 2014 respectively&lt;&#x2F;p&gt;
&lt;p&gt;Mhacks 6 had 15% (12% if take out VR and smartwatch only hacks) out of 276 submissions, MHacks 5 had 19% (11% if you take out VR + smartwatches) out of 274 submissions&lt;&#x2F;p&gt;
&lt;p&gt;Boilermake, the hardware hackathon got 21% (19% without smartwatches or VR) in 2015 out of 84 submissions, 24% in 2014 (20% without smartwatches (10% of which featured the boilermake badge)) out of 99 submissions&lt;&#x2F;p&gt;
&lt;p&gt;The increase at HackIllinois 2016 is most likely due the increased availability of hackable hardware. Intel pulled hard here, as well as us not focusing on having every type of resistor but more stuff like myo, drones, arduino shields, etc.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;experience&quot;&gt;Experience&lt;&#x2F;h5&gt;
&lt;p&gt;For the hacker, the value of an open source event comes from several key experiences . Primarily,  it lowers the learning curve for getting involved in FOSS, a very rewarding but initially intimidating community . This is a gap that many people find hard to cross and having someone to hold your hand through the process is tremendously reassuring . Once students cross the gap, being involved in FOSS is as simple as committing to Github - it is no longer otherworldly. Throughout their experience, students will learn about aspects of FOSS that are not talked about outside the FOSS circles such as licensing, governance, communication and organization . Students will make valuable connections with people in and out of college and create connections that will last beyond the hackathon, not just from a personal perspective (as happens in most events), but also as a technical&#x2F;developer peer.  As participants  will be working with the mindset that their code will be used and freely distributed, they will  be required to adhere to good engineering practices and as a result have something to be proud off &#x2F; show off at the conclusion of the event. By closing ceremony,  participants will head home having had a good time, having learned a lot in a unique developer ecosystem, met some top tier people and a full bag of swag and prizes.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;mentors&quot;&gt;Mentors&lt;&#x2F;h4&gt;
&lt;p&gt;Mentors would want to come to HackIllinois because it is a wonderful platform to find new people to contribute to their projects. It is also a way to showcase their projects in front of companies and students, and just as companies do in traditional hackathons ( representatives of FOSS projects do have an interest in evangelizing their projects). Mentoring  is also a great way to get involved in education; training the next generation of engineers in good engineering practices. Benefits should include hotels for the night between Sat and Sun, and eligibility for prizes just like the hackers.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;mentorship&quot;&gt;Mentorship&lt;&#x2F;h5&gt;
&lt;p&gt;Mentorship should consist of large groups i.e 10 - 15 hackers, and ~3-5 mentors for each project. We learned from Open Source of HackIllinois 2016 that the most successful groups are those that can lose or add people as necessary, while keeping the ratio between hackers and mentors low. It is imperative that participating projects bring as many mentors as they can.&lt;&#x2F;p&gt;
&lt;p&gt;Outreach should be based around projects,  e.g. React, Angular, Tensorflow, Debian, Ubuntu, ASP.NET.&lt;&#x2F;p&gt;
&lt;p&gt;Having high profile projects well represented at HackIllinois is  key to making Open Source work. Using the networks created by Google Summer of Code, the Apache Foundation and others will give us a way to expand our contacts and put us in touch with more projects.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;potential-vips-speakers-or-judges&quot;&gt;Potential VIPs (Speakers or Judges)&lt;&#x2F;h5&gt;
&lt;p&gt;Chris DiBona, head of Google Open Source (!!!) has already reached out. Other great speakers would include&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Saurik (spoke last year, Cydia)&lt;&#x2F;li&gt;
&lt;li&gt;Juan Bennet (spoke last year and was a favorite, IPFS)&lt;&#x2F;li&gt;
&lt;li&gt;James Gosling (Java)&lt;&#x2F;li&gt;
&lt;li&gt;Linus Torvalds&lt;&#x2F;li&gt;
&lt;li&gt;Vikram Adve, Chris Lattner (Creators of LLVM)&lt;&#x2F;li&gt;
&lt;li&gt;Brendan Eich, Jamie Zawinski (UIUC Alumni, creator of Javascript and co-founder Mozilla Foundation)&lt;&#x2F;li&gt;
&lt;li&gt;Andy Rubin, et. al. (Android)&lt;&#x2F;li&gt;
&lt;li&gt;Bjarne Stroustrup (C++ creator)&lt;&#x2F;li&gt;
&lt;li&gt;Guido van Rossum (Python Creator)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Anyone from any organization within Google Summer of Code 2016. It’s 176 orgs, you can’t really miss.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;sponsors&quot;&gt;Sponsors&lt;&#x2F;h4&gt;
&lt;p&gt;Sponsors can point to this event as a huge signal that they are committed to Open Source, something that many companies try to do but struggle to find an avenue to do so through. By sponsoring HackIllinois, a company is investing in the next generation of open source  not only with their dollars but by getting their hands dirty sitting down with people and writing code. As in hackathons of year past, they will still benefit from the traditional hackathon perks, resumes, having a recruiter on site etc. However, they will now  be  converting a set of hackathon goers into contributors (more than just developers)  for their platforms, and will benefit from the exposure in such a high profile community (Hackathon-FOSS). Sponsoring the event will also present the opportunity to gain mindshare with a very productive set of hackers who are known for creating and maintaining more involved projects, something more valuable to a company than the broadcast approach to API advertising. As a result, a participating sponsor has more to take home than API usage numbers, they have attracted elite developers, found collaborators to improve or maintain Open Source resources, and exposed themselves to the community as champions of furthering the community they sponsor.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;who-sponsors-an-open-source-hackathon&quot;&gt;Who Sponsors an Open Source Hackathon&lt;&#x2F;h3&gt;
&lt;p&gt;Prominent examples of companies that make Open Source a core part of their value system include: Google, Microsoft, Facebook, Apple, CoreOS, Mesosphere, Meteor and Databricks. Some of these companies have explicitly reached out to get involved with Open Source (specifically, [Chris DiBona]( https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Chris_DiBona, head of Google Open Source). &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developers.google.com&#x2F;open-source&#x2F;gsoc&#x2F;&quot;&gt;Google’s Summer of Code&lt;&#x2F;a&gt; annually connects ~1,000 students to ~200 Open Source projects.)&lt;&#x2F;p&gt;
&lt;p&gt;Sponsors from last year involved in Open Source&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Google&lt;&#x2F;li&gt;
&lt;li&gt;Apple&lt;&#x2F;li&gt;
&lt;li&gt;Facebook&lt;&#x2F;li&gt;
&lt;li&gt;Microsoft&lt;&#x2F;li&gt;
&lt;li&gt;Airbnb&lt;&#x2F;li&gt;
&lt;li&gt;A16z&lt;&#x2F;li&gt;
&lt;li&gt;KPCB&lt;&#x2F;li&gt;
&lt;li&gt;Yahoo&lt;&#x2F;li&gt;
&lt;li&gt;JetBrains&lt;&#x2F;li&gt;
&lt;li&gt;Salesforce&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Potential Sponsors&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CoreOS&lt;&#x2F;li&gt;
&lt;li&gt;Databricks&lt;&#x2F;li&gt;
&lt;li&gt;Canonical&lt;&#x2F;li&gt;
&lt;li&gt;Docker&lt;&#x2F;li&gt;
&lt;li&gt;RedHat&lt;&#x2F;li&gt;
&lt;li&gt;Mozilla&lt;&#x2F;li&gt;
&lt;li&gt;Github (!!!)&lt;&#x2F;li&gt;
&lt;li&gt;MongoDB&lt;&#x2F;li&gt;
&lt;li&gt;Yelp&lt;&#x2F;li&gt;
&lt;li&gt;Nvidia&lt;&#x2F;li&gt;
&lt;li&gt;OpenAI&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Note: Something important about reaching out concerning Open Source is to hit an engineer or director of the project because recruiters may not see the benefit immediately as an engineer would. Having an engineer on the inside, especially higher up in the organization will make our jobs much easier as they can help advocate for the importance of supporting FOSS.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Potential Projects&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Tensorflow&lt;&#x2F;li&gt;
&lt;li&gt;Caffe&lt;&#x2F;li&gt;
&lt;li&gt;Ruby&lt;&#x2F;li&gt;
&lt;li&gt;Python&lt;&#x2F;li&gt;
&lt;li&gt;Go&lt;&#x2F;li&gt;
&lt;li&gt;Arduino&lt;&#x2F;li&gt;
&lt;li&gt;Angular&lt;&#x2F;li&gt;
&lt;li&gt;React&lt;&#x2F;li&gt;
&lt;li&gt;Node&lt;&#x2F;li&gt;
&lt;li&gt;Debian&lt;&#x2F;li&gt;
&lt;li&gt;Ubuntu&lt;&#x2F;li&gt;
&lt;li&gt;Arch&lt;&#x2F;li&gt;
&lt;li&gt;OpenSUSE&lt;&#x2F;li&gt;
&lt;li&gt;etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Note. Be careful when reaching out to FOSS groups to use the correct terminology. Many groups (e.g GNU) will tell you to go away if you use the term Open Source or Free Software with the wrong group. It is worthwhile to have a briefing on the differences between free software and open source and to research the groups before reaching out. When in doubt use the term FOSS (Free and Open Source Software). It will also be important in terms of branding to make sure HackIllinois is a FOSS hackathon not an Open Source Hackathon for similar reasons. Note that many of these organizations are interconnected (e.g Apache) and thus it is important to create a strategy that hits the most people personally without spamming.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;staff&quot;&gt;Staff&lt;&#x2F;h4&gt;
&lt;p&gt;The value proposition and incentives for the staff is important as well if we are to avoid the staff churn by other large hackathons (read: MHacks). By pivoting to Open Source, the staff will feel that they are part of something actively growing, brand new, and in control of a very significant new paradigm. Not only are individual staff members getting more responsibility, they are in a unique position to shape a completely new movement in the Hackathon space. If HackIllinois continues to be a “college hackathon” many of the people who have the most to contribute will not stick around, because there is nothing to solve. Chris McAvoy of Mozilla Open Badge has an analogy for this:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“The attackers and defenders of an empire. In an empire, no one is eager to stick around and defend what is captured, just as developers are drawn to active development and not documentation of what has been created, despite the importance of doing so. “&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;hackillinois-in-2-3-years&quot;&gt;HackIllinois in 2-3 years&lt;&#x2F;h3&gt;
&lt;p&gt;HackIllinois has the potential to be the Open Source version of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Apple_Worldwide_Developers_Conference&quot;&gt;WWDC&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;South_by_Southwest&quot;&gt;SXSW&lt;&#x2F;a&gt; (though there are also other great events such as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;conferences.oreilly.com&#x2F;oscon&#x2F;oscon-or&quot;&gt;OSCON&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;allthingsopen.org&#x2F;&quot;&gt;All Things Open&lt;&#x2F;a&gt;), especially in the sense of evangelizing Open Source to those who have yet to be exposed. It could be where people who are interested in Open Source come to meet each other, work on projects and listen to the biggest names in open source speak. UIUC has one of the most storied traditions of Open Source software, rivaling Berkeley (BSD, RISC-V, Mesos, etc.) and MIT (GNU) with Javascript, Firefox, LLVM and more. If we can get enough people who are not just students to come and work, we may have something extremely special that no other university could rival (especially assuming we get there first).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-organization&quot;&gt;The Organization&lt;&#x2F;h2&gt;
&lt;p&gt;HackIllinois must fully commit to a transition from an event staff to a real year-round organization to back this shift to Open Source. This ensures that there are always community members ready to get involved while maxing the utility of each staff member. The current model of 15-30 people working year-round on putting on HackIllinois (contacting mentors, contacting hackers, sponsors etc.) and the rest running other events within CS&#x2F;ECE community is a step in the right direction. HackNights is a good start, however we can leverage existing CS communities to put on events like a GameJam with Gamebuilders or putting on the Datasummit with ADSA. This has the twofold benefit of creating sustainable (each will be learning experience for the staff) and interesting events (empowering specialists to put on a great event). As an organization, HackIllinois can use these events as another avenue of fundraising for the main event as multiple companies will be interested in private events depending on their recruiting focus. This opens the possibility of focusing on companies that strongly align and add value to the main event, while developing stronger, more specialized sponsor-community relations in these private events.  As a result, we can concentrate companies who are truly serious about supporting our vision and not tagging along for recruiting or platform evangelization (as is the common case in today’s hackathons admittedly).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;vision-1&quot;&gt;Vision&lt;&#x2F;h3&gt;
&lt;p&gt;This grand vision of this pivot questions HackIllinois’ current position in the CS @ ILLINOIS ecosystem - does HackIllinois just put on events or does it mean more? HackIllinois should be the representation of the hacker movement at UIUC: it should work to move the idea of hacking from prizes and startups (which quite frankly aligns better with Founders&#x2F;54.io) to creative ideas and making something that changes how people think or makes something better. Illini Hackers is a shell of an organization that often refers to itself as “just a facebook group”. This should not be the way it is: hackers should have a place and set of resources at their disposal, whether it is the ability to checkout hardware for a hackathon, to travel scholarships, or busses arranged (all of which can be provided by HackIllinois Org currently). It will also make HackIllinois a more cohesive part of the hacker community, where organizers and attendees are the same set of people and are constantly in touch with a variety of other groups,  other university’s hacking organizations, companies, etc.. It also ensures that HackIllinois will always be run by hackers, people who are in the loop and know what needs to change about hackathons. This alleviates an issue that other large hackathons are suffering through (read: MHacks), where the hackers and the organizers are starting to split into two bipartite sets (and often averse to unification). Through unification, we open more opportunities for hackers and organizers, as they will always have either other’s knowledge to tap.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;services-and-roles&quot;&gt;Services and Roles&lt;&#x2F;h3&gt;
&lt;p&gt;The organization should be split broadly into two parts, one focusing on the hackers of UIUC and the other on putting on the events.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-hackers&quot;&gt;The Hackers&lt;&#x2F;h4&gt;
&lt;p&gt;There should be one person elected as the representative of the Hackers, his or her role is to provide organization and resources to the hackers. This includes being the point of contact for other hackathons, organizing busses, setting up hardware loans, and scholarships. Scholarships in particular should be a point of importance to the hacker representative. It may be tempting for people to apply for a scholarship so they get a free trip to some other University, a good condition of acceptance to mitigate maybe being that hackers awarded a scholarship are required to make some sort of contribution to the FOSS community at the hackathon they are attending. This will continue HackIllinois’ commitment to FOSS and be a valuable motivation for hackers to get more involved in FOSS. This could range from a small platform the hacker creates to hacker contributing to a major FOSS project. Perhaps this representative can contact other universities hacking organizations to set up interesting remote events, arrange to have hosts for UIUC hackers and more. Overall, this side of the organization is responsible for organizing the hackers: through a tutorial series, small codejams in the middle room of ACM, or just getting them to come to HackNights, as well as managing relationships with other hacking organizations. At the minimum this side of the organization should have a general meeting once a semester to remind people of the resources available and of upcoming hackathons that semester.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-organizers&quot;&gt;The Organizers&lt;&#x2F;h4&gt;
&lt;p&gt;The Organizers’ role is to put on HackIllinois events. They should be focusing on HackIllinois but also work to engage people in the hacker community through events and opportunities at UIUC. Obviously, this includes the main event but should extend beyond. Events such as HackNights are vital. In addition to the above, they should be looking for ways to present people with the chance to get involved on campus in hacking and FOSS in creative ways, as well as connecting the UIUC community with outside groups.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;structure&quot;&gt;Structure&lt;&#x2F;h3&gt;
&lt;p&gt;The face of the organization should be the director(s) of the HackIllinois event, since they can represent both the interests of the hackers and organizers as a result of the relationships (with the department and other organizations) built during the planning and execution of the Main Event. The five main leads should consist of the representative of the hackers, the director of HackNights and the 3 major branches of HackIllinois, forming a balanced team that keeps the hackers in mind while still remaining conscious of the requirements of putting on a hackathon.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;meetings-and-workflow&quot;&gt;Meetings and Workflow&lt;&#x2F;h3&gt;
&lt;p&gt;The format for meetings for each brand&#x2F;subgroup will be a little different.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;illinihackers&quot;&gt;IlliniHackers&lt;&#x2F;h4&gt;
&lt;p&gt;IlliniHackers should have at least one general meeting at the beginning of each semester just like UIUC’s IEEE Chapter, that reminds people of the services that IlliniHackers can provide, the hackathons for the coming semester, and to get feedback on which people would like transportation to. This is essential to starting to build a community. Further meetings should be organized by the Hacker representative and may include tutorials and workshops. IlliniHackers should also strongly encourage attendance at HackNights.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;hackillinois&quot;&gt;HackIllinois&lt;&#x2F;h4&gt;
&lt;p&gt;As HackIllinois Staff has decreased in size, one weekly meeting is all that is required to remain synced. A second weekly meeting may be put on in conjunction with the organizers of HackNights in the style of the HackIllinois 2016 staff meetings. This will give students a chance to learn from the HackIllinois Staff and for the staff to consider succession and new hires. HackIllinois should be actively looking to bring more people on as they prove themselves, and all members of this group should be aware of the sheer amount of work that is required to make HackIllinois happen. &lt;strong&gt;TL;DR:&lt;&#x2F;strong&gt; Hire slow, fire never (ideally).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;hacknights&quot;&gt;HackNights&lt;&#x2F;h4&gt;
&lt;p&gt;HackNights should have one meeting a week with more if necessary for the success of a planned event. This meeting should include the organizers of HackIllinois to serve as mentors and ensure that the greater organization&#x27;s interests are maintained.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;openhackathon&quot;&gt;OpenHackathon&lt;&#x2F;h4&gt;
&lt;p&gt;Software and documentation developed for OpenHackathon should be created in the process of creating HackIllinois and the HackNights. However, there should be someone to maintain the organization, accept pull requests to the code base, and maintain overall presence.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;regarding-slack&quot;&gt;Regarding Slack&lt;&#x2F;h3&gt;
&lt;p&gt;Slack was found to be a great method of communication in the planning of HackIlinois 2016. However, several key lessons were learned. First, only active organizers who are working for the Organizers side of the org should have access, signified by having a hackillinois.org email (which should be cleaned each year). IlliniHackers can have its own org wide slack, but might not be necessary since there already exists a Facebook group.&lt;&#x2F;p&gt;
&lt;p&gt;Almost everything on the HackIllinois Slack should be public (minus budget discussions which should be confined to the Director, the head of HackNights, the 3 Department heads for HackIllinois and the representative of the hackers). This means that anyone who wants to contribute ideas can do so to any part of the organization. In addition, this will ensure that ideas and themes are more easily shared among all parties. Tiers of Slack access was the predominant reason most of Hackillinois 2016 staff felt that they did not know what was going on, in addition to stifling inter-department conversation within the HackIllinois organizing team. Maintaining this transparency  also serves to further respect the time that people are putting into this organization by not presuming that only certain people should be allowed to comment or be informed on certain topics. Further, individuals’ contributions to this open slack will expose solid candidates for future roles in HackIllinois, as these contributions are a solid metric by which to recruit.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;slack-layout&quot;&gt;Slack Layout&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Public
&lt;ul&gt;
&lt;li&gt;#general &amp;lt;- @channel disabled here (for non admins)&lt;&#x2F;li&gt;
&lt;li&gt;#random &amp;lt;- @channel disabled here&lt;&#x2F;li&gt;
&lt;li&gt;#hackillinois (general for hackillinois)&lt;&#x2F;li&gt;
&lt;li&gt;#hacknights (general for hacknights)&lt;&#x2F;li&gt;
&lt;li&gt;#hackillinois_outreach&lt;&#x2F;li&gt;
&lt;li&gt;#hackillinois_branding&lt;&#x2F;li&gt;
&lt;li&gt;#hackillinois_experience&lt;&#x2F;li&gt;
&lt;li&gt;#hackillinois_systems&lt;&#x2F;li&gt;
&lt;li&gt;#hacknight_[date] &amp;lt;- these are small staffs so further breakdown is not needed&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Private&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;#leadership
&lt;ul&gt;
&lt;li&gt;Leadership of major branches of the org + treasurers + active advisors&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;#advisors
&lt;ul&gt;
&lt;li&gt;Past directors and core who still want to help&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Any further private communication can go through DMs
Adhering to this layout will maximize transparency within the organization, excellent for avoiding the creation of factions and discontent.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;branding-brand-management&quot;&gt;Branding &#x2F; Brand Management&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;illinihackers-1&quot;&gt;IlliniHackers&lt;&#x2F;h4&gt;
&lt;p&gt;IlliniHackers should be the presumptive name of the unified organization that represents the hackers and the organizers of the event. It will also be used to refer to the hackers themselves. We currently have admin rights to the FB group though admin rights to FB page need to be acquired. As noted above, IlliniHackers also must grow into an actual community past a loose collection of hackathon goers. This includes outreach programs, like hardware checkout, and scholarships.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note: ‘IlliniHackers’ should be stylized to have no space to mirror the branding of HackIllinois and HackNights.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hackillinois-1&quot;&gt;HackIllinois&lt;&#x2F;h3&gt;
&lt;p&gt;HackIllinois is the flagship event of the IlliniHackers&#x2F;HackIllinois organization, its brand has been maintained over the years as a whimsical, highly produced hackathon. This image must be maintained while integrating the Open Source aspect. This means that the same level of art, design and execution must be maintained.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hacknights-1&quot;&gt;HackNights&lt;&#x2F;h3&gt;
&lt;p&gt;HackNights are events put on by the unified IlliniHackers&#x2F;HackIllinois organization that serve several purposes: they train the next generation of HackIllinois Staff, work to serve those who may not want to attend hackathons but still want to be apart of the community, and allow fundraising. HackNights should be individually branded and themed toward the topic of focus but should strive to have the same level of production as the main event.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openhackathon-1&quot;&gt;OpenHackathon&lt;&#x2F;h3&gt;
&lt;p&gt;OpenHackathon is a FOSS initiative to give people the resources and software to make throwing a hackathon as easy as possible. We already have control of a domain (openahackathon.org), github org (&#x2F;open-hackathon) and twitter account (@openhackathon). What is left is to craft a brand around this movement, with a set of design guidelines and terms of usage to protect the brand.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hacknights-2&quot;&gt;HackNights&lt;&#x2F;h2&gt;
&lt;h4 id=&quot;vision-2&quot;&gt;Vision&lt;&#x2F;h4&gt;
&lt;p&gt;HackNights serve multiple purposes both within the organization,  department, and greater community. HackNights are the training ground for our next HackIllinois Staff members, where they can run an event at a smaller scale and learn the skills required to plan and execute events. This comes from the experience of smaller CS events Flight_196 and SAIL&#x2F;Splash, where alums of those events were more tuned into the requirements of putting on an event, e.g. getting food, booking rooms and facilities, sponsors, making engaging content etc. For companies, HackNights are an opportunity to hold a more interesting&#x2F;specialized techtalk, either via a tutorial &amp;amp; hack structure or just a pure ‘use-our-platform’ event. Finally, HackNights are an entry point for many new hackers to get involved within a low stakes environment and for more experienced hackers to learn about new tools. This will make a great substitute for the sort of targeted intro level workshops that were part of HackIllinois (How to Make a Mobile App, How to Use Node, What is Azure, etc.)&lt;&#x2F;p&gt;
&lt;p&gt;Each HackNight should have a technology focus. This focus may be platform based (such as Microsoft Azure), or a more broad theme such as games (similar to a GameJam). Each HackNight should also have a domain-related sponsor attached, who is responsible for funding the event and providing (some to all) mentorship.  If possible, HackNights may also want to partner with a group within the University who focus on the topic. For instance EA could sponsor a gamejam with Gamebuilders providing some mentorship, or IDEO sponsor a design hackathon with Design for America.&lt;&#x2F;p&gt;
&lt;p&gt;Despite a focus on a technology, the organizers should still try to bring the HackIllinois whimsicality to the event as well. This may not have to be done through thematic choices, it could be through mini games, or some other method (the creative decisions to which we leave as an exercise to the reader).&lt;&#x2F;p&gt;
&lt;p&gt;As previously noted, HackNights should also feature the same sort of attention to design and branding that HackIllinois does. This means assets should be created (e.g FB banner image), good graphical layout practices should be adhered to and a global set of branding guidelines should be created in conjunction with HackIllinois to serve as a starting point.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;target-audience&quot;&gt;Target Audience&lt;&#x2F;h4&gt;
&lt;p&gt;Obviously we want to target people who are members of the CS community, but we should also be looking to engage people around campus, whether it means having a hardware HackNight in ECEB, or a Bio inspired HackNight. In a generic sense, the goal of HackNights should be introduce people to what hacking as an activity and culture is, in some unique context&#x2F;domain, and thus the target audience is wide.
Engagement and Incentives&lt;&#x2F;p&gt;
&lt;p&gt;Past HackNights efforts were met with varying success. The ACM tradition of a ‘start of the year’ hacknight was met with great engagement as it was as much hacking as you could get on campus outside of HackIllinois in Fall 2013. The HackNight in the beginning of Fall 2014 was sponsored by Dropbox and also had great engagement. However, as time worn on, the vibe shifted to working on homework while taking advantage of the free food as people became more numb to the novelness of hacking. There a number of ways to mitigate this and it starts with strongly differentiating coming to a HackNight and staying home and hacking. The primary way to do this is a huge amount of personal mentorship. If you can present mentorship more personalized than stackoverflow, then people will come to learn and ask questions (even if debugging). The second part of the strategy is to broaden the focus from just CS majors, to people who have yet to catch the hacking bug. An an example, if a bunch of design majors are invited, their enthusiasm will alter the atmosphere because they bring something new to the table (and to continue the metaphor, we bring something new to theirs). Having mini games w&#x2F; associated prizes will also help, as it changes the feel from staring at a screen writing code to more of a LAN party feel. Prizes will help the atmosphere, but must fit several constraints. Prizes should not just be money, a good prize is something that interacts with the theme or sponsoring company, e.g tickets to WWDC for a HackNight sponsored by Apple. Participants vying for a prize must present the technical specifications of their hacks and not just the functionality of their creation (must disclose APIs&#x2F;significant codebases used). Winners can either be chosen by consensus of the attendees or by the sponsors given some criteria determined by the HackNight Organizers.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;sponsors-1&quot;&gt;Sponsors&lt;&#x2F;h4&gt;
&lt;p&gt;Sponsors of HackNights should not be sponsors of HackIllinois and vice versa unless there is a clear benefit for all three parties (e.g RedHat may want to do a security HackNight leading up to HackIllinois as part of their sponsorship). Many traditional HackIllinois sponsors will not be a fit for the FOSS version and HackNights is an excellent  way to maintain that corporate relationship. There will be some sponsors who prefer one over the other (HackIllinois vs HackNights and vice versa). As such, a good price must be established which does not overcompete with HackIllinois and would generate income for HackIllinois but is not too high to scare sponsors off. Part of the deal should be the requirement that actual engineers be present at the hackathon, as there is little to gain for hackers otherwise. As a sidenote, sponsors should also be companies that hackers would like to interact with and are well regarded within the community; the sponsoring company should be part of the attraction.
Integration with HackIllinois and IlliniHackers&lt;&#x2F;p&gt;
&lt;p&gt;HackNights is quite obviously the training ground for HackIllinois and also how we maintain the IlliniHackers community throughout the year. It might be interesting to explore HackNights as events which build up to HackIllinois in some way. This is ultimately up to the directors of HackIllinois, the Hacker Rep and HackNights.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;next-steps&quot;&gt;Next Steps&lt;&#x2F;h4&gt;
&lt;p&gt;A theme needs to be decided on. Action points need to be drawn up. A sponsorship doc needs to be created that that presents HackIllinois as the Free and Open Source hackathon, lays out the benefits and established what we seek in a sponsor. The sponsorship game plan should include a place for HackNights, whether it is recommended  to companies that don’t match the Open Source profile or as an additional benefit. Outreach for mentors from Open Source groups and sponsors needs to be executed this summer. A summer budget must be established so Experience can start to plan and execute fast. Outreach for HackNights must explicitly start this summer as well and HackNights should be starting to set up for the first HackNight (being held 3-4 weeks into the semester). Systems work should be aware of OpenHackathon and start to work within that context. The fate of IlliniHackers needs to be determined (basically getting control of the FB Page) and a representative for the hackers needs to be chosen. He or she needs to develop a game plan to formalize the organization from the hackers side and prepare for the general meeting at the beginning of the year. This means setting up scholarships, determining how hardware checkout works, and executing on other ideas that come up organically. If well executed, this will secure the org in a position where it is stable and growing, encouraging a refined style of hacking and ready to run a great set of events.&lt;&#x2F;p&gt;
&lt;p&gt;Checkmate, Hackathon Hackers.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Baxter the Bartender</title>
          <pubDate>Sun, 18 Sep 2016 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/ab-hackathon/</link>
          <guid>https://www.narendasan.com/blog/ab-hackathon/</guid>
          <description xml:base="https://www.narendasan.com/blog/ab-hackathon/">&lt;p&gt;In 2016 interestingly enough Anheuser Busch sponsored a hackathon in the ECE Department. At the time I started working
in &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;bretl.csl.illinois.edu&#x2F;&quot;&gt;Prof. Tim Bretl&#x27;s Lab&lt;&#x2F;a&gt; on robotic grasping research and our lab had a Baxter from Rethink Robotics. A few labmates and I thought
it would be fun to turn it into a bartender.&lt;&#x2F;p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https:&#x2F;&#x2F;www.youtube-nocookie.com&#x2F;embed&#x2F;Pg7LaToT5g0&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;</description>
      </item>
      <item>
          <title>Arbor - Designing To Be Replaced</title>
          <pubDate>Thu, 01 Sep 2016 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/arbor/</link>
          <guid>https://www.narendasan.com/blog/arbor/</guid>
          <description xml:base="https://www.narendasan.com/blog/arbor/">&lt;p&gt;The impetus to create such a framework stems from the reality that the majority of developers who work in our development group, will not be there in 4 years (and most will leave earlier). We also see new developers walk in oblivious of the frameworks we have used in the past. Just in the past four years, Rails has been supplanted by Node.js and Angular&#x2F;React, and PHP has gone from a “goto” language to an outdated language with only a few purposes.
This poses a few issues to these high churn development groups when considering choices for technology stacks in the context of maintainability and future-proofing. Pragmatically, original authors of a project for a student club, for example, will not be in school for more than a few years to maintain the project, and the newcomers will not know how to sustain the technology stack of the project created just a couple years ago.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sustainable-infrastructure&quot;&gt;Sustainable Infrastructure&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h3&gt;
&lt;p&gt;ACM@UIUC is a student-run organization that looks to [….]. We maintain a significant amount of infrastructure for a organization of our size […].  However as we are associated with a university, the members of the organization change every year as students graduate and new ones take their place. In the past our infrastructure was based on a large monolithic codebase which manages all of the member services we have (e.g….). While monolithic architectures have their benefits such as clear model ownership (a-write-once-use-everywhere mentality) making it easy for an up to speed team to make incremental improvements, the inherent difficultly in understanding a highly interconnected system coupled with the high churn rate in maintainers made it challenging to maintain such a project and it means that development efforts were a mad push to get to stable and then hope nothing breaks because no one will try to fix it after a couple years.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;microservices&quot;&gt;Microservices&lt;&#x2F;h3&gt;
&lt;p&gt;Our response to this problem was to adopt the aforementioned microservice architecture, which looks to promote modularity and minimization of external dependencies. The main proponents of this architecture include large scale companies like Netflix and many startups. The system breaks down into two groups: clients and services. All components of the infrastructure are completely separate applications running on separate processes in deployment. To prevent client (and service) developers to manage an ever-increasing list of services and their APIs, many implementations of the microservice architectures include what is referred to as an API Gateway. This gateway exposes all the services as a unified RESTful API while managing application level security, inter-service communication, and routing of requests. This approach provides several key benefits:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Services are inherently simple. Application scale ranges from a standard 1000-line Sinatra app with multiple database models to a 100-line Node app which simply reads and writes to a YAML file.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Any service can be discarded and replaced without affecting other services (provided functionality parity).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Third party APIs are easily and securely accessible by any client that can access the API Gateway. This moves the burden off the client developer to juggle tokens.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Clients are far simpler because the application logic has been abstracted behind the gateway.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Maintainers can focus and own their own codebase.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;api-gateway&quot;&gt;API Gateway&lt;&#x2F;h3&gt;
&lt;p&gt;The key to the  microservice architecture is the API gateway. There are many platforms which provide the functionality of an API gateway; Amazon Web Services, Nginx, and others have offerings that manage access to services and coordinate micro-service systems. There also exists a few frameworks to self-host an API Gateway. We will examine in detail Tyk and Kong, two popular options, however, there are others that are language or web framework specific.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;tyk&quot;&gt;Tyk&lt;&#x2F;h4&gt;
&lt;p&gt;Tyk is a full-featured gateway that looks centralized much of the common tasks that exist within common infrastructure setups. It does things like having a centralized Authentication provided in the gateway, allows for granular access control to routes and hosts API documentation. It configures its system using a series of JSON objects either held in a database or in a series of files that are parsed and include many options controlling the massive feature set Tyk offers.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;kong&quot;&gt;Kong&lt;&#x2F;h4&gt;
&lt;p&gt;Kong also has a vast set of features and plugins, as also looks to centralize much of the common tasks in managing the infrastructure
Kong, however, takes a different approach to its proxy. It only takes a hostname in and relies on the client to provide the host it’s looking for (it does allow for a host proxy though the documentation is not clear as to how that works exactly). Since everything is done through DNS listings, it is very easy to add your service, but it means that it’s hard to come in and see what is going on without the use of its admin API
There are many other platforms that include gateway functionality, in addition to other features, such as Docker Compose. However, all these systems are high performance, complex pieces of software that are meant to serve millions of users at once, which is a bit heavy handed for nonindustrial use. Additionally, the use of these systems may require platform buy-in, suffer from lack of ease-of-use and clarity and perhaps require the user to spend money to set up a gateway.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;arbor&quot;&gt;Arbor&lt;&#x2F;h2&gt;
&lt;p&gt;We were not happy with the current offerings for API Gateways as many were just too complex to maintain in our organization (again churn being a big factor here). We, therefore, created our own API Gateway framework which we call Arbor.
Arbor is a statically configured API Gateway framework written in Go. It provides the key gateway services, having a full-featured REST proxy all behind its hostname, with websockets and more modern protocols in the pipeline, it manages application level security and simple request sanitization, it also features a human readable service definition format.
Arbor is broken into four sub-packages, server, proxy, services, and security. The full system architecture is described in Figure 1. and is centralized around the Arbor server. The server manages the execution of the subsystems within Arbor.
The first layer on the server is the router. As of now, the router is vanilla &lt;code&gt;gorilla&#x2F;mux&lt;&#x2F;code&gt; but we fully expect to need to modify the router to support future development.
Route definitions are user defined through two types defined by Arbor&#x2F;services, &lt;code&gt;Routes&lt;&#x2F;code&gt; and RouteCollections, in which &lt;code&gt;Routes&lt;&#x2F;code&gt; define a specific route, and &lt;code&gt;RouteCollections&lt;&#x2F;code&gt; encompass a service’s routes. As part of the service definition, the user specifies the proxy handler that would manage the communication between the client and the service from the set of functions in the proxy package.
At runtime these service definitions are loaded into the router and as a request comes in the router hands the request to the appropriate proxy handler.
Before any further processing, if the user enables security features, the next step for the request is to go through two main security features. First is a client authorization verification step. When security features are enabled the gateway requires clients to provide a token generated by the security package. If this is not provided the request is denied at the gateway level. Any successful access is logged in a access log file and then the request is moved on to the second step. We wanted to take the burden off our service and client developers to do proper html sanitization, so we have a module in the pipeline to clean the request. Services are still required to do some validation but we are looking to centralize common tasks.
Afterwards, the request is sent to the proxy server, which will inject any required access keys or extra data in order to fulfil a request. This allows clients to avoid needing to manage a huge set of tokens and keys. The request goes out from the proxy server and then the response is forwarded back to the client.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;arbor&#x2F;imgs&#x2F;arch.jpg&quot; alt=&quot;arch&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This means that registering a new service is just adding a file, recompiling and deploying, and authorizing a client is a just simple command as of now. The question of what data is available is answered by the definition itself.
Arbor attempts to be simple, making very few assumptions, and is easily extensible.&lt;&#x2F;p&gt;
&lt;p&gt;This new framework and architecture choice has accelerated the creation of new pieces infrastructure in our organization many times over. It has given us the freedom to replace many aging systems with new modern ones without fear of breaking other things. It also gives the developers the leeway to focus more on functionality over sustainability, since it is now expected their code will last perhaps two or three years max. Each service can now range from 100 lines of code to 1000. Our infrastructure is now language agnostic as well. We have a ruby, a python and a javascript developer all developing code for the same system. It is also easier now to replace a system since a spec of what needs to be supported is kept in the schema file for that service. We now have 15 services and two clients all managed through Arbor serving 1000 people.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;future-work&quot;&gt;Future Work&lt;&#x2F;h2&gt;
&lt;p&gt;Throughout Arbor’s development, we have uncovered a few issues which should be identified and addressed:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Arbor currently only supports RESTful APIs, we are looking to add support for websockets so that the final parts of our infrastructure can come under the gateway umbrella.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Documentation generation from parsing schema files would be a welcomed feature so unaffiliated consumers of our API will have documentation other than our repo&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Improved centralized functionality for things like security is being considered. Currently, there is a simple sanitizer in the proxy pipeline that can be enabled. We have this so that service developers do not need to consider security other than that which is specific to their service. This sanitizer is not very powerful at this point and we must also balance the urge to centralize functionality with not making assumptions about development processes.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;We do not expect Arbor to be serving millions; we see it as a Sinatra&#x2F;Flask to Kong or AWS’s Rails &#x2F;Django, but we think that this framework will let a whole new set of developers experiment with microservices. It looks to provide the barebones API Gateway functionality and let the developer focus on the application functionality. Ultimately for us, it means we no longer have to race against time to train developers before the lead maintainers leave and that the infrastructure of our organization can now better reflect the needs of its members. We are now more open to one-off contributors, who wish to add one service and leave. When the next web framework of choice emerges, we will have a system ready to accept it with minimal wrestling&lt;&#x2F;p&gt;
&lt;p&gt;The source code is released under the University of Illinois&#x2F;NCSA Open Source License and on Github&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Check it out at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;acm-uiuc&#x2F;arbor&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;acm-uiuc&#x2F;arbor&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
      <item>
          <title>Weave DSL - A DSL for IoT Device specification</title>
          <pubDate>Sun, 21 Aug 2016 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/open-weave/</link>
          <guid>https://www.narendasan.com/blog/open-weave/</guid>
          <description xml:base="https://www.narendasan.com/blog/open-weave/">&lt;h2 id=&quot;weave&quot;&gt;Weave&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;open-weave&#x2F;imgs&#x2F;thermostat.jpg&quot; alt=&quot;thermostat&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The potential of IoT in the mid 2010s was really embodied by Nest, a company founded by the same
people who developed the iPod and ultimately was bought by Google. Nest had focus
on elegant design and intelligent behavior and this was embodied best by the Nest Thermostat,
a small puck which at the time was completely different than anything on the market.
It not only looked different, it was truly smart, tracking usage and self programming to
make your home more comfortable and more efficient. As Nest branched out into other products
like smoke detectors and cameras, it started to think about how all these devices would work together.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;open-weave&#x2F;.&#x2F;imgs&#x2F;weave.png&quot; alt=&quot;weave&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Nest developed the Thread protocol which is like the low power, IoT version of WiFi. The idea is that
you don&#x27;t want these devices to clog up the WiFi network and consume a lot of power doing so and instead
could run on a separate network which specializes in low energy operation. Also unlike WiFi, Thread
is mesh based, it creates a spanning tree across all devices and uses some devices to route to others.
This ensures that there is a stable connection for each IoT device. Nest wanted to center as much of the
information and decision making inside the Thread network as possible, instead of relying on a bunch of
cloud services needed to interact on your devices behalf. So they developed an application layer protocol
for Thread called Weave.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;open-weave&#x2F;imgs&#x2F;han.png&quot; alt=&quot;han&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The role of Weave is to be the layer that allows structured information like requests for the current temperature
or the status of the smoke alarm can be transmitted. This is all done within the &quot;Home Area Network&quot; (HAN). The
issue is it becomes pretty complicated and time consuming to build complex features when you need to worry about
not just the device and Weave implementation but also the cloud services side to handle updates and remote access
and the UI on smart phones and the web.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;weave-schema-description-language&quot;&gt;Weave Schema Description Language&lt;&#x2F;h3&gt;
&lt;p&gt;My internship work was to help address this problem. My team built into Weave a formalization of devices, called a device
schema. This is the data model for the device.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;
The schema defines three elements:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Traits: A unit of basic capability, such as the state of a property, a notification of the state, or a request to change the state&lt;&#x2F;li&gt;
&lt;li&gt;Interfaces:  A group of traits that represent a specific function, such as the properties and events that make up a deadbolt lock&lt;&#x2F;li&gt;
&lt;li&gt;Resources: A logical or physical thing comprised of traits and interfaces, such as a Nest device, a structure, or a user
&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So a user can define a light which has the trait whether its on or off, and an interface which is a command to turn it on or off and the light itself is the resource.&lt;&#x2F;p&gt;
&lt;p&gt;We define this formalism using the Weave Schema Description Language, a DSL which gives us a structured artifact that describes a device.&lt;&#x2F;p&gt;
&lt;p&gt;Here is an example schema of an interface that implements a door lock:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;proto&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    Copyright (c) 2019 Google LLC.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    Copyright (c) 2016-2018 Nest Labs, Inc.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    All rights reserved.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    Licensed under the Apache License, Version 2.0 (the &amp;quot;License&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    you may not use this file except in compliance with the License.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    You may obtain a copy of the License at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *        http:&#x2F;&#x2F;www.apache.org&#x2F;licenses&#x2F;LICENSE-2.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    Unless required by applicable law or agreed to in writing, software&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; BASIS,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    See the License for the specific language governing permissions and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    limitations under the License.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    @file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      This file specifies a Weave Common interface for a PIN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      code-actuated bolt lock.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;syntax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;proto3&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;package&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; weave.iface.lock&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;option&lt;&#x2F;span&gt;&lt;span&gt; java_package&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;quot;weave.lock&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;option&lt;&#x2F;span&gt;&lt;span&gt; java_outer_classname&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;WeaveInternalPincodeLockIface&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;option&lt;&#x2F;span&gt;&lt;span&gt; objc_class_prefix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;SCM&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;wdl&#x2F;wdl_options.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;iface&#x2F;lock&#x2F;basic_lock_iface.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;trait&#x2F;security&#x2F;bolt_lock_trait.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;trait&#x2F;security&#x2F;bolt_lock_settings_trait.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;trait&#x2F;security&#x2F;bolt_lock_capabilities_trait.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;trait&#x2F;security&#x2F;user_pincodes_settings_trait.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;trait&#x2F;security&#x2F;user_pincodes_capabilities_trait.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;trait&#x2F;schedule&#x2F;basic_user_schedules_settings_trait.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;trait&#x2F;schedule&#x2F;basic_user_schedules_capabilities_trait.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;trait&#x2F;security&#x2F;pincode_input_trait.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;trait&#x2F;security&#x2F;pincode_input_settings_trait.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;trait&#x2F;auth&#x2F;application_keys_trait.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; PincodeLockIface&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  option&lt;&#x2F;span&gt;&lt;span&gt; (wdl.message_type)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; IFACE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  option&lt;&#x2F;span&gt;&lt;span&gt; (wdl.iface)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    stability&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; ALPHA,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    vendor_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0x0000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    version&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  weave.trait.security.BoltLockTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; lock&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  weave.trait.security.BoltLockSettingsTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; lock_settings&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  weave.trait.security.BoltLockCapabilitiesTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; lock_capabilities&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  weave.trait.security.UserPincodesSettingsTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; pincodes_settings&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  weave.trait.security.UserPincodesCapabilitiesTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; pincodes_capabilities&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  weave.trait.schedule.BasicUserSchedulesSettingsTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; schedules_settings&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  weave.trait.schedule.BasicUserSchedulesCapabilitiesTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; schedules_capabilities&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  weave.trait.security.PincodeInputTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; keypad&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  weave.trait.security.PincodeInputSettingsTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; keypad_settings&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  weave.trait.auth.ApplicationKeysTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; application_keys&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Implements&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    option&lt;&#x2F;span&gt;&lt;span&gt; (wdl.message_type)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; IFACE_IMPLEMENTATIONS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    weave.iface.lock.BasicLockIface&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; basic_lock&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can see that for this lock interface there is a bunch of traits that describe states like the lock, its settings, the pincode etc.
Here is an implementation of the bolt lock trait:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;proto&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    Copyright (c) 2019 Google LLC.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    Copyright (c) 2016-2018 Nest Labs, Inc.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    All rights reserved.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    Licensed under the Apache License, Version 2.0 (the &amp;quot;License&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    you may not use this file except in compliance with the License.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    You may obtain a copy of the License at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *        http:&#x2F;&#x2F;www.apache.org&#x2F;licenses&#x2F;LICENSE-2.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    Unless required by applicable law or agreed to in writing, software&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; BASIS,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    See the License for the specific language governing permissions and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    limitations under the License.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    @file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      This file defines the Bolt Lock trait.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;syntax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;proto3&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;package&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; weave.trait.security&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;wdl&#x2F;wdl_options.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;weave&#x2F;common&#x2F;identifiers.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;google&#x2F;protobuf&#x2F;timestamp.proto&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;option&lt;&#x2F;span&gt;&lt;span&gt; java_outer_classname&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;WeaveInternalBoltLockTrait&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;option&lt;&#x2F;span&gt;&lt;span&gt; objc_class_prefix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;quot;SCM&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * Residential Bolt Lock Trait is meant to cover a physical residential lock that uses a deadbolt as its locking mechanism.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * Beyond its physical attributes, it is REQUIRED to have the following functionality:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * - Retract&#x2F;Extend Bolt remotely&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * - Retract&#x2F;Extend Bolt locally&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * - Report the bolt state itself (i.e. Extended, Retracted, etc.  See BoltState for more info)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * - Report the bolt actuator state (i.e. OK, Moving, Locking, Unlocking, etc.  See BoltActuatorState for more info)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * - Report what caused the bolt state or actuator state to change (i.e. Inside, Outside, Outside Keypad.  See BoltBlame)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * Optionally, a lock may&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * - Report the locked state of the lock as a whole (i.e. Unlocked, Locked, etc.  See LockedState)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * V2 adds support for voice arming (via cloud)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * Scenarios:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * - Bolt extended and locked, User retracts bolt w&#x2F;a pin code&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      1) Bolt begins retracting&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      2) Notify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_UNLOCKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      locked_state = BOLT_LOCKED_STATE_UNLOCKED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      3) Event BoltActuatorStateChangeEvent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      state = BOLT_STATE_EXTENDED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_UNLOCKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      locked_state = BOLT_LOCKED_STATE_UNLOCKED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      blame = BOLT_BLAME_OUTSIDE_KEYPAD_PIN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      userid = someuserid of matching pincode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      4) Bolt retraction completes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      5) Notify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      state = BOLT_STATE_RETRACTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      6) Event BoltActuatorStateChangeEvent w&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      state = BOLT_STATE_RETRACTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      locked_state = BOLT_LOCKED_STATE_UNLOCKED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      blame = BOLT_BLAME_OUTSIDE_KEYPAD_PIN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      userid = someuserid of matching pincode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * - Bolt retracted and unlocked, User extends bolt w&#x2F;one touch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      1) Bolt begins extending&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      2) Notify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      state = BOLT_STATE_EXTENDED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_LOCKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      locked_state = BOLT_LOCKED_STATE_UNLOCKED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      3) Event BoltActuatorStateChangeEvent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      state = BOLT_STATE_EXTENDED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_LOCKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      locked_state = BOLT_LOCKED_STATE_UNLOCKED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      blame = BOLT_BLAME_OUTSIDE_MANUAL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      userid = &amp;lt;omitted&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      4) Bolt extension completes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      5) Notify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      locked_state = BOLT_LOCKED_STATE_LOCKED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      6) Event BoltActuatorStateChangeEvent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      state = BOLT_STATE_EXTENDED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      locked_state = BOLT_LOCKED_STATE_LOCKED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      blame = BOLT_BLAME_OUTSIDE_MANUAL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      userid = &amp;lt;omitted&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; * - Bolt retracted and unlocked, User extends bolt w&#x2F;mobile but does not lock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      1) Update w&#x2F;metadata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *          blame = BOLT_BLAME_REMOTE_USER&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *          userid = someuserid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      2) Bolt begins extending&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      3) Notify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      state = BOLT_STATE_EXTENDED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_LOCKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      locked_state = BOLT_LOCKED_STATE_UNLOCKED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      3) Event BoltActuatorStateChangeEvent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      state = BOLT_STATE_EXTENDED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_LOCKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      locked_state = BOLT_LOCKED_STATE_UNLOCKED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      blame = BOLT_BLAME_REMOTE_USER&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      userid = someuserid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      4) Bolt extension completes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      5) Notify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      6) Event BoltActuatorStateChangeEvent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      state = BOLT_STATE_EXTENDED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      actuator_state = BOLT_ACTUATOR_STATE_OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      locked_state = BOLT_LOCKED_STATE_UNLOCKED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      blame = BOLT_BLAME_REMOTE_USER&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *      userid = someuserid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockTrait&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  option&lt;&#x2F;span&gt;&lt;span&gt; (wdl.message_type)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; TRAIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  option&lt;&#x2F;span&gt;&lt;span&gt; (wdl.trait)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    stability&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; ALPHA,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0x0E02&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    vendor_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0x0000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    version&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * The current state of the bolt itself&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * Remember, this only tells you the state of the bolt itself and doesn&amp;#39;t tell you&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * anything about whether the door is locked (i.e. bolt is in jamb) or not.  To&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * get the full picture you must look to information represented by the LockedState enum&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * Implementors of this trait must implement all values below&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltState&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_STATE_UNSPECIFIED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_STATE_RETRACTED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;       &#x2F;&#x2F;&#x2F; Bolt is fully retracted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_STATE_EXTENDED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F;&#x2F; Bolt is AT LEAST partially extended.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  * The method &#x2F; UI interacting with the bolt lock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  * Depending on the method originator may or may not be available&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockActorMethod&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_UNSPECIFIED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * Change produced by an unspecified entity that doesn&amp;#39;t fall into one of the defined categories below&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *  - Who may not be present&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *  - Expected to be correlated with an event&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_OTHER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; On-device actor methods&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * Change produced by the physical interaction on the lock but with no PIN entered (Typically for locking or unlocking with the thumb turn)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *  - Who MUST NOT be present&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_PHYSICAL&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * Change produced by the physical keypad by typing in a PIN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *  - Who MUST be present&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *  - Expected to be correlated with an event that represents &amp;quot;keypad pin entered successfully&amp;quot; (see PinCodeInputTrait for an example event)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_KEYPAD_PIN&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * Change produced by the device internally. For instance, if the device has a mechanisim to automatically lock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * after a period of time.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * - Who may not be present.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_LOCAL_IMPLICIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; App actor methods&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * Change produced by a user using the app&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *  - Who may not be present&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_REMOTE_USER_EXPLICIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * Change produced by a user with implicit intent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * ex. Toggling structure mode with the app mode switcher&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *  - Who may not be present&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *  - Expected to be correlated with a structure mode change event?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_REMOTE_USER_IMPLICIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * Change produced by a user that does not fit in one of the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * other app remote categories&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_REMOTE_USER_OTHER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; Other actor methods&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * Change produced by a remote service with no user intent (ex: Goose)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *  - Who may not be present&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *  - Expected to be correlated with an event (???)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_REMOTE_DELEGATE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * Lock will (???) on its own before a critically low battery shutdown&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_LOW_POWER_SHUTDOWN&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      * Change produced through a voice assistant based surface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;      *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_VOICE_ASSISTANT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt; [(wdl.enumvalue) = {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;compatibility&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;min_version&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;}}]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * Common construction of &amp;#39;blames&amp;#39;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * How an action was taken and by whom.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockActorStruct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    option&lt;&#x2F;span&gt;&lt;span&gt; (wdl.message_type)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; STRUCT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; how an action was taken&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    BoltLockActorMethod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; method&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; originator of the action, if available&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    weave.common.ResourceId&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; originator&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt; [(wdl.prop) = {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;nullable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; true}]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Resource that took action on behalf of the originator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    weave.common.ResourceId&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; agent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt; [(wdl.prop) = {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;nullable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; true, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;compatibility&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;min_version&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;}}]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * The current actuator state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * Implementors of this trait must at a minimum be able to report:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * - BOLT_ACTUATOR_STATE_OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * - BOLT_ACTUATOR_STATE_LOCKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * - BOLT_ACTUATOR_STATE_UNLOCKING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * - BOLT_ACTUATOR_STATE_MOVING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltActuatorState&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_UNSPECIFIED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_OK&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;         &#x2F;&#x2F;&#x2F; Actuator is not moving and is in a fully settled position.  If its not settled use BOLT_ACTUATOR_STATE_MOVING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_LOCKING&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; Actuator is attempting to lock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_UNLOCKING&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; Actuator is attempting to unlock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;** Actuator is moving though it’s not necessarily clear the intended direction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;     * This is typically used when the user is physically manipulating the bolt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_MOVING&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_JAMMED_LOCKING&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;     &#x2F;&#x2F;&#x2F; Actuator jammed while the device was locking and cannot move.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_JAMMED_UNLOCKING&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   &#x2F;&#x2F;&#x2F; Actuator jammed while the device was unlocking and cannot move.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_JAMMED_OTHER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;       &#x2F;&#x2F;&#x2F; Actuator jammed and cannot move. The direction the lock was moving was not provided.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * The current locked state of the bolt lock as a whole&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * This state takes into account the resource&amp;#39;s best ability to determine how physically secure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * the resource is with respect to this bolt lock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * Implementors of this trait must at a minimum be able to report:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * - LOCKED_STATE_UNKNOWN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockedState&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCKED_STATE_UNSPECIFIED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;** The lock as a whole is not locked to the best knowledge of the implementor.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;     * i.e. the door that this lock is attached to can be opened&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCKED_STATE_UNLOCKED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;** The lock as a whole is locked to the best knowledge of the implementor.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;     *  i.e. the door that this lock is attached to cannot be opened&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCKED_STATE_LOCKED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;** The implementor is not able to determine whether the door is locked or unlocked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;     *  i.e. &amp;quot;Locked&amp;quot; sensing is based on a history of readings and that history is now gone or lost&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;     *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCKED_STATE_UNKNOWN&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F; ----------- PROPERTIES ----------- &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  option&lt;&#x2F;span&gt;&lt;span&gt; (wdl.properties)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    extendable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; true,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    reserved_tag_min&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    reserved_tag_max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 31&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; The current state of the bolt itself&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; Remember this only tells you about the bolt state not about the locked state of the lock as a whole&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; The lock as a whole is only fully secure if bolt_state == BOLT_STATE_EXTENDED AND locked_state == LOCKED_STATE_LOCKED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; If state == BOLT_STATE_RETRACTED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; - actuator_state must be BOLT_ACTUATOR_STATE_OK or BOLT_ACTUATOR_STATE_JAMMED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; - locked_state must be LOCKED_STATE_UNLOCKED or LOCKED_STATE_UNKNOWN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; If state == BOLT_STATE_EXTENDED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; - actuator_state may be any value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; - locked_state may be any&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  BoltState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; The current state of the bolt&amp;#39;s actuator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  BoltActuatorState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; actuator_state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt; [(wdl.prop) = {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;writable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; READ_ONLY}]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; The current state of how secure the lock is as whole&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  BoltLockedState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; locked_state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt; [(wdl.prop) = {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;writable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; READ_ONLY}]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; Describes who&#x2F;what last caused the bolt actuator state to change and how they did it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; Should be updated together whenever locked_state is changed, i.e. via BoltLockChangeRequest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  BoltLockActorStruct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; bolt_lock_actor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt; [(wdl.prop) = {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;writable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; READ_ONLY, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;nullable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; true, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;ephemeral&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; true}]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; The time at which the lock state was changed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F;&#x2F; Updated together with locked_state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  google.protobuf.Timestamp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; locked_state_last_changed_at&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt; [(wdl.prop) = {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;writable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; READ_ONLY,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                                                        timestamp_constraints&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;signed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; true,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                                                        precision&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0.001&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                                                        nullable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; true,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                                                        ephemeral&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; true}]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F; ----------- COMMANDS ----------- &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * Command to request a change to bolt state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * Should be used when with explicit or implicit user intent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * Returns success when execution of the command has begun&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * Returns error if the command cannot be started&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockChangeRequest&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    option&lt;&#x2F;span&gt;&lt;span&gt; (wdl.message_type)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; COMMAND&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    option&lt;&#x2F;span&gt;&lt;span&gt; (wdl.command)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;      id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0x01&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; New requested state of the bolt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    BoltState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; Describes who&#x2F;what is sending the BoltLockChangeRequest and reason for the request.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    BoltLockActorStruct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; bolt_lock_actor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;&#x2F; ----------- EVENTS ----------- &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  &#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * Event that is sent whenever actuator_state changes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * See BoltLockActorMethod enum above for information on when to fill in &amp;quot;who&amp;quot; below and potential&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   * correlated events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;   *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltActuatorStateChangeEvent&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    option&lt;&#x2F;span&gt;&lt;span&gt; (wdl.message_type)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; EVENT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    option&lt;&#x2F;span&gt;&lt;span&gt; (wdl.event)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;      id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;      event_importance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; EVENT_IMPORTANCE_PRODUCTION_CRITICAL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; See BoltLockTrait for description&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    BoltState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; See BoltLockTrait for description&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    BoltActuatorState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; actuator_state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; See BoltLockTrait for description&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    BoltLockedState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; locked_state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; Describes who&#x2F;what last caused the bolt actuator state to change and how they did it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; Should be updated together whenever locked_state is changed, i.e. via BoltLockChangeRequest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    BoltLockActorStruct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; bolt_lock_actor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can see here the different things that the trait manages like the state of the bolt actuator and the user and sets out hooks for how to request that the
lock opens and closes.&lt;&#x2F;p&gt;
&lt;p&gt;The nice thing about the WDL language is that you can start to build out libraries of traits and interfaces that
can be reused and shared amongst developers.&lt;&#x2F;p&gt;
&lt;p&gt;My internship work was on the component which really makes Weave powerful, &lt;code&gt;wdlc&lt;&#x2F;code&gt;. &lt;code&gt;wdlc&lt;&#x2F;code&gt; let&#x27;s users take a device schema and generate embedded C++ code
that will serve as the hooks for Weave to interface with the device. You can see here the code that gets generated from the schema.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    Copyright (c) 2019 Google LLC.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    All rights reserved.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    Licensed under the Apache License, Version 2.0 (the &amp;quot;License&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    you may not use this file except in compliance with the License.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    You may obtain a copy of the License at&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *        http:&#x2F;&#x2F;www.apache.org&#x2F;licenses&#x2F;LICENSE-2.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    Unless required by applicable law or agreed to in writing, software&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; BASIS,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    See the License for the specific language governing permissions and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *    limitations under the License.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;ifndef&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; _WEAVE_TRAIT_SECURITY__BOLT_LOCK_TRAIT_H_&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; _WEAVE_TRAIT_SECURITY__BOLT_LOCK_TRAIT_H_&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Weave&#x2F;Profiles&#x2F;data-management&#x2F;DataManagement.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Weave&#x2F;Support&#x2F;SerializationUtils.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;namespace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Schema&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;namespace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Weave&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;namespace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Trait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;namespace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; Security&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;namespace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;extern const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; nl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;Weave&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;Profiles&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;DataManagement&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;TraitSchemaEngine TraitSchema&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;      kWeaveProfileId&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;U&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;e02&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;U&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; Properties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kPropertyHandle_Root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;---------------------------------------------------------------------------------------------------------------------------&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;  Name                                IDL Type                            TLV Type           Optional?       Nullable?     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;---------------------------------------------------------------------------------------------------------------------------&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;  state                               BoltState                            int               NO              NO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kPropertyHandle_State&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;  actuator_state                      BoltActuatorState                    int               NO              NO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kPropertyHandle_ActuatorState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;  locked_state                        BoltLockedState                      int               NO              NO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kPropertyHandle_LockedState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;  bolt_lock_actor                     BoltLockActorStruct                  structure         NO              YES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kPropertyHandle_BoltLockActor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;  method                              BoltLockActorMethod                  int               NO              NO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kPropertyHandle_BoltLockActor_Method&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;  originator                          weave.common.ResourceId              bytes             NO              YES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kPropertyHandle_BoltLockActor_Originator&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;  agent                               weave.common.ResourceId              bytes             NO              YES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kPropertyHandle_BoltLockActor_Agent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;  locked_state_last_changed_at        google.protobuf.Timestamp            int64 millisecondsNO              YES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kPropertyHandle_LockedStateLastChangedAt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Enum for last handle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kLastSchemaHandle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; Event Structs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockActorStruct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    int32_t&lt;&#x2F;span&gt;&lt;span&gt; method&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    nl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;SerializedByteString originator&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; SetOriginatorNull&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; SetOriginatorPresent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; IsOriginatorPresent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;endif&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    nl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;SerializedByteString agent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; SetAgentNull&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; SetAgentPresent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; IsAgentPresent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;endif&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    uint8_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; __nullified_fields__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    static const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; nl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;SchemaFieldDescriptor FieldSchema&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockActorStruct_array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    uint32_t&lt;&#x2F;span&gt;&lt;span&gt; num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    BoltLockActorStruct &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;buf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;inline void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockActorStruct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;SetOriginatorNull&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    SET_FIELD_NULLIFIED_BIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;__nullified_fields__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;inline void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockActorStruct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;SetOriginatorPresent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    CLEAR_FIELD_NULLIFIED_BIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;__nullified_fields__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;inline bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockActorStruct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;IsOriginatorPresent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;GET_FIELD_NULLIFIED_BIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;__nullified_fields__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;endif&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;inline void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockActorStruct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;SetAgentNull&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    SET_FIELD_NULLIFIED_BIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;__nullified_fields__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;inline void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockActorStruct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;SetAgentPresent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    CLEAR_FIELD_NULLIFIED_BIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;__nullified_fields__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;inline bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockActorStruct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;IsAgentPresent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;GET_FIELD_NULLIFIED_BIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;__nullified_fields__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;endif&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; Events&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltActuatorStateChangeEvent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    int32_t&lt;&#x2F;span&gt;&lt;span&gt; state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    int32_t&lt;&#x2F;span&gt;&lt;span&gt; actuatorState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    int32_t&lt;&#x2F;span&gt;&lt;span&gt; lockedState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    Schema&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;Weave&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;Trait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;Security&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;BoltLockTrait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;BoltLockActorStruct boltLockActor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    static const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; nl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;SchemaFieldDescriptor FieldSchema&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Statically-known Event Struct Attributes:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            kWeaveProfileId&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;U&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;e02&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;U&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        kEventTypeId&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;U&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    static const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; nl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;Weave&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;Profiles&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;DataManagement&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;EventSchema Schema&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltActuatorStateChangeEvent_array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    uint32_t&lt;&#x2F;span&gt;&lt;span&gt; num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    BoltActuatorStateChangeEvent &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;buf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; Commands&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kBoltLockChangeRequestId&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockChangeRequestParameters&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kBoltLockChangeRequestParameter_State&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    kBoltLockChangeRequestParameter_BoltLockActor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F; Enums&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_STATE_RETRACTED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_STATE_EXTENDED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockActorMethod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_OTHER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_PHYSICAL&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_KEYPAD_PIN&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_LOCAL_IMPLICIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_REMOTE_USER_EXPLICIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_REMOTE_USER_IMPLICIT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_REMOTE_USER_OTHER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_REMOTE_DELEGATE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_LOW_POWER_SHUTDOWN&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCK_ACTOR_METHOD_VOICE_ASSISTANT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltActuatorState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_OK&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_LOCKING&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_UNLOCKING&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_MOVING&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_JAMMED_LOCKING&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_JAMMED_UNLOCKING&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_ACTUATOR_STATE_JAMMED_OTHER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BoltLockedState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCKED_STATE_UNLOCKED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCKED_STATE_LOCKED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BOLT_LOCKED_STATE_UNKNOWN&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; &#x2F;&#x2F; namespace BoltLockTrait&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; &#x2F;&#x2F; namespace Security&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; &#x2F;&#x2F; namespace Trait&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; &#x2F;&#x2F; namespace Weave&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; &#x2F;&#x2F; namespace Schema&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;endif&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; &#x2F;&#x2F; _WEAVE_TRAIT_SECURITY__BOLT_LOCK_TRAIT_H_&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In addition to generating the embedded core, the compiler will also generate the cloud services
code that will allow the cloud to interface with a device in the HAN via a Thread&#x2F;WiFi Border Router, a device that will
be both on the WiFi and Thread networks and serving as a bridge between the two. Finally, the compiler can also
generate the Swift and Java code to hook the interfaces defined in the schema to UIs in a mobile app. For Nest this means
that for any device they create or a partner creates they just need to have the Weave Schema and the actual device to
fully integrate a new device into the Weave Network and show up in the Nest App. No frontend, or cloud development needed.
This lets developers focus on the device itself and less on the infrastructure.&lt;&#x2F;p&gt;
&lt;p&gt;To show off my work, I created a couple Weave devices on
top of Nest&#x27;s internal development platform. This device simulated a door lock, turning an LED on and off when the user tries to unlock or lock the device.
I by myself was able to write the embedded code, and stand up a full end to end smart lock service integrated into the existing
Nest app in less than a week.&lt;&#x2F;p&gt;
&lt;p&gt;Weave is a strong choice for the protocol that will truly unify IoT ecosystems. Weave has the potential not just to make device
implementation easy but also could allow developers to make virtual devices. Developers could say describe an intercom system which in
might use a microphone and speakers. You could setup a weave device schema which says for the intercom interface you need a microphone trait and
multiple speaker traits. Then some physical device could query the HAN to find some devices that have a speaker trait or a mic trait then recruit them
to come together in this new intercom virtual device. So you could use the microphone on a Nest Cam and the speakers in Nest smoke detectors and
now have an in house intercom system without needed to buy any new hardware.&lt;&#x2F;p&gt;
&lt;p&gt;Nest was and Google is now committed to opening up weave to all sorts of developers by open sourcing Weave, WDL and the WDL compiler. Nest also open sourced Thread.
Thread has been adopted by companies like Eero &#x2F; Amazon and Apple so maybe OpenWeave will come next.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;open-weave&#x2F;imgs&#x2F;ow.png&quot; alt=&quot;ow&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;WDL Compiler: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;openweave&#x2F;openweave-wdlc&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;openweave&#x2F;openweave-wdlc&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;OpenWeave: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;openweave&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;openweave&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;OpenThread: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;openthread&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;openthread&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Peter Pan: Semantic Image Compression</title>
          <pubDate>Wed, 15 Jun 2016 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/peter-pan/</link>
          <guid>https://www.narendasan.com/blog/peter-pan/</guid>
          <description xml:base="https://www.narendasan.com/blog/peter-pan/">&lt;blockquote&gt;
&lt;p&gt;This work was done during the Greylock Hackfest 2016&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We entered the 2016 Greylock Hackfest and for the first couple hours didn&#x27;t know what to work on. We
actually left Facebook HQ where the hackathon was being held to make a run to Fry&#x27;s to see what hardware they had available.&lt;&#x2F;p&gt;
&lt;p&gt;During this time not having an idea we were browsing Facebook and one of us remarked on how bad the image compression was.
There was noticable artifiacting all over the image. We got to thinking, what we really cared about in the image was
the subject, our friends in this case. The background itself can take the majority of the pixels but ultimately is
much less important. I had been doing research in computer vision for the last couple years and so was starting to
hear a lot about neural networks and their applications. One application is segmentation, being able to seperate out
different objects in an image pixelwise. So we thought well this is an easy way to find the subject of an image. What
if we created a new image compression format where we keep the subject of the image at full resolution but significantly
compress the background? We called our project Peter Pan, a reference to Pied Piper from Silicon Valley who created their
own fictional compression scheme.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;peter-pan&#x2F;.&#x2F;imgs&#x2F;meme.png&quot; alt=&quot;meme&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-compression-works&quot;&gt;How compression works&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;lossy-vs-lossless&quot;&gt;Lossy vs. Lossless&lt;&#x2F;h3&gt;
&lt;p&gt;There&#x27;s two ways to approach compression. One is to find a compressed representation that completely encode the source data without
losing any information. This is important for mediums like text or binaries where potentially a single bit flip will break you program.
This is called lossless compression.&lt;&#x2F;p&gt;
&lt;p&gt;For mediums where its hard to tell between the original and very good imitations there methods which willing accept that some data
will be modified from the original source since they expect people will not be able to tell the difference anyway. This is called lossy compression.
It&#x27;s common to use lossy compression for audio, video and photos to save a significant amount of space on disk.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;human-centered-compression&quot;&gt;Human centered compression&lt;&#x2F;h3&gt;
&lt;p&gt;Some components of an image are more important than others. We as people care more
about the details in the subject than the details in the background in the general
(there are cases like landscape photography where we do care more about the background).&lt;&#x2F;p&gt;
&lt;p&gt;Hence instead of uniformly compressing the entire image, it may be worth while to
compress the background significantly in some lossy way while essentially maintaining the
full resolution of the subject of the image. This also leverages the fact that typically
the background is out of focus and so minor discrepancies are harder to detect. This is almost a hybrid approach
of lossy and lossless compression and allows us to use our bits more wisely.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;system-architecture&quot;&gt;System Architecture&lt;&#x2F;h3&gt;
&lt;p&gt;As this work was done at a hackathon, we couldn&#x27;t train some end to end system that from scratch learned human preferences for
compression. Instead we leverage the work done in semantic segmentation using a pretrained model from the Oxford Vision Group. We create
segmentation masks for each subject in the image and separate the subject pixels from
the background pixels. Then we losslessly compress the subject pixels and we downsample (as a cheap
form of lossy compression) the background. This now represents the compressed form of the
image and can be transmitted. We then transfer the compressed image, upsample the background and
overlay the subjects.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;performance&quot;&gt;Performance&lt;&#x2F;h3&gt;
&lt;p&gt;We did a short performance analysis against the inspiration for this project which is Facebook&#x27;s
image compression scheme, which notoriously creates noisy images after compression.
We see that for the subjects comparing the full resolution image to the image produced after compression that as you&#x27;d expect the discrepancies are only in the background and harder to notice.
For Facebook the differences are spread uniformly and therefore there is a lot of artifacting in the
subject of the image. From a quick visual inspect we see better images from our approach than Facebook&#x27;s.
Size wise we are on the order of magnitude of 2-3x smaller package size than the image you download from Facebook.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example&quot;&gt;Example&lt;&#x2F;h3&gt;
&lt;p&gt;Here is an example photo of a couple of our friends:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;peter-pan&#x2F;imgs&#x2F;og.jpg&quot; alt=&quot;original&quot; &#x2F;&gt;
Original image&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;peter-pan&#x2F;imgs&#x2F;mask.png&quot; alt=&quot;mask&quot; &#x2F;&gt;
Here is the segmentation mask for the semantically important subjects in the photo. Notice that it also picks up the person in the background out of focus.
Though he is out of focus, it is still important to preserve detail in that component of the image because people will focus on it after moving from the primary subject&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;peter-pan&#x2F;imgs&#x2F;pan.png&quot; alt=&quot;pan&quot; &#x2F;&gt;
Peter Pan compressed image. Notice that all detail in the two people in the image has been preserved while there is slight visual artifacting in the background&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;peter-pan&#x2F;imgs&#x2F;fb.jpg&quot; alt=&quot;fb&quot; &#x2F;&gt;
Facebook compressed image. Notice the uniform artifacting, both subject and background are treated the same making artifacting more noticeable&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;limitations&quot;&gt;Limitations&lt;&#x2F;h3&gt;
&lt;p&gt;You can see in the Peter Pan image that borders between the subject and the background are quite abrupt. This is mostly a result of the time constraint for a hackathon but
running a smoothing pass over the borders would help to make a more cohesive image. This format also has significant edge cases. If the subject takes up the majority of the image then size savings will be limited. The size of the image is now correlated with the semantic content of the image and no longer the size and image entropy. This would make it harder to deploy in a setting like Facebooks.&lt;&#x2F;p&gt;
&lt;p&gt;You can find the source code for Peter Pan here&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;narendasan&#x2F;peter-pan&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;narendasan&#x2F;peter-pan&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
      <item>
          <title>3DFS: Deformable Dense Depth Fusion and Segmentation for Object Reconstruction from a Handheld Camera</title>
          <pubDate>Sun, 05 Jun 2016 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/3dfs/</link>
          <guid>https://www.narendasan.com/blog/3dfs/</guid>
          <description xml:base="https://www.narendasan.com/blog/3dfs/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;3dfs&#x2F;imgs&#x2F;head.png&quot; alt=&quot;head&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;From video to 3D model automatically&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;During my time working in the UIUC Vision Group with Prof. Hoiem I worked on 3DFS (Deformable Dense Depth Fusion and Segmentation).
3DFS is a 3D reconstruction and segmentation system from standard video.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;3dfs&#x2F;imgs&#x2F;process.png&quot; alt=&quot;process&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The processing stages of 3DFS in order to go from video to object reconstruction and segmentation masks&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Users can take a video filming different angles of an object,
3DFS then goes through four stages. First it uses LSD-SLAM to estimate camera poses in the video, select key frames, and produce
semi-dense depth maps. Then 3DFS conducts surface modeling to estimate dense depth maps. Next the depth maps are volumetrically
fused to create a function field that describes for each voxel the distance to the nearest surface. Because there is a bias in the initial
fusing, using the estimated camera poses and key frames from LSD-SLAM, we apply the Patch Based Multiview Stereo method which is able
to generate an accurate sparse point cloud of the surface of object and use that point cloud to refine the function field. Finally
3DFS conducts a joint segmentation of all the key frames and the voxel map using graph cuts. This gives us both the refined object
reconstruction and segmentation masks for the object.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;3dfs&#x2F;imgs&#x2F;results.png&quot; alt=&quot;results&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Reconstruction results (SDF + 2D-3D Voxel) compared against other methods&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The reconstructions are pretty good and unlike other methods that are highly choreographed, with highly constrained filming conditions and using complex equipment or targeting easier to models objects to satisfy assumptions, 3DFS can be used by someone with their smartphone in standard
lighting conditions and is robust to material characteristics like low surface texture, complex shapes, and specular materials.&lt;&#x2F;p&gt;
&lt;p&gt;There are some limitations however. The main source of error in the system is the camera pose estimation from LSD SLAM which
effects both the construction of the depth maps and the accuracy of the PMVS point clouds. This is caused by significant occlusion
or changes in lighting mid video. There also may be errors due to the handheld nature of the video including out of focus frames.
Also though 3DFS does better than other methods when it comes to low surface texture and specularity, the errors from these
material characteristics still do effect reconstruction. These issues make it harder to model very flat objects for instance.
This method is also mostly targeted at small objects and so the choice of using a discreet voxel grid may hamper scalability
to much larger objects and we also assume that objects are on a flat planar surface so some amount of staging is required by the
user. Finally our method still fails to recover small geometric details which is still an open research problem.&lt;&#x2F;p&gt;
&lt;p&gt;There are cool applications for this technology. It enables almost anyone to become a 3D modeler without needing to know
CAD or modeling tools. This could let animators more quickly create 3D assets for films and games. It could be applied
in the world of augmented reality, letting people quickly move objects into the virtual world. One of most fun applications
to me is the potential to be able to quickly scan an object with your phone and then 3D print it right then and there,
an easy way to clone objects in the real world.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can read the full paper on 3DFS here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1606.05002.pdf&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1606.05002.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https:&#x2F;&#x2F;www.youtube-nocookie.com&#x2F;embed&#x2F;qP_uLYYBi70&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
</description>
      </item>
      <item>
          <title>Ekko and Greylock Hackfest 2015</title>
          <pubDate>Thu, 09 Jul 2015 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/ekko/</link>
          <guid>https://www.narendasan.com/blog/ekko/</guid>
          <description xml:base="https://www.narendasan.com/blog/ekko/">&lt;blockquote&gt;
&lt;p&gt;This work was done during the 2015 Greylock Hackfest&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Coming to a hackathon with no idea what you want to work on is always leads to the same thing.
Once you have your team, the HQ for the next 36ish hours and unpacked the two backpacks worth of
computer hardware, maybe an extra keyboard and mouse and some pillows you then preceed to spend the
next 2-3 hours throwing around ideas, most of which are either stupid or too hard. This is exactly
what happened when we got to the old TellApart office that Greylock converted into one of the best
run hackathon spaces I&#x27;ve been to. There was a chocolate fountain, a carnival outside with churros,
food trucks, a ping pong table and hammocks. So you can waste a bit of time exploring the space and
talking to people but ultimately you need to sit down and figure out what to do. Sitting side by
side next to my team at the cleared out desk of some engineer we started talking about technologies we
wanted to try out, looking up documentation and finding out that our genius idea was done 6 times before.
I had a web page open and was telling my teammate next to me to look it up and thats when we had the idea for our project.
&quot;Why can&#x27;t I just drag my browser window onto your desktop?&quot;&lt;&#x2F;p&gt;
&lt;p&gt;It started out as a silly idea but as we thought about it, the ability to just open a page on someone
else&#x27;s machine is actually really cool (given you do the work to curb spamming and other security
concerns). Especially in the one to many case, i.e. I open a window on all of my teammates screens. We also thought that the movemement of dragging the window off the screen was a nice intuitive interaction that is easy to remember since it feels contextual.&lt;&#x2F;p&gt;
&lt;p&gt;Now you may ask why sending the URL isnt good enough and it is, but if you break down the steps to
do so you get:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Click on the URL bar&lt;&#x2F;li&gt;
&lt;li&gt;Highlight the entire URL (while there are shortcuts to do this, its &quot;not inuitive&quot; you need to create the muscle memory, and using the mouse can incure errors)&lt;&#x2F;li&gt;
&lt;li&gt;Copy the URL&lt;&#x2F;li&gt;
&lt;li&gt;Paste it&lt;&#x2F;li&gt;
&lt;li&gt;Send the message&lt;&#x2F;li&gt;
&lt;li&gt;Everyone else has to click on it&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This is compared to:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Drag the window off the screen&lt;&#x2F;li&gt;
&lt;li&gt;There is no step 2&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;ekko&quot;&gt;Ekko&lt;&#x2F;h2&gt;
&lt;p&gt;So cool idea, how do you implement it?&lt;&#x2F;p&gt;
&lt;p&gt;Everyone on our team had Macs and we wanted to play with Swift so we chose to make a toolbar extention.
It creates a hotzone on the right hand side, where if a browser is dragged into it, it turns slightly grey and instantly the same website is opened on everyone else&#x27;s machine. To limit the scope of the sharing we created rooms, so links are only share amongst users in that room.&lt;&#x2F;p&gt;
&lt;p&gt;We get the URL from the browser using AppleScript, which is an incredible feature of the operating system. AppleScript allows developers to access all sorts of
underlying APIs for different applications. In our case it let us query what the URL open in the current window of the browser is (on Firefox, Chrome and Safari).&lt;&#x2F;p&gt;
&lt;p&gt;We then used Firebase to manage the URL transmission to the different users in the room. Their Ekko instances will recive a notification and then open the browser and
the web page.&lt;&#x2F;p&gt;
&lt;p&gt;In concept it&#x27;s really simple but in actual usage it was a pretty perfound experience. The first time I could share a web page with the flick of the mouse was a
incredible moment. The judges agreed. We were able to allow them to play directly with the app on a couple of laptops and we could tell by the reactions on
their faces the first time a window popped open with a funny meme that we had something good. Ultimately we won Top 10 at Greylock Hackfest but more importantly
we actually kept using Ekko when were working on class work or wanted to share a YouTube video long after we left the hackathon, a rare outcome for most hackathon projects.&lt;&#x2F;p&gt;
&lt;p&gt;You can checkout the source code for Ekko here:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Perilynn&#x2F;Ekko&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;Perilynn&#x2F;Ekko&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
      <item>
          <title>Developing the Course Work for UIUC&#x27;s CS196</title>
          <pubDate>Wed, 21 Jan 2015 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/cs196/</link>
          <guid>https://www.narendasan.com/blog/cs196/</guid>
          <description xml:base="https://www.narendasan.com/blog/cs196/">&lt;p&gt;Something unique about UIUC is that they let a bunch of undergrads try to and teach a course in the form of the CS Department&#x27;s Freshman Projects Course.
They took this course as an oppurtunity for undergrads to decide what they thought was important to learn when you are an ambitious student just
entering college and want to get up to speed quickly. Everyone has heard the complaints about how a course is outdated or teaching technology that
you will never use but this was an oppurtunity to change that.&lt;&#x2F;p&gt;
&lt;p&gt;We decided that the format would be one that tries to replicate the working enviorment you might experience at a job or your first internship, hopefully
giving a people a leg up that coming summer. We also wanted to instill in the students at UIUC a culture of making, that people should take their
creativity and realize it into something instead of like other classes being given a brief and a set of steps and then executing.&lt;&#x2F;p&gt;
&lt;p&gt;The class had two halves, the lecture half and the project half. We took lectures as an oppurtunity to expose freshmen to all the interesting things
you might want to know about just starting out in CS. We had lectures on VR, Machine Learning, new programming languages like Rust, how to be
a better developer using tooling like Git, Emacs, and Bash and how to approach interviewing for jobs and interships. It was an hour a week
where upper classmen can impart some knowledge to new students. The project half was the main meat of the course. Students at the beginning of the
semester would needed to come up with a topic and pitch it to the rest of the class. Students then selected what they wanted to work on and were assigned an upperclassman &quot;Project Manager&quot; who has a background in that topic and through out the semester students will
run that project in an agile fashion with weekly scrums, a kanban board and the PM helping students break down the tasks needed to complete the project.&lt;&#x2F;p&gt;
&lt;p&gt;The course was pretty successful. There were a ton of fantastic projects people made. Students who finished the class wanted to comeback as PMs to go through the experience again. Lot&#x27;s of people said their 196 project, the process of going through agile development, the prep for interviews and the advice they got from their mentors helped them get their first internships. For the upperclassmen it was a great experience too, it gave them a shot to try out project managment and learn how to lead a team.
And for the department they saw a lot of the things we did in CS196 and took it as inspiration to update parts of the CS curriculum, reordering the class progression
and adding a new class for 1st and 2nd year students teaching software engineering practices using the same ideas in 196 (we actually collaborated on the design of that course).&lt;&#x2F;p&gt;
&lt;p&gt;The course was our sort of playground as well to try out new pedagogies. We actually hosted a full fledged conference featuring Professors presenting their research
and insight about CS to the students. We hosted hackathons to give students large blocks of time to work with their teams and PMs. We sort of got to create the class we wanted to take when we came to UIUC for the first time.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Here is a sample lecture:&lt;&#x2F;p&gt;
&lt;iframe width=&quot;530&quot; height=&quot;300&quot; src=&quot;https:&#x2F;&#x2F;www.youtube-nocookie.com&#x2F;embed&#x2F;oOw1VOAXa7E&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;CS 196 Website: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cs196.cs.illinois.edu&#x2F;&quot;&gt;http:&#x2F;&#x2F;cs196.cs.illinois.edu&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
      <item>
          <title>Learning for an Interdisciplinary World</title>
          <pubDate>Sat, 10 May 2014 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/tedxmilehigh/</link>
          <guid>https://www.narendasan.com/blog/tedxmilehigh/</guid>
          <description xml:base="https://www.narendasan.com/blog/tedxmilehigh/">&lt;p&gt;I gave a TEDx Talk on my work at NOAA on climate modeling, CU on swarm robotics and Design and Developement work for my High School
and how you can use design thinking as a framework to approach for interdisiplinary studies.&lt;&#x2F;p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https:&#x2F;&#x2F;www.youtube-nocookie.com&#x2F;embed&#x2F;4BBIfI-O6rk&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;</description>
      </item>
      <item>
          <title>The Amorphous Facade and Developing a Gesture Based Decentralized User Interface</title>
          <pubDate>Sun, 16 Feb 2014 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/amorphous-facade/</link>
          <guid>https://www.narendasan.com/blog/amorphous-facade/</guid>
          <description xml:base="https://www.narendasan.com/blog/amorphous-facade/">&lt;p&gt;For 2013 and 2014, I spent a good deal of my free time and all of my summer working on research in Swarm Robotics at the University of Colorado Boulder in Professor Nikolaus Correll&#x27;s Lab. My main research interest was in exploring ways swarm robotics could be deployed to create new interesting interaction models.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;amorphous-facade&#x2F;.&#x2F;imgs&#x2F;sketch.png&quot; alt=&quot;concept wall of the amorphous facade&quot; &#x2F;&gt;
Concept art for the Amorphous Facade&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;My work centered on a platform developed at Correll Lab called the Amorphous Facade; a concept for a modular smart wall where the &quot;operating system&quot; of the wall was completely decentralized and leveraged ad-hoc self-organization to do useful work. The idea is that you could build spaces out of the blocks were the intellegent features of the wall allowed you to manage enviormental conditions like lighting, HVAC, privacy and sound and also serve as display and control surface. Each block in the wall is embedded with a ATmega microcontroller, a sensor array, power systems, communication and LEDs. Each block was made out of acrylic, with an aluminum border which is sensitive to touch and a variable transparency faceplate which goes from opaque to clear when a voltage is applied.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;amorphous-facade&#x2F;.&#x2F;imgs&#x2F;block.jpg&quot; alt=&quot;blocks of the wall&quot; &#x2F;&gt;
Three blocks stacked, pins on the sides of the blocks facilitate power distribution and communication between blocks&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The system becomes interesting because though the core functionality and software of the RTOS is identical from block to block, the blocks can have heterogenous hardware. So one block may be a camera block, another block may be use for HVAC or another could be for sound. Because of the networked nature of the system, capabilities can be shared and combined, for instance a single microphone block and a set of speaker blocks could be combined to create a loud speaker.&lt;&#x2F;p&gt;
&lt;p&gt;Because the system is required to be reconfigurable, the question of a decentralized user interface becomes important. Touch is a natural interaction medium for a wall. However, since the configuration of blocks could entirely different from one setup to another, in order to establish a usable touch wall, touches must be able to be put in context (i.e. we need to know where on the wall a touch was detected). We therefore need a way when the system starts up for blocks to establish their location relative to other blocks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;initialization-of-the-wall&quot;&gt;Initialization of the Wall&lt;&#x2F;h2&gt;
&lt;p&gt;Without localization, touch or any sort of multi-node display or action is impossible. The approach we used leverages the fact that each block is the same dimensions and that each block is created with a unique identifier. We designate a block the origin node (though in the implementation in the paper this is hard coded, a simple leader election algorithm would suffice to define the origin node of the network). The origin node first calculates the coordinates of its borders (where the touch sensors are). Then the origin node multicasts to the bordering blocks the calculated center of the border blocks in relation to its center. Each of these border nodes then does the same process, propagating localization through the network. The location setting message also includes a hop count so blocks will localized based on the message with the lowest hop count.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;amorphous-facade&#x2F;.&#x2F;imgs&#x2F;loc.jpg&quot; alt=&quot;localization in the wall&quot; &#x2F;&gt;
Blocks mid localization, different colors represent different states in the localization process.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Now that each block knows where it is in relation to others, it is now possible to start creating more interesting interfaces to leverage the features of the wall.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gesture-based-distributed-user-interaction-system-for-a-reconfigurable-self-organizing-smart-wall&quot;&gt;Gesture Based Distributed User Interaction System for a Reconfigurable Self-Organizing Smart Wall&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;See paper for full details: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;pdf&#x2F;10.1145&#x2F;2540930.2540967&quot;&gt;Gesture Based Distributed User Interaction System for a Reconfigurable Self-Organizing Smart Wall&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;At the time of the paper, there were a lot of potential functions that the wall could implement based on the sensors embedded in the control board. The wall can change transparency, it can act as a lighting system, a sound system, an HVAC system and a display.&lt;&#x2F;p&gt;
&lt;p&gt;All of these systems require user controls that are intuitive but also possible to be implemented within the network. The simplest technical solution is to have each block expose itself as the interface for the wall, using the six touch buttons as the input mechanism. The issue with this is that its is hard to convey useful information on a single block that can has no display.&lt;&#x2F;p&gt;
&lt;p&gt;A better solution is a multi-node system where a subset of the wall work together to expose a more useful interface.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;establishing-a-multi-node-interface&quot;&gt;Establishing a Multi-node Interface&lt;&#x2F;h3&gt;
&lt;p&gt;Since the system is distributed and there is no hierarchy in the system, the blocks must self organize to create the interface. The way we do this is when a user touches on of the blocks on the wall in an effort to accomplish a task, the block that was touched recruits the surrounding nodes to create a flower like menu system. At the time of the paper the menu functions are represented as colors, however when displays are integrated into the face of the block, the menu becomes more descriptive.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;amorphous-facade&#x2F;imgs&#x2F;flower.jpg&quot; alt=&quot;Flower menu&quot; &#x2F;&gt;
An example of the flower menu open, each color represents a different function for the wall.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;A user can then select a function by sliding a block color into the center.&lt;&#x2F;p&gt;
&lt;p&gt;We then describe a set of interaction models to address various tasks.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interaction-models&quot;&gt;Interaction Models&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;binary-settings&quot;&gt;Binary Settings&lt;&#x2F;h4&gt;
&lt;p&gt;For binary settings (ON &#x2F; OFF) we show a switch like interface where swiping from the bottom to the top or the top to the bottom flips the switch.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;amorphous-facade&#x2F;imgs&#x2F;binary.png&quot; alt=&quot;binary menu&quot; &#x2F;&gt;
An interaction where flipping the binary switch makes the wall transparent instead of opaque&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;em&gt;A more intuitive interaction maybe to make a similar looking interface but in order to reflect device state, the current state is illuminated and the opposite state should be white. Then the user should just have to touch the block representing the state desired&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;granular-settings&quot;&gt;Granular Settings&lt;&#x2F;h4&gt;
&lt;p&gt;For settings that have more granular controls than on or off, we describe a dial interface. The user swipes around the center block in a clockwise or counter-clockwise motion in order to increase or decrease the setting value.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;amorphous-facade&#x2F;imgs&#x2F;dial.png&quot; alt=&quot;dial menu&quot; &#x2F;&gt;
An interaction where swiping around the dial increases the volume of the speaker&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;amorphous-facade&#x2F;imgs&#x2F;tei.jpg&quot; alt=&quot;tei&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nicholas Farrow, Prof. Correll and I presenting our work at TEI 2014 in Munich&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
      <item>
          <title>Finding the First 10 Digits Prime Number in the Digits of e</title>
          <pubDate>Fri, 20 Dec 2013 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.narendasan.com/blog/digits-of-e/</link>
          <guid>https://www.narendasan.com/blog/digits-of-e/</guid>
          <description xml:base="https://www.narendasan.com/blog/digits-of-e/">&lt;blockquote&gt;
&lt;p&gt;Transcription of my IB Math HL Paper from 2013&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Google being a leading company in the technology industry in order to remain competitive needs to find the best talent in computer science, mathematics and the hard sciences. However pure recruitment does not always find the best and the brightest. In an effort to attract driven and curious people to work for Google, the company released this billboard ad.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;digits-of-e&#x2F;imgs&#x2F;problem.jpg&quot; alt=&quot;original billboard&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Personally, this problem is of interests as it is an seemingly simple computer science problem, yet it is used by a company with high standards to screen talent. Therefore it is a good problem to measure ones skills. Though it seems simple, with closer inspection, this problem begins to examine not only a mathematical curiosity but with a little pursuit of elegance also examines number theory, the frequency of primes within a set of digits and efficiency of algorithms. Computer science itself is an interesting extension of a variety of fields including mathematics and engineering. Computer science has enabled mathematics, scientists, engineers and even high school students to explore the curiosities and patterns of mathematics and science and to create new things. Algorithms in computer science start to become very similar to fields in mathematics like combinatorics, probability and number theory. While looking at algorithms, it is interesting to see where the two fields overlap. For instance, for loops and recursive methods in many programming languages are comparable to summations and factorials.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;public static int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; factorial&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;num &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F;recursive (calls itself again)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        num &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; factorial&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span&gt;num &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;  1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At first glance, a brute force method of checking if each ten digit number $i$ is divisible by any of the numbers from $2$ to $x - 1$ should not take that long. However, It is unclear though how far into the digits of $e$ the program would have to go. Eventhough it may take one iteration 10 seconds, 100 iterations could take 10000 and so on. Therefore a more feasible approach to this problem may be in order.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;discussion-of-the-problem-in-depth&quot;&gt;Discussion of the Problem In-depth&lt;&#x2F;h2&gt;
&lt;p&gt;From a high level this problem has two parts. Part one is to develop a sufficiently precise definition of $e$ to test for the prime in question. The odds are extremely low that the answer would occur in the standard definition of $e$ of most programming languages. Part two is to develop a algorithm that will test numbers for primarily since a brute force method is not scalable.&lt;&#x2F;p&gt;
&lt;p&gt;$e$ as it is defined in Java’s java.lang.Math class is $2.718281828459045$. Java is a object oriented programming language that is meant to be compatible across different computers.The decision to use Java will be explained later In the majority of computer science problems, this definition is sufficient, however as this problem is to find the first ten digit prime, in this definitions there are six ten digit possible numbers to test. The likelihood that the prime exists in these digits are fairly low and therefore it would be useful to generate a more precise definition. $e$ can be calculated in a variety of ways, the first of which would be the method used by Bernoulli:&lt;&#x2F;p&gt;
&lt;p&gt;$$\lim_{n\to\infty} (1 + \frac{1}{n})^n$$&lt;&#x2F;p&gt;
&lt;p&gt;This is a method that is really easy to understand and is therefore the first definition of $e$ many students learn, yet is not very practical in a computational sense as limits are not very easily implemented. Others issues like the lack of control of the precision of the number since the number’s precision does not change linearly. It is therefore hard to predict a point at which the number is sufficiently large and the program can terminate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.narendasan.com&#x2F;blog&#x2F;digits-of-e&#x2F;imgs&#x2F;fraction.png&quot; alt=&quot;fraction&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Finally, the third method and the one chosen was the Taylor series definition of $e$:&lt;&#x2F;p&gt;
&lt;p&gt;$$e = \sum_{n=1}^{\infty} \frac{1}{n!}$$&lt;&#x2F;p&gt;
&lt;p&gt;The Taylor series definition is easy to understand and the most elegant to implement as it is simply a while loop continually adding the next element to the sum of the previous ones. An implementation is below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;public static double&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; e_taylor_series&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    double&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; iteration&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        temp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; temp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;factorial&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;iteration&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F;see factorial function above&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        iteration&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course this method would create and infinite loop, but it would calculate the true value of $e$. Simply changing the while loop to a for loop and selecting a number of iterations allows the program to be terminated at the desired level of precision:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;public static double&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; e_taylor_series&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    double&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 500&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        temp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; temp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;factorial&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F;see factorial function above&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However a new issue arises that has not to do with mathematics but with computer science. The primitive &lt;code&gt;double&lt;&#x2F;code&gt; which is used by computers to store large decimals as defined by IEEE is a primitive with 52 bits available for fraction storage and 11 bits for exponents. This means that the smallest number that can stored in a &lt;code&gt;double&lt;&#x2F;code&gt; $4.94065645841246544e-324$ with 18 digits of significant figures. If $e$ was calculated using a double primitive the program could only test 7 possible values which does not improve the test set very much over the language’s definition. This is where the choice of the correct programming language can make the program very simple or very complicated. The run time of the program is very important since the precise location of the first prime is not yet known. If this program is to be scalable the runtime should not require hours. Using a language like C which is an extremely low level language will increase speed significantly since C is run without very many peripheral activities, but a solution in C because of the lack of data types other than the standard float and double for decimals would require parsing decimals into large integer arrays and adding those together in the right locations which is very difficult to implement without errors and a large amount of time committed to debugging. Meanwhile, a higher level language like Java may be slightly slower since all of its commands are run through essentially another computer called the Java Virtual Machine (JVM) which increases compatibility (also a positive for writing scalable code). However, defined in the &lt;code&gt;java.lang&lt;&#x2F;code&gt; library is a class bigDecimal that allows for more digits to be stored solving this issue easily. The algorithm for $e$ is as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;public static&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BigDecimal calc_e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    BigDecimal&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; BigDecimal&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ONE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;the definition of e, big decimal object is required to hold the value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    BigDecimal&lt;&#x2F;span&gt;&lt;span&gt; factorial&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; BigDecimal&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ONE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;factorial object, must be the same type as e to be able to use the big decimal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; methods add and divide&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 500&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F;summation of the taylor series definition of e for the first 500 iterations &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F; 1&#x2F;1+1&#x2F;1+1&#x2F;2....+1&#x2F;499+1&#x2F;500&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        factorial &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; factorial&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;multiply&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BigDecimal&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&amp;quot;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        e &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; BigDecimal&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; “”&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;divide&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;factorial&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; MathContext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;10000&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;* String eString = (e + &amp;quot;&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;       supposed to print out e, computing resources run out of memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;       long eDef = Long.parseLong(eString);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;       System.out.println(&amp;quot;e = &amp;quot; +eDef); *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now that a sufficiently precise value of $e$ has be generated, it is now necessary to develop a way to test numbers for their primality. A computer could easily given sufficient time test for a number $n$ every number from $2$ to $n - 1$ for divisibility. A slightly more efficient method would be to check each number from $2$ to $\sqrt{n}$ as shown below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;public static boolean&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; isPrime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;long&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;){&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F;if the number is less than 1 it cannot be prime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;         &#x2F;&#x2F;if the number is divisable by 2 then is cannot be prime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    long&lt;&#x2F;span&gt;&lt;span&gt; m&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;long&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt; Math&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sqrt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;there is no need to test past the square root of a number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;since the square root is always a divisor of a number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;long&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; m&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F;tests every number from three to the square root of n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, this is not scalable. A successful program should be able to find the first 20 digit or 40 digit prime number, (provided enough memory) in a reasonable time. Therefore, it is necessary to examine some other methods of determining primality of a number. A method that is quite popular is &lt;em&gt;Wilson’s Theorem&lt;&#x2F;em&gt;. &lt;em&gt;Wilson’s Theorem&lt;&#x2F;em&gt; states that:&lt;&#x2F;p&gt;
&lt;p&gt;$$ (n - 1) \equiv - 1 \ (mod \ n) $$&lt;&#x2F;p&gt;
&lt;p&gt;or that a number $n$ is prime if and only if the factorial of $(n - 1)$ is exactly 1 less that a multiple of $n$. This is an extremely powerful statement and one that is extremely easy to implement in code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;public static boolean&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; prime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; test&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; factorial&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;Calculate the test number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;test &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F; check divisibility&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Wilson’s Theorem&lt;&#x2F;em&gt; is very easy to prove and is as follows:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;proof-of-wilson-s-theorem&quot;&gt;Proof of Wilson’s Theorem&lt;&#x2F;h3&gt;
&lt;p&gt;The when $p = 2, 3$ the result is obvious, therefore $p$ is an odd prime, $p &amp;gt; 3$. If $p$ is a composite number then its divisors are in the set ${1,2,3,..., p - 1}$ and $((p - 1)!, p) &amp;gt; 1$, therefore $(p - 1)! = -1 \ (mod \ p)$ for a composite number. If $p$ is prime, then each integers in the set relatively prime to $p$. Each of these integers a there is another $b$ such that $ab = 1 \ (mod \ p)$. It is important to note that this b is unique modulo $p$, and that since $p$ is prime, $a = b$ if and only if $a$ is $1$ or $p - 1$. Now if we omit $1$ and $p - 1$, then the others can be grouped into pairs whose product is one showing&lt;&#x2F;p&gt;
&lt;p&gt;$$ 2 * 3 * 4 * \ ... * \ (p-2) = 1 \ (mod \ p) $$&lt;&#x2F;p&gt;
&lt;p&gt;or&lt;&#x2F;p&gt;
&lt;p&gt;$$ (p - 2)! = 1 \ (mod \ p) $$&lt;&#x2F;p&gt;
&lt;p&gt;This equation multiplied by $(p - 1)$ proves the theorem.&lt;&#x2F;p&gt;
&lt;p&gt;Though the implementation of the theorem was quite simple, an issue that arises is that the theorem requires factorials and the factorial of a ten digit number let a 30 or 50 digit one requires some serious computational power and this program should not depend on access to a supercomputer to successfully run.&lt;&#x2F;p&gt;
&lt;p&gt;There is a a similar theorem to &lt;em&gt;Wilson’s Theorem&lt;&#x2F;em&gt; called &lt;em&gt;Fermat’s Little Theorem&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;$$ a^{(p -1)} \equiv 1 \ (mod \ p) \ s.t. \ (a,p) = 1$$&lt;&#x2F;p&gt;
&lt;p&gt;Fermat’s Little Theorem states that for a prime number $p$ and any number $a$ where the greatest common divisor is $1$ that a to the power of $p - 1$ is $1$ more than a multiple of $p$.
A corollary to this theorem is&lt;&#x2F;p&gt;
&lt;p&gt;$$a^p \equiv a \ (mod \ p)$$&lt;&#x2F;p&gt;
&lt;p&gt;where a is any number and $p`$ is a prime. The proof of this theorem is as follows:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;proof-of-the-fermat-s-little-theorem&quot;&gt;Proof of the Fermat’s Little Theorem&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;proof-by-induction&quot;&gt;Proof By Induction&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;em&gt;P0&lt;&#x2F;em&gt;. $0^p \equiv 0 \ (mod \ p)$ is true for all integers&lt;&#x2F;p&gt;
&lt;h4 id=&quot;lemma&quot;&gt;Lemma&lt;&#x2F;h4&gt;
&lt;p&gt;For any prime $p$, $(x + y)^p = x^P + y^p$ or $(x + y)^p \equiv x^P + y^p \ (mod \ p)$ for any $x$ and $y$ in the finite field $GF(p)$
&lt;em&gt;To be proved later.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;P1&lt;&#x2F;em&gt;. Assume $kp \equiv k \ (mod \ p)$, and consider $p(k + 1)$&lt;&#x2F;p&gt;
&lt;p&gt;Using the lemma $(k + 1)^p \equiv k^p + 1^p \ (mod \ p)$&lt;&#x2F;p&gt;
&lt;p&gt;By the assumption, $kp \equiv k \ (mod \ p)$ -&amp;gt; $1p = 1$. Thus $(k + 1)^p \equiv k^p + 1 \ (mod \ p)$&lt;&#x2F;p&gt;
&lt;h4 id=&quot;proof-of-lemma&quot;&gt;Proof of Lemma&lt;&#x2F;h4&gt;
&lt;p&gt;Using binomial theorem, the binomial coefficients are all integers and when $0 &amp;lt; i &amp;lt; p$, neither of the terms in the denominator includes a factor of $p$, leaving the coefficient itself to possess a prime factor of $p$ which must exist in the numerator, implying that $\binom{p}{i} \equiv 0 \ (mod \ p), \ 0 &amp;lt; i &amp;lt; p$&lt;&#x2F;p&gt;
&lt;p&gt;Modulo $p$, this eliminates all but the first and last terms of the sum on the right-hand side of the binomial theorem for prime p. ∎&lt;&#x2F;p&gt;
&lt;p&gt;The primality of p is essential to the lemma; otherwise, we have examples like $\binom{4}{2} = 6$ which is not divisible by 4.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Fermat’s Little Theorem&lt;&#x2F;em&gt; also has a simple implementation. By using 2 for a the resources necessary for the program are minimized. note. an extra library is required: &lt;code&gt;java.lang.math&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    public static boolean&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; prime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; test&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Math&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;pow&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F;Calculate the test number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;test &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F; check divisibility&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This solution would be quite elegant if it were not for one caveat of &lt;em&gt;Fermat’s Little Theorem&lt;&#x2F;em&gt;. &lt;em&gt;Fermat’s Little Theorem&lt;&#x2F;em&gt; in addition to revealing primes reveals pseudoprimes or composite numbers that have a quality that primes have, namely fulfilling v. Though specific bases have specific pseudoprimes, a pseudoprime that is a pseudoprime for all values of base a is called a Carmichael number. Carmichael numbers are the set of all numbers that fulfill the following equation.&lt;&#x2F;p&gt;
&lt;p&gt;$$({\sum_{a=1}^{p-1} a^{p-1}}, p) = 1 $$&lt;&#x2F;p&gt;
&lt;p&gt;Meaning the greatest common divisor of the summation from $a$ to $p - 1$ of $a^{p-1}$ and $p$ is 1.&lt;&#x2F;p&gt;
&lt;p&gt;While it would be easy to check for Carmichael numbers in the code, it would be difficult to check for all the other pseudoprimes not confined to the set of Carmichael numbers.
A more robust form of Fermat’s Little Theorem called the Lucas Primality Test is probably the most scalable version of a primality test. The test states:&lt;&#x2F;p&gt;
&lt;p&gt;$$a^{n-1} \equiv 1 \ (mod \ n)$$&lt;&#x2F;p&gt;
&lt;p&gt;$$a^{(n-1)&#x2F;q} \not\equiv 1 \ (mod \ n)$$&lt;&#x2F;p&gt;
&lt;p&gt;If both of the above statements are true, where $q$ is each prime factor of $(n-1)$, the number is prime. This test gets rid of the false positives of &lt;em&gt;Fermat’s little theorem&lt;&#x2F;em&gt; of making it not necessity to include a test for Carmichael numbers and running the risk of getting a pseudoprime returned and could be implemented to check the output. The code implementation of the Lucas primality test is below.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; prime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    public static boolean&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; prime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span&gt; test&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Math&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;pow&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span&gt;n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F;Calculate the test number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;test &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;){&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;            &#x2F;&#x2F; check divisibility (for find_prime_factors() see below)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[]&lt;&#x2F;span&gt;&lt;span&gt; prime_factors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; find_prime_factors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; ) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;prime_factors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;                    &#x2F;&#x2F;make sure not to divide by zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;                    int&lt;&#x2F;span&gt;&lt;span&gt; carmichael&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt;  Math&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;pow&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,((&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    prime_factors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;carmichael &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;){&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    private static int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; find_prime_factors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[]&lt;&#x2F;span&gt;&lt;span&gt; factors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F;  #2 that divide n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            factors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F; n is odd a. can skip one test (Note i = i +2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; Math&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sqrt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;            &#x2F;&#x2F; While i divides n, print i and divide n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                factors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F; final prime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            factors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; factors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;&#x2F;h2&gt;
&lt;p&gt;With &lt;em&gt;Lucas’s Primality Test&lt;&#x2F;em&gt; all of the algorithms should be designed to find the first ten digit prime number in the digits of &lt;em&gt;e&lt;&#x2F;em&gt;. First a Taylor series will calculate a value of $e$ through 500 iterations of the series. Then using the &lt;em&gt;Lucas Primality Test&lt;&#x2F;em&gt; each ten consecutive digits will be sampled to test for primality. It is hard to tell if the arbitrary settings of 500 iterations and 40 prime factors will be sufficient to complete the program but since those are easily changeable, that is not a significant issue.&lt;&#x2F;p&gt;
&lt;p&gt;There will be two programs included in this paper, one use the brute force method and the other the Lucas Test to test numbers for primality, both are included in Appendix A. This will check the answers against each other. Both programs work by calculating a value for $e$ and storing it in a &lt;code&gt;bigDecimal&lt;&#x2F;code&gt; object. This is then parsed into a &lt;code&gt;String&lt;&#x2F;code&gt; removing the first 2 and the decimal point for simplicity. Afterwards 10 character chunks are casted into a single integer and tested through the two prime tests. If the number is prime, the system prints it out with the number prime it is in the set and the digit after the decimal point at which the first digit appears.&lt;&#x2F;p&gt;
&lt;p&gt;After running through the two programs I found that the first prime in the digits of $e$ is 7427466391 starting at digit 99 of the string or the 100th digit. This is a fairly surprising result since it is at such a significant digit. And, when navigating to the website described on the billboard, it turns out the website was taken down. Yet, many other sources have reported the same answer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;application-of-this-problem&quot;&gt;Application of this Problem&lt;&#x2F;h2&gt;
&lt;p&gt;Prime numbers are not just of interest because they are different from other numbers.
Prime numbers are a mathematical singularity and therefore are of interest for research. In Pure Maths fields like Number Theory prime numbers play a huge role. Great figures in Mathematics devoted a lot of time to the pursuit of prime numbers such as Fermat, Euler and Wilson. But this problem is not just a novelty or just a point of interest. The frequency of prime numbers in irrational ones is of mathematical interest. Prime numbers are vital to the cryptography and security industry as prime numbers are used to seed encryption algorithms. Prime numbers are the basis of the up incoming currency called Bitcoins where computers solving an algorithm using prime numbers to seed the problem generate a currency. It is valued at over $200 per Bitcoin (lol tbt to 2013). Fermat’s Theorem itself is used to validate RSA’s encryption methods. Prime numbers are also a competitive endeavor. An extension of Lucas’s Primality Test is the Lucas–Lehmer primality test which is used to calculate larger primes that follow the form:&lt;&#x2F;p&gt;
&lt;p&gt;$$M_{n} = 2^n - 1$$&lt;&#x2F;p&gt;
&lt;p&gt;These are called Mersenne primes. These primes are calculated as tests for new supercomputers and are part of a competition to calculate the largest prime number since it is easier to calculate one of these primes than any given one. The most recent one was calculated January 25, 2013 and had 17,425,170 digits. $e$ is also used to test computer systems, NASA itself calculated 5 million digits with their system The algorithms outlined in this paper are standard in the realm of computer science as not only benchmark tests and competitions but as key parts of security, privacy and the economy.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;This paper set out to find the first 10 digit prime number in the digits of $e$. This seems to be a trivial problem when one thinks about the steps. It is only to test each set of 10 consecutive digits for primality until the first one is found. However, issues with the inherent capabilities of computers force a more complex solution than expected. A more precise $e$ required to begin testing which itself requires special classes to be implemented. Then the actually testing can be done with brute force, yet a solution like that is not scalable to find longer and longer primes in a set. Therefore tests like Wilson’s Theorem, Fermat’s Little Theorem, and the Lucas Primality Test need to be examined for possible implantation. Ultimately a solution was found in a singularly surprising spot. At the 100th digit the prime 7427466391 was found. This problem shows the overlap between computer science and mathematics and gives an introduction into Number Theory and the practices of the cryptography and security. It also was a challenging programming challenge that can help companies like Google discover new talent.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Link to Source code: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;narendasan&#x2F;google_e&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;narendasan&#x2F;google_e&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</description>
      </item>
    </channel>
</rss>
