CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
228 lines
8.0 KiB
Markdown
228 lines
8.0 KiB
Markdown
# Adding a New GPU Architecture to StinkyTofu
|
|
|
|
This guide walks through all the steps required to add support for a new GPU architecture to the StinkyTofu framework.
|
|
|
|
> **Note:** This guide uses **Gfx1250** as a concrete example. When adding your own architecture, follow the same pattern using Gfx1250 as your template.
|
|
|
|
## Overview
|
|
|
|
Adding a new architecture involves:
|
|
1. Updating the architecture list (Step 1 and 2)
|
|
2. Creating the architecture folder with `arch.cmake`, `.def` files, and `.cpp` (Step 3)
|
|
3. Updating generated-file lists: Config.h.in, tablegen CMakeLists, RocisaArchInfo (Step 4)
|
|
4. Implementing Rocisa-related header (Step 5)
|
|
|
|
**Instruction definitions and costs** are in `.def` files; tablegen generates `*_init.inc`, `*_costs.inc`. The `defineGfxXXXInsts` and cost application are **auto-generated** from `GfxArchDefines_block.inc.in` and `arch.cmake`. You only provide the maps in `GfxXXX.cpp`.
|
|
|
|
| Architecture | Type | arch.cmake defaults | Notes |
|
|
|--------------|------|--------------------|-------|
|
|
| **Gfx1250** | RDNA4 | cycle=1, latency=1, VGPR=256, SGPR=102, AGPR=0 | Currently the only supported architecture |
|
|
|
|
## Step-by-Step Guide
|
|
|
|
### Step 1: Update Architecture List
|
|
|
|
Add the new architecture to `cmake/StinkytofuArchList.cmake`:
|
|
|
|
```cmake
|
|
set(STINKYTOFU_ALL_ARCHS
|
|
Gfx1250
|
|
GfxYourArch # <-- Add here
|
|
)
|
|
```
|
|
|
|
### Step 2: Update Config.h.in
|
|
|
|
Add a `#cmakedefine` entry in `include/stinkytofu/Config.h.in`:
|
|
|
|
```cpp
|
|
#cmakedefine STINKYTOFU_ARCH_GFX1250
|
|
#cmakedefine STINKYTOFU_ARCH_GFXYOURARCH // <-- Add here
|
|
```
|
|
|
|
### Step 3: Create Architecture Definitions
|
|
|
|
**Best approach:** Copy an existing architecture folder and modify it.
|
|
|
|
```bash
|
|
cp -r hardware/src/gfx/Gfx1250 hardware/src/gfx/GfxYourArch
|
|
cd hardware/src/gfx/GfxYourArch
|
|
mv Gfx1250.cpp GfxYourArch.cpp
|
|
mv Gfx1250Formats.def GfxYourArchFormats.def
|
|
mv Gfx1250Instructions.def GfxYourArchInstructions.def
|
|
```
|
|
|
|
#### 3a. Create `arch.cmake`
|
|
|
|
This file defines architecture metadata. **All values are required.** ARCH_MAX_AGPR may be 0 for RDNA.
|
|
|
|
```cmake
|
|
# GfxYourArch arch properties
|
|
set(ARCH_MAJOR X)
|
|
set(ARCH_MINOR Y)
|
|
set(ARCH_STEPPING Z)
|
|
set(ARCH_WAVEFRONT 64) # 64 for CDNA, 32 for RDNA
|
|
set(ARCH_DEFAULT_CYCLE 4) # 4 for CDNA, 1 for RDNA
|
|
set(ARCH_DEFAULT_LATENCY 4) # 4 for CDNA, 1 for RDNA
|
|
set(ARCH_MAX_VGPR 256) # Must be > 0
|
|
set(ARCH_MAX_SGPR 102) # Must be > 0
|
|
set(ARCH_MAX_AGPR 256) # May be 0 for RDNA
|
|
```
|
|
|
|
#### 3b. Create `GfxYourArchInstructions.def` and `GfxYourArchFormats.def`
|
|
|
|
- **Instructions**: Add `DEF_T(ClassName, "mnemonic", .format = X, .flags = {...}, .cost = {cycle, latency})` for each instruction. Tablegen generates `*_init.inc` and `*_costs.inc`.
|
|
- **Formats**: Copy from a similar arch and adjust. See [Adding Instructions](adding-instructions.md) for DEF_T syntax details.
|
|
|
|
#### 3c. Create `GfxYourArch.cpp`
|
|
|
|
The `.cpp` file **only** contains the three map functions. No instruction definitions, no cost tables--those are generated.
|
|
|
|
```cpp
|
|
#include "gfx/InstDefDSL.hpp"
|
|
|
|
namespace stinkytofu
|
|
{
|
|
void setGfxYourArchLogicalToArchMap(GpuArch& registry)
|
|
{
|
|
std::unordered_map<std::string, std::string> logicalToHwInstMap = {
|
|
{"SBranch", "s_branch"},
|
|
// ... add Logical IR name -> assembly mnemonic mappings
|
|
};
|
|
registry.setLogicalToArchMap(std::move(logicalToHwInstMap));
|
|
}
|
|
|
|
void setGfxYourArchRocisaToArchMap(GpuArch& registry)
|
|
{
|
|
std::unordered_map<std::string, std::string> rocisaToArchMap = {
|
|
// ... Rocisa type name -> mnemonic
|
|
};
|
|
registry.setRocisaToArchMap(std::move(rocisaToArchMap));
|
|
}
|
|
|
|
void setGfxYourArchConversionMap(GpuArch& registry)
|
|
{
|
|
std::unordered_map<std::string, std::string> rocisaConversionMap = {
|
|
// ... Rocisa conversion mappings
|
|
};
|
|
registry.setRocisaConversionMap(std::move(rocisaConversionMap));
|
|
}
|
|
}
|
|
```
|
|
|
|
**What is auto-generated (no manual code):**
|
|
- `defineGfxYourArchInsts()` -- from `GfxArchDefines_block.inc.in`, configured per arch
|
|
- Instruction definitions -- from `GfxYourArchInstructions.def` via tablegen
|
|
- Cost tables -- from `.cost` in DEF_T, tablegen emits `*_costs.inc`
|
|
- Wavefront size, register limits, default costs -- from `arch.cmake`
|
|
|
|
### Step 4: Update Tablegen and Generated Headers
|
|
|
|
#### 4a. Update `tools/tablegen/CMakeLists.txt`
|
|
|
|
Add your arch to the `INSTRUCTION_GEN_FILES` and `INSTRUCTION_DEF_FILES` lists:
|
|
|
|
```cmake
|
|
foreach(arch Gfx1250 GfxYourArch) # Add GfxYourArch
|
|
...
|
|
endforeach()
|
|
set(INSTRUCTION_DEF_FILES
|
|
...
|
|
"${INSTRUCTION_DEF_BASE_DIR}/GfxYourArch/GfxYourArchFormats.def"
|
|
"${INSTRUCTION_DEF_BASE_DIR}/GfxYourArch/GfxYourArchInstructions.def"
|
|
)
|
|
```
|
|
|
|
#### 4b. GfxXXX.hpp and ArchHelper
|
|
|
|
`GfxXXX.hpp` is **auto-generated** from `hardware/GfxArch.hpp.in` by CMake. No manual file needed. `ArchHelper_includes.inc` is also generated from the arch list. As long as your arch is in `StinkytofuArchList.cmake`, it will be included.
|
|
|
|
### Step 5: Create Rocisa-related Header
|
|
|
|
#### 5a. Create `src/conversion/rocisa/GfxYourArchRocisaArchInfo.hpp`
|
|
|
|
Copy from `Gfx1250RocisaArchInfo.hpp` and replace `1250` with your arch number.
|
|
|
|
#### 5b. Update `src/conversion/rocisa/RocisaArchInfo.hpp`
|
|
|
|
Add:
|
|
|
|
```cpp
|
|
#ifdef STINKYTOFU_ARCH_GFXYOURARCH
|
|
#include "GfxYourArchRocisaArchInfo.hpp"
|
|
#endif
|
|
```
|
|
|
|
### Step 6: Create Backend Pipeline and Register Anchor
|
|
|
|
Each architecture needs an optimization pipeline registered with `BackendRegistry`. Create `src/pipeline/backend/GfxYourArchBackend.cpp` (copy from `Gfx1250Backend.cpp`) containing:
|
|
|
|
1. A `buildGfxYourArchPipeline()` function that populates a `PassManager`
|
|
2. A static registrar struct that calls `BackendRegistry::setArchPipeline()`
|
|
3. An **anchor function** to prevent dead-stripping in static builds
|
|
|
|
```cpp
|
|
namespace stinkytofu {
|
|
namespace {
|
|
bool buildGfxYourArchPipeline(PassManager& pm, StinkyAsmModule& module) {
|
|
// Add passes here...
|
|
return true;
|
|
}
|
|
|
|
struct GfxYourArchRegistrar {
|
|
GfxYourArchRegistrar() {
|
|
BackendRegistry::setArchPipeline(
|
|
GFXYOURARCH_ARCH, {buildGfxYourArchPipeline, {"group0", "group1"}});
|
|
}
|
|
};
|
|
static GfxYourArchRegistrar s_gfxYourArchRegistrar;
|
|
} // namespace
|
|
|
|
// Anchor: prevents linker from dead-stripping this TU in static builds.
|
|
void anchorGfxYourArchBackend() {}
|
|
|
|
} // namespace stinkytofu
|
|
```
|
|
|
|
Then register the anchor in `BackendRegistry.cpp`:
|
|
|
|
```cpp
|
|
// In BackendRegistry::registerAllBackends():
|
|
void anchorGfxYourArchBackend(); // Add declaration
|
|
|
|
void BackendRegistry::registerAllBackends() {
|
|
anchorGfx1250Backend();
|
|
anchorGfxYourArchBackend(); // Add call
|
|
}
|
|
```
|
|
|
|
Finally, add the source file to `src/pipeline/backend/CMakeLists.txt`.
|
|
|
|
---
|
|
|
|
## Summary Checklist
|
|
|
|
- [ ] Add to `cmake/StinkytofuArchList.cmake`
|
|
- [ ] Add `#cmakedefine STINKYTOFU_ARCH_GFXYOURARCH` in `include/stinkytofu/Config.h.in`
|
|
- [ ] Create `hardware/src/gfx/GfxYourArch/`:
|
|
- [ ] `arch.cmake` -- ARCH_MAJOR, ARCH_MINOR, ARCH_STEPPING, ARCH_WAVEFRONT, ARCH_DEFAULT_CYCLE, ARCH_DEFAULT_LATENCY, ARCH_MAX_VGPR, ARCH_MAX_SGPR, ARCH_MAX_AGPR
|
|
- [ ] `GfxYourArchFormats.def`
|
|
- [ ] `GfxYourArchInstructions.def` -- DEF_T for all instructions
|
|
- [ ] `GfxYourArch.cpp` -- only `setGfxYourArchLogicalToArchMap`, `setGfxYourArchRocisaToArchMap`, `setGfxYourArchConversionMap`
|
|
- [ ] Update `tools/tablegen/CMakeLists.txt` -- add arch to INSTRUCTION_GEN_FILES and INSTRUCTION_DEF_FILES
|
|
- [ ] Create `src/conversion/rocisa/GfxYourArchRocisaArchInfo.hpp`
|
|
- [ ] Update `src/conversion/rocisa/RocisaArchInfo.hpp` -- add #include for new arch
|
|
- [ ] Create `src/pipeline/backend/GfxYourArchBackend.cpp` with pipeline, registrar, and anchor function
|
|
- [ ] Add anchor call to `BackendRegistry::registerAllBackends()` in `BackendRegistry.cpp`
|
|
- [ ] Add source to `src/pipeline/backend/CMakeLists.txt`
|
|
- [ ] Rebuild and test:
|
|
```bash
|
|
cd build && cmake .. && cmake --build . -j && ctest -j
|
|
```
|
|
|
|
**Pro tip:** Use search-and-replace on copied files:
|
|
```bash
|
|
sed -i 's/1250/YourArch/g' hardware/src/gfx/GfxYourArch/GfxYourArch.cpp
|
|
sed -i 's/12, 5, 0/X, Y, Z/g' hardware/src/gfx/GfxYourArch/arch.cmake
|
|
```
|