diff --git a/.github/workflows/jekyll.yml b/.github/workflows/jekyll.yml index 9d47656..72a1885 100644 --- a/.github/workflows/jekyll.yml +++ b/.github/workflows/jekyll.yml @@ -2,10 +2,6 @@ name: Deploy Jekyll site to Pages on: push: - branches: ["main"] - paths: - - ".github/workflows/**" - - "docs/**" workflow_dispatch: permissions: @@ -24,6 +20,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Copy examples and source files to docs + run: | + cp -r examples docs/examples + cp *.mjs docs/ 2>/dev/null || true + - name: Setup Pages uses: actions/configure-pages@v4 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f5233c1..a4f4465 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,9 +2,7 @@ name: Test Jekyll Build on: push: - branches: [ test-css-fix-github-actions ] pull_request: - branches: [ main ] jobs: build: @@ -16,13 +14,10 @@ jobs: - name: Setup Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.1' + ruby-version: '3.2' bundler-cache: true - working-directory: ./docs - name: Build site - run: | - cd docs - bundle exec jekyll build + run: bundle exec jekyll build env: JEKYLL_ENV: production diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..c26f9cd --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,314 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (8.1.1) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + json + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + base64 (0.3.0) + bigdecimal (3.3.1) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.12.2) + colorator (1.1.0) + commonmarker (0.23.12) + concurrent-ruby (1.3.5) + connection_pool (2.5.4) + csv (3.3.5) + dnsruby (1.73.1) + base64 (>= 0.2) + logger (~> 1.6) + simpleidn (~> 0.2.1) + drb (2.2.3) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + ethon (0.15.0) + ffi (>= 1.15.0) + eventmachine (1.2.7) + execjs (2.10.0) + faraday (2.14.0) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-net_http (3.4.2) + net-http (~> 0.5) + ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-aarch64-linux-musl) + ffi (1.17.2-arm-linux-gnu) + ffi (1.17.2-arm-linux-musl) + ffi (1.17.2-arm64-darwin) + ffi (1.17.2-x86_64-darwin) + ffi (1.17.2-x86_64-linux-gnu) + ffi (1.17.2-x86_64-linux-musl) + forwardable-extended (2.6.0) + gemoji (4.1.0) + github-pages (232) + github-pages-health-check (= 1.18.2) + jekyll (= 3.10.0) + jekyll-avatar (= 0.8.0) + jekyll-coffeescript (= 1.2.2) + jekyll-commonmark-ghpages (= 0.5.1) + jekyll-default-layout (= 0.1.5) + jekyll-feed (= 0.17.0) + jekyll-gist (= 1.5.0) + jekyll-github-metadata (= 2.16.1) + jekyll-include-cache (= 0.2.1) + jekyll-mentions (= 1.6.0) + jekyll-optional-front-matter (= 0.3.2) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.3.0) + jekyll-redirect-from (= 0.16.0) + jekyll-relative-links (= 0.6.1) + jekyll-remote-theme (= 0.4.3) + jekyll-sass-converter (= 1.5.2) + jekyll-seo-tag (= 2.8.0) + jekyll-sitemap (= 1.4.0) + jekyll-swiss (= 1.0.0) + jekyll-theme-architect (= 0.2.0) + jekyll-theme-cayman (= 0.2.0) + jekyll-theme-dinky (= 0.2.0) + jekyll-theme-hacker (= 0.2.0) + jekyll-theme-leap-day (= 0.2.0) + jekyll-theme-merlot (= 0.2.0) + jekyll-theme-midnight (= 0.2.0) + jekyll-theme-minimal (= 0.2.0) + jekyll-theme-modernist (= 0.2.0) + jekyll-theme-primer (= 0.6.0) + jekyll-theme-slate (= 0.2.0) + jekyll-theme-tactile (= 0.2.0) + jekyll-theme-time-machine (= 0.2.0) + jekyll-titles-from-headings (= 0.5.3) + jemoji (= 0.13.0) + kramdown (= 2.4.0) + kramdown-parser-gfm (= 1.1.0) + liquid (= 4.0.4) + mercenary (~> 0.3) + minima (= 2.5.1) + nokogiri (>= 1.16.2, < 2.0) + rouge (= 3.30.0) + terminal-table (~> 1.4) + webrick (~> 1.8) + github-pages-health-check (1.18.2) + addressable (~> 2.3) + dnsruby (~> 1.60) + octokit (>= 4, < 8) + public_suffix (>= 3.0, < 6.0) + typhoeus (~> 1.3) + html-pipeline (2.14.3) + activesupport (>= 2) + nokogiri (>= 1.4) + http_parser.rb (0.8.0) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + jekyll (3.10.0) + addressable (~> 2.4) + colorator (~> 1.0) + csv (~> 3.0) + em-websocket (~> 0.5) + i18n (>= 0.7, < 2) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 2.0) + kramdown (>= 1.17, < 3) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (>= 1.7, < 4) + safe_yaml (~> 1.0) + webrick (>= 1.0) + jekyll-avatar (0.8.0) + jekyll (>= 3.0, < 5.0) + jekyll-coffeescript (1.2.2) + coffee-script (~> 2.2) + coffee-script-source (~> 1.12) + jekyll-commonmark (1.4.0) + commonmarker (~> 0.22) + jekyll-commonmark-ghpages (0.5.1) + commonmarker (>= 0.23.7, < 1.1.0) + jekyll (>= 3.9, < 4.0) + jekyll-commonmark (~> 1.4.0) + rouge (>= 2.0, < 5.0) + jekyll-default-layout (0.1.5) + jekyll (>= 3.0, < 5.0) + jekyll-feed (0.17.0) + jekyll (>= 3.7, < 5.0) + jekyll-gist (1.5.0) + octokit (~> 4.2) + jekyll-github-metadata (2.16.1) + jekyll (>= 3.4, < 5.0) + octokit (>= 4, < 7, != 4.4.0) + jekyll-include-cache (0.2.1) + jekyll (>= 3.7, < 5.0) + jekyll-mentions (1.6.0) + html-pipeline (~> 2.3) + jekyll (>= 3.7, < 5.0) + jekyll-optional-front-matter (0.3.2) + jekyll (>= 3.0, < 5.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.3.0) + jekyll (>= 3.0, < 5.0) + jekyll-redirect-from (0.16.0) + jekyll (>= 3.3, < 5.0) + jekyll-relative-links (0.6.1) + jekyll (>= 3.3, < 5.0) + jekyll-remote-theme (0.4.3) + addressable (~> 2.0) + jekyll (>= 3.5, < 5.0) + jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) + rubyzip (>= 1.3.0, < 3.0) + jekyll-sass-converter (1.5.2) + sass (~> 3.4) + jekyll-seo-tag (2.8.0) + jekyll (>= 3.8, < 5.0) + jekyll-sitemap (1.4.0) + jekyll (>= 3.7, < 5.0) + jekyll-swiss (1.0.0) + jekyll-theme-architect (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-cayman (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-dinky (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-hacker (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-leap-day (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-merlot (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-midnight (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-minimal (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-modernist (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-primer (0.6.0) + jekyll (> 3.5, < 5.0) + jekyll-github-metadata (~> 2.9) + jekyll-seo-tag (~> 2.0) + jekyll-theme-slate (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-tactile (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-time-machine (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-titles-from-headings (0.5.3) + jekyll (>= 3.3, < 5.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + jemoji (0.13.0) + gemoji (>= 3, < 5) + html-pipeline (~> 2.2) + jekyll (>= 3.0, < 5.0) + json (2.16.0) + kramdown (2.4.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.4) + listen (3.9.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + logger (1.7.0) + mercenary (0.3.6) + minima (2.5.1) + jekyll (>= 3.5, < 5.0) + jekyll-feed (~> 0.9) + jekyll-seo-tag (~> 2.1) + minitest (5.26.2) + net-http (0.8.0) + uri (>= 0.11.1) + nokogiri (1.18.10-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.10-aarch64-linux-musl) + racc (~> 1.4) + nokogiri (1.18.10-arm-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.10-arm-linux-musl) + racc (~> 1.4) + nokogiri (1.18.10-arm64-darwin) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-linux-musl) + racc (~> 1.4) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (5.1.1) + racc (1.8.1) + rb-fsevent (0.11.2) + rb-inotify (0.11.1) + ffi (~> 1.0) + rexml (3.4.4) + rouge (3.30.0) + rubyzip (2.4.1) + safe_yaml (1.0.5) + sass (3.7.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sawyer (0.9.3) + addressable (>= 2.3.5) + faraday (>= 0.17.3, < 3) + securerandom (0.4.1) + simpleidn (0.2.3) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + typhoeus (1.5.0) + ethon (>= 0.9.0, < 0.16.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (1.8.0) + uri (1.1.1) + webrick (1.9.1) + +PLATFORMS + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + x86_64-darwin + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + github-pages (~> 232) + http_parser.rb (~> 0.6.0) + jekyll-feed + jekyll-remote-theme + tzinfo (>= 1, < 3) + tzinfo-data + wdm (~> 0.1) + +BUNDLED WITH + 2.7.2 diff --git a/_config.yml b/_config.yml index d5e75b6..ed3c58a 100644 --- a/_config.yml +++ b/_config.yml @@ -12,10 +12,11 @@ plugins: - jekyll-feed - jekyll-remote-theme -# Only show About in header navigation + header_pages: - about.markdown + exclude: - misc/ - Gemfile diff --git a/_site/about/index.html b/_site/about/index.html index 1eef0e3..72b534f 100644 --- a/_site/about/index.html +++ b/_site/about/index.html @@ -1,8 +1,8 @@ - - - + + + About | Gridwise @@ -18,89 +18,166 @@ - - - -
-
+
+ + + + +
+
+

About

+
-
-

About

-
- -
-

Gridwise is a JavaScript library for WebGPU compute primitives including scan, reduce, and sort.

+
+

Gridwise is a JavaScript library for WebGPU compute primitives including scan, reduce, and sort.

View the source code on GitHub.

-
- -
- -
-
+ + + + - diff --git a/_site/architecture/index.html b/_site/architecture/index.html new file mode 100644 index 0000000..6e9a3ff --- /dev/null +++ b/_site/architecture/index.html @@ -0,0 +1,211 @@ + + + + + +Gridwise Architecture | Gridwise + + + + + + + + + + + + + + + + +
+
+
+ + + + +
+
+
+

Gridwise Architecture

+
+ +
+

The primary goal of Gridwise is to deliver best-in-class performance on WebGPU compute primitives while minimizing the amount of code that must be written by the library user. Ideally, a Gridwise user will declare and then execute a primitive and Gridwise will handle all low-level details of setting up and calling the necessary WebGPU primitives.

+ +

Gridwise Abstraction

+ +

Primitive

+ +

The primary abstraction in Gridwise is a Primitive. Primitives are instances of a primitive-specific subclass of a JavaScript Primitive class. They have an execute member function, and the typical usage is to instantiate a primitive using new() and then call execute() on that primitive. Both instantiation and execution have numerous options. As an example, let’s look at a scan primitive, which is an instance of the DLDFScan class (“decoupled-lookback, decoupled-fallback scan”):

+ +
const datatype = "u32";
+const dldfscanPrimitive = new DLDFScan({
+  device,
+  binop: new BinOpAdd({ datatype }),
+  type: "exclusive", // "exclusive" is the default
+  datatype,
+});
+
+await dldfscanPrimitive.execute({
+  inputBuffer,
+  outputBuffer,
+});
+
+ +

This particular primitive is parameterized by its datatype (in this case, “u32”), by the binary operation (“binop”) performed by the scan (in this case, addition on u32 data), and by the scan operation (exclusive or inclusive).

+ +

When the scan is actually executed, its arguments are buffers that store its input and output. This particular primitive has named arguments of an input buffer named inputBuffer and an output buffer named outputBuffer. These buffers can be WebGPU buffers of type GPUBuffer but can also be Buffers, described next.

+ +

The primitive performs all necessary WebGPU operations, including (optionally) setting up an encoder, building up and setting WebGPU layouts and pipelines, running the pipeline, and optionally recording GPU-side or CPU-side timing. It also caches WebGPU layouts and pipelines to avoid the expense of recreating them if they have already been created.

+ +

Buffer

+ +

One of the challenges of writing a primitive library is handling data, which may be stored on the CPU (in a JavaScript typed array) or on the GPU (as a WebGPU GPUBuffer). Gridwise’s Buffer class attempts to abstract away the details of separately managing CPU and GPU buffer data structures with one unified data structure that stores, and moves data between, both. This data structure has grown organically to handle many use cases and deserves more focus by future developers as a principled data structure in WebGPU programming.

+ +
+
+
+
+ + + +
+
+ + diff --git a/_site/gridwise/binop/index.html b/_site/binop/index.html similarity index 64% rename from _site/gridwise/binop/index.html rename to _site/binop/index.html index a31180c..2c5d63e 100644 --- a/_site/gridwise/binop/index.html +++ b/_site/binop/index.html @@ -1,64 +1,118 @@ - - - + + + Gridwise’s Binary Operator Class | Gridwise - - + + +{"@context":"https://schema.org","@type":"WebPage","description":"Understanding the BinOp class that represents monoids with binary operations, datatypes, and identity elements for use in primitives.","headline":"Gridwise’s Binary Operator Class","url":"http://localhost:4000/gridwise/binop/"} - - - -
-
+ +
+
+

Gridwise's Binary Operator Class

+
-
-

Gridwise's Binary Operator Class

-
- -
-

Gridwise’s binary operator class is called binop. This class represents a monoid, which has as its constituent parts a binary operation, a datatype for the data on which the operator is applied, and an identity element. (If we call the identity element I and the operator op, then x = I op x. For instance, addition’s identity is zero, and multiplication’s is one.) In Gridwise, we package these elements into an instance of a JS class, BinOp. This class then defines a number of objects that are used in WGSL code generation and CPU correctness checking.

+
+

Gridwise’s binary operator class is called binop. This class represents a monoid, which has as its constituent parts a binary operation, a datatype for the data on which the operator is applied, and an identity element. (If we call the identity element I and the operator op, then x = I op x. For instance, addition’s identity is zero, and multiplication’s is one.) In Gridwise, we package these elements into an instance of a JS class, BinOp. This class then defines a number of objects that are used in WGSL code generation and CPU correctness checking.

BinOp is implemented in the source file binop.md. We specialize BinOp to particular operations (e.g., Add) and then further specialize it with a datatype. Many Gridwise primitives require a BinOp argument and the common use will be something like:

@@ -135,45 +189,68 @@

What does a BinOp p }

-
- - - - -
+ + + + - diff --git a/_site/gridwise/buffer/index.html b/_site/buffer/index.html similarity index 68% rename from _site/gridwise/buffer/index.html rename to _site/buffer/index.html index 9897dda..f91944e 100644 --- a/_site/gridwise/buffer/index.html +++ b/_site/buffer/index.html @@ -1,64 +1,118 @@ - - - + + + Gridwise’s Buffer Class | Gridwise - - + + +{"@context":"https://schema.org","@type":"WebPage","description":"The Buffer class encapsulates data that spans both CPU (typed arrays) and GPU (GPUBuffer), providing a unified interface for data management.","headline":"Gridwise’s Buffer Class","url":"http://localhost:4000/gridwise/buffer/"} - - - -
-
+
+ + + + +
+
+

Gridwise's Buffer Class

+
-
-

Gridwise's Buffer Class

-
- -
-

During Gridwise’s development, we found a need to encapsulate the concept of a single wad of data that spans CPU and GPU. We call this class Buffer. It contains both a CPU-side JS typed array and a GPU-side GPUBuffer. The abstraction is that these two objects are (roughly) consistent with each other (they are not meant to store two logically different objects).

+
+

During Gridwise’s development, we found a need to encapsulate the concept of a single wad of data that spans CPU and GPU. We call this class Buffer. It contains both a CPU-side JS typed array and a GPU-side GPUBuffer. The abstraction is that these two objects are (roughly) consistent with each other (they are not meant to store two logically different objects).

We believe this is an object whose design could be revisited and improved, because it is generally useful in WebGPU primitive development and more generally across WebGPU development. We welcome a redesign. For that purpose, we list our use cases:

@@ -200,45 +254,68 @@

device
  • get: Returns the associated GPUDevice.
  • -

    - -
    - -
    -
    + + + + - diff --git a/_site/builtins-strategy/index.html b/_site/builtins-strategy/index.html new file mode 100644 index 0000000..d193aff --- /dev/null +++ b/_site/builtins-strategy/index.html @@ -0,0 +1,181 @@ + + + + + +Gridwise WebGPU @builtins Strategy | Gridwise + + + + + + + + + + + + + + + + +
    +
    + + + + +
    +
    + + diff --git a/_site/docs/2025/04/08/writing-a-webgpu-wgsl-workgroup-reduce-function/index.html b/_site/docs/2025/04/08/writing-a-webgpu-wgsl-workgroup-reduce-function/index.html index f3fbd13..a2b71e8 100644 --- a/_site/docs/2025/04/08/writing-a-webgpu-wgsl-workgroup-reduce-function/index.html +++ b/_site/docs/2025/04/08/writing-a-webgpu-wgsl-workgroup-reduce-function/index.html @@ -1,8 +1,8 @@ - - - + + + Abstraction Challenges in Writing a WebGPU/WGSL Workgroup Reduce Function | Gridwise @@ -19,38 +19,31 @@ - - -