|
1 | | -<!DOCTYPE html> |
| 1 | +<!doctype html> |
2 | 2 | <html> |
3 | 3 | <head> |
4 | 4 | <meta charset="utf-8" /> |
5 | 5 | <title>Standalone WebGPU Scan/Reduce Primitive Test</title> |
6 | 6 | <link rel="stylesheet" href="gridwise.css" /> |
| 7 | + <link |
| 8 | + rel="stylesheet" |
| 9 | + href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" |
| 10 | + /> |
7 | 11 | </head> |
8 | 12 | <body> |
9 | | - <h1>Scan / Reduce Example</h1> |
| 13 | + <h1>WebGPU Scan / Reduce Primitive Example</h1> |
| 14 | + <p> |
| 15 | + This example calls Gridwise's <code>scan</code> primitive. You can look |
| 16 | + at your developer console and see the input and output of this primitive, |
| 17 | + and whether the output matches what is expected (in which case the |
| 18 | + developer console will indicate "Validation passed"). |
| 19 | + </p> |
| 20 | + <p> |
| 21 | + It computes an exclusive prefix-sum (scan) over an input array of |
| 22 | + 2<sup>24</sup> i32s, producing an output array of the same length. |
| 23 | + In an exclusive scan, output element <em>i</em> is the sum of all input |
| 24 | + elements before position <em>i</em>; the first output element is always |
| 25 | + the identity value (0 for addition). |
| 26 | + <a |
| 27 | + href="https://github.com/gridwise-webgpu/gridwise/blob/main/examples/scan_example.mjs" |
| 28 | + >The entire JS source file is in github.</a |
| 29 | + > |
| 30 | + While the entire file contains substantial WebGPU and input-output setup |
| 31 | + boilerplate, the important parts follow. |
| 32 | + </p> |
| 33 | + <p> |
| 34 | + First, we declare the scan primitive. We configure its datatype (i32), |
| 35 | + the binary operation (sum), and the scan type (exclusive). |
| 36 | + </p> |
| 37 | + <pre><code class="language-javascript">const datatype = "i32"; |
| 38 | +const binop = new BinOpAdd({ datatype }); |
| 39 | +const scanType = "exclusive"; |
| 40 | +const dldfscanPrimitive = new DLDFScan({ |
| 41 | + device, |
| 42 | + binop, |
| 43 | + type: scanType, |
| 44 | + datatype, |
| 45 | +}); |
| 46 | +const primitive = dldfscanPrimitive;</code></pre> |
| 47 | + <p> |
| 48 | + We have declared buffers (using WebGPU's <code>device.createBuffer</code>) |
| 49 | + called <code>memsrcBuffer</code> and <code>memdestBuffer</code>. For scan, |
| 50 | + the output buffer is the same size as the input. We then call the |
| 51 | + primitive's <code>execute</code> procedure (note that |
| 52 | + <code>execute</code> is an <code>async</code> call): |
| 53 | + </p> |
| 54 | + <pre><code class="language-javascript">await primitive.execute({ |
| 55 | + inputBuffer: memsrcBuffer, |
| 56 | + outputBuffer: memdestBuffer, |
| 57 | +});</code></pre> |
| 58 | + <p>We then read back the result from the GPU and validate it.</p> |
| 59 | + <p> |
| 60 | + Your developer console should show a result that allows you to inspect the |
| 61 | + input and output, and prints "Validation passed" if the output matches the |
| 62 | + (CPU-computed) reference. It should look something like: |
| 63 | + </p> |
| 64 | + <pre><code>input array Int32Array(16777216) [11, 12, 13, 14, ...] |
| 65 | +output Int32Array(16777216) [0, 11, 23, 36, ...] |
| 66 | +Validation passed |
| 67 | +</code></pre> |
10 | 68 | <div id="plot"></div> |
| 69 | + <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script> |
| 70 | + <script> |
| 71 | + hljs.highlightAll(); |
| 72 | + </script> |
11 | 73 | <script src="scan_example.mjs" type="module"></script> |
12 | 74 | </body> |
13 | 75 | </html> |
0 commit comments