Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .agents/resume
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ command -v cmake >/dev/null
command -v clang-20 >/dev/null
command -v clang++-20 >/dev/null
command -v clang-tidy-20 >/dev/null
command -v doxygen >/dev/null
command -v run-clang-tidy-20.py >/dev/null
command -v uv >/dev/null
test -f "$llvm_root/lib/cmake/mlir/MLIRConfig.cmake"
Expand Down
1 change: 1 addition & 0 deletions .agents/setup
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ install_system_dependencies() {
clang-tidy-20
cmake
curl
doxygen
gnupg
libmlir-20-dev
llvm-20-dev
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ jobs:
clang-${LLVM_VERSION} \
clang-format-${LLVM_VERSION} \
clang-tidy-${LLVM_VERSION} \
doxygen \
llvm-${LLVM_VERSION}-dev \
libmlir-${LLVM_VERSION}-dev \
mlir-${LLVM_VERSION}-tools

- uses: astral-sh/setup-uv@v4

- name: Install Python dependencies
run: uv sync
run: uv sync --group docs

- name: Configure
run: |
Expand All @@ -45,14 +46,18 @@ jobs:
-DCMAKE_C_COMPILER=clang-${LLVM_VERSION} \
-DCMAKE_CXX_COMPILER=clang++-${LLVM_VERSION} \
-DMLIR_DIR=/usr/lib/llvm-${LLVM_VERSION}/lib/cmake/mlir \
-DLLVM_DIR=/usr/lib/llvm-${LLVM_VERSION}/lib/cmake/llvm
-DLLVM_DIR=/usr/lib/llvm-${LLVM_VERSION}/lib/cmake/llvm \
-DWARPFORTH_ENABLE_DOCS=ON

- name: Build
run: cmake --build build

- name: Test
run: cmake --build build --target check-warpforth

- name: Build documentation
run: cmake --build build --target docs-warpforth

- name: Check C++ with clang-tidy
run: cmake --build build --target check-clang-tidy

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
build/
build-*/
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ add_subdirectory(include)
add_subdirectory(lib)
add_subdirectory(tools)

option(WARPFORTH_ENABLE_DOCS "Build WarpForth documentation" OFF)
if(WARPFORTH_ENABLE_DOCS)
add_subdirectory(docs)
endif()

# Add clang-tidy target after the TableGen targets it depends on are defined.
find_program(CLANG_TIDY_EXECUTABLE
NAMES clang-tidy-${LLVM_VERSION_MAJOR} clang-tidy
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ WarpForth compiles Forth through a series of MLIR dialect lowerings, each replac

## Demo

The `demo/` directory contains a GPT-2 text generation demo that routes scaled dot-product attention through a WarpForth-compiled kernel. See [demo/README.md](demo/README.md) for setup instructions.
The `demo/` directory contains a GPT-2 text generation demo that routes scaled dot-product attention through a WarpForth-compiled kernel. See [docs/demo.md](docs/demo.md) for setup instructions.

## Testing

Expand Down
56 changes: 0 additions & 56 deletions demo/README.md

This file was deleted.

67 changes: 67 additions & 0 deletions docs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
find_program(SPHINX_EXECUTABLE
NAMES sphinx-build
HINTS ${PROJECT_SOURCE_DIR}/.venv/bin
REQUIRED)
find_package(Doxygen REQUIRED)

set(WARPFORTH_DOC_SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/source)
set(WARPFORTH_DOC_HTML_DIR ${CMAKE_CURRENT_BINARY_DIR}/html)
set(WARPFORTH_DIALECT_DOC
${PROJECT_BINARY_DIR}/include/warpforth/Dialect/Forth/ForthDialect.md)
set(WARPFORTH_STAGED_DIALECT_DOC
${WARPFORTH_DOC_SOURCE_DIR}/ForthDialect.md)

file(MAKE_DIRECTORY ${WARPFORTH_DOC_SOURCE_DIR}/_templates/sidebar)
configure_file(conf.py ${WARPFORTH_DOC_SOURCE_DIR}/conf.py COPYONLY)
configure_file(index.md ${WARPFORTH_DOC_SOURCE_DIR}/index.md COPYONLY)
configure_file(language.md ${WARPFORTH_DOC_SOURCE_DIR}/language.md COPYONLY)
configure_file(demo.md ${WARPFORTH_DOC_SOURCE_DIR}/demo.md COPYONLY)
configure_file(
_templates/sidebar/navigation.html
${WARPFORTH_DOC_SOURCE_DIR}/_templates/sidebar/navigation.html
COPYONLY)
configure_file(Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)

add_custom_command(
OUTPUT ${WARPFORTH_STAGED_DIALECT_DOC}
COMMAND ${CMAKE_COMMAND}
-DINPUT=${WARPFORTH_DIALECT_DOC}
-DOUTPUT=${WARPFORTH_STAGED_DIALECT_DOC}
-P ${CMAKE_CURRENT_SOURCE_DIR}/stage-dialect-doc.cmake
DEPENDS
ForthDialectDocGen
${WARPFORTH_DIALECT_DOC}
${CMAKE_CURRENT_SOURCE_DIR}/stage-dialect-doc.cmake
COMMENT "Staging generated Forth dialect documentation"
VERBATIM)
add_custom_target(warpforth-doc-sources
DEPENDS ${WARPFORTH_STAGED_DIALECT_DOC})

add_custom_target(docs-warpforth-api
COMMAND ${CMAKE_COMMAND} -E make_directory
${WARPFORTH_DOC_HTML_DIR}/api
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
COMMENT "Generating WarpForth C++ API documentation"
VERBATIM)

add_custom_target(docs-warpforth-html
COMMAND ${SPHINX_EXECUTABLE}
-b html
-a
-W
--keep-going
-d ${CMAKE_CURRENT_BINARY_DIR}/doctrees
${WARPFORTH_DOC_SOURCE_DIR}
${WARPFORTH_DOC_HTML_DIR}
DEPENDS
warpforth-doc-sources
docs-warpforth-api
COMMENT "Generating WarpForth HTML documentation"
VERBATIM)

add_custom_target(docs-warpforth DEPENDS docs-warpforth-html)

set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
${WARPFORTH_DOC_SOURCE_DIR}
${WARPFORTH_DOC_HTML_DIR}
${CMAKE_CURRENT_BINARY_DIR}/doctrees)
29 changes: 29 additions & 0 deletions docs/Doxyfile.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
PROJECT_NAME = "WarpForth"
PROJECT_BRIEF = "C++ API Reference"
OUTPUT_DIRECTORY = "@WARPFORTH_DOC_HTML_DIR@/api"
INPUT = "@PROJECT_SOURCE_DIR@/docs/api.md" \
"@PROJECT_SOURCE_DIR@/include/warpforth" \
"@PROJECT_SOURCE_DIR@/lib" \
"@PROJECT_SOURCE_DIR@/tools"
INCLUDE_PATH = "@PROJECT_SOURCE_DIR@/include" \
"@PROJECT_BINARY_DIR@/include"
STRIP_FROM_PATH = "@PROJECT_SOURCE_DIR@"
STRIP_FROM_INC_PATH = "@PROJECT_SOURCE_DIR@/include"
USE_MDFILE_AS_MAINPAGE = "@PROJECT_SOURCE_DIR@/docs/api.md"
RECURSIVE = YES
FILE_PATTERNS = *.h *.cpp
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
JAVADOC_AUTOBRIEF = YES
QUIET = YES
WARNINGS = NO
GENERATE_HTML = YES
HTML_OUTPUT = .
GENERATE_TREEVIEW = YES
SOURCE_BROWSER = YES
INLINE_SOURCES = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
GENERATE_LATEX = NO
HAVE_DOT = NO
8 changes: 8 additions & 0 deletions docs/_templates/sidebar/navigation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="sidebar-tree">
{{ furo_navigation_tree }}
<ul>
<li class="toctree-l1">
<a class="reference internal" href="api/index.html">C++ API reference</a>
</li>
</ul>
</div>
6 changes: 6 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# WarpForth C++ API

This reference is generated from all WarpForth C++ headers and implementation files.
It covers the compiler pipeline, conversion passes, translations, dialect implementation, command-line tools, and handwritten internal implementation types.

Use the **Classes** and **Files** navigation to browse the API, or return to the [WarpForth guide](../index.html).
18 changes: 18 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
project = "WarpForth"
author = "WarpForth contributors"

extensions = ["myst_parser"]
source_suffix = {".md": "markdown"}
master_doc = "index"
templates_path = ["_templates"]

myst_heading_anchors = 4
myst_enable_extensions = ["colon_fence"]

html_theme = "furo"
html_title = "WarpForth"
html_theme_options = {
"source_repository": "https://github.com/tetsuo-cpp/warpforth/",
"source_branch": "canon",
"source_directory": "docs/",
}
60 changes: 60 additions & 0 deletions docs/demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# GPT-2 demo

The GPT-2 demo performs text generation with GPT-2-124M using a WarpForth-compiled attention kernel.
It loads the stock Hugging Face model, then patches `eager_attention_forward` to route scaled dot-product attention through a WarpForth kernel compiled to PTX.
PyCUDA shares PyTorch's CUDA context through `autoprimaryctx`, so device pointers pass directly between the two without copies or CPU round trips.

## Prerequisites

- WarpForth built locally with `cmake --build build`
- A Vast.ai GPU instance with a PyTorch image such as `pytorch/pytorch:2.6.0-cuda12.6-cudnn9-runtime`

## Compile the kernel locally

```bash
./build/bin/warpforthc demo/attention.forth > demo/attention.ptx
```

A precompiled `attention.ptx` is included in the `demo` directory.

## Upload the demo

```bash
scp -r demo/ root@HOST:/workspace
```

## Install remote dependencies

```bash
pip install pycuda transformers
```

## Generate text

```bash
python /workspace/demo/gpt2_generate.py \
--ptx /workspace/demo/attention.ptx \
--prompt "The meaning of life is"
```

| Flag | Default | Description |
|---|---|---|
| `--ptx` | required | Path to the compiled `attention.ptx`. |
| `--prompt` | `"The meaning of life is"` | Input text prompt. |
| `--max-tokens` | `100` | Maximum number of new tokens. |

## Limitations

- **Batch size 1:** the kernel processes one sequence at a time.
- **No KV cache:** all positions are recomputed at each step with `use_cache=False`.
- **Maximum sequence length 1024:** shared-memory allocation limits the sequence length.
- **12 kernel launches per layer:** one launch is made for each attention head.

## Files

| File | Description |
|---|---|
| `attention.forth` | Attention kernel source using f32 global and f64 shared memory. |
| `attention.ptx` | Precompiled PTX. |
| `warpforth.py` | PyCUDA wrapper for loading and launching the kernel. |
| `gpt2_generate.py` | Loads GPT-2, patches attention, and generates text. |
15 changes: 15 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# WarpForth

An MLIR-based Forth compiler for programming GPU kernels. WarpForth defines a custom MLIR dialect for Forth stack operations and lowers through a pipeline of passes to PTX assembly.

```{toctree}
:maxdepth: 1
:caption: Documentation
:hidden:
:titlesonly:

Home <self>
language
demo
ForthDialect
```
3 changes: 3 additions & 0 deletions docs/stage-dialect-doc.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
file(READ "${INPUT}" DIALECT_DOC)
string(REPLACE "\n[TOC]\n" "\n" DIALECT_DOC "${DIALECT_DOC}")
file(WRITE "${OUTPUT}" "${DIALECT_DOC}")
5 changes: 5 additions & 0 deletions include/warpforth/Conversion/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ struct WarpForthPipelineOptions
: public PassPipelineOptions<WarpForthPipelineOptions> {
WarpForthPipelineOptions();

/// NVVM target chip, such as `sm_70`.
PassOptions::Option<std::string> chip;
/// NVVM target features, such as `+ptx60`.
PassOptions::Option<std::string> features;
/// Path to the CUDA libdevice bitcode library.
PassOptions::Option<std::string> libdevicePath;
/// NVVM target optimization level.
PassOptions::Option<llvm::CodeGenOptLevel> optLevel;
/// GPU output format: LLVM bitcode, assembly, binary, or fat binary.
PassOptions::Option<gpu::CompilationTarget> compilationTarget;
};

Expand Down
5 changes: 4 additions & 1 deletion include/warpforth/Dialect/Forth/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
add_mlir_dialect(ForthOps forth)
add_mlir_doc(ForthDialect ForthDialect Dialects/ -gen-dialect-doc)

set(LLVM_TARGET_DEFINITIONS ForthOps.td)
mlir_tablegen(ForthDialect.md -gen-dialect-doc)
add_public_tablegen_target(ForthDialectDocGen)
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ dependencies = [

[dependency-groups]
dev = ["ruff", "pytest-timeout"]
docs = [
"furo",
"myst-parser",
"sphinx",
]

[tool.pytest.ini_options]
log_cli = true
Expand Down
Loading
Loading