[{"data":1,"prerenderedAt":30},["ShallowReactive",2],{"chapter:teenygrad\u002Fkernels-and-backends\u002Fkernel-macro.json":3},{"project":4,"route":5,"title":6,"titleHtml":7,"navTitle":6,"part":8,"sourcePath":9,"editUrl":10,"html":11,"toc":12,"hasMermaid":23,"prev":24,"next":27},"teenygrad","\u002Fteenygrad\u002Fkernels-and-backends\u002Fkernel-macro","The #[kernel] Macro","The \u003Ccode>#[kernel]\u003C\u002Fcode> Macro","Kernels & Backends","kernels-and-backends\u002Fkernel-macro.md","https:\u002F\u002Fgithub.com\u002Fteenygrad\u002Fteenygrad\u002Fedit\u002Fmain\u002Fbooks\u002Fteenygrad\u002Fsrc\u002Fkernels-and-backends\u002Fkernel-macro.md","\u003Cp>Fully documented in the kernels book: \u003Cstrong>\u003Ca href=\"\u002Fkernels\u002Ffirst-kernel\u002Fkernel-macro\">What \u003Ccode>#[kernel]\u003C\u002Fcode>\nGenerates\u003C\u002Fa>\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Cp>\u003Ca href=\"\u002Fapi\u002Fteenygrad\u002Fteenygrad\u002Fteeny_macros\u002F\">\u003Ccode>teeny-macros\u003C\u002Fcode>\u003C\u002Fa> provides\nthe \u003Ccode>#[kernel]\u003C\u002Fcode> attribute macro (\u003Ccode>teeny_macros::kernel\u003C\u002Fcode>), which marks a function\nas a kernel definition consumed by \u003Ccode>teeny-triton\u003C\u002Fcode>\u002F\u003Ccode>teeny-kernels\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"what-it-emits\">What it emits\u003C\u002Fh2>\n\u003Cp>From one annotated function, three items:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Your function, unchanged.\u003C\u002Fstrong> It type-checks as ordinary Rust. Nothing calls\nit — the macro converts its tokens back to a string, and that string is what\nthe GPU compiler sees.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>A struct\u003C\u002Fstrong>, named by PascalCasing the function name: \u003Ccode>vector_add\u003C\u002Fcode> becomes\n\u003Ccode>VectorAdd\u003C\u002Fcode>. Const generics become runtime fields, lowercased —\n\u003Ccode>const BLOCK_SIZE\u003C\u002Fcode> becomes \u003Ccode>block_size\u003C\u002Fcode>, and an argument to \u003Ccode>new()\u003C\u002Fcode>. It\nimplements \u003Ccode>teeny_core::device::program::Kernel\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>A dispatcher\u003C\u002Fstrong>, only when you pass \u003Ccode>dtypes = [...]\u003C\u002Fcode> or \u003Ccode>backward = ...\u003C\u002Fcode>.\nIt maps a runtime \u003Ccode>DtypeRepr\u003C\u002Fcode> to a monomorphized kernel.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>It also generates an \u003Ccode>extern &quot;C&quot;\u003C\u002Fcode> entry point, as text, with the generics filled\nin — \u003Ccode>{name}_entry_point\u003C\u002Fcode> — because \u003Ccode>teenyc\u003C\u002Fcode> cannot call a generic Rust\nfunction. That symbol is what the loader resolves.\u003C\u002Fp>\n\u003Ch2 id=\"arguments\">Arguments\u003C\u002Fh2>\n\u003Cpre data-lang=\"rust\" class=\"shiki teeny-datasheet\" style=\"background-color:#16181a;color:#e6e8e3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#8A9088\">#[\u003C\u002Fspan>\u003Cspan style=\"color:#6FBF98\">kernel\u003C\u002Fspan>\u003Cspan style=\"color:#8A9088\">]\u003C\u002Fspan>\u003Cspan style=\"color:#7F877D;font-style:italic\">                                 \u002F\u002F no dispatch\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#8A9088\">#[\u003C\u002Fspan>\u003Cspan style=\"color:#6FBF98\">kernel\u003C\u002Fspan>\u003Cspan style=\"color:#8A9088\">(\u003C\u002Fspan>\u003Cspan style=\"color:#6FBF98\">backward \u003C\u002Fspan>\u003Cspan style=\"color:#8A9088\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6FBF98\"> GeluBackward\u003C\u002Fspan>\u003Cspan style=\"color:#8A9088\">)]\u003C\u002Fspan>\u003Cspan style=\"color:#7F877D;font-style:italic\">        \u002F\u002F pair with a gradient kernel\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#8A9088\">#[\u003C\u002Fspan>\u003Cspan style=\"color:#6FBF98\">kernel\u003C\u002Fspan>\u003Cspan style=\"color:#8A9088\">(\u003C\u002Fspan>\u003Cspan style=\"color:#6FBF98\">dtypes \u003C\u002Fspan>\u003Cspan style=\"color:#8A9088\">=\u003C\u002Fspan>\u003Cspan style=\"color:#8A9088\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#6FBF98\">f32\u003C\u002Fspan>\u003Cspan style=\"color:#8A9088\">,\u003C\u002Fspan>\u003Cspan style=\"color:#6FBF98\"> f64\u003C\u002Fspan>\u003Cspan style=\"color:#8A9088\">])]\u003C\u002Fspan>\u003Cspan style=\"color:#7F877D;font-style:italic\">            \u002F\u002F explicit dtype set\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>backward\u003C\u002Fcode> opts into dispatch too, inferring the dtype set from the dtype\nparameter’s trait bound.\u003C\u002Fp>\n\u003Cp>See \u003Ca href=\"\u002Fkernels\u002Fpatterns\u002Fspecialisation\">Compile-Time Parameters and Dtype\nDispatch\u003C\u002Fa> for the\ninference rules, and \u003Ca href=\"\u002Fkernels\u002Freference\u002Fcompile-errors\">Common Compile\nErrors\u003C\u002Fa> for the\nmacro’s diagnostics and what they mean.\u003C\u002Fp>\n\u003Ch2 id=\"where-to-go\">Where to go\u003C\u002Fh2>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>You want\u003C\u002Fth>\n\u003Cth>Read\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>The generated struct, field by field\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fkernels\u002Ffirst-kernel\u002Fkernel-macro\">What \u003Ccode>#[kernel]\u003C\u002Fcode> Generates\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>The real generated entry point\u003C\u002Ftd>\n\u003Ctd>Same chapter — it quotes the committed snapshot\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>How a kernel fits the pipeline\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fteenygrad\u002Fkernels-and-backends\u002Fwriting-a-kernel\">Writing a Triton Kernel\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>What \u003Ccode>teenyc\u003C\u002Fcode> does with the text\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fkernels\u002Forientation\u002Frust-to-ptx\">From Rust to PTX\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n",[13,17,20],{"id":14,"text":15,"level":16},"what-it-emits","What it emits",2,{"id":18,"text":19,"level":16},"arguments","Arguments",{"id":21,"text":22,"level":16},"where-to-go","Where to go",false,{"title":25,"titleHtml":25,"route":26},"Writing a Triton Kernel","\u002Fteenygrad\u002Fkernels-and-backends\u002Fwriting-a-kernel",{"title":28,"titleHtml":28,"route":29},"The egg\u002Fz3 Optimizer","\u002Fteenygrad\u002Fcompiler-internals\u002Foptimizer",1786271829004]