diff --git a/README.md b/README.md new file mode 100644 index 0000000..e174374 --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# Operator Runtime Training Camp + +This repository is a training-oriented GPU operator runtime. It is intentionally +small, but its workflow mirrors production operator libraries: + +1. Define the operator contract in `ops//operator.yaml`. +2. Generate build and runtime registries from the manifest. +3. Implement a backend-specific descriptor lifecycle. +4. Expose a Python API with out-of-place, out-variant, and prepared execution. +5. Validate correctness against PyTorch and benchmark steady-state execution. + +The project is rooted directly at `/workspace`; it does not create a nested +`/workspace/camp` project directory. + +## Operators + +| Operator | NVIDIA C++ | TileLang | MetaX | +| --- | --- | --- | --- | +| `copy` | runnable | runnable when TileLang is installed | stub | +| `vector_add` | runnable | runnable when TileLang is installed | stub | +| `reduce_sum` | runnable, row-wise fp32 | runnable when TileLang is installed | stub | +| `softmax` | runnable, row-wise fp32 | runnable when TileLang is installed | stub | + +## Build + +```bash +mkdir -p build +cd build +cmake .. -DCAMP_ENABLE_NVIDIA=ON -DCAMP_ENABLE_METAX=OFF +cmake --build . -j$(nproc) +``` + +## Validate + +```bash +python tools/validate_operator_manifest.py --ops-root ops --tests-root tests +CAMP_BUILD_DIR=build pytest tests/ -v --backend nvidia +pytest tests/ -v --backend tilelang +python tests/bench_all.py --backend nvidia --profile tests/perf_profiles/local_gpu.yaml +``` + +The TileLang backend requires the `tilelang` Python package. + +## Production Mapping + +| Training concept | Production equivalent | +| --- | --- | +| `operator.yaml` | reviewed operator spec / manifest | +| descriptor lifecycle | create, workspace, execute, destroy | +| generated registry | operation table / backend registry | +| `tests/cases/.py` | correctness, layout, and API contract coverage | +| `PerformanceResult` | profiler report row with latency, bytes, flops, bandwidth | diff --git a/examples/01_copy.py b/examples/01_copy.py new file mode 100644 index 0000000..4f8c8bf --- /dev/null +++ b/examples/01_copy.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "python")) + +import torch + +from operator_runtime import copy + + +def main() -> None: + src = torch.randn((1024,), device="cuda", dtype=torch.float32) + out = copy(src, backend="nvidia") + torch.testing.assert_close(out, src) + print("copy ok") + + +if __name__ == "__main__": + main() + diff --git a/examples/02_vector_add.py b/examples/02_vector_add.py new file mode 100644 index 0000000..48c2685 --- /dev/null +++ b/examples/02_vector_add.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "python")) + +import torch + +from operator_runtime import vector_add + + +def main() -> None: + a = torch.randn((1024,), device="cuda", dtype=torch.float32) + b = torch.randn_like(a) + out = vector_add(a, b, backend="nvidia") + torch.testing.assert_close(out, a + b) + print("vector_add ok") + + +if __name__ == "__main__": + main() + diff --git a/examples/03_reduce_sum.py b/examples/03_reduce_sum.py new file mode 100644 index 0000000..2fcbc2e --- /dev/null +++ b/examples/03_reduce_sum.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "python")) + +import torch + +from operator_runtime import reduce_sum + + +def main() -> None: + src = torch.randn((32, 128), device="cuda", dtype=torch.float32) + out = reduce_sum(src, dim=1, backend="nvidia") + torch.testing.assert_close(out, torch.sum(src, dim=1), atol=1e-5, rtol=1e-5) + print("reduce_sum ok") + + +if __name__ == "__main__": + main() + diff --git a/examples/04_softmax.py b/examples/04_softmax.py new file mode 100644 index 0000000..0ce1471 --- /dev/null +++ b/examples/04_softmax.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "python")) + +import torch + +from operator_runtime import softmax + + +def main() -> None: + src = torch.randn((32, 128), device="cuda", dtype=torch.float32) + out = softmax(src, dim=1, backend="nvidia") + torch.testing.assert_close(out, torch.softmax(src, dim=1), atol=1e-5, rtol=1e-5) + print("softmax ok") + + +if __name__ == "__main__": + main() +