<p><pre><code> > It's extremely simple, and breaks down the most complex networks into 4 OpTypes:
>
> - UnaryOps operate on one tensor and run elementwise. RELU, LOG, RECIPROCAL, etc...
> - BinaryOps operate on two tensors and run elementwise to return one. ADD, MUL, etc...
> - ReduceOps operate on one tensor and return a smaller tensor. SUM, MAX
> - MovementOps operate on one tensor and move the data around, copy-free with ShapeTracker. RESHAPE, PERMUTE, EXPAND, etc...
>
> But how...where are your CONVs and MATMULs? Read the code to solve this mystery.
</code></pre>
Ok, I was curious, so I read the code. The answer is that it represents a MATMUL as a 1x1 CONV. And it lied about CONV, which is a ProcessingOps.CONV and explicitly represented and implemented: <a href="https://github.com/geohot/tinygrad/blob/c0050fab8ff0bc667e40da11980f4ac4c21affda/tinygrad/llops/ops_cpu.py#L40" rel="nofollow">https://github.com/geohot/tinygrad/blob/c0050fab8ff0bc667e40...</a> Quite the letdown of figuring out this 'mystery'.