Compare commits

..
Author SHA1 Message Date
geohot e336f3cf8c CALL with return value is FUNCTION 2026-04-16 12:36:14 +08:00
chenyuandGitHub 10c262ced8 update tests that use UOp.size (#15753) 2026-04-15 21:58:27 -04:00
qazalandGitHub 96092d110c fix process_replay Ops.BEAM [pr] (#15752) 2026-04-16 07:35:28 +09:00
chenyuandGitHub 41421c3b48 BUFFER size is their arg (#15750) 2026-04-15 18:08:29 -04:00
sirhcmandGitHub be8005c5dc DEV: secondary targets (#15748) 2026-04-15 17:26:20 -04:00
chenyuandGitHub 507c02cecb fix symbolic contiguous_view_offset (#15749)
* fix symbolic contiguous_view_offset

* flatten
2026-04-15 16:54:38 -04:00
nimlgenandGitHub 164495678c test_graph to use uops (#15746)
* test_graph to use uops

* x

* n
2026-04-15 21:59:41 +03:00
qazalandGitHub 1f26584b2e viz/cli: cleanups from linter (#15745)
* run linter

* pmc
2026-04-16 03:36:24 +09:00
chenyuandGitHub 7cbfa1896a comment out unused arm, triton in toml (#15741)
fixed `PYTHONPATH=. uv run tinygrad/apps/llm.py`
2026-04-15 10:05:19 -04:00
sirhcmandGitHub 1c36878008 DEV: suggest alternatives (#15732) 2026-04-14 23:42:32 -04:00
George HotzandGitHub 1ae6528bb6 move schedule into schedule (#15736)
* move schedule into schedule

* callify to root

* sched docs
2026-04-15 11:03:25 +08:00
wozeparrotandGitHub 3721c60bef llama: bs 16 (#15737) 2026-04-14 19:52:03 -07:00
wozeparrotandGitHub 480ad264a4 llama: per device amax (#15735) 2026-04-14 19:01:17 -07:00
sirhcmandGitHub adc96cd724 qcom: synchronize for copyin (#15731)
fixes: #15698
2026-04-14 18:31:15 -04:00
chenyuandGitHub 3394d18066 size*itemsize -> nbytes (#15729)
and some UOp.size removal to prep for size to mixin change
2026-04-14 16:27:54 -04:00
nimlgenandGitHub e9ecc990ea amd: add r9700 devid (#15721) 2026-04-14 20:15:00 +03:00
George HotzandGitHub 2450c8cba8 rename to callify + fix mypy (#15727)
* rename to callify + fix mypy

* update test
2026-04-14 23:43:19 +08:00
chenyuandGitHub 528faa18ec update env_vars.md (#15722)
remove HCQ_VISIBLE_DEVICES, IMAGE=2 and old DEBUG=3 stuff
2026-04-14 09:13:35 -04:00
George HotzandGitHub 359b1582d6 amd: EMU DPP support (#15719)
* EMU DPP support from GPT 5.4

* cleanups

* simple

* nope

* fix
2026-04-14 14:58:41 +08:00
wozeparrotandGitHub 2b8d303f75 allreduce in precast dtype (#15689) 2026-04-13 20:24:12 -07:00
George HotzandGitHub 5683126844 llm: support for tekken tokenizer (#15720) 2026-04-14 10:52:07 +08:00
chenyuandGitHub 70883a6950 cat the stack to mixin (#15715) 2026-04-13 18:44:39 -04:00
qazalandGitHub 355e2729d3 viz: keep program UOp in data (#15714)
* refactor program uop access

* c.name
2026-04-14 07:04:16 +09:00
qazalandGitHub 905b8adc97 viz: cli and server cleanups (#15713)
* update get_profile arg[0]

* uop_to_json arg[0]

* data is standalone in cli
2026-04-14 06:42:29 +09:00
sirhcmandGitHub d83707ec29 autogen: explicit types (#15679) 2026-04-13 16:54:39 -04:00
chenyuandGitHub ac41f15fc1 cumsum to mixin (#15712)
built on top of getitem
2026-04-13 15:06:08 -04:00
nimlgenandGitHub eac481b67f mlx: fix ctypes (#15711)
* mlx: fix ctypes

* x
2026-04-13 20:43:56 +03:00
nimlgenandGitHub b370f5c5ac hcq: call free for unmap (#15710) 2026-04-13 20:30:21 +03:00
chenyuandGitHub 931d6cc62a basic getitem to mixin (#15697)
* basic getitem to mixin

* cleanup

* fix

* cleanup
2026-04-13 13:04:36 -04:00
George HotzandGitHub 7610bdc59e block multistore, it's not supported (#15708) 2026-04-13 20:57:59 +08:00
geohot 84d64b5835 hotfix: abstractions4 works in mock except asm 2026-04-13 20:57:00 +08:00
George HotzandGitHub 16f50a40a5 remove REMU from tree (#15706)
* no more compare emulators

* remove remu from tree
2026-04-13 20:43:08 +08:00
qazalandGitHub ac027055ef viz: no global state (#15705)
* start viz data

* get_full_rewrites also moves

* update ref_map

* work

* update consumers

* cleaner cli

* linter

* cleanup tests

* back

* better

* sqtt tests
2026-04-13 21:35:20 +09:00
George HotzandGitHub 4c1fb18a09 Revert "Revert "Tests for GatedDeltaNetBlock + fix multi after assign issue (…" (#15703)
This reverts commit 0cec42db71.
2026-04-13 19:09:38 +08:00
George HotzandGitHub 0cec42db71 Revert "Tests for GatedDeltaNetBlock + fix multi after assign issue (#15700)" (#15702)
This reverts commit 6f5d756282.
2026-04-13 19:06:44 +08:00
George HotzandGitHub 6f5d756282 Tests for GatedDeltaNetBlock + fix multi after assign issue (#15700)
* broken after/assign test

* test for GatedDeltaNet

* better comments

* fix issue 1 with multi kernel

* fix 2

* fix

* linter

* public api + cleanup
2026-04-13 18:43:23 +08:00
160 changed files with 56655 additions and 71566 deletions
+1 -4
View File
@@ -225,14 +225,12 @@ runs:
if: inputs.amd == 'true' && runner.os == 'Linux'
shell: bash
run: |
cargo build --release --manifest-path ./extra/remu/Cargo.toml
sudo ln -sf ${{ github.workspace }}/extra/remu/target/release/libremu.so /usr/local/lib/libremu.so
sudo tee --append /etc/ld.so.conf.d/rocm.conf <<'EOF'
/opt/rocm/lib
/opt/rocm/lib64
EOF
sudo ldconfig
- name: Setup AMD comgr+remu (macOS)
- name: Setup AMD comgr (macOS)
if: inputs.amd == 'true' && runner.os == 'macOS'
shell: bash
run: |
@@ -240,7 +238,6 @@ runs:
curl -s -H "Authorization: token $GH_TOKEN" curl -s https://api.github.com/repos/tinygrad/amdcomgr_dylib/releases/latest | \
jq -r '.assets[] | select(.name == "libamd_comgr.dylib").browser_download_url' | \
sudo xargs curl -fL -o /usr/local/lib/libamd_comgr.dylib
cargo build --release --manifest-path ./extra/remu/Cargo.toml
# **** gpuocelot ****
-4
View File
@@ -71,10 +71,6 @@ jobs:
uv venv /tmp/tinygrad_pytest_ci
source /tmp/tinygrad_pytest_ci/bin/activate
uv pip install .[testing]
- name: setup other stuff
run: |
mkdir -p extra/remu/target/release/
ln -s ~/tinygrad/extra/remu/target/release/libremu.so extra/remu/target/release/libremu.so
- name: setup staging db
run: |
echo "CACHEDB=/tmp/pytest-db-ci.db" >> $GITHUB_ENV
-1
View File
@@ -644,7 +644,6 @@ jobs:
timeout-minutes: 20
env:
DEV: AMD
PYTHON_REMU: 1
MOCKGPU: 1
steps:
- name: Checkout Code
+1 -1
View File
@@ -38,7 +38,7 @@ optim.schedule_step() # this will step the optimizer without running realize
# The weight Tensors have been assigned to, but not yet realized. Everything is still lazy at this point
# l1.uop and l2.uop define a computation graph
from tinygrad.engine.schedule import ExecItem
from tinygrad.schedule import ExecItem
schedule: List[ExecItem] = Tensor.schedule(l1, l2)
print(f"The schedule contains {len(schedule)} items.")
+2 -1
View File
@@ -16,12 +16,13 @@ def eval_harness(name, tensor, fxn, check=None):
print(f"computed in {GlobalCounters.time_sum_s*1000:.2f} ms, {(a.nbytes()/1e9)/GlobalCounters.time_sum_s:.2f} GB/s")
return out
SZ = 32*1024 if getenv("MOCKGPU") else 1024*1024*1024
SZ = 256*1024 if getenv("MOCKGPU") else 1024*1024*1024
def example_2_hip(a:Tensor, correct):
GLOBALS = 1024
THREADS = 256
def hip_reduce_sum(out:UOp, buf:UOp) -> UOp:
assert SZ % (GLOBALS * THREADS) == 0
CHUNK = SZ // (GLOBALS * THREADS)
# NOTE: tinygrad doesn't populate HIP hidden kernargs, so blockDim.x/gridDim.x read as 0.
# We hardcode block/grid sizes as constexpr to avoid any dependency on those builtins.
+2 -2
View File
@@ -17,9 +17,9 @@ The `UOp` graph specifies the compute in terms of low level tinygrad ops. Not al
## Scheduling
The [scheduler](https://github.com/tinygrad/tinygrad/tree/master/tinygrad/engine/schedule.py) converts the graph of UOps into a list of `ExecItem`. One `ExecItem` is one kernel on the GPU, and the scheduler is responsible for breaking the large compute graph into subgraphs that can fit in a kernel. `ast` specifies what compute to run, and `bufs` specifies what buffers to run it on.
The [scheduler](https://github.com/tinygrad/tinygrad/tree/master/tinygrad/schedule/__init__.py) converts the graph of UOps into a list of `ExecItem`. One `ExecItem` is one kernel on the GPU, and the scheduler is responsible for breaking the large compute graph into subgraphs that can fit in a kernel. `ast` specifies what compute to run, and `bufs` specifies what buffers to run it on.
::: tinygrad.engine.schedule.ExecItem
::: tinygrad.schedule.ExecItem
## Lowering
+3 -4
View File
@@ -34,9 +34,8 @@ DEBUG | [1-7] | enable debugging output (operations, timings,
DEV | [AMD, NV, ...] | enable a specific backend, see [below](#dev-variable)
BEAM | [#] | number of beams in kernel beam search
DEFAULT_FLOAT | [HALF, ...]| specify the default float dtype (FLOAT32, HALF, BFLOAT16, FLOAT64, ...), default to FLOAT32
IMAGE | [1-2] | enable 2d specific optimizations
IMAGE | [1] | enable 2d specific optimizations
FLOAT16 | [1] | use float16 for images instead of float32
HCQ_VISIBLE_DEVICES | [list[int]]| restricts the HCQ devices that are available. The format is a comma-separated list of identifiers (indexing starts with 0).
JIT | [0-2] | 0=disabled, 1=[jit enabled](quickstart.md#jit) (default), 2=jit enabled, but graphs are disabled
VIZ | [1] | 0=disabled, 1=[viz enabled](https://github.com/tinygrad/tinygrad/tree/master/tinygrad/viz)
ALLOW_TF32 | [1] | enable TensorFloat-32 tensor cores on Ampere or newer GPUs.
@@ -65,8 +64,8 @@ Variable | Value | Description
---|---|---
DEBUG | >= 1 | Enables debugging and lists devices being used
DEBUG | >= 2 | Provides performance metrics for operations, including timing, memory usage, bandwidth for each kernel execution
DEBUG | >= 3 | Outputs buffers used for each kernel (shape, dtype and strides) and the applied optimizations at a kernel level
DEBUG | >= 3 | Outputs the applied optimizations at a kernel level
DEBUG | >= 4 | Outputs the generated kernel code
DEBUG | >= 5 | Displays the intermediate representation of the computation UOps (AST)
DEBUG | >= 5 | Displays the intermediate representation of the computation UOps
DEBUG | >= 6 | Displays the intermediate representation of the computation UOps in a linearized manner, detailing the operation sequence
DEBUG | >= 7 | Outputs the assembly code generated for the target hardware
+1 -1
View File
@@ -445,7 +445,7 @@ After you are done speaking, output [EOS]. You are not Chad.
print(f"using LLaMA{LLAMA_SUFFIX}-{args.size} model")
device = tuple(f"{Device.DEFAULT}:{i}" for i in range(args.shard)) if args.shard > 1 else Device.DEFAULT
llama = LLaMa.build(MODEL_PATH, TOKENIZER_PATH, model_gen=args.gen, model_size=args.size, quantize=args.quantize, device=device)
param_bytes = sum(x.uop.size * x.dtype.itemsize for x in get_parameters(llama.model))
param_bytes = sum(x.nbytes() for x in get_parameters(llama.model))
outputted = pre_prompt if chatbot else args.prompt
start_pos, toks = 0, [llama.tokenizer.bos_id()] + llama.tokenizer.encode(outputted)
+1 -1
View File
@@ -324,7 +324,7 @@ if __name__ == "__main__":
device = tuple(f"{Device.DEFAULT}:{i}" for i in range(args.shard)) if args.shard > 1 else Device.DEFAULT
model = build_transformer(args.model, model_size=args.size, quantize=args.quantize, device=device)
param_bytes = sum(x.uop.size * x.dtype.itemsize for x in get_parameters(model))
param_bytes = sum(x.nbytes() for x in get_parameters(model))
if not args.no_api and not args.benchmark:
from bottle import Bottle, request, response, HTTPResponse, abort, static_file
+1 -1
View File
@@ -5,7 +5,7 @@ from tinygrad import Device, nn, Tensor, dtypes
from train_gpt2 import GPT, GPTConfig
from tinygrad.helpers import DEV, dedup, flatten, getenv, GlobalCounters, to_function_name
from tinygrad.engine.realize import get_kernel
from tinygrad.engine.memory import memory_planner
from tinygrad.schedule.memory import memory_planner
from tinygrad.uop.ops import Ops
DEV.value = "CPU"
+17 -1
View File
@@ -23,8 +23,20 @@ FP8_DTYPE = dtypes.fp8e4m3
FP8_GRAD_DTYPE = dtypes.fp8e5m2
FP8_MAX = 448.0
# per-device abs max without allreduce (matches TE delayed scaling behavior)
@functools.cache
def _local_abs_max_fxn(x_p, device):
x = Tensor(x_p, device=device)
inner = Tensor(x.uop.src[0]) if x.uop.op is Ops.MULTI else x
return (inner.abs().max(),)
def _local_abs_max(x:Tensor) -> Tensor:
param = x.as_param(0)
fxn = _local_abs_max_fxn(param.uop, x.device)
return Tensor(fxn[0].uop.call(x.uop).gettuple(0))
def quantize_fp8(x:Tensor, amax_state:Tensor|None=None):
new_amax = x.abs().max().detach()
new_amax = (_local_abs_max(x) if isinstance(x.device, tuple) else x.abs().max()).detach()
scale = FP8_MAX / ((amax_state if amax_state is not None else new_amax) + 1e-8)
x_scaled = x * scale
x_clamped = x_scaled + (x_scaled.detach().clamp(-FP8_MAX, FP8_MAX) - x_scaled.detach()) # STE
@@ -193,6 +205,10 @@ class FlatTransformer:
self.tok_embeddings.weight.shard_(device, axis=0).realize()
self.output.shard_(device, axis=1).realize()
self.freqs_cis.shard_(device, axis=None).realize()
if FP8:
for name in self._fp8_amax:
for i in range(len(self._fp8_amax[name])):
self._fp8_amax[name][i] = self._fp8_amax[name][i].to(device).contiguous().requires_grad_(False)
def __call__(self, tokens:Tensor):
h = self.tok_embeddings(tokens)
@@ -14,9 +14,10 @@ export ASM_GEMM=${ASM_GEMM:-1}
export WQKV=${WQKV:-1}
export MASTER_WEIGHTS=${MASTER_WEIGHTS:-1}
export FP8=${FP8:-1}
export ALLREDUCE_CAST=${ALLREDUCE_CAST:-1}
export DEFAULT_FLOAT="bfloat16" OPTIM_DTYPE="bfloat16"
export DP=${DP:-8} MP=${MP:-1} BS=${BS:-8} EVAL_BS=${EVAL_BS:-8} GRADIENT_ACC_STEPS=${GRADIENT_ACC_STEPS:-4}
export DP=${DP:-8} MP=${MP:-1} BS=${BS:-16} EVAL_BS=${EVAL_BS:-16} GRADIENT_ACC_STEPS=${GRADIENT_ACC_STEPS:-2}
export GBS=$((BS * GRADIENT_ACC_STEPS))
export MODEL="llama3"
@@ -14,9 +14,10 @@ export ASM_GEMM=${ASM_GEMM:-1}
export WQKV=${WQKV:-1}
export MASTER_WEIGHTS=${MASTER_WEIGHTS:-1}
export FP8=${FP8:-1}
export ALLREDUCE_CAST=${ALLREDUCE_CAST:-1}
export DEFAULT_FLOAT="bfloat16" OPTIM_DTYPE="bfloat16"
export DP=${DP:-8} MP=${MP:-1} BS=${BS:-8} EVAL_BS=${EVAL_BS:-8} GRADIENT_ACC_STEPS=${GRADIENT_ACC_STEPS:-4}
export DP=${DP:-8} MP=${MP:-1} BS=${BS:-16} EVAL_BS=${EVAL_BS:-16} GRADIENT_ACC_STEPS=${GRADIENT_ACC_STEPS:-2}
export GBS=$((BS * GRADIENT_ACC_STEPS))
export MODEL="llama3"
@@ -15,9 +15,10 @@ export ASM_GEMM=1
export WQKV=1
export MASTER_WEIGHTS=1
export FP8=1
export ALLREDUCE_CAST=1
export DEFAULT_FLOAT="bfloat16" OPTIM_DTYPE="bfloat16"
export DP=8 MP=1 BS=8 EVAL_BS=8 GRADIENT_ACC_STEPS=4
export DP=8 MP=1 BS=16 EVAL_BS=16 GRADIENT_ACC_STEPS=2
export GBS=$((BS * GRADIENT_ACC_STEPS))
export MODEL="llama3"
+1 -1
View File
@@ -66,7 +66,7 @@ if __name__ == "__main__":
model_path = Path(args.weights) if args.weights else download_weights(model_info["total_num_weights"])
transformer = load_model(model_path, model_info["model_params"])
tokenizer = AutoTokenizer.from_pretrained(model_info["tokenizer"])
param_bytes = sum(x.uop.size * x.dtype.itemsize for x in get_parameters(transformer))
param_bytes = sum(x.nbytes() for x in get_parameters(transformer))
outputted = args.prompt
start_pos, toks = 0, tokenizer(outputted)["input_ids"]
+3 -3
View File
@@ -44,9 +44,9 @@ nc = np.random.randn(N, N).astype(np.float32)
ns = nb.reshape(-1, 32).sum(axis=0)
a = MallocAllocator.alloc(na.size * np.dtype(np.float32).itemsize)
b = MallocAllocator.alloc(nb.size * np.dtype(np.float32).itemsize)
c = MallocAllocator.alloc(nc.size * np.dtype(np.float32).itemsize)
a = MallocAllocator.alloc(na.nbytes)
b = MallocAllocator.alloc(nb.nbytes)
c = MallocAllocator.alloc(nc.nbytes)
MallocAllocator._copyin(b, flat_mv(nb.data))
MallocAllocator._copyin(c, flat_mv(nc.data))
-66
View File
@@ -1,66 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "float-cmp"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
dependencies = [
"num-traits",
]
[[package]]
name = "half"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872"
dependencies = [
"cfg-if",
"crunchy",
"num-traits",
]
[[package]]
name = "libm"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "remu"
version = "0.1.0"
dependencies = [
"float-cmp",
"half",
"num-traits",
]
-15
View File
@@ -1,15 +0,0 @@
[package]
name = "remu"
version = "0.1.0"
edition = "2021"
rust-version = "1.80.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
half = { version = "2.3.1", features = ["num-traits"] }
num-traits = "0.2.17"
[dev-dependencies]
float-cmp = "0.9.0"
-80
View File
@@ -1,80 +0,0 @@
## Intro
Remu is an RDNA3 emulator built to test correctness of RDNA3 code. It is used in [tinygrad's AMD CI](https://github.com/tinygrad/tinygrad).
Most of the common instructions are implemented, but some formats like IMG are not supported.
Remu is only for testing correctness of program output, it is not a cycle accurate simulator.
## Build Locally
Remu is written in Rust. Make sure you have [Cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html).
To build the project, run:
```bash
cargo build --release --manifest-path ./extra/remu/Cargo.toml
```
This will produce a binary in the `extra/remu/target/release` directory.
## Usage with tinygrad
The latest binaries are released in https://github.com/Qazalin/remu/releases. Alternatively, you can [build locally](#build-locally).
Tinygrad does not yet output RDNA3 kernels directly. You can either install comgr or use `DEV=AMD:LLVM` (default) if you have [LLVM@19](https://github.com/tinygrad/tinygrad/blob/e2ed673c946c8f1774d816c75e52a994c2dd8a88/.github/actions/setup-tinygrad/action.yml#L208).
`PYTHONPATH="." MOCKGPU=1 DEV=AMD python test/test_tiny.py TestTiny.test_plus` runs an emulated RDNA3 kernel with Remu.
Add `DEBUG=6` to see Remu's logs.
### DEBUG output
Remu runs each thread one at a time in a nested for loop, see lib.rs. The DEBUG output prints information about the current thread.
The DEBUG output has 3 sections:
```
<------------ 1 ----------> <--- 2 ---> <--------------------------------------- 3 ------------------------------------------>
[0 0 0 ] [0 0 0 ] 0 F4080100 SMEM { op: 2, sdata: 4, sbase: 0, offset: 0, soffset: 124, glc: false, dlc: false }
```
#### Section 1: Grid info
`[gid.x, gid.y, gid.z], [lid.x, lid.y, lid.z]` of the current thread.
#### Section 2: Wave info
`<lane> <instruction hex>`
RDNA3 divides threads into chunks of 32. Each thread is assigned to a "lane" from 0-31.
In Remu, even though all threads run one at a time, each 32 thread chunk (a wave) shares state like SGPR, VGPR, LDS, EXEC mask, etc.
Remu can simulate up to one wave sync instruction.
For more details, see work_group.rs.
Section 2 can have a green or gray color.
Green = The thread is actively executing the instruction.
Gray = The thread has been "turned off" by the EXEC mask, it skips execution of some instructions. (refer to "EXECute Mask" on [page 23](https://www.amd.com/content/dam/amd/en/documents/radeon-tech-docs/instruction-set-architectures/rdna3-shader-instruction-set-architecture-feb-2023_0.pdf#page=23) of ISA docs for more details.)
To see the colors in action, try running `DEBUG=6 PYTHONPATH="." MOCKGPU=1 DEV=AMD python test/test_ops.py TestOps.test_arange_big`. See how only lane 0 writes to global memory:
```
[255 0 0 ] [0 0 0 ] 0 DC6A0000 FLAT { op: 26, offset: 0, dlc: false, glc: false, slc: false, seg: 2, addr: 8, data: 0, saddr: 0, sve: false, vdst: 0 }
[255 0 0 ] [1 0 0 ] 1 DC6A0000
[255 0 0 ] [2 0 0 ] 2 DC6A0000
[255 0 0 ] [3 0 0 ] 3 DC6A0000
[255 0 0 ] [3 0 0 ] 4 DC6A0000
```
#### Section 3: Decoded Instruction
This prints the instruction type and all the parsed bitfields.
Remu output vs llvm-objdump:
```
s_load_b64 s[0:1], s[0:1], 0x10 // 00000000160C: F4040000 F8000010
SMEM { op: 1, sdata: 0, sbase: 0, offset: 16, soffset: 124, glc: false, dlc: false }
```
-1
View File
@@ -1 +0,0 @@
max_width = 150
-162
View File
@@ -1,162 +0,0 @@
use half::f16;
use num_traits::{float::FloatCore, PrimInt, Unsigned, clamp};
pub fn bits<T>(word: T, hi: usize, lo: usize) -> T where T: PrimInt + Unsigned {
assert!(hi >= lo);
let width = hi - lo + 1;
(word >> lo) & ((T::one() << width) - T::one())
}
pub fn nth(val: u32, pos: usize) -> u32 {
(val >> (31 - pos as u32)) & 1
}
pub fn f16_lo(val: u32) -> f16 {
f16::from_bits((val & 0xffff) as u16)
}
pub fn f16_hi(val: u32) -> f16 {
f16::from_bits(((val >> 16) & 0xffff) as u16)
}
pub fn sign_ext(num: u64, bits: usize) -> i64 {
let mut value = num;
let is_negative = (value >> (bits - 1)) & 1 != 0;
if is_negative {
value |= !0 << bits;
}
value as i64
}
pub trait IEEEClass<T> {
fn exponent(&self) -> T;
}
impl IEEEClass<u32> for f32 {
fn exponent(&self) -> u32 {
(self.to_bits() & 0b01111111100000000000000000000000) >> 23
}
}
impl IEEEClass<u16> for f16 {
fn exponent(&self) -> u16 {
(self.to_bits() & 0b0111110000000000) >> 10
}
}
impl IEEEClass<u64> for f64 {
fn exponent(&self) -> u64 {
(self.to_bits() & 0b0111111111110000000000000000000000000000000000000000000000000000) >> 52
}
}
pub trait VOPModifier<T> {
fn negate(&self, pos: usize, modifier: usize) -> T;
fn absolute(&self, pos: usize, modifier: usize) -> T;
fn clmp(&self, cm: bool) -> T;
}
impl<T> VOPModifier<T> for T
where
T: FloatCore,
{
fn negate(&self, pos: usize, modifier: usize) -> T {
match (modifier >> pos) & 1 {
1 => -*self,
_ => *self,
}
}
fn absolute(&self, pos: usize, modifier: usize) -> T {
match (modifier >> pos) & 1 {
1 => self.abs(),
_ => *self,
}
}
fn clmp(&self, cm:bool) -> T {
if !cm { return *self }
let r = clamp(*self, T::zero(), T::one());
if r == T::zero() { T::zero() } else { r }
}
}
pub fn extract_mantissa(x: f64) -> f64 {
if x.is_infinite() || x.is_nan() {
return x;
}
let bits = x.to_bits();
let mantissa_mask: u64 = 0x000FFFFFFFFFFFFF;
let bias: u64 = 1023;
let normalized_mantissa_bits = (bits & mantissa_mask) | ((bias - 1) << 52);
return f64::from_bits(normalized_mantissa_bits);
}
pub fn ldexp(x: f64, exp: i32) -> f64 {
x * 2f64.powi(exp)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_extract_mantissa() {
assert_eq!(extract_mantissa(2.0f64), 0.5);
}
#[test]
fn test_normal_exponent() {
assert_eq!(2.5f32.exponent(), 128);
assert_eq!(1.17549435e-38f32.exponent(), 1);
assert_eq!(f32::INFINITY.exponent(), 255);
assert_eq!(f32::NEG_INFINITY.exponent(), 255);
}
#[test]
fn test_denormal_exponent() {
assert_eq!(1.0e-40f32.exponent(), 0);
assert_eq!(1.0e-42f32.exponent(), 0);
assert_eq!(1.0e-44f32.exponent(), 0);
assert_eq!((1.17549435e-38f32 / 2.0).exponent(), 0);
}
#[test]
fn test_normal_exponent_f16() {
assert_eq!(f16::from_f32(3.14f32).exponent(), 16);
assert_eq!(f16::NEG_INFINITY.exponent(), 31);
assert_eq!(f16::INFINITY.exponent(), 31);
}
#[test]
fn test_neg() {
assert_eq!(0.3_f32.negate(0, 0b001), -0.3_f32);
assert_eq!(0.3_f32.negate(1, 0b010), -0.3_f32);
assert_eq!(0.3_f32.negate(2, 0b100), -0.3_f32);
assert_eq!(0.3_f32.negate(0, 0b110), 0.3_f32);
assert_eq!(0.3_f32.negate(1, 0b010), -0.3_f32);
assert_eq!(0.0_f32.negate(0, 0b001).to_bits(), (-0.0f32).to_bits());
assert_eq!((-0.0_f32).negate(0, 0b001).to_bits(), 0);
}
#[test]
fn test_sign_ext() {
assert_eq!(sign_ext(0b000000000000000101000, 21), 40);
assert_eq!(sign_ext(0b111111111111111011000, 21), -40);
assert_eq!(sign_ext(0b000000000000000000000, 21), 0);
assert_eq!(sign_ext(0b111111111111111111111, 21), -1);
assert_eq!(sign_ext(0b111000000000000000000, 21), -262144);
assert_eq!(sign_ext(0b000111111111111111111, 21), 262143);
assert_eq!(sign_ext(7608, 13), -584);
}
}
use std::sync::LazyLock;
pub static DEBUG: LazyLock<bool> = LazyLock::new(|| std::env::var("DEBUG").map(|v| v.parse::<usize>().unwrap_or(0) >= 6).unwrap_or(false));
pub fn colored(st:&str, color:&str) -> String {
let ansi_code = match color {
"green" => format!("\x1b[{};2;39;176;139m", 38),
"gray" => format!("\x1b[{};2;169;169;169m", 38),
_ => format!("\x1b[{};2;255;255;255m", 38),
};
format!("{}{}{}", ansi_code, st, "\x1b[0m")
}
#[macro_export]
macro_rules! todo_instr {
($x:expr) => {{
println!("{:08X}", $x);
Err(1)
}};
}
-77
View File
@@ -1,77 +0,0 @@
use crate::state::StateSnapshot;
use crate::work_group::{WaveContext, WorkGroup};
use std::os::raw::c_char;
use std::slice;
mod helpers;
mod rdna3;
mod state;
mod thread;
mod work_group;
#[no_mangle]
pub extern "C" fn run_asm(lib: *const c_char, lib_sz: u32, gx: u32, gy: u32, gz: u32, lx: u32, ly: u32, lz: u32, args_ptr: *const u64) -> i32 {
if lib.is_null() || (lib_sz % 4) != 0 {
panic!("Pointer is null or length is not properly aligned to 4 bytes");
}
let kernel = unsafe { slice::from_raw_parts(lib as *const u32, (lib_sz / 4) as usize).to_vec() };
let dispatch_dim = match (gy != 1, gz != 1) {
(true, true) => 3,
(true, false) => 2,
_ => 1,
};
for gx in 0..gx {
for gy in 0..gy {
for gz in 0..gz {
let mut wg = WorkGroup::new(dispatch_dim, [gx, gy, gz], [lx, ly, lz], &kernel, args_ptr);
if let Err(err) = wg.exec_waves() {
return err;
}
}
}
}
0
}
// FFI functions for single-stepping comparison tests
#[no_mangle]
pub extern "C" fn wave_create(lib: *const c_char, lib_sz: u32, n_lanes: u32) -> *mut WaveContext {
if lib.is_null() || (lib_sz % 4) != 0 { return std::ptr::null_mut(); }
let kernel = unsafe { slice::from_raw_parts(lib as *const u32, (lib_sz / 4) as usize).to_vec() };
Box::into_raw(Box::new(WaveContext::new(kernel, n_lanes as usize)))
}
#[no_mangle]
pub extern "C" fn wave_step(ctx: *mut WaveContext) -> i32 {
if ctx.is_null() { return -99; }
unsafe { (*ctx).step() }
}
#[no_mangle]
pub extern "C" fn wave_get_snapshot(ctx: *const WaveContext, out: *mut StateSnapshot) {
if ctx.is_null() || out.is_null() { return; }
unsafe { *out = (*ctx).get_snapshot(); }
}
#[no_mangle]
pub extern "C" fn wave_set_sgpr(ctx: *mut WaveContext, idx: u32, val: u32) {
if ctx.is_null() || idx >= 128 { return; }
unsafe { (*ctx).scalar_reg[idx as usize] = val; }
}
#[no_mangle]
pub extern "C" fn wave_set_vgpr(ctx: *mut WaveContext, lane: u32, idx: u32, val: u32) {
if ctx.is_null() || lane >= 32 || idx >= 256 { return; }
unsafe { (*ctx).vec_reg.get_lane_mut(lane as usize)[idx as usize] = val; }
}
#[no_mangle]
pub extern "C" fn wave_init_lds(ctx: *mut WaveContext, size: u32) {
if ctx.is_null() { return; }
unsafe { (*ctx).lds.data.resize(size as usize, 0); }
}
#[no_mangle]
pub extern "C" fn wave_free(ctx: *mut WaveContext) {
if !ctx.is_null() { unsafe { drop(Box::from_raw(ctx)); } }
}
-223
View File
@@ -1,223 +0,0 @@
use crate::helpers::{bits, sign_ext};
#[derive(Debug, PartialEq)]
pub enum Instruction {
SOP2 { op: u8, ssrc0: u8, ssrc1: u8, sdst: u8 },
SOP1 { op: u8, ssrc0: u8, sdst: u8 },
SOPK { op: u8, simm16: i16, sdst: u8 },
SOPP { op: u8, simm16: i16 },
SOPC { op: u8, ssrc0: u8, ssrc1: u8 },
SMEM { op: u8, sdata: u8, sbase: u8, offset: i32, soffset: u8, glc: bool, dlc: bool },
VOP1 { op: u8, vdst: u8, src: u16 },
VOP2 { op: u8, vdst: u8, vsrc: u8, src: u16 },
VOPC { op: u8, vsrc: u8, src: u16 },
VOP3 { op: u32, opsel: u8, cm: bool, abs: u8, vdst: u8, neg: u8, omod: u8, src2: u16, src1: u16, src0: u16 },
VOP3SD { op: u32, cm: bool, sdst: u8, vdst: u8, neg: u8, omod: u8, src2: u16, src1: u16, src0: u16 },
VOP3P { op: u8, vdst: u8, neg_hi: u8, opsel: u8, opsel_hi: u8, opsel_hi2: bool, cm: bool, src2: u16, src1: u16, src0: u16, neg: u8 },
VOPD { opx: u8, opy: u8, vdstx: u8, vdsty: u8, vsrcx1: u8, vsrcy1: u8, srcx0: u16, srcy0: u16 },
DS { op: u8, gds: bool, offset1: u8, offset0: u8, vdst: u8, data1: u8, data0: u8, addr: u8 },
FLAT { op: u8, offset: u16, dlc: bool, glc: bool, slc: bool, seg: u8, addr: u8, data: u8, saddr: u8, sve: bool, vdst: u8 }
}
const VOP3SD_OPS: [u32; 7] = [764, 765, 766, 767, 768, 769, 770];
pub fn decode(word:u32, word1:Option<&u32>) -> Instruction {
match bits(word, 31, 30) {
0b11 => {
let word = (*word1.unwrap() as u64) << 32 | (word as u64);
match bits(word, 29, 26) {
0b1101 => {
let sbase = (bits(word, 5, 0) as u8) << 1;
let sdata = bits(word, 12, 6) as u8;
let dlc = bits(word, 13, 13) != 0;
let glc = bits(word, 14, 14) != 0;
let op = bits(word, 25, 18) as u8;
let offset = sign_ext(bits(word, 52, 32), 21) as i32;
let soffset = bits(word, 63, 57) as u8;
Instruction::SMEM { sbase, sdata, dlc, glc, op, offset, soffset }
}
0b0101 => {
let op = bits(word, 25, 16) as u32;
let vdst = bits(word, 7, 0) as u8;
let cm = bits(word, 15, 15) != 0;
let src0 = bits(word, 40, 32) as u16;
let src1 = bits(word, 49, 41) as u16;
let src2 = bits(word, 58, 50) as u16;
let omod = bits(word, 60, 59) as u8;
let neg = bits(word, 63, 61) as u8;
if VOP3SD_OPS.contains(&op) {
let sdst = bits(word, 14, 8) as u8;
Instruction::VOP3SD { op, vdst, sdst, cm, src0, src1, src2, omod, neg }
} else {
let abs = bits(word, 10, 8) as u8;
let opsel = bits(word, 14, 11) as u8;
Instruction::VOP3 { opsel, cm, abs, vdst, neg, omod, src2, src1, src0, op }
}
}
0b0011 => {
let op = bits(word, 22, 16) as u8;
let vdst = bits(word, 7, 0) as u8;
let neg_hi = bits(word, 10, 8) as u8;
let opsel = bits(word, 13, 11) as u8;
let opsel_hi2 = bits(word, 14, 14) != 0;
let cm = bits(word, 15, 15) != 0;
let src0 = bits(word, 40, 32) as u16;
let src1 = bits(word, 49, 41) as u16;
let src2 = bits(word, 58, 50) as u16;
let opsel_hi = bits(word, 60, 59) as u8;
let neg = bits(word, 63, 61) as u8;
Instruction::VOP3P { op, vdst, neg_hi, opsel, opsel_hi, opsel_hi2, cm, src0, src1, src2, neg }
}
0b0110 => {
let offset0 = bits(word, 7, 0) as u8;
let offset1 = bits(word, 15, 8) as u8;
let gds = bits(word, 17, 17) != 0;
let op = bits(word, 25, 18) as u8;
let addr = bits(word, 39, 32) as u8;
let data0 = bits(word, 47, 40) as u8;
let data1 = bits(word, 55, 48) as u8;
let vdst = bits(word, 63, 56) as u8;
Instruction::DS { op, gds, offset1, offset0, vdst, data1, data0, addr }
}
0b0111 => {
let offset = bits(word, 12, 0) as u16;
let dlc = bits(word, 13, 13) != 0;
let glc = bits(word, 14, 14) != 0;
let slc = bits(word, 15, 15) != 0;
let seg = bits(word, 17, 16) as u8;
let op = bits(word, 24, 18) as u8;
let addr = bits(word, 39, 32) as u8;
let data = bits(word, 47, 40) as u8;
let saddr = bits(word, 54, 48) as u8;
let sve = bits(word, 55, 55) != 0;
let vdst = bits(word, 63, 56) as u8;
Instruction::FLAT { offset, dlc, glc, slc, seg, op, addr, data, saddr, sve, vdst }
},
0b0010 => {
let srcx0 = bits(word, 8, 0) as u16;
let vsrcx1 = bits(word, 16, 9) as u8;
let opy = bits(word, 21, 17) as u8;
let opx = bits(word, 25, 22) as u8;
let srcy0 = bits(word, 40, 32) as u16;
let vsrcy1 = bits(word, 48, 41) as u8;
let vdsty = bits(word, 55, 49) as u8;
let vdstx = bits(word, 63, 56) as u8;
Instruction::VOPD { opx, opy, vdstx, vdsty, vsrcx1, vsrcy1, srcx0, srcy0 }
}
_ => todo!(),
}
}
0b10 => {
let ssrc0 = bits(word, 7, 0) as u8;
let ssrc1 = bits(word, 15, 8) as u8;
let simm16 = word as i16;
let sdst = bits(word, 22, 16) as u8;
match bits(word, 29, 23) {
0b1111101 => Instruction::SOP1 { ssrc0, sdst, op: bits(word, 15, 8) as u8 },
0b1111110 => Instruction::SOPC { ssrc0, ssrc1, op: bits(word, 22, 16) as u8 },
0b1111111 => Instruction::SOPP { simm16, op: bits(word, 22, 16) as u8 },
_ => {
match bits(word, 29, 28) {
0b11 => Instruction::SOPK { simm16, sdst, op: bits(word, 27, 23) as u8 },
_ => Instruction::SOP2 { ssrc0, ssrc1, sdst, op: bits(word, 29, 23) as u8 }
}
}
}
}
_ => {
let vdst = bits(word, 24, 17) as u8;
let src = bits(word, 8, 0) as u16;
let vsrc = bits(word, 16, 9) as u8;
match bits(word, 30, 25) {
0b111110 => Instruction::VOPC { vsrc, src, op: bits(word, 24, 17) as u8 },
0b111111 => Instruction::VOP1 { vdst, src, op: vsrc },
_ => Instruction::VOP2 { vdst, vsrc, src, op: bits(word, 30, 25) as u8 },
}
},
}
}
#[cfg(test)]
mod test_rdna3 {
use super::*;
use std::process::{Stdio, Command};
use std::io::{Result, Write};
const LLVM_ARGS: &[&str; 3] = &["--arch=amdgcn", "--mcpu=gfx1100", "--triple=amdgcn-amd-amdhsa"];
const OFFSET_PRG: usize = 16;
const NULL: u8 = 124;
fn llvm_assemble(asm: &str) -> Result<Vec<u8>> {
let mut proc = Command::new("llvm-mc").args(LLVM_ARGS).args(["-filetype=obj", "-o", "-"]).stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
proc.stdin.as_mut().unwrap().write_all(asm.as_bytes())?;
let out = proc.wait_with_output()?;
match out.status.success() {
true => Ok(out.stdout),
false => Err(std::io::Error::new(std::io::ErrorKind::Other, "llvm-mc err")),
}
}
fn llvm_disassemble(code: &Vec<u8>) -> Result<String> {
let mut proc = Command::new("llvm-objdump").args(LLVM_ARGS).args(["--disassemble", "-"]).stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
proc.stdin.as_mut().unwrap().write_all(code)?;
let out = proc.wait_with_output()?;
match out.status.success() {
true => Ok(String::from_utf8(out.stdout).unwrap()),
false => Err(std::io::Error::new(std::io::ErrorKind::Other, "llvm-objdump err")),
}
}
fn test_decode(asm: &str) -> Instruction {
let lib = llvm_assemble(asm).unwrap();
println!("{}", llvm_disassemble(&lib).unwrap());
let stream: Vec<u32> = lib.chunks_exact(4).map(|chunk| u32::from_le_bytes(chunk.try_into().unwrap())).skip(OFFSET_PRG).collect();
decode(stream[0], stream.get(1))
}
#[test]
fn test_decode_smem() {
assert_eq!(test_decode("s_load_b128 s[4:7], s[0:1], null"), Instruction::SMEM { op: 2, sdata: 4, sbase: 0, offset: 0, soffset: NULL, glc: false, dlc: false });
assert_eq!(test_decode("s_load_b32 s10, s[0:1], 0xc"), Instruction::SMEM { op: 0, sdata: 10, sbase: 0, offset: 0xc, soffset: NULL, glc: false, dlc: false });
assert_eq!(test_decode("s_load_b32 s0, s[4:5], s6"), Instruction::SMEM { op: 0, sdata: 0, sbase: 4, offset: 0, soffset: 6, glc: false, dlc: false });
assert_eq!(test_decode("s_load_b32 s0, s[4:5], glc dlc"), Instruction::SMEM { op: 0, sdata: 0, sbase: 4, offset: 0, soffset: NULL, glc: true, dlc: true });
assert_eq!(test_decode("s_load_b32 s0, s[4:5], glc"), Instruction::SMEM { op: 0, sdata: 0, sbase: 4, offset: 0, soffset: NULL, glc: true, dlc: false });
assert_eq!(test_decode("s_load_b32 s0, s[4:5], -20"), Instruction::SMEM { op: 0, sdata: 0, sbase: 4, offset: -20, soffset: NULL, glc: false, dlc: false });
assert_eq!(test_decode("s_load_b32 s0, s[4:5], -1048576"), Instruction::SMEM { op: 0, sdata: 0, sbase: 4, offset: -1048576, soffset: NULL, glc: false, dlc: false });
}
#[test]
fn test_decode_salu() {
assert_eq!(test_decode("s_add_u32 s1 s2 s3"), Instruction::SOP2 { op: 0, ssrc0: 2, ssrc1: 3, sdst: 1 });
assert_eq!(test_decode("s_add_u32 vcc_hi exec_lo vcc_lo"), Instruction::SOP2 { op: 0, ssrc0: 126, ssrc1: 106, sdst: 107 });
assert_eq!(test_decode("s_mov_b32 s1 -0.5"), Instruction::SOP1 { op: 0, ssrc0: 241, sdst: 1 });
assert_eq!(test_decode("s_cmpk_eq_i32 s0 -30"), Instruction::SOPK { op: 3, sdst: 0, simm16: -30 });
assert_eq!(test_decode("s_cmpk_eq_u32 s0 65535"), Instruction::SOPK { op: 9, sdst: 0, simm16: -1 });
assert_eq!(test_decode("s_cmp_ge_i32 s1 s2"), Instruction::SOPC { op: 3, ssrc0: 1, ssrc1: 2 });
}
#[test]
fn test_decode_valu_e32() {
assert_eq!(test_decode("v_mov_b32 v0, v0"), Instruction::VOP1 { op: 1, vdst: 0, src: 256 });
assert_eq!(test_decode("v_mov_b32 v0, s0"), Instruction::VOP1 { op: 1, vdst: 0, src: 0 });
assert_eq!(test_decode("v_cmp_t_f32 v1, v0"), Instruction::VOPC { op: 31, vsrc: 0, src: 257 });
}
#[test]
fn test_decode_valu_e64() {
assert_eq!(test_decode("v_log_f32_e64 v2, |v0|"), Instruction::VOP3 { op: 423, vdst: 2, src0: 256, src1: 0, src2: 0, abs: 0b001, neg: 0, opsel: 0, omod: 0, cm: false });
assert_eq!(test_decode("v_div_scale_f32 v2, s1, v0, v1, v2"), Instruction::VOP3SD { op: 764, cm: false, vdst: 2, sdst: 1, src0: 256, src1: 257, src2: 258, omod: 0, neg: 0 });
assert_eq!(test_decode("v_pk_add_i16 v1, v0, v2"), Instruction::VOP3P { op: 2, vdst: 1, neg_hi: 0, opsel: 0, opsel_hi: 3, opsel_hi2: true, cm: false, src2: 0, src1: 258, src0: 256, neg: 0 });
}
#[test]
fn test_decode_ds() {
assert_eq!(test_decode("ds_add_u32 v2, v4 offset:16"), Instruction::DS { op: 0, gds: false, offset1: 0, offset0: 0x10, vdst: 0, data1: 0, data0: 4, addr: 2 });
assert_eq!(test_decode("ds_store_b32 v0, v1, offset: 0x04 gds"), Instruction::DS { op: 13, gds: true, offset1: 0, offset0: 0x04, vdst: 0, data1: 0, data0: 1, addr: 0 });
assert_eq!(test_decode("ds_load_u8 v1, v0 offset:16"), Instruction::DS { op: 58, gds: false, offset1: 0, offset0: 16, vdst: 1, data1: 0, data0: 0, addr: 0 });
}
}
-272
View File
@@ -1,272 +0,0 @@
use std::ops::{Index, IndexMut};
pub trait Register {
fn read64(&self, idx: usize) -> u64;
fn write64(&mut self, idx: usize, addr: u64);
}
impl<T> Register for T where T: Index<usize, Output = u32> + IndexMut<usize> {
fn read64(&self, idx: usize) -> u64 {
let lsb = self[idx] as u64;
let msb = self[idx + 1] as u64;
(msb << 32) | lsb
}
fn write64(&mut self, idx: usize, value: u64) {
self[idx] = (value & 0xffffffff) as u32;
self[idx + 1] = ((value & (0xffffffff << 32)) >> 32) as u32;
}
}
#[derive(Debug, Clone)]
pub struct VGPR {
values: [[u32; 256]; 32],
pub default_lane: Option<usize>,
}
impl Index<usize> for VGPR {
type Output = u32;
fn index(&self, index: usize) -> &Self::Output {
&self.values[self.default_lane.unwrap()][index]
}
}
impl IndexMut<usize> for VGPR {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.values[self.default_lane.unwrap()][index]
}
}
impl VGPR {
pub fn new() -> Self {
VGPR {
values: [[0; 256]; 32],
default_lane: None,
}
}
pub fn get_lane(&self, lane: usize) -> [u32; 256] {
*self.values.get(lane).unwrap()
}
pub fn get_lane_mut(&mut self, lane: usize) -> &mut [u32; 256] {
self.values.get_mut(lane).unwrap()
}
}
pub trait Value {
fn mut_hi16(&mut self, val: u16);
fn mut_lo16(&mut self, val: u16);
}
impl Value for u32 {
fn mut_hi16(&mut self, val: u16) {
*self = ((val as u32) << 16) | (*self as u16 as u32);
}
fn mut_lo16(&mut self, val: u16) {
*self = ((((*self & (0xffff << 16)) >> 16) as u32) << 16) | val as u32;
}
}
#[derive(Debug, Clone, Copy)]
pub struct WaveValue {
pub value: u32,
pub warp_size: usize,
pub default_lane: Option<usize>,
pub mutations: Option<[bool; 32]>,
}
impl WaveValue {
pub fn new(value: u32, warp_size: usize) -> Self {
Self {
value,
warp_size,
default_lane: None,
mutations: None,
}
}
pub fn read(&self) -> bool {
(self.value >> self.default_lane.unwrap()) & 1 == 1
}
pub fn set_lane(&mut self, value: bool) {
if self.mutations.is_none() {
self.mutations = Some([false; 32])
}
self.mutations.as_mut().unwrap()[self.default_lane.unwrap()] = value;
}
pub fn apply_muts(&mut self) {
self.value = 0;
for lane in 0..self.warp_size {
if self.mutations.unwrap()[lane] {
self.value |= 1 << lane;
}
}
}
}
/// C-compatible state snapshot for FFI - used for comparing emulator states
#[repr(C)]
#[derive(Clone, Debug)]
pub struct StateSnapshot {
pub pc: u32,
pub scc: u32,
pub vcc: u32,
pub exec_mask: u32,
pub sgpr: [u32; 128],
pub vgpr: [[u32; 256]; 32],
}
impl StateSnapshot {
pub fn new() -> Self {
Self { pc: 0, scc: 0, vcc: 0, exec_mask: 0, sgpr: [0; 128], vgpr: [[0; 256]; 32] }
}
}
#[derive(Clone, Debug)]
pub struct VecDataStore {
pub data: Vec<u8>,
}
impl VecDataStore {
pub fn new() -> Self {
Self { data: Vec::new() }
}
pub fn write(&mut self, addr: usize, val: u32) {
if addr + 4 >= self.data.len() {
self.data.resize(self.data.len() + addr + 5, 0);
}
self.data[addr..addr + 4].iter_mut().enumerate().for_each(|(i, x)| {
*x = val.to_le_bytes()[i];
});
}
pub fn write64(&mut self, addr: usize, val: u64) {
self.write(addr, (val & 0xffffffff) as u32);
self.write(addr + 4, ((val & (0xffffffff << 32)) >> 32) as u32);
}
pub fn read(&self, addr: usize) -> u32 {
let mut bytes: [u8; 4] = [0; 4];
bytes.copy_from_slice(&self.data[addr + 0..addr + 4]);
u32::from_le_bytes(bytes)
}
pub fn read64(&mut self, addr: usize) -> u64 {
let lsb = self.read(addr);
let msb = self.read(addr + 4);
((msb as u64) << 32) | lsb as u64
}
}
#[cfg(test)]
mod test_state {
use super::*;
#[test]
fn test_wave_value() {
let mut val = WaveValue::new(0b11000000000000011111111111101110, 32);
val.default_lane = Some(0);
assert!(!val.read());
val.default_lane = Some(31);
assert!(val.read());
}
#[test]
fn test_wave_value_small() {
let mut val = WaveValue::new(0, 1);
val.default_lane = Some(0);
assert!(!val.read());
assert_eq!(val.value, 0);
val.set_lane(true);
val.apply_muts();
assert!(val.read());
assert_eq!(val.value, 1);
}
#[test]
fn test_wave_value_small_alt() {
let mut val = WaveValue::new(0, 2);
val.default_lane = Some(0);
assert!(!val.read());
assert_eq!(val.value, 0);
val.set_lane(true);
val.apply_muts();
assert!(val.read());
assert_eq!(val.value, 1);
}
#[test]
fn test_wave_value_exec() {
let warp_size = 32;
let val = WaveValue::new(u32::MAX, warp_size);
assert_eq!(val.value, u32::MAX);
let warp_size = 3;
let val = WaveValue::new((1 << warp_size) - 1, warp_size);
assert_eq!(val.value, 7)
}
#[test]
fn test_wave_value_toggle_one() {
let warp_size = 2;
let mut val = WaveValue::new(0b11, warp_size);
// 0
val.default_lane = Some(0);
val.set_lane(false);
// 1
val.default_lane = Some(1);
val.set_lane(true);
val.apply_muts();
assert_eq!(val.value, 2);
}
#[test]
fn test_wave_value_mutate_small() {
let mut val = WaveValue::new(0, 2);
val.default_lane = Some(0);
assert!(!val.read());
assert_eq!(val.value, 0);
val.set_lane(true);
val.apply_muts();
assert!(val.read());
assert_eq!(val.value, 1);
}
#[test]
fn test_wave_value_mutations() {
let mut val = WaveValue::new(0b10001, 32);
val.default_lane = Some(0);
val.set_lane(false);
assert!(val.mutations.unwrap().iter().all(|x| !x));
val.default_lane = Some(1);
val.set_lane(true);
assert_eq!(val.value, 0b10001);
assert_eq!(
val.mutations,
Some([
false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false, false, false, false,
])
);
val.apply_muts();
assert_eq!(val.value, 0b10);
}
#[test]
fn test_write16() {
let mut vgpr = VGPR::new();
vgpr.default_lane = Some(0);
vgpr[0] = 0b11100000000000001111111111111111;
vgpr[0].mut_lo16(0b1011101111111110);
assert_eq!(vgpr[0], 0b11100000000000001011101111111110);
}
#[test]
fn test_write16hi() {
let mut vgpr = VGPR::new();
vgpr.default_lane = Some(0);
vgpr[0] = 0b11100000000000001111111111111111;
vgpr[0].mut_hi16(0b1011101111111110);
assert_eq!(vgpr[0], 0b10111011111111101111111111111111);
}
#[test]
fn test_vgpr() {
let mut vgpr = VGPR::new();
vgpr.default_lane = Some(0);
vgpr[0] = 42;
vgpr.default_lane = Some(10);
vgpr[0] = 10;
assert_eq!(vgpr.get_lane(0)[0], 42);
assert_eq!(vgpr.get_lane(10)[0], 10);
}
}
File diff suppressed because it is too large Load Diff
-323
View File
@@ -1,323 +0,0 @@
use crate::helpers::{colored, DEBUG};
use crate::state::{Register, StateSnapshot, VecDataStore, WaveValue, VGPR};
use crate::thread::{Thread, END_PRG, SGPR_COUNT};
use std::collections::HashMap;
pub const WAVE_SIZE: usize = 32;
pub struct WorkGroup<'a> {
dispatch_dim: u32,
id: [u32; 3],
lds: VecDataStore,
kernel: &'a Vec<u32>,
kernel_args: *const u64,
launch_bounds: [u32; 3],
wave_state: HashMap<usize, WaveState>,
}
#[derive(Debug, Clone)]
struct WaveState {
scalar_reg: [u32; SGPR_COUNT],
scc: u32,
vcc: WaveValue,
exec: WaveValue,
vec_reg: VGPR,
pc: usize,
sds: HashMap<usize, VecDataStore>,
}
const SYNCS: [u32; 4] = [0xBF89FC07, 0xBC7C0000, 0xBF890007, 0xbFB60003];
const S_BARRIER: u32 = 0xBFBD0000;
/// Context for single-stepping through a wave - holds all mutable state
pub struct WaveContext {
pub kernel: Vec<u32>,
pub scalar_reg: [u32; SGPR_COUNT],
pub scc: u32,
pub pc: usize,
pub vec_reg: VGPR,
pub vcc: WaveValue,
pub exec: WaveValue,
pub lds: VecDataStore,
pub sds: HashMap<usize, VecDataStore>,
pub n_lanes: usize,
}
impl WaveContext {
pub fn new(kernel: Vec<u32>, n_lanes: usize) -> Self {
let active = (!0u32).wrapping_shr(32 - (n_lanes as u32));
Self {
kernel,
scalar_reg: [0; SGPR_COUNT],
scc: 0,
pc: 0,
vec_reg: VGPR::new(),
vcc: WaveValue::new(0, n_lanes),
exec: WaveValue::new(active, n_lanes),
lds: VecDataStore::new(),
sds: (0..=31).map(|i| (i, VecDataStore::new())).collect(),
n_lanes,
}
}
/// Execute a single instruction. Returns: 0=continue, -1=endpgm, -2=barrier, 1=done (pc past program), negative=error
pub fn step(&mut self) -> i32 {
if self.pc >= self.kernel.len() { return 1; }
if self.kernel[self.pc] == END_PRG { return -1; }
if self.kernel[self.pc] == S_BARRIER { self.pc += 1; return -2; }
// Skip sync/nop instructions
if SYNCS.contains(&self.kernel[self.pc]) || self.kernel[self.pc] >> 20 == 0xbf8 || self.kernel[self.pc] == 0x7E000000 {
self.pc += 1;
return 0;
}
let mut sgpr_co = None;
for lane_id in 0..self.n_lanes {
self.vec_reg.default_lane = Some(lane_id);
self.vcc.default_lane = Some(lane_id);
self.exec.default_lane = Some(lane_id);
let mut thread = Thread {
scalar_reg: &mut self.scalar_reg,
scc: &mut self.scc,
vec_reg: &mut self.vec_reg,
vcc: &mut self.vcc,
exec: &mut self.exec,
lds: &mut self.lds,
sds: &mut self.sds.get_mut(&lane_id).unwrap(),
pc_offset: 0,
stream: self.kernel[self.pc..].to_vec(),
scalar: false,
simm: None,
warp_size: self.n_lanes,
sgpr_co: &mut sgpr_co,
};
if let Err(e) = thread.interpret() { return e; }
if thread.scalar {
self.pc = ((self.pc as isize) + 1 + (thread.pc_offset as isize)) as usize;
break;
}
if lane_id == self.n_lanes - 1 {
self.pc = ((self.pc as isize) + 1 + (thread.pc_offset as isize)) as usize;
}
}
if self.vcc.mutations.is_some() { self.vcc.apply_muts(); self.vcc.mutations = None; }
if self.exec.mutations.is_some() { self.exec.apply_muts(); self.exec.mutations = None; }
if let Some((idx, mut wv)) = sgpr_co.take() { wv.apply_muts(); self.scalar_reg[idx] = wv.value; }
0
}
pub fn get_snapshot(&self) -> StateSnapshot {
let mut snap = StateSnapshot::new();
snap.pc = self.pc as u32;
snap.scc = self.scc;
snap.vcc = self.vcc.value;
snap.exec_mask = self.exec.value;
snap.sgpr = self.scalar_reg;
for lane in 0..32 { snap.vgpr[lane] = self.vec_reg.get_lane(lane); }
snap
}
}
impl<'a> WorkGroup<'a> {
pub fn new(dispatch_dim: u32, id: [u32; 3], launch_bounds: [u32; 3], kernel: &'a Vec<u32>, kernel_args: *const u64) -> Self {
Self { dispatch_dim, id, kernel, launch_bounds, kernel_args, lds: VecDataStore::new(), wave_state: HashMap::new() }
}
pub fn exec_waves(&mut self) -> Result<(), i32> {
let mut threads = vec![];
for z in 0..self.launch_bounds[2] {
for y in 0..self.launch_bounds[1] {
for x in 0..self.launch_bounds[0] {
threads.push([x, y, z])
}
}
}
let waves = threads.chunks(WAVE_SIZE).collect::<Vec<_>>();
let mut sync = false;
for (i, x) in self.kernel.iter().enumerate() {
if i != 0 && *x == S_BARRIER {
sync = true;
break;
}
}
for _ in 0..=(sync as usize) {
for w in waves.iter().enumerate() {
self.exec_wave(w)?
}
}
Ok(())
}
fn exec_wave(&mut self, (wave_id, threads): (usize, &&[[u32; 3]])) -> Result<(), i32> {
let (mut scalar_reg, mut scc, mut pc, mut vec_reg, mut vcc, mut exec, mut sds) = match self.wave_state.get(&wave_id) {
None => {
let mut scalar_reg = [0; SGPR_COUNT];
scalar_reg.write64(0, self.kernel_args as u64);
let [gx, gy, gz] = self.id;
match self.dispatch_dim {
3 => (scalar_reg[13], scalar_reg[14], scalar_reg[15]) = (gx, gy, gz),
2 => (scalar_reg[14], scalar_reg[15]) = (gx, gy),
_ => scalar_reg[15] = gx,
}
let mut vec_reg = VGPR::new();
for (t, [x, y, z]) in threads.iter().enumerate() {
vec_reg.get_lane_mut(t)[0] = match &self.launch_bounds {
[_, 1, 1] => *x,
_ => (z << 20) | (y << 10) | x,
}
}
let vcc = WaveValue::new(0, threads.len());
let active = (!0u32).wrapping_shr(32 - (threads.len() as u32));
let exec = WaveValue::new(active, threads.len());
let sds = (0..=31).map(|i| (i, VecDataStore::new())).collect();
(scalar_reg, 0, 0, vec_reg, vcc, exec, sds)
}
Some(val) => {
let val = val.clone();
(val.scalar_reg, val.scc, val.pc, val.vec_reg, val.vcc, val.exec, val.sds)
}
};
loop {
if self.kernel[pc] == END_PRG {
break Ok(());
}
if self.kernel[pc] == S_BARRIER && self.wave_state.get(&wave_id).is_none() {
self.wave_state.insert(wave_id, WaveState { scalar_reg, scc, vec_reg, vcc, exec, pc, sds });
break Ok(());
}
if self.kernel[pc] == S_BARRIER || SYNCS.contains(&self.kernel[pc]) || self.kernel[pc] >> 20 == 0xbf8 || self.kernel[pc] == 0x7E000000 {
pc += 1;
continue;
}
let mut sgpr_co = None;
for (lane_id, [x, y, z]) in threads.iter().enumerate() {
vec_reg.default_lane = Some(lane_id);
vcc.default_lane = Some(lane_id);
exec.default_lane = Some(lane_id);
if *DEBUG {
let lane = format!("{:<2} {:08X} ", lane_id, self.kernel[pc]);
let state = match exec.read() {
true => "green",
false => "gray",
};
let [id0, id1, id2] = self.id;
print!("[{id0:<3} {id1:<3} {id2:<3}] [{x:<3} {y:<3} {z:<3}] {}", colored(&lane, state));
}
let mut thread = Thread {
scalar_reg: &mut scalar_reg,
scc: &mut scc,
vec_reg: &mut vec_reg,
vcc: &mut vcc,
exec: &mut exec,
lds: &mut self.lds,
sds: &mut sds.get_mut(&lane_id).unwrap(),
pc_offset: 0,
stream: self.kernel[pc..self.kernel.len()].to_vec(),
scalar: false,
simm: None,
warp_size: threads.len(),
sgpr_co: &mut sgpr_co,
};
thread.interpret()?;
if *DEBUG {
println!();
}
if thread.scalar {
pc = ((pc as isize) + 1 + (thread.pc_offset as isize)) as usize;
break;
}
if lane_id == threads.len() - 1 {
pc = ((pc as isize) + 1 + (thread.pc_offset as isize)) as usize;
}
}
if vcc.mutations.is_some() {
vcc.apply_muts();
vcc.mutations = None;
}
if exec.mutations.is_some() {
exec.apply_muts();
exec.mutations = None;
}
if let Some((idx, mut wv)) = sgpr_co.take() {
wv.apply_muts();
scalar_reg[idx] = wv.value;
}
}
}
}
#[cfg(test)]
mod test_workgroup {
use super::*;
// TODO: make this generic by adding the assembler
fn global_store_sgpr(addr: u64, instructions: Vec<u32>, src: u32) -> Vec<u32> {
[
instructions,
vec![
0x7E020200 + src,
0x7E0402FF,
addr as u32,
0x7E0602FF,
(addr >> 32) as u32,
0xDC6A0000,
0x007C0102,
],
vec![END_PRG],
]
.concat()
}
#[test]
fn test_wave_value_state_vcc() {
let mut ret: u32 = 0;
let kernel = vec![
0xBEEA00FF,
0b11111111111111111111111111111111, // initial vcc state
0x7E140282,
0x7C94010A, // cmp blockDim.x == 2
];
let addr = (&mut ret as *mut u32) as u64;
let kernel = global_store_sgpr(addr, kernel, 106);
let mut wg = WorkGroup::new(1, [0, 0, 0], [3, 1, 1], &kernel, [addr].as_ptr());
wg.exec_waves().unwrap();
assert_eq!(ret, 0b100);
}
#[test]
fn test_wave_value_state_exec() {
let mut ret: u32 = 0;
let kernel = vec![
0xBEFE00FF,
0b11111111111111111111111111111111,
0x7E140282,
0x7D9C010A, // cmpx blockDim.x <= 2
];
let addr = (&mut ret as *mut u32) as u64;
let kernel = global_store_sgpr(addr, kernel, 126);
let mut wg = WorkGroup::new(1, [0, 0, 0], [4, 1, 1], &kernel, [addr].as_ptr());
wg.exec_waves().unwrap();
assert_eq!(ret, 0b0111);
}
#[test]
fn test_wave_value_sgpr_co() {
let mut ret: u32 = 0;
let kernel = vec![0xBE8D00FF, 0x7FFFFFFF, 0x7E1402FF, u32::MAX, 0xD700000A, 0x0002010A];
let addr = (&mut ret as *mut u32) as u64;
let kernel = global_store_sgpr(addr, kernel, 0);
let mut wg = WorkGroup::new(1, [0, 0, 0], [5, 1, 1], &kernel, [addr].as_ptr());
wg.exec_waves().unwrap();
assert_eq!(ret, 0b11110);
}
}
-155
View File
@@ -1,155 +0,0 @@
# ruff: noqa: F405, F403
# allow define from star imports
import numpy as np
import unittest
import subprocess, struct, math, functools
from tinygrad import Tensor, dtypes, Device
from tinygrad.helpers import getenv
from tinygrad.runtime.autogen.amd.rdna3.ins import *
from tinygrad.renderer.amd.asm import waitcnt
from test.testextra.test_cfg_viz import asm_kernel
def get_output(asm:list, n_threads:int=1, vdst:VGPR=v[1]):
out = Tensor([0]*n_threads, dtype=dtypes.uint32).realize()
insts = [
s_load_b64(s[0:1], s[0:1], NULL),
*asm,
v_lshlrev_b32_e32(v[0], 2, v[0]),
s_waitcnt(simm16=waitcnt(lgkmcnt=0)),
#global_store_b32(v[0], v[1], s[0:1]),
global_store_b32(addr=v[0], data=vdst, saddr=s[0:1]),
s_endpgm()
]
out = Tensor.custom_kernel(out, fxn=functools.partial(asm_kernel, name="test", insts=insts, device=out.device, n_threads=n_threads))[0]
out.realize()
return out.tolist()
def f16_to_bits(x:float) -> int: return struct.unpack('<H', struct.pack('<e', x))[0]
def f32_from_bits(x:int) -> float: return struct.unpack('<f', struct.pack('<I', x))[0]
def f32_to_bits(x:float) -> int: return struct.unpack('<I', struct.pack('<f', x))[0]
@unittest.skipUnless(Device.DEFAULT == "AMD", "tests RDNA3")
class TestHW(unittest.TestCase):
def setUp(self):
if getenv("MOCKGPU"): subprocess.run(["cargo", "build", "--release", "--manifest-path", "./extra/remu/Cargo.toml"], check=True)
def test_simple_v_mov(self):
out = get_output([
v_mov_b32_e32(v[1], 2),
])
self.assertEqual(out, [2])
def test_simple_s_mov(self):
out = get_output([
s_mov_b32(s[7], 0x7fffffff),
v_mov_b32_e32(v[1], s[7]),
])
self.assertEqual(out, [0x7fffffff])
def test_exec_mov(self):
out = get_output([
v_mov_b32_e32(v[1], 42),
s_mov_b32(EXEC_LO, 0b10),
v_mov_b32_e32(v[1], 10),
s_mov_b32(EXEC_LO, 0b11),
], n_threads=2)
np.testing.assert_equal(out, [42, 10])
def test_exec_cmp_vopc(self):
out = get_output([
s_mov_b32(VCC_LO, 0), # reset vcc
v_mov_b32_e32(v[1], 42),
v_mov_b32_e32(v[2], 10),
s_mov_b32(EXEC_LO, 0b01),
v_cmp_ne_u32_e32(v[1], v[2]),
s_mov_b32(EXEC_LO, 0b11),
v_mov_b32_e32(v[1], VCC_LO),
], n_threads=2)[0]
np.testing.assert_equal(out, 1)
def test_exec_cmpx_vop3(self):
out = get_output([
s_mov_b32(EXEC_LO, 0b11),
v_mov_b32_e32(v[1], 42),
v_mov_b32_e32(v[2], 10),
s_mov_b32(EXEC_LO, 0b01),
v_cmpx_ne_u32_e32(v[1], v[2]),
s_mov_b32(s[10], EXEC_LO),
s_mov_b32(EXEC_LO, 0b11),
v_mov_b32_e32(v[1], s[10]),
], n_threads=2)[0]
np.testing.assert_equal(out & 0b11, 0b01)
def test_fmac_vop3_modifier(self):
init_state = [
v_mov_b32_e32(a:=v[1], f16_to_bits(4.0)),
v_mov_b32_e32(b:=v[2], f16_to_bits(3.0)),
v_mov_b32_e32(c:=v[3], f16_to_bits(2.0)),
]
def run_fmac(a, b): return get_output(init_state+[v_fmac_f16_e64(c, a, b)], vdst=c)[0]
self.assertEqual(run_fmac(a, b), f16_to_bits(14.0))
self.assertEqual(run_fmac(a, -b), f16_to_bits(-10.0))
self.assertEqual(run_fmac(-a, -b), f16_to_bits(14.0))
def test_s_abs_i32(self):
def check(x, y, dst=s[10], scc=0):
for reg,val in [(dst, y), (SCC, scc)]:
self.assertEqual(get_output([
s_mov_b32(dst, x),
s_abs_i32(dst, dst),
v_mov_b32_e32(v[1], reg)
])[0], val)
check(0x00000001, 0x00000001, scc=1)
check(0x7fffffff, 0x7fffffff, scc=1)
check(0x80000000, 0x80000000, scc=1)
check(0x80000001, 0x7fffffff, scc=1)
check(0x80000002, 0x7ffffffe, scc=1)
check(0xffffffff, 0x00000001, scc=1)
check(0, 0, scc=0)
def test_v_rcp_f32_neg_vop3(self):
def v_neg_rcp_f32(x:float, y:float):
out = get_output([
v_mov_b32_e32(v[2], f32_to_bits(x)),
v_rcp_f32_e64(v[2], -v[2]),
], vdst=v[2])[0]
assert out == f32_to_bits(y), f"{f32_from_bits(out)} != {y} / {out} != {f32_to_bits(y)}"
v_neg_rcp_f32(math.inf, -0.0)
v_neg_rcp_f32(-math.inf, 0.0)
v_neg_rcp_f32(0.0, -math.inf)
v_neg_rcp_f32(-0.0, math.inf)
v_neg_rcp_f32(-2.0, 0.5)
v_neg_rcp_f32(2.0, -0.5)
def test_v_cndmask_b32_neg(self):
def v_neg(x:float, y:float):
out = get_output([
v_mov_b32_e32(v[1], f32_to_bits(x)),
s_mov_b32(s[10], 1),
v_cndmask_b32_e64(v[1], v[1], -v[1], s[10]),
])[0]
assert out == f32_to_bits(y), f"{f32_from_bits(out)} != {y} / {out} != {f32_to_bits(y)}"
v_neg(-0.0, 0.0)
v_neg(0.0, -0.0)
v_neg(2.0, -2.0)
v_neg(math.inf, -math.inf)
v_neg(-math.inf, math.inf)
@unittest.skip("how does VOPD work in the dsl")
def test_v_subrev_wrap(self):
out = get_output([
#v_dual_mov_b32(v[1], 0xffffffff, v[2], 0x0),
#v_dual_mov_b32(vdstx=v[1], srcx=0xffffffff, vdsty=v[2], srcy=0x0),
#VOPD(opx=VOPDOp.V_DUAL_MOV_B32, opy=VOPDOp.V_DUAL_MOV_B32, vdstx=v[1], srcx=0xffffffff, vdsty=v[2], srcy=0x0),
v_subrev_co_u32(v[2], VCC_LO, v[2], v[1]),
], vdst=v[2])[0]
self.assertEqual(out, 0xffff_ffff)
if __name__ == "__main__":
unittest.main()
+1 -6
View File
@@ -3,7 +3,7 @@ INSTALL_PATH="${1:-/opt/homebrew/lib}"
if [ ! -d "$INSTALL_PATH" ]; then
USER=$(whoami)
echo "No path $INSTALL_PATH. Will create. Might need your password..."
echo "You can stop now and provide any location as an argument where you want to save the libs (note, that not default locations should be in LD_LIBRARY_PATH, so tinygrad can find the libs)."
echo "You can stop now and provide any location as an argument where you want to save the library (note, that not default locations should be in LD_LIBRARY_PATH, so tinygrad can find it)."
echo "Press any key or symbol to continue..."
read -n 1 -s
@@ -11,11 +11,6 @@ if [ ! -d "$INSTALL_PATH" ]; then
sudo chown -R "$USER":staff "$INSTALL_PATH"
fi
# Download libremu.dylib
curl -s https://api.github.com/repos/Qazalin/remu/releases/latest | \
jq -r '.assets[] | select(.name == "libremu.dylib").browser_download_url' | \
xargs curl -L -o $INSTALL_PATH/libremu.dylib
# Download libamd_comgr.dylib
curl -s https://api.github.com/repos/tinygrad/amdcomgr_dylib/releases/latest | \
jq -r '.assets[] | select(.name == "libamd_comgr.dylib").browser_download_url' | \
+7 -6
View File
@@ -136,7 +136,8 @@ def print_data(data:dict) -> None:
def main() -> None:
import tinygrad.viz.serve as viz
viz.ctxs = []
from tinygrad.uop.ops import RewriteTrace
data = viz.VizData()
parser = argparse.ArgumentParser()
parser.add_argument('--profile', type=pathlib.Path, metavar="PATH", help='Path to profile (optional file, default: latest profile)',
@@ -147,24 +148,24 @@ def main() -> None:
with args.profile.open("rb") as f: profile = pickle.load(f)
viz.get_profile(profile)
viz.get_profile(profile, data=data)
# List all kernels
if args.kernel is None:
for c in viz.ctxs:
for c in data.ctxs:
print(c["name"])
for s in c["steps"]: print(" "+s["name"])
return None
# Find kernel trace
trace = next((c for c in viz.ctxs if c["name"] == f"Exec {args.kernel}"), None)
trace = next((c for c in data.ctxs if c["name"] == f"SQTT {args.kernel}"), None)
if not trace: raise RuntimeError(f"no matching trace for {args.kernel}")
n = 0
for s in trace["steps"]:
if "PKTS" in s["name"]: continue
print(s["name"])
data = viz.get_render(s["query"])
print_data(data)
ret = viz.get_render(data, s["query"])
print_data(ret)
n += 1
if n > args.n: break
+13 -14
View File
@@ -52,16 +52,15 @@ def get(data:dict, key:str):
raise RuntimeError(f'item "{key}" not found in list'+(f", did you mean {match[0]!r}?" if match else ''))
def main(args) -> None:
viz.trace = viz.load_pickle(args.rewrites_path, default=RewriteTrace([], [], {}))
viz.ctxs = viz.get_rewrites(viz.trace)
viz.load_rewrites(viz_data:=viz.VizData(viz.load_pickle(args.rewrites_path, default=RewriteTrace([], [], {}))))
def format_colored(s:str) -> str: return ansistrip(s) if args.no_color else s
if args.profile:
events:list = viz.load_pickle(args.profile_path, default=[])
if (profile_bytes:=viz.get_profile(events)) is None: raise RuntimeError(f"empty profile in {args.profile_path}")
if (profile_bytes:=viz.get_profile(viz_data, events)) is None: raise RuntimeError(f"empty profile in {args.profile_path}")
profile = decode_profile(profile_bytes)
profile["layout"].update([(f'{c["name"][5:]}{" SQTT" if s["name"].endswith("PKTS") else ""} {s["name"]}', s["data"]) for c in viz.ctxs
profile["layout"].update([(f'{c["name"][5:]}{" SQTT" if s["name"].endswith("PKTS") else ""} {s["name"]}', s["data"]) for c in viz_data.ctxs
if c["name"].startswith("SQTT") for s in c["steps"] if s["name"].endswith(("PMC", "PKTS"))])
if args.src is None:
for k in profile["layout"]:
@@ -103,10 +102,10 @@ def main(args) -> None:
# ** PMC printer
if "PMC" in args.src:
table = viz.unpack_pmc(data[0])
cols = table["cols"]
pmc = viz.unpack_pmc(data)
cols = pmc["cols"]
rows:list = []
for r in table["rows"]:
for r in pmc["rows"]:
if args.item is None: rows.append(r[:2])
elif args.item == r[0]:
rows = r[2]["rows"] if len(r) > 2 else [r[:2]]
@@ -132,17 +131,17 @@ def main(args) -> None:
if agg and total > 0:
from tabulate import tabulate
items = sorted(agg.items(), key=lambda kv:kv[1][0], reverse=True)
rows = 20
table = [[format_colored(name), time_to_str(t, w=9), c, f"{(t/total*100.0):.2f}%"] for name,(t,c) in items[:rows]]
if items[rows:]:
other_t = sum(t for _,(t,_) in items[rows:])
other_c = sum(c for _,(_,c) in items[rows:])
num_rows = 20
table = [[format_colored(name), time_to_str(t, w=9), c, f"{(t/total*100.0):.2f}%"] for name,(t,c) in items[:num_rows]]
if items[num_rows:]:
other_t = sum(t for _,(t,_) in items[num_rows:])
other_c = sum(c for _,(_,c) in items[num_rows:])
table.append(["Other", time_to_str(other_t, w=9), other_c, f"{(other_t/total*100.0):.2f}%"])
print(tabulate(table, headers=["name", "total", "count", "pct"], tablefmt="github"))
return None
# ** Graph rewrites printer
rewrites = {c["name"]:{s["name"]:s for s in c["steps"]} for c in viz.ctxs if c.get("steps")}
rewrites = {c["name"]:{s["name"]:s for s in c["steps"]} for c in viz_data.ctxs if c.get("steps")}
if args.src is None:
for k in rewrites: print(f" {format_colored(k)}")
return None
@@ -150,7 +149,7 @@ def main(args) -> None:
if args.item is None:
for k,v in steps.items(): print(" "*v["depth"]+k+(f" - {v['match_count']}" if v.get('match_count', 0) else ''))
else:
data = viz.get_render(get(steps, args.item)["query"])
data = viz.get_render(data, get(steps, args.item)["query"])
if isinstance(data.get("value"), Iterator):
for m in data["value"]:
if m.get("uop"): print(f"Input UOp:\n{m['uop']}")
+2 -2
View File
@@ -50,8 +50,8 @@ tinygrad = ["py.typed"]
[project.optional-dependencies]
arm = ["unicorn"]
triton = ["triton-nightly>=2.1.0.dev20231014192330"]
# arm = ["unicorn"]
# triton = ["triton-nightly>=2.1.0.dev20231014192330"]
linting = [
"pylint",
"mypy==1.19.1",
+6 -16
View File
@@ -2,6 +2,7 @@
from __future__ import annotations
import re
from typing import Callable
from test.amd.helpers import decode_dpp16
from tinygrad.renderer.amd.dsl import Inst, Reg
# Special register mappings for disassembly
@@ -838,22 +839,11 @@ def _disasm_vop1_sdwa(inst) -> str:
def _decode_dpp(dpp: int) -> str:
"""Decode DPP control value to string."""
if dpp < 0x100: return f"quad_perm:[{dpp&3},{(dpp>>2)&3},{(dpp>>4)&3},{(dpp>>6)&3}]"
if 0x100 <= dpp <= 0x10f: return f"row_shl:{dpp & 0xf}"
if 0x110 <= dpp <= 0x11f: return f"row_shr:{dpp & 0xf}"
if 0x120 <= dpp <= 0x12f: return f"row_ror:{dpp & 0xf}"
if dpp == 0x130: return "wave_shl:1"
if dpp == 0x134: return "wave_rol:1"
if dpp == 0x138: return "wave_shr:1"
if dpp == 0x13c: return "wave_ror:1"
if dpp == 0x140: return "row_mirror"
if dpp == 0x141: return "row_half_mirror"
if dpp == 0x142: return "row_bcast:15"
if dpp == 0x143: return "row_bcast:31"
if 0x150 <= dpp <= 0x15f: return f"row_newbcast:{dpp & 0xf}"
if 0x160 <= dpp <= 0x16f: return f"row_share:{dpp & 0xf}"
if 0x170 <= dpp <= 0x17f: return f"row_xmask:{dpp & 0xf}"
return f"dpp:{dpp:#x}"
op, arg = decode_dpp16(dpp)
if op == "quad_perm": return f"quad_perm:[{','.join(str(x) for x in arg)}]"
if op in ("row_mirror", "row_half_mirror"): return op
if op == "dpp": return f"dpp:{arg:#x}"
return f"{op}:{arg}"
def _disasm_vop1_dpp(inst) -> str:
name = inst.op_name.lower().replace('_e32', '')
+11
View File
@@ -12,8 +12,19 @@ ARCH_TO_TARGET:dict[str, list[str]] = {
TARGET_TO_ARCH:dict[str, str] = {t:arch for arch,targets in ARCH_TO_TARGET.items() for t in targets}
_DPP16_RANGE_OPS = {0x100: "row_shl", 0x110: "row_shr", 0x120: "row_ror", 0x150: "row_newbcast", 0x160: "row_share", 0x170: "row_xmask"}
_DPP16_EXACT_OPS = {0x130: ("wave_shl", 1), 0x134: ("wave_rol", 1), 0x138: ("wave_shr", 1), 0x13c: ("wave_ror", 1),
0x140: ("row_mirror", 0), 0x141: ("row_half_mirror", 0), 0x142: ("row_bcast", 15), 0x143: ("row_bcast", 31)}
def get_target(arch:str) -> str: return ARCH_TO_TARGET[arch][0]
def decode_dpp16(dpp: int) -> tuple[str, int | tuple[int, int, int, int]]:
"""Decode a DPP16 control word into a symbolic operation and argument."""
if dpp < 0x100: return "quad_perm", ((dpp >> 0) & 0x3, (dpp >> 2) & 0x3, (dpp >> 4) & 0x3, (dpp >> 6) & 0x3)
if dpp in _DPP16_EXACT_OPS: return _DPP16_EXACT_OPS[dpp]
if (base := dpp & 0x1f0) in _DPP16_RANGE_OPS: return _DPP16_RANGE_OPS[base], dpp & 0xf
return "dpp", dpp
def get_mattr(arch:str) -> str:
return {"rdna3":"+real-true16,+wavefrontsize32", "rdna4":"+real-true16,+wavefrontsize32", "cdna":"+wavefrontsize64"}[arch]
+187
View File
@@ -0,0 +1,187 @@
"""Tests for DPP16 source swizzles.
These instructions trap in the default wave32 hw helper, so this file uses a
minimal wave64 lane-store harness and compares emulator vs hardware directly
when USE_HW=1.
"""
import ctypes, unittest
from tinygrad.runtime.autogen.amd.rdna3.ins import *
from tinygrad.helpers import flat_mv
from test.amd.hw.helpers import USE_HW, assemble
from test.mockgpu.amd.emu import run_asm
WAVE64 = 64
def _wave64_code(instructions: list, out_reg: int = 1) -> bytes:
return assemble([
s_mov_b32(s[80], s[0]),
s_mov_b32(s[81], s[1]),
v_mov_b32_e32(v[255], v[0]),
*instructions,
s_load_b64(s[92:93], s[80:81], 0, soffset=NULL),
s_waitcnt(0),
v_lshlrev_b32_e32(v[240], 2, v[255]),
global_store_b32(addr=v[240], data=v[out_reg], saddr=s[92:93], offset=0),
s_endpgm(),
])
def _run_wave64_emu(instructions: list, out_reg: int = 1) -> list[int]:
out_buf = (ctypes.c_uint32 * WAVE64)(*([0] * WAVE64))
args = (ctypes.c_uint64 * 1)(ctypes.addressof(out_buf))
code = _wave64_code(instructions, out_reg)
kernel_buf = (ctypes.c_char * len(code)).from_buffer_copy(code)
rsrc2 = 0x19c | (128 << 15)
scratch_size = 0x10000
result = run_asm(ctypes.addressof(kernel_buf), len(code), 1, 1, 1, WAVE64, 1, 1, ctypes.addressof(args), rsrc2, scratch_size)
assert result == 0, f"run_asm failed with {result}"
return list(out_buf)
def _run_wave64_hw(instructions: list, out_reg: int = 1) -> list[int]:
from tinygrad.device import Device
from tinygrad.runtime.ops_amd import AMDProgram
from tinygrad.runtime.support.compiler_amd import HIPCompiler
dev = Device["AMD"]
compiler = HIPCompiler(dev.arch) # type: ignore[attr-defined]
code = _wave64_code(instructions, out_reg)
byte_str = ', '.join(f'0x{b:02x}' for b in code)
asm_src = f""".text
.globl test
.p2align 8
.type test,@function
test:
.byte {byte_str}
.rodata
.p2align 6
.amdhsa_kernel test
.amdhsa_next_free_vgpr 256
.amdhsa_next_free_sgpr 96
.amdhsa_user_sgpr_kernarg_segment_ptr 1
.amdhsa_kernarg_size 8
.amdhsa_group_segment_fixed_size 65536
.amdhsa_private_segment_fixed_size 65536
.amdhsa_enable_private_segment 1
.end_amdhsa_kernel
.amdgpu_metadata
---
amdhsa.version:
- 1
- 0
amdhsa.kernels:
- .name: test
.symbol: test.kd
.kernarg_segment_size: 8
.group_segment_fixed_size: 65536
.private_segment_fixed_size: 65536
.kernarg_segment_align: 8
.wavefront_size: 64
.sgpr_count: 96
.vgpr_count: 256
.max_flat_workgroup_size: 1024
...
.end_amdgpu_metadata
"""
lib = compiler.compile(asm_src)
prg = AMDProgram(dev, "test", lib) # type: ignore[arg-type]
out_gpu = dev.allocator.alloc(WAVE64 * 4)
prg(out_gpu, global_size=(1, 1, 1), local_size=(WAVE64, 1, 1), wait=True)
out = bytearray(WAVE64 * 4)
dev.allocator._copyout(flat_mv(memoryview(out)), out_gpu)
return [int.from_bytes(out[i*4:(i+1)*4], 'little') for i in range(WAVE64)]
def run_wave64(instructions: list, out_reg: int = 1) -> list[int]:
emu = _run_wave64_emu(instructions, out_reg)
if not USE_HW: return emu
hw = _run_wave64_hw(instructions, out_reg)
if emu != hw:
diffs = [f"lane {i}: emu=0x{e:08x} hw=0x{h:08x}" for i, (e, h) in enumerate(zip(emu, hw)) if e != h]
raise AssertionError("Emulator vs Hardware mismatch:\n" + '\n'.join(diffs[:16]))
return hw
class TestDPP16(unittest.TestCase):
def _run_copy(self, dpp: int, *, row_mask: int = 0xf, bank_mask: int = 0xf, bc: int = 1, dst_seed: int | None = None) -> list[int]:
instructions = [
v_mul_u32_u24_e32(v[0], 10, v[255]),
v_add_nc_u32_e32(v[0], 3, v[0]),
]
if dst_seed is not None: instructions.append(v_mov_b32_e32(v[1], dst_seed))
instructions += [v_mov_b32_e32(v[2], 0), v_or_b32_e32(v[1], DPP, v[2], vsrc0=v[0], dpp=dpp, row_mask=row_mask, bank_mask=bank_mask, bc=bc)]
return run_wave64(instructions)
def test_quad_perm_reverse(self):
out = self._run_copy(0x1b)
self.assertEqual(out[0], 33)
self.assertEqual(out[1], 23)
self.assertEqual(out[2], 13)
self.assertEqual(out[3], 3)
self.assertEqual(out[4], 73)
def test_row_shl(self):
out = self._run_copy(0x101)
self.assertEqual(out[0], 13)
self.assertEqual(out[7], 83)
self.assertEqual(out[14], 153)
self.assertEqual(out[15], 0)
self.assertEqual(out[16], 173)
def test_row_shr(self):
out = self._run_copy(0x111)
self.assertEqual(out[0], 0)
self.assertEqual(out[1], 3)
self.assertEqual(out[8], 73)
self.assertEqual(out[15], 143)
self.assertEqual(out[16], 0)
self.assertEqual(out[17], 163)
def test_row_ror(self):
out = self._run_copy(0x121)
self.assertEqual(out[0], 153)
self.assertEqual(out[1], 3)
self.assertEqual(out[15], 143)
self.assertEqual(out[16], 313)
def test_row_mirror(self):
out = self._run_copy(0x140)
self.assertEqual(out[0], 153)
self.assertEqual(out[5], 103)
self.assertEqual(out[8], 73)
self.assertEqual(out[16], 313)
def test_row_half_mirror(self):
out = self._run_copy(0x141)
self.assertEqual(out[0], 73)
self.assertEqual(out[7], 3)
self.assertEqual(out[8], 153)
self.assertEqual(out[15], 83)
self.assertEqual(out[16], 233)
def test_row_mask(self):
out = self._run_copy(0x101, row_mask=0x5, dst_seed=0xDEADBEEF)
self.assertEqual(out[0], 13)
self.assertEqual(out[15], 0)
self.assertEqual(out[16], 0xDEADBEEF)
self.assertEqual(out[32], 333)
self.assertEqual(out[47], 0)
self.assertEqual(out[48], 0xDEADBEEF)
def test_bank_mask(self):
out = self._run_copy(0x101, bank_mask=0x5, dst_seed=0xDEADBEEF)
self.assertEqual(out[0], 13)
self.assertEqual(out[3], 43)
self.assertEqual(out[4], 0xDEADBEEF)
self.assertEqual(out[8], 93)
self.assertEqual(out[12], 0xDEADBEEF)
class TestVOPCDPP16(unittest.TestCase):
def test_row_bcast15_materializes_vcc(self):
out = run_wave64([
v_mov_b32_e32(v[0], v[255]),
v_cmp_eq_u32_e32(DPP, v[0], vsrc0=v[0], dpp=0x142, row_mask=0xf, bank_mask=0xf, bc=1),
v_mov_b32_e32(v[2], 0),
v_mov_b32_e32(v[3], 1),
v_cndmask_b32_e32(v[1], v[2], v[3]),
])
for lane in (0, 16, 32, 48): self.assertEqual(out[lane], 1)
for lane in (1, 15, 31, 47, 63): self.assertEqual(out[lane], 0)
-2
View File
@@ -833,8 +833,6 @@ class TestDsPermute(unittest.TestCase):
src_lane = lane ^ 1
expected = src_lane + 100
self.assertEqual(st.vgpr[lane][2], expected, f"lane {lane}: expected v[1] from lane {src_lane} = {expected}, got {st.vgpr[lane][2]}")
class TestDSSubDword(unittest.TestCase):
"""Tests for sub-dword DS operations (ds_store_b16, ds_store_b16_d16_hi)."""
+129
View File
@@ -0,0 +1,129 @@
"""RDNA4 V_PERMLANE16_VAR_B32 / V_PERMLANEX16_VAR_B32 coverage.
Exercises the generated pcode path end-to-end in the emulator and compares against
real RDNA4 hardware when USE_HW=1.
"""
import ctypes, unittest
import tinygrad.runtime.autogen.amd.rdna4.ins as r4
from tinygrad.helpers import flat_mv
from tinygrad.renderer.amd.dsl import NULL
from test.amd.hw.helpers import USE_HW, assemble
from test.mockgpu.amd.emu import run_asm
LANES = 32
def _code(instructions: list, out_reg: int = 2) -> bytes:
return assemble([
r4.s_mov_b32(r4.s[80], r4.s[0]),
r4.s_mov_b32(r4.s[81], r4.s[1]),
r4.v_mov_b32_e32(r4.v[255], r4.v[0]),
*instructions,
r4.s_load_b64(r4.s[92:93], r4.s[80:81], soffset=NULL),
r4.s_wait_kmcnt(simm16=0),
r4.v_lshlrev_b32_e32(r4.v[240], 2, r4.v[255]),
r4.v_mov_b32_e32(r4.v[241], 0),
r4.global_store_b32(vaddr=r4.v[240:241], saddr=r4.s[92:93], vsrc=r4.v[out_reg]),
r4.s_endpgm(),
])
def _run_emu(instructions: list, out_reg: int = 2) -> list[int]:
out_buf = (ctypes.c_uint32 * LANES)(*([0] * LANES))
args = (ctypes.c_uint64 * 1)(ctypes.addressof(out_buf))
code = _code(instructions, out_reg)
kernel_buf = (ctypes.c_char * len(code)).from_buffer_copy(code)
result = run_asm(ctypes.addressof(kernel_buf), len(code), 1, 1, 1, LANES, 1, 1, ctypes.addressof(args), arch='rdna4')
assert result == 0, f"run_asm failed with {result}"
return list(out_buf)
def _run_hw(instructions: list, out_reg: int = 2) -> list[int]:
from tinygrad.device import Device
from tinygrad.runtime.ops_amd import AMDProgram
from tinygrad.runtime.support.compiler_amd import HIPCompiler
dev = Device['AMD']
if not dev.arch.startswith('gfx12'): raise unittest.SkipTest('requires RDNA4 hardware')
compiler = HIPCompiler(dev.arch)
code = _code(instructions, out_reg)
byte_str = ', '.join(f'0x{b:02x}' for b in code)
asm_src = f""".text
.globl test
.p2align 8
.type test,@function
test:
.byte {byte_str}
.rodata
.p2align 6
.amdhsa_kernel test
.amdhsa_next_free_vgpr 256
.amdhsa_next_free_sgpr 96
.amdhsa_wavefront_size32 1
.amdhsa_user_sgpr_kernarg_segment_ptr 1
.amdhsa_kernarg_size 8
.amdhsa_group_segment_fixed_size 65536
.amdhsa_private_segment_fixed_size 65536
.amdhsa_enable_private_segment 1
.end_amdhsa_kernel
.amdgpu_metadata
---
amdhsa.version:
- 1
- 0
amdhsa.kernels:
- .name: test
.symbol: test.kd
.kernarg_segment_size: 8
.group_segment_fixed_size: 65536
.private_segment_fixed_size: 65536
.kernarg_segment_align: 8
.wavefront_size: 32
.sgpr_count: 96
.vgpr_count: 256
.max_flat_workgroup_size: 1024
...
.end_amdgpu_metadata
"""
lib = compiler.compile(asm_src)
prg = AMDProgram(dev, 'test', lib)
out_gpu = dev.allocator.alloc(LANES * 4)
prg(out_gpu, global_size=(1, 1, 1), local_size=(LANES, 1, 1), wait=True)
out = bytearray(LANES * 4)
dev.allocator._copyout(flat_mv(memoryview(out)), out_gpu)
return [int.from_bytes(out[i*4:(i+1)*4], 'little') for i in range(LANES)]
def run_rdna4(instructions: list, out_reg: int = 2) -> list[int]:
emu = _run_emu(instructions, out_reg)
if not USE_HW: return emu
hw = _run_hw(instructions, out_reg)
if emu != hw:
diffs = [f"lane {i}: emu=0x{e:08x} hw=0x{h:08x}" for i, (e, h) in enumerate(zip(emu, hw)) if e != h]
raise AssertionError("Emulator vs Hardware mismatch:\n" + '\n'.join(diffs[:16]))
return hw
class TestPermlaneVarRDNA4(unittest.TestCase):
def test_v_permlane16_var_b32_reverse(self):
out = run_rdna4([
r4.v_mov_b32_e32(r4.v[0], r4.v[255]),
r4.v_xor_b32_e32(r4.v[1], 15, r4.v[255]),
r4.v_permlane16_var_b32(r4.v[2], r4.v[0], r4.v[1]),
])
self.assertEqual(out[0], 15)
self.assertEqual(out[5], 10)
self.assertEqual(out[15], 0)
self.assertEqual(out[16], 31)
self.assertEqual(out[21], 26)
self.assertEqual(out[31], 16)
def test_v_permlanex16_var_b32_cross_row(self):
out = run_rdna4([
r4.v_mov_b32_e32(r4.v[0], r4.v[255]),
r4.v_mov_b32_e32(r4.v[1], r4.v[255]),
r4.v_permlanex16_var_b32(r4.v[2], r4.v[0], r4.v[1]),
])
self.assertEqual(out[0], 16)
self.assertEqual(out[5], 21)
self.assertEqual(out[15], 31)
self.assertEqual(out[16], 0)
self.assertEqual(out[21], 5)
self.assertEqual(out[31], 15)
+35
View File
@@ -0,0 +1,35 @@
"""Tests for VINTERP instructions."""
import unittest
from test.amd.hw.helpers import *
class TestVInterp(unittest.TestCase):
def test_v_interp_p10_f32(self):
instructions = [
v_mov_b32_e32(v[10], v[255]),
v_cvt_f32_u32_e32(v[1], v[10]),
s_mov_b32(s[0], f2i(100.0)),
v_add_f32_e32(v[1], s[0], v[1]),
v_cvt_f32_u32_e32(v[3], v[10]),
s_mov_b32(s[1], f2i(10.0)),
v_add_f32_e32(v[3], s[1], v[3]),
s_mov_b32(s[2], f2i(2.0)),
v_interp_p10_f32(v[4], v[1], s[2], v[3]),
]
st = run_program(instructions, n_lanes=8)
for lane in range(4): self.assertAlmostEqual(i2f(st.vgpr[lane][4]), 212.0, places=5)
for lane in range(4, 8): self.assertAlmostEqual(i2f(st.vgpr[lane][4]), 224.0, places=5)
def test_v_interp_p10_f16_f32(self):
instructions = [
v_mov_b32_e32(v[10], v[255]),
v_cvt_f32_u32_e32(v[11], v[10]),
v_cvt_f16_f32_e32(v[1], v[11]),
s_mov_b32(s[0], f2i(10.0)),
v_add_f32_e32(v[12], s[0], v[11]),
v_cvt_f16_f32_e32(v[3], v[12]),
s_mov_b32(s[1], f2i(2.0)),
v_interp_p10_f16_f32(v[4], v[1], s[1], v[3]),
]
st = run_program(instructions, n_lanes=8)
for lane in range(4): self.assertAlmostEqual(i2f(st.vgpr[lane][4]), 12.0, places=5)
for lane in range(4, 8): self.assertAlmostEqual(i2f(st.vgpr[lane][4]), 24.0, places=5)
+11
View File
@@ -30,6 +30,17 @@ class TestBasicArithmetic(unittest.TestCase):
st = run_program(instructions, n_lanes=1)
self.assertAlmostEqual(i2f(st.vgpr[0][2]), 8.0, places=5)
def test_v_add_f32_dpp_row_shl(self):
"""V_ADD_F32 DPP row_shl swizzles src0 before the add."""
instructions = [
v_cvt_f32_u32_e32(v[0], v[255]),
v_add_f32_e32(v[1], DPP, v[0], vsrc0=v[0], dpp=0x101, row_mask=0xf, bank_mask=0xf, bc=1),
]
st = run_program(instructions, n_lanes=16)
self.assertAlmostEqual(i2f(st.vgpr[0][1]), 1.0, places=5)
self.assertAlmostEqual(i2f(st.vgpr[1][1]), 3.0, places=5)
self.assertAlmostEqual(i2f(st.vgpr[14][1]), 29.0, places=5)
def test_v_fmac_f32(self):
"""V_FMAC_F32: d = d + a*b using inline constants."""
instructions = [
+35 -16
View File
@@ -20,6 +20,28 @@ class TestFMA(unittest.TestCase):
st = run_program(instructions, n_lanes=1)
self.assertAlmostEqual(i2f(st.vgpr[0][3]), 9.0, places=5)
def test_v_mullit_f32_basic(self):
"""V_MULLIT_F32 multiplies when the guard input is valid."""
instructions = [
v_mov_b32_e32(v[0], f2i(2.0)),
v_mov_b32_e32(v[1], f2i(3.0)),
v_mov_b32_e32(v[2], f2i(1.0)),
v_mullit_f32(v[3], v[0], v[1], v[2]),
]
st = run_program(instructions, n_lanes=1)
self.assertAlmostEqual(i2f(st.vgpr[0][3]), 6.0, places=5)
def test_v_mullit_f32_invalid_guard(self):
"""V_MULLIT_F32 returns -MAX_FLOAT_F32 when the guard input is non-positive."""
instructions = [
v_mov_b32_e32(v[0], f2i(2.0)),
v_mov_b32_e32(v[1], f2i(3.0)),
v_mov_b32_e32(v[2], f2i(0.0)),
v_mullit_f32(v[3], v[0], v[1], v[2]),
]
st = run_program(instructions, n_lanes=1)
self.assertEqual(st.vgpr[0][3], 0xFF7FFFFF)
def test_v_fma_f32_negative(self):
"""V_FMA_F32 with negative multiplier."""
instructions = [
@@ -1592,8 +1614,7 @@ class TestModifierInteractions(unittest.TestCase):
self.assertEqual(st.vgpr[0][2], 0x80000000, "-|(-0.0)| = -0.0")
def test_clamp_with_nan(self):
"""Clamp with NaN input should still produce NaN."""
import math
"""Clamp with NaN input saturates to 0 on RDNA3 hardware."""
quiet_nan = 0x7fc00000
instructions = [
s_mov_b32(s[0], quiet_nan),
@@ -1601,7 +1622,7 @@ class TestModifierInteractions(unittest.TestCase):
VOP3(VOP3Op.V_ADD_F32, vdst=v[1], src0=v[0], src1=0.0, clmp=1),
]
st = run_program(instructions, n_lanes=1)
self.assertTrue(math.isnan(i2f(st.vgpr[0][1])))
self.assertEqual(st.vgpr[0][1], 0)
def test_omod_ignored(self):
"""OMOD field is ignored on RDNA3 hardware."""
@@ -3605,32 +3626,30 @@ class TestPermlane(unittest.TestCase):
"""V_PERMLANE16_B32 broadcast lane 0 to all lanes in row."""
# lanesel = all zeros -> all positions read from lane 0 within row
instructions = [
v_mov_b32_e32(v[0], 0xCAFEBABE), # source data
v_mov_b32_e32(v[0], v[255]),
s_mov_b32(s[0], 0), # lanesel low = 0 (all read lane 0)
s_mov_b32(s[1], 0), # lanesel high = 0
v_permlane16_b32(v[1], v[0], s[0], s[1]),
]
st = run_program(instructions, n_lanes=4)
# All lanes read from lane 0 of their row
for lane in range(4):
self.assertEqual(st.vgpr[lane][1], 0xCAFEBABE)
st = run_program(instructions, n_lanes=32)
for lane in range(16): self.assertEqual(st.vgpr[lane][1], 0)
for lane in range(16, 32): self.assertEqual(st.vgpr[lane][1], 16)
def test_v_permlanex16_b32_identity(self):
"""V_PERMLANEX16_B32 cross-row read with identity selection."""
# In wave32: row 0 (lanes 0-15) reads from row 1 (lanes 16-31) and vice versa
# With single lane in row 0, it reads from lane 0 of row 1 (lane 16)
# But lane 16 doesn't exist in 1-lane test, so use 32 lanes
instructions = [
v_mov_b32_e32(v[0], 0x11111111), # All lanes have this initially
v_mov_b32_e32(v[0], v[255]),
s_mov_b32(s[0], 0x76543210), # lanesel low
s_mov_b32(s[1], 0xFEDCBA98), # lanesel high
v_permlanex16_b32(v[1], v[0], s[0], s[1]),
]
st = run_program(instructions, n_lanes=32)
# Lane 0 in row 0 reads from lane 0 of row 1 (lane 16)
self.assertEqual(st.vgpr[0][1], 0x11111111)
# Lane 16 in row 1 reads from lane 0 of row 0 (lane 0)
self.assertEqual(st.vgpr[16][1], 0x11111111)
self.assertEqual(st.vgpr[0][1], 16)
self.assertEqual(st.vgpr[5][1], 21)
self.assertEqual(st.vgpr[15][1], 31)
self.assertEqual(st.vgpr[16][1], 0)
self.assertEqual(st.vgpr[21][1], 5)
self.assertEqual(st.vgpr[31][1], 15)
if __name__ == '__main__':
-528
View File
@@ -1,528 +0,0 @@
# Test to compare Python and Rust RDNA3 emulators by running real tinygrad kernels
import unittest, ctypes
from dataclasses import dataclass
from pathlib import Path
from tinygrad import Device
from test.mockgpu.amd.emu import WaveState, _decode_at, WAVE_SIZE, VCC_LO, EXEC_LO, SCC
from tinygrad.renderer.amd import decode_inst
import tinygrad
REMU_PATH = Path(tinygrad.__file__).parent.parent / "extra/remu/target/release/libremu.so"
if not REMU_PATH.exists(): REMU_PATH = Path(tinygrad.__file__).parent.parent / "extra/remu/target/release/libremu.dylib"
def set_valid_mem_ranges(ranges): pass # emu2 doesn't need this
def _is_f32_nan(bits: int) -> bool:
"""Check if 32-bit value is a NaN (exponent all 1s, mantissa non-zero)."""
return (bits & 0x7f800000) == 0x7f800000 and (bits & 0x007fffff) != 0
def _vals_equal(a: int, b: int) -> bool:
"""Compare two 32-bit values, treating all NaN bit patterns as equal."""
if a == b: return True
return _is_f32_nan(a) and _is_f32_nan(b)
@dataclass
class KernelSnapshot:
code: bytes
src: str
global_size: tuple[int, int, int]
local_size: tuple[int, int, int]
buf_idxs: list[int] # indices into shared buffer pool
buf_sizes: list[int] # sizes for each buffer index
@dataclass
class StateSnapshot:
pc: int
scc: int
vcc: int
exec_mask: int
sgpr: list[int]
vgpr: list[list[int]]
def diff(self, other: 'StateSnapshot', n_lanes: int, arrow: str = " vs ") -> list[str]:
"""Return list of differences between two states."""
diffs = []
if self.pc != other.pc: diffs.append(f"pc: {self.pc}{arrow}{other.pc}")
if self.scc != other.scc: diffs.append(f"scc: {self.scc}{arrow}{other.scc}")
if self.vcc != other.vcc: diffs.append(f"vcc: 0x{self.vcc:08x}{arrow}0x{other.vcc:08x}")
if self.exec_mask != other.exec_mask: diffs.append(f"exec: 0x{self.exec_mask:08x}{arrow}0x{other.exec_mask:08x}")
for i, (a, b) in enumerate(zip(self.sgpr, other.sgpr)):
# Skip VCC_LO/HI (106/107) and EXEC_LO/HI (126/127) as they alias vcc/exec_mask which are compared separately
if i in (106, 107, 126, 127): continue
if not _vals_equal(a, b): diffs.append(f"sgpr[{i}]: 0x{a:08x}{arrow}0x{b:08x}")
for lane in range(n_lanes):
for i, (a, b) in enumerate(zip(self.vgpr[lane], other.vgpr[lane])):
if not _vals_equal(a, b): diffs.append(f"vgpr[{lane}][{i}]: 0x{a:08x}{arrow}0x{b:08x}")
return diffs
class CStateSnapshot(ctypes.Structure):
_fields_ = [("pc", ctypes.c_uint32), ("scc", ctypes.c_uint32), ("vcc", ctypes.c_uint32), ("exec_mask", ctypes.c_uint32),
("sgpr", ctypes.c_uint32 * 128), ("vgpr", (ctypes.c_uint32 * 256) * 32)]
def to_snapshot(self) -> StateSnapshot:
return StateSnapshot(pc=self.pc, scc=self.scc, vcc=self.vcc, exec_mask=self.exec_mask,
sgpr=list(self.sgpr), vgpr=[list(self.vgpr[i]) for i in range(32)])
class RustEmulator:
def __init__(self):
self.lib = ctypes.CDLL(str(REMU_PATH))
self.lib.wave_create.argtypes = [ctypes.c_void_p, ctypes.c_uint32, ctypes.c_uint32]
self.lib.wave_create.restype = ctypes.c_void_p
self.lib.wave_step.argtypes = [ctypes.c_void_p]
self.lib.wave_step.restype = ctypes.c_int32
self.lib.wave_get_snapshot.argtypes = [ctypes.c_void_p, ctypes.POINTER(CStateSnapshot)]
self.lib.wave_set_sgpr.argtypes = [ctypes.c_void_p, ctypes.c_uint32, ctypes.c_uint32]
self.lib.wave_set_vgpr.argtypes = [ctypes.c_void_p, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32]
self.lib.wave_init_lds.argtypes = [ctypes.c_void_p, ctypes.c_uint32]
self.lib.wave_free.argtypes = [ctypes.c_void_p]
self.ctx = None
def create(self, kernel: bytes, n_lanes: int):
kernel_buf = (ctypes.c_char * len(kernel)).from_buffer_copy(kernel)
self.ctx = self.lib.wave_create(ctypes.addressof(kernel_buf), len(kernel), n_lanes)
self._kernel_buf = kernel_buf
def step(self) -> int: return self.lib.wave_step(self.ctx)
def set_sgpr(self, idx: int, val: int): self.lib.wave_set_sgpr(self.ctx, idx, val)
def set_vgpr(self, lane: int, idx: int, val: int): self.lib.wave_set_vgpr(self.ctx, lane, idx, val)
def init_lds(self, size: int): self.lib.wave_init_lds(self.ctx, size)
def get_snapshot(self) -> StateSnapshot:
snap = CStateSnapshot()
self.lib.wave_get_snapshot(self.ctx, ctypes.byref(snap))
return snap.to_snapshot()
def free(self):
if self.ctx:
self.lib.wave_free(self.ctx)
self.ctx = None
class PythonEmulator:
def __init__(self):
self.state: WaveState | None = None
self.program: dict[int, tuple] = {} # lazily populated: pc -> (name, fxn, globals)
self.vmem_buf = None
self.lds_buf = None
self.kernel_buf = None # Keep kernel bytes alive
self.lib_addr = 0 # Base address of kernel code
def create(self, kernel: bytes, n_lanes: int):
import ctypes
from tinygrad.device import Buffer, BufferSpec
from tinygrad.dtype import dtypes
# Store kernel in a ctypes buffer so _decode_at can read from memory at actual PC address
self.kernel_buf = (ctypes.c_char * len(kernel)).from_buffer_copy(kernel)
self.lib_addr = ctypes.addressof(self.kernel_buf)
self.program = {}
self.state = WaveState(n_lanes)
self.state.pc = self.lib_addr # Set PC to code base address
self.vmem_buf = Buffer('CPU', 1 << 40, dtypes.uint32, options=BufferSpec(external_ptr=0)).ensure_allocated()
self.lds_buf = Buffer('CPU', 65536 // 4, dtypes.uint32).ensure_allocated()
def _ensure_decoded(self, pc: int):
if pc not in self.program:
runner, _ = _decode_at(pc, "rdna3")
self.program[pc] = (runner.p.function_name, runner._prg.fxn, runner.p.globals)
def step(self) -> int:
import ctypes
assert self.state is not None
pc = self.state.pc
if pc == 0xFFFFFFFFFFFFFFFF: return -1
self._ensure_decoded(pc)
name, fxn, globals_list = self.program[pc]
buf_addrs = {0: self.state.sgpr_buf._buf.va_addr, 1: self.state.vgpr_buf._buf.va_addr, # type: ignore[union-attr]
2: self.vmem_buf._buf.va_addr, 3: self.lds_buf._buf.va_addr} # type: ignore[union-attr]
fxn(*[ctypes.c_uint64(buf_addrs[g]) for g in globals_list], ctypes.c_int32(0))
return -1 if self.state.pc == 0xFFFFFFFFFFFFFFFF else 0
def set_sgpr(self, idx: int, val: int):
assert self.state is not None
self.state._write_sgpr(idx, val)
def set_vgpr(self, lane: int, idx: int, val: int):
assert self.state is not None
self.state._write_vgpr(idx, lane, val)
def get_snapshot(self) -> StateSnapshot:
assert self.state is not None
sgpr = [self.state._read_sgpr(i) for i in range(128)]
vgpr = [[self.state._read_vgpr(reg, lane) for reg in range(256)] for lane in range(WAVE_SIZE)]
# Convert actual PC address to word offset for comparison with Rust emulator
pc_offset = (self.state.pc - self.lib_addr) // 4 if self.state.pc != 0xFFFFFFFFFFFFFFFF else 0xFFFFFFFFFFFFFFFF
return StateSnapshot(pc=pc_offset, scc=self.state._read_sgpr(SCC.offset), vcc=sgpr[VCC_LO.offset],
exec_mask=sgpr[EXEC_LO.offset], sgpr=sgpr, vgpr=vgpr)
def run_single_kernel(kernel: bytes, n_lanes: int, args_ptr: int, global_size: tuple[int, int, int],
local_size: tuple[int, int, int], max_steps: int, debug: bool, trace_len: int,
kernel_idx: int = 0, max_workgroups: int = 8) -> tuple[bool, str, int]:
"""Run a single kernel through both emulators. Returns (success, message, total_steps)."""
gx, gy, gz = global_size
lx, ly, lz = local_size
total_steps = 0
wg_count = 0
for gidz in range(gz):
for gidy in range(gy):
for gidx in range(gx):
if wg_count >= max_workgroups: return True, f"Completed {wg_count} workgroups (limit reached)", total_steps
wg_count += 1
rust = RustEmulator()
python = PythonEmulator()
rust.create(kernel, n_lanes)
python.create(kernel, n_lanes)
# Initialize LDS (64KB, standard size for AMD GPUs)
rust.init_lds(65536)
for emu in (rust, python):
emu.set_sgpr(0, args_ptr & 0xffffffff)
emu.set_sgpr(1, (args_ptr >> 32) & 0xffffffff)
emu.set_sgpr(13, gidx)
emu.set_sgpr(14, gidy)
emu.set_sgpr(15, gidz)
# Initialize v[0] with packed workitem IDs for each lane
for lane in range(n_lanes):
tid = lane
z, y, x = tid // (lx * ly), (tid // lx) % ly, tid % lx
emu.set_vgpr(lane, 0, (z << 20) | (y << 10) | x)
step = 0
trace: list[tuple[int, int, str, StateSnapshot, StateSnapshot]] = []
prev_sync_after = False # Track if previous instruction had known Rust bugs
try:
while step < max_steps:
rust_before = rust.get_snapshot()
python_before = python.get_snapshot()
pc_addr = python.lib_addr + python_before.pc * 4 # Convert word offset to actual address
python._ensure_decoded(pc_addr)
inst_hex_name = python.program[pc_addr][0]
# Decode the instruction to get mnemonic for sync_after checks
try:
# Format is mnemonic_hexbytes, e.g. v_exp_f32_e32_014b027e -> hex is 014b027e
parts = inst_hex_name.rsplit('_', 1)
inst_bytes_hex = parts[1] if len(parts) == 2 else ""
inst_bytes = bytes.fromhex(inst_bytes_hex) if inst_bytes_hex else b''
decoded = decode_inst(inst_bytes) if inst_bytes else None
inst_mnemonic = repr(decoded).split('(')[0] if decoded else ""
except Exception:
inst_mnemonic = ""
# For generic instructions, use function name for sync_after check
if not inst_mnemonic: inst_mnemonic = inst_hex_name
inst_str = inst_hex_name
trace.append((step, python_before.pc, inst_str, rust_before, python_before))
if len(trace) > trace_len: trace.pop(0)
if debug: print(f"K{kernel_idx} WG({gidx},{gidy},{gidz}) Step {step}: PC={python_before.pc}, inst={inst_str}")
# Instructions with known Rust emulator bugs or precision differences - sync Python to Rust after execution
# v_div_scale/v_div_fixup: Rust has different VCC handling
# v_cvt_f16_f32: Rust clears high 16 bits, but hardware (and Python) preserves them
# s_add_i32/s_sub_i32: Rust has incorrect SCC overflow detection
# v_exp_f32/v_log_f32/v_ldexp_f32: precision differences in transcendental functions
# s_delay_alu: Rust handles differently
# v_add_co_ci_u32/v_sub_co_ci_u32/v_subrev_co_ci_u32: Rust preserves inactive VCC bits, but hardware clears all bits
sync_after = any(x in inst_mnemonic.lower() for x in ('v_div_scale', 'v_div_fixup', 'v_cvt_f16_f32', 's_add_i32', 's_sub_i32',
'v_exp_f32', 'v_log_f32', 'v_ldexp_f32', 's_delay_alu',
'v_add_co_ci_u32', 'v_sub_co_ci_u32', 'v_subrev_co_ci_u32'))
# Skip comparison if previous instruction had known Rust bugs (states were synced but may still differ slightly)
diffs = rust_before.diff(python_before, n_lanes) if not prev_sync_after else []
if diffs:
trace_lines = []
for idx, (s, pc, d, rb, pb) in enumerate(trace):
trace_lines.append(f" step {s}: PC={pc:3d} {d}")
if idx < len(trace) - 1:
next_rb, next_pb = trace[idx + 1][3:5]
rust_diffs = rb.diff(next_rb, n_lanes, "->")
python_diffs = pb.diff(next_pb, n_lanes, "->")
if rust_diffs: trace_lines.append(f" rust: {', '.join(rust_diffs[:5])}")
if python_diffs: trace_lines.append(f" python: {', '.join(python_diffs[:5])}")
elif rust_diffs: trace_lines.append(" python: (no changes)")
else:
# Last traced instruction - compare with current state
rust_diffs = rb.diff(rust_before, n_lanes, "->")
python_diffs = pb.diff(python_before, n_lanes, "->")
if rust_diffs: trace_lines.append(f" rust: {', '.join(rust_diffs[:5])}")
if python_diffs: trace_lines.append(f" python: {', '.join(python_diffs[:5])}")
elif rust_diffs: trace_lines.append(" python: (no changes)")
trace_str = "\n".join(trace_lines)
msg = f"K{kernel_idx} WG({gidx},{gidy},{gidz}) Step {step} before inst '{inst_str}': states differ (rust vs python):\n "
msg += "\n ".join(diffs[:10]) + f"\n Recent instructions:\n{trace_str}"
return False, msg, total_steps
rust_result = rust.step()
python_result = python.step()
if rust_result != python_result:
# Rust returns 1 for unsupported instructions - skip test
if rust_result == 1 and python_result == 0:
raise unittest.SkipTest(f"Rust emulator doesn't support instruction: {inst_str}")
trace_str = "\n".join(f" step {s}: PC={pc:3d} {d}" for s, pc, d, _, _ in trace)
msg = (f"K{kernel_idx} WG({gidx},{gidy},{gidz}) Step {step}: different return codes: "
f"rust={rust_result}, python={python_result}, inst={inst_str}\n Recent instructions:\n{trace_str}")
return False, msg, total_steps
# Sync Python state to Rust after instructions with known Rust emulator differences
if sync_after:
rust_after = rust.get_snapshot()
for i in range(128): python.set_sgpr(i, rust_after.sgpr[i])
for lane in range(n_lanes):
for i in range(256): python.set_vgpr(lane, i, rust_after.vgpr[lane][i])
assert python.state is not None
# Convert Rust's word-based PC to Python's actual address
python.state.pc = python.lib_addr + rust_after.pc * 4
python.state._write_sgpr(SCC.offset, rust_after.scc)
python.state._write_sgpr(VCC_LO.offset, rust_after.vcc)
python.state._write_sgpr(EXEC_LO.offset, rust_after.exec_mask)
prev_sync_after = sync_after
if rust_result == -1:
total_steps += step + 1
break
if rust_result == 1:
total_steps += step + 1
break
if rust_result < 0 and rust_result != -2:
return False, f"K{kernel_idx} WG({gidx},{gidy},{gidz}) Step {step}: error code {rust_result}", total_steps
step += 1
else:
return False, f"K{kernel_idx} WG({gidx},{gidy},{gidz}) Max steps ({max_steps}) reached", total_steps
finally:
rust.free()
return True, f"Completed {gx*gy*gz} workgroups", total_steps
def compare_emulators_multi_kernel(kernels: list[KernelSnapshot], buf_pool: dict[int, int], max_steps: int = 1000,
debug: bool = False, trace_len: int = 10, buf_data: dict[int, bytes] | None = None) -> tuple[bool, str]:
"""Run all kernels through both emulators with shared buffer pool."""
if buf_data is None: buf_data = {}
# Allocate shared buffer pool with padding for over-reads (GPU loads up to 16 bytes at once)
buf_id_to_ptr: dict[int, int] = {}
buffers = []
for buf_id, size in buf_pool.items():
padded_size = ((size + 15) // 16) * 16 + 16 # round up to 16 bytes + extra padding
# Initialize with data from COPY if available
init_data = buf_data.get(buf_id, b'\x00' * padded_size)
init_list = list(init_data) + [0] * (padded_size - len(init_data))
buf = (ctypes.c_uint8 * padded_size)(*init_list[:padded_size])
buffers.append((buf, padded_size))
buf_id_to_ptr[buf_id] = ctypes.addressof(buf)
# Set up valid memory ranges
ranges = {(ctypes.addressof(b), size) for b, size in buffers}
total_steps = 0
for ki, kernel in enumerate(kernels):
# Create args array for this kernel's buffers
args = (ctypes.c_uint64 * len(kernel.buf_idxs))(*[buf_id_to_ptr[bid] for bid in kernel.buf_idxs])
args_ptr = ctypes.addressof(args)
# Update valid ranges to include this args array
kernel_ranges = ranges | {(args_ptr, ctypes.sizeof(args))}
set_valid_mem_ranges(kernel_ranges)
n_lanes = kernel.local_size[0] * kernel.local_size[1] * kernel.local_size[2]
ok, msg, steps = run_single_kernel(
kernel.code, min(n_lanes, 32), args_ptr, kernel.global_size,
kernel.local_size, max_steps, debug, trace_len, ki
)
total_steps += steps
if not ok:
return False, msg
return True, f"Completed {len(kernels)} kernels, {total_steps} total steps"
def compare_emulators_with_memory(kernel: bytes, n_lanes: int, buf_sizes: list, max_steps: int = 1000, debug: bool = False,
global_size: tuple[int, int, int] = (1, 1, 1), trace_len: int = 10) -> tuple[bool, str]:
"""Run both emulators with memory set up for tinygrad kernels, executing all workgroups. Legacy wrapper."""
# Allocate buffers
buffers = []
for size in buf_sizes:
buf = (ctypes.c_uint8 * size)(*[0] * size)
buffers.append(buf)
# Create args array with buffer pointers
args = (ctypes.c_uint64 * len(buffers))(*[ctypes.addressof(b) for b in buffers])
args_ptr = ctypes.addressof(args)
# Set up valid memory ranges for Python emulator
ranges = {(ctypes.addressof(b), len(b)) for b in buffers}
ranges.add((args_ptr, ctypes.sizeof(args)))
set_valid_mem_ranges(ranges)
# Legacy wrapper assumes local_size = (n_lanes, 1, 1)
ok, msg, _ = run_single_kernel(kernel, n_lanes, args_ptr, global_size, (n_lanes, 1, 1), max_steps, debug, trace_len)
return ok, msg
def get_kernels_from_tinygrad(op_fn) -> tuple[list[KernelSnapshot], dict[int, int], dict[int, bytes]]:
"""Compile a tinygrad operation and extract all kernels with their buffer mappings."""
from tinygrad import Tensor
from tinygrad.runtime.support.elf import elf_loader
out = op_fn(Tensor)
sched = out.schedule()
kernels = []
buf_pool: dict[int, int] = {} # buffer id -> size
buf_data: dict[int, bytes] = {} # buffer id -> initial data from COPY
for ei in sched:
lowered = ei.lower()
if ei.ast.op.name == 'COPY':
# Handle COPY: extract source data to initialize destination buffer
if len(lowered.bufs) >= 2:
dst_buf, src_buf = lowered.bufs[0], lowered.bufs[1]
dst_id = id(dst_buf)
if dst_id not in buf_pool:
buf_pool[dst_id] = dst_buf.nbytes
# Get source data if it's from numpy/CPU
if hasattr(src_buf, 'base') and src_buf.base is not None and hasattr(src_buf.base, '_buf'):
src_data = bytes(src_buf.base._buf)
buf_data[dst_id] = src_data
elif ei.ast.op.name == 'SINK':
if lowered.prg and lowered.prg.p.lib:
lib = bytes(lowered.prg.p.lib)
_, sections, _ = elf_loader(lib)
for sec in sections:
if sec.name == '.text':
buf_idxs = []
buf_sizes = []
for b in lowered.bufs:
buf_id = id(b)
if buf_id not in buf_pool:
buf_pool[buf_id] = b.nbytes
buf_idxs.append(buf_id)
buf_sizes.append(b.nbytes)
kernels.append(KernelSnapshot(
code=bytes(sec.content),
src=lowered.prg.p.src,
global_size=tuple(lowered.prg.p.global_size),
local_size=tuple(lowered.prg.p.local_size),
buf_idxs=buf_idxs,
buf_sizes=buf_sizes
))
if not kernels: raise RuntimeError("No kernel found")
return kernels, buf_pool, buf_data
def get_kernel_from_tinygrad(op_fn) -> tuple[bytes, tuple[int, int, int], tuple[int, int, int], list]:
"""Compile a tinygrad operation and extract the last (main) kernel binary. Legacy wrapper."""
kernels, _, _ = get_kernels_from_tinygrad(op_fn)
k = kernels[-1]
return k.code, k.global_size, k.local_size, k.buf_sizes
@unittest.skipUnless(Device.DEFAULT == "AMD", "requires AMD device")
class TestTinygradKernels(unittest.TestCase):
"""Compare emulators on real tinygrad-compiled kernels."""
def _test_kernel(self, op_fn, max_steps=10000):
kernels, buf_pool, buf_data = get_kernels_from_tinygrad(op_fn)
ok, msg = compare_emulators_multi_kernel(kernels, buf_pool, max_steps=max_steps, buf_data=buf_data)
self.assertTrue(ok, msg)
# Basic ops - consolidated tests covering key instruction patterns
def test_unary_ops(self): self._test_kernel(lambda T: T([-1.0, 0.0, 1.0, 2.0]).relu().exp().log().sqrt().reciprocal())
def test_binary_ops(self): self._test_kernel(lambda T: (T([1.0, 2.0]) + T([3.0, 4.0])) * T([0.5, 0.5]) - T([1.0, 1.0]))
def test_trig(self): self._test_kernel(lambda T: T([0.1, 1.0, 3.14, -1.0]*8).sin() + T([0.1, 1.0, 3.14, -1.0]*8).cos())
def test_compare(self): self._test_kernel(lambda T: (T.empty(64) < T.empty(64)).where(T.empty(64), T.empty(64)))
def test_bitwise(self): self._test_kernel(lambda T: (T([0xF0, 0x0F, 0xFF]*11).int() & T([0x0F, 0x0F, 0x00]*11).int()) | T([1]*33).int())
def test_int_ops(self): self._test_kernel(lambda T: ((T.empty(64).int() + T.empty(64).int()) * T.empty(64).int()).float())
# Reductions
def test_reduce(self): self._test_kernel(lambda T: T.empty(64).sum() + T.empty(64).max())
def test_argmax(self): self._test_kernel(lambda T: T.empty(64).argmax())
# Matmul
def test_gemm(self): self._test_kernel(lambda T: T.empty(8, 8) @ T.empty(8, 8), max_steps=100000)
@unittest.skip("Rust emulator crashes on this kernel (assertion failure in thread.rs)")
def test_gemm_fp16(self): self._test_kernel(lambda T: T.empty(16, 16).half() @ T.empty(16, 16).half(), max_steps=100000)
# Complex ops
def test_softmax(self): self._test_kernel(lambda T: T.empty(16).softmax())
def test_layernorm(self): self._test_kernel(lambda T: T.empty(8, 8).layernorm())
# Memory patterns
def test_memory(self): self._test_kernel(lambda T: T.empty(4, 4).permute(1, 0).contiguous() + T.empty(4, 1).expand(4, 4))
# Cast ops
def test_cast(self): self._test_kernel(lambda T: T.empty(32).half().float() + T.empty(32).int().float())
# Pooling - regression for VCC wave32 mode
def test_pool2d(self):
self._test_kernel(lambda T: T.empty(1, 1, 8, 8).avg_pool2d(kernel_size=(4,4)) + T.empty(1, 1, 8, 8).max_pool2d(kernel_size=(4,4)))
# Convolution
def test_conv2d(self): self._test_kernel(lambda T: T.empty(1, 2, 8, 8).conv2d(T.empty(2, 2, 3, 3)), max_steps=50000)
# Regression tests
def test_topk(self): self._test_kernel(lambda T: T.empty(64).topk(3)[0])
def test_interpolate(self): self._test_kernel(lambda T: T.empty(1,2,16,16).relu().cast('uint8').interpolate((8,8), mode="linear"))
def test_index_int64(self):
from tinygrad import dtypes
self._test_kernel(lambda T: T.empty(4, 4)[T.arange(4).cast(dtypes.int64), :])
def test_gelu(self): self._test_kernel(lambda T: T.empty(32, 32).gelu())
def test_exp(self): self._test_kernel(lambda T: T.empty(1024).exp())
def test_cross_entropy(self):
import numpy as np
np.random.seed(0)
classes = np.random.randint(0, 10, (16,), dtype=np.int32).tolist()
x_np = np.random.randn(16, 10).astype(np.float32)
self._test_kernel(lambda T: (T(x_np.tolist()).reshape(16,10) + 0).cross_entropy((T(classes).int().reshape(16) + 0)))
def test_isinf(self): self._test_kernel(lambda T: T([float('-inf'), 0., float('inf'), 1.1]*8).isinf())
def test_sin_f64(self):
from tinygrad import dtypes
self._test_kernel(lambda T: T([2.0], dtype=dtypes.float64).sin())
def test_sin_large_f32(self):
"""Test sin with large values that trigger Payne-Hanek range reduction."""
# Values around 859240 trigger the Payne-Hanek algorithm
# This tests the integer multiply-high instructions used in range reduction
self._test_kernel(lambda T: T([859240.0, 1000000.0, 100594688.0]).sin())
def test_clip_zero_one(self):
"""Test clip(0, 1) - regression for binary_crossentropy failure."""
import numpy as np
np.random.seed(0)
x_np = np.random.uniform(-2, 2, (32, 10)).astype(np.float32).tolist()
self._test_kernel(lambda T: T(x_np).clip(0, 1))
def test_mod_int64(self):
"""Test int64 modulo, especially edge cases like 1 % -1."""
from tinygrad import dtypes
self._test_kernel(lambda T: T([1, 10, -10, 7], dtype=dtypes.int64) % T([-1, 3, 3, -3], dtype=dtypes.int64))
def test_expand_flatten_sum(self):
"""Test flatten of expanded tensor followed by sum.
Bug: flatten() of an expanded tensor produces wrong results for certain sizes.
Sizes that are multiples of 32 work (32, 48, 64), but sizes like 33, 49, 50 fail.
This breaks masked_select and nonzero operations.
"""
import numpy as np
np.random.seed(0)
x_np = np.random.uniform(-2, 2, (33,)).astype(np.float32)
self._test_kernel(lambda T: (T(x_np.tolist()) > 0.5).unsqueeze(-1).expand(33, 3).flatten().sum())
@unittest.skip("slow and broken with AMD:LLVM")
def test_nonzero(self):
"""Test nonzero operation - counts and gathers indices of non-zero elements."""
import numpy as np
np.random.seed(42)
x_np = np.random.rand(10, 5, 3).astype(np.float32)
self._test_kernel(lambda T: (T(x_np.tolist()) > 0.5).nonzero())
@unittest.skip("Precision differences in v_exp/v_log accumulate across kernels, causing memory divergence")
def test_softmax_argmax_fused(self):
"""Test fused softmax+argmax - tracks exp2 precision issue.
The fused kernel recomputes softmax inline and Python emulator's exp2 polynomial
has up to 1 ULP error vs native exp2f, causing accumulated differences.
"""
import torch
torch.manual_seed(0)
x_np = torch.rand(4, 10).numpy()
self._test_kernel(lambda T: T(x_np.tolist()).softmax(1).argmax())
if __name__ == "__main__":
unittest.main()
+5 -5
View File
@@ -15,7 +15,7 @@ from extra.gemm.amd_asm_matmul import Kernel
def custom_add_one(A:UOp) -> UOp:
A = A.flatten()
assert dtypes.is_float(A.dtype.base), f"buffer dtype must be float32, got {A.dtype}"
threads = UOp.special(A.size, "lidx0")
threads = UOp.special(A.numel(), "lidx0")
insts = [
s_load_b64(s[0:1], s[0:1], soffset=NULL),
s_waitcnt_lgkmcnt(sdst=NULL, simm16=0),
@@ -27,13 +27,13 @@ def custom_add_one(A:UOp) -> UOp:
global_store_b32(addr=v[0], data=v[1], saddr=s[0:1]),
s_endpgm(),
]
sink = UOp.sink(A.base, threads, arg=KernelInfo(f"custom_add_one_{A.size}", estimates=Estimates(ops=A.size, mem=A.size*4*2)))
sink = UOp.sink(A.base, threads, arg=KernelInfo(f"custom_add_one_{A.numel()}", estimates=Estimates(ops=A.numel(), mem=A.numel()*4*2)))
return UOp(Ops.PROGRAM, src=(sink, UOp(Ops.DEVICE, arg="AMD"), UOp(Ops.LINEAR, src=tuple([UOp(Ops.INS, arg=x) for x in insts]))))
def custom_add_var(A:UOp, B:UOp) -> UOp:
A,B = A.flatten(), B.flatten()
assert A.dtype.base == dtypes.uint32, f"buffer dtype must be uint32, got {A.dtype}"
threads = UOp.special(A.size, "lidx0")
threads = UOp.special(A.numel(), "lidx0")
var = UOp.variable("var", 0, 10)
insts = [
s_load_b128(s[4:7], s[0:1]),
@@ -46,7 +46,7 @@ def custom_add_var(A:UOp, B:UOp) -> UOp:
global_store_b32(addr=v[0], data=v[1], saddr=s[4:5]),
s_endpgm(),
]
sink = UOp.sink(A.base, B.base, var, threads, arg=KernelInfo(f"custom_add_var_{A.size}"))
sink = UOp.sink(A.base, B.base, var, threads, arg=KernelInfo(f"custom_add_var_{A.numel()}"))
return UOp(Ops.PROGRAM, src=(sink, UOp(Ops.DEVICE, arg="AMD"), UOp(Ops.LINEAR, src=tuple([UOp(Ops.INS, arg=x) for x in insts]))))
def custom_wave_sync(A:UOp, arch:str) -> UOp:
@@ -132,7 +132,7 @@ def custom_handwritten(A:UOp, arch:str) -> UOp:
def custom_data_deps(A:UOp, arch:str) -> UOp:
A = A.flatten()
threads = UOp.special(A.size, "lidx0")
threads = UOp.special(A.numel(), "lidx0")
k = Kernel(arch)
k.emit(s_load_b64(s[0:1], s[0:1], soffset=NULL))
k.emit(s_waitcnt_lgkmcnt(sdst=NULL, simm16=0))
+57 -1
View File
@@ -7,7 +7,7 @@ from tinygrad.uop.ops import UOp, Ops
from test.mockgpu.amd.emu import parse_pcode
from test.mockgpu.amd.pcode import parse_expr
from tinygrad.runtime.autogen.amd.rdna3.str_pcode import PCODE
from tinygrad.runtime.autogen.amd.rdna3.enum import VOP1Op, VOP2Op, SOP2Op, DSOp
from tinygrad.runtime.autogen.amd.rdna3.enum import VOP1Op, VOP2Op, SOP2Op, DSOp, GLOBALOp
def _srcs():
"""Create minimal source variables for pcode parsing."""
@@ -113,6 +113,7 @@ class TestParseExpr(unittest.TestCase):
result = parse_expr('cond ? a : b', vrs)
self.assertEqual(result.op, Ops.WHERE)
class TestForLoopParsing(unittest.TestCase):
"""Test for loop parsing (CLZ/CTZ patterns)."""
@@ -164,6 +165,20 @@ class TestForLoopParsing(unittest.TestCase):
class TestDSPcodePatterns(unittest.TestCase):
"""Test DS instruction pcode patterns."""
def test_global_atomic_add_f32_parsing(self):
"""Test GLOBAL_ATOMIC_ADD_F32 keeps memory values in float dtype."""
vmem = UOp(Ops.PARAM, dtypes.uint32.ptr(1024), arg=2)
srcs = {
'ADDR': UOp.const(dtypes.uint64, 0),
'DATA': UOp.const(dtypes.uint32, 0x3f800000),
'_vmem': vmem,
}
_, assigns = parse_pcode(PCODE[GLOBALOp.GLOBAL_ATOMIC_ADD_F32], srcs)
mem_write = next(val for dest, val in assigns if dest == 'MEM[ADDR].f32')
self.assertEqual(mem_write[1].op, Ops.ADD) # type: ignore[index]
self.assertEqual(mem_write[1].dtype, dtypes.float32) # type: ignore[index]
def test_ds_load_b32_pcode(self):
"""Test DS_LOAD_B32 pcode is parseable."""
pcode = PCODE.get(DSOp.DS_LOAD_B32)
@@ -285,6 +300,47 @@ class TestConditionalParsing(unittest.TestCase):
# Result should be a WHERE (ternary becomes WHERE)
self.assertEqual(val.op, Ops.WHERE)
class TestConcatWidthParsing(unittest.TestCase):
"""Test that bit extracts keep the right width for concat/unary ops."""
def test_permlanex16_altrow_concat(self):
for row, expected in [(0, 1), (1, 0), (2, 3), (3, 2)]:
parsed = parse_expr('{ row[1], ~row[0] }', {'row': UOp.const(dtypes.uint32, row)})
self.assertEqual(parsed.simplify().arg, expected)
def test_permlane64_altlane_concat(self):
for lane, expected in [(0, 32), (1, 33), (31, 63), (32, 0), (63, 31)]:
parsed = parse_expr('{ ~lane[5], lane[4:0] }', {'lane': UOp.const(dtypes.uint32, lane)})
self.assertEqual(parsed.simplify().arg, expected)
def test_permlane64_wave64_pcode_indices(self):
vgpr = UOp(Ops.PARAM, dtypes.uint32.ptr(256), arg=0)
srcs = {
'SRC0': UOp.const(dtypes.uint32, 0),
'VDST': UOp.const(dtypes.uint32, 1),
'EXEC_LO': UOp.const(dtypes.uint32, 0xFFFFFFFF),
'EXEC': UOp.const(dtypes.uint64, 0xFFFFFFFFFFFFFFFF),
'_vgpr': vgpr,
'_wave_size': 64,
'S0': UOp.const(dtypes.uint32, 0),
'S1': UOp.const(dtypes.uint32, 0),
'S2': UOp.const(dtypes.uint32, 0),
}
def load_idx(v: UOp) -> int:
simp = v.simplify()
self.assertEqual(simp.op, Ops.LOAD)
self.assertEqual(simp.src[0].op, Ops.INDEX)
idx = simp.src[0].src[1].simplify()
self.assertEqual(idx.op, Ops.CONST)
return idx.arg
_, assigns = parse_pcode(PCODE[VOP1Op.V_PERMLANE64_B32_E32], srcs)
self.assertEqual(len(assigns), 64)
for lane, (dst_idx, src_idx) in {0: (64, 32), 31: (95, 63), 32: (96, 0), 63: (127, 31)}.items():
self.assertEqual(assigns[lane][1][0].simplify().arg, dst_idx) # type: ignore[index]
self.assertEqual(load_idx(assigns[lane][1][1]), src_idx) # type: ignore[index]
class TestAllPcode(unittest.TestCase):
"""Test that all pcode from all architectures can be parsed."""
-1
View File
@@ -39,7 +39,6 @@ dev.synchronize()
env = os.environ.copy()
env["AMD"] = "1"
env["MOCKGPU"] = "1"
env["PYTHON_REMU"] = "1"
env["HCQDEV_WAIT_TIMEOUT_MS"] = "10000"
st = time.perf_counter()
+59 -1
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
"""Roundtrip tests: generate tinygrad kernels, decode instructions, re-encode, verify match."""
import unittest, io, sys, re
from dataclasses import dataclass
from tinygrad import Device
from tinygrad.renderer.amd import detect_format
from test.amd.helpers import llvm_assemble, llvm_disasm, get_target, get_mattr
@@ -44,6 +45,64 @@ def compile_and_disasm_batch(instrs: list[str], arch: str = 'rdna3') -> list[str
code = b''.join(llvm_assemble(instrs, mcpu, mattr))
return llvm_disasm(code, mcpu, mattr)[:len(instrs)]
@dataclass
class KernelSnapshot:
code: bytes
src: str
global_size: tuple[int, int, int]
local_size: tuple[int, int, int]
buf_idxs: list[int] # indices into shared buffer pool
buf_sizes: list[int] # sizes for each buffer index
def get_kernels_from_tinygrad(op_fn) -> tuple[list[KernelSnapshot], dict[int, int], dict[int, bytes]]:
"""Compile a tinygrad operation and extract all kernels with their buffer mappings."""
from tinygrad import Tensor
from tinygrad.runtime.support.elf import elf_loader
out = op_fn(Tensor)
sched = out.schedule()
kernels = []
buf_pool: dict[int, int] = {} # buffer id -> size
buf_data: dict[int, bytes] = {} # buffer id -> initial data from COPY
for ei in sched:
lowered = ei.lower()
if ei.ast.op.name == 'COPY':
# Handle COPY: extract source data to initialize destination buffer
if len(lowered.bufs) >= 2:
dst_buf, src_buf = lowered.bufs[0], lowered.bufs[1]
dst_id = id(dst_buf)
if dst_id not in buf_pool:
buf_pool[dst_id] = dst_buf.nbytes
# Get source data if it's from numpy/CPU
if hasattr(src_buf, 'base') and src_buf.base is not None and hasattr(src_buf.base, '_buf'):
src_data = bytes(src_buf.base._buf)
buf_data[dst_id] = src_data
elif ei.ast.op.name == 'SINK':
if lowered.prg and lowered.prg.p.lib:
lib = bytes(lowered.prg.p.lib)
_, sections, _ = elf_loader(lib)
for sec in sections:
if sec.name == '.text':
buf_idxs = []
buf_sizes = []
for b in lowered.bufs:
buf_id = id(b)
if buf_id not in buf_pool:
buf_pool[buf_id] = b.nbytes
buf_idxs.append(buf_id)
buf_sizes.append(b.nbytes)
kernels.append(KernelSnapshot(
code=bytes(sec.content),
src=lowered.prg.p.src,
global_size=tuple(lowered.prg.p.global_size),
local_size=tuple(lowered.prg.p.local_size),
buf_idxs=buf_idxs,
buf_sizes=buf_sizes
))
if not kernels: raise RuntimeError("No kernel found")
return kernels, buf_pool, buf_data
@unittest.skipUnless(Device.DEFAULT == "AMD", "requires AMD device")
class TestTinygradKernelRoundtrip(unittest.TestCase):
"""Test roundtrip on real tinygrad-generated kernels using get_kernels_from_tinygrad pattern."""
@@ -57,7 +116,6 @@ class TestTinygradKernelRoundtrip(unittest.TestCase):
"""
arch = self.arch
from test.amd.test_compare_emulators import get_kernels_from_tinygrad
from tinygrad.runtime.support.elf import elf_loader
from tinygrad.runtime.support.compiler_amd import HIPCompiler, AMDLLVMCompiler
from tinygrad.helpers import DEV
+5 -4
View File
@@ -1,15 +1,16 @@
import unittest, contextlib
from tinygrad import Device, Tensor, Context, TinyJit
from tinygrad.device import Compiled, ProfileProgramEvent, ProfileDeviceEvent
from tinygrad.viz.serve import load_amd_counters
from tinygrad.viz.serve import load_amd_counters, VizData
@contextlib.contextmanager
def save_sqtt():
yield (ret:=[])
data = VizData()
yield data.ctxs
Device[Device.DEFAULT].synchronize()
Device[Device.DEFAULT]._at_profile_finalize()
load_amd_counters(ret, Compiled.profile_events)
ret[:] = [r for r in ret if r["name"].startswith("SQTT")]
load_amd_counters(data, Compiled.profile_events)
data.ctxs[:] = [r for r in data.ctxs if r["name"].startswith("SQTT")]
@unittest.skipUnless(Device.DEFAULT == "AMD", "only runs on AMD")
class TestSQTTProfiler(unittest.TestCase):
+1 -1
View File
@@ -4,7 +4,7 @@ from tinygrad import Tensor, GlobalCounters, dtypes, nn, Device, Variable
from tinygrad.helpers import Context, getenv, DEV
from tinygrad.engine.realize import run_schedule
from tinygrad.engine.realize import CompiledRunner, get_program
from tinygrad.engine.schedule import ExecItem
from tinygrad.schedule import ExecItem
from tinygrad.renderer import Estimates
from tinygrad.renderer.ptx import PTXRenderer
from test.helpers import needs_second_gpu
+12 -12
View File
@@ -6,8 +6,8 @@ from tinygrad.uop.ops import KernelInfo, AxisType
# **** kernels ****
def custom_arange_kernel(C:UOp) -> UOp:
i = UOp.range(C.size, 0)
return C[i].store(i.cast(C.dtype.base)).end(i).sink(arg=KernelInfo(name=f"custom_arange_{C.size}"))
i = UOp.range(C.shape[0], 0)
return C[i].store(i.cast(C.dtype.base)).end(i).sink(arg=KernelInfo(name=f"custom_arange_{C.shape[0]}"))
def custom_eye_kernel(C:UOp) -> UOp:
i = UOp.range(C.shape[0], 0)
@@ -16,22 +16,22 @@ def custom_eye_kernel(C:UOp) -> UOp:
def custom_add_one_kernel(B:UOp, A:UOp) -> UOp:
A,B = A.flatten(), B.flatten()
assert B.size == A.size
i = UOp.range(A.size, 0)
return B[i].store(A[i] + 1).end(i).sink(arg=KernelInfo(name=f"add_one_{A.size}"))
assert B.numel() == A.numel()
i = UOp.range(A.numel(), 0)
return B[i].store(A[i] + 1).end(i).sink(arg=KernelInfo(name=f"add_one_{A.numel()}"))
def custom_elementwise_add_kernel(C:UOp, A:UOp, B:UOp) -> UOp:
C,A,B = C.flatten(), A.flatten(), B.flatten()
i = UOp.range(C.size, 0)
return C[i].store(A[i]+B[i]).end(i).sink(arg=KernelInfo(name=f"custom_add_kernel_{C.size}")).simplify()
i = UOp.range(C.numel(), 0)
return C[i].store(A[i]+B[i]).end(i).sink(arg=KernelInfo(name=f"custom_add_kernel_{C.numel()}")).simplify()
def custom_elementwise_addmul_kernel(C:UOp, D:UOp, A:UOp, B:UOp) -> UOp:
C,D,A,B = C.flatten(), D.flatten(), A.flatten(), B.flatten()
assert C.size == D.size
i = UOp.range(C.size, 0)
assert C.numel() == D.numel()
i = UOp.range(C.numel(), 0)
store_c = C[i].store(A[i]+B[i])
store_d = D[i].store(A[i]*B[i])
return UOp.group(store_c, store_d).end(i).sink(arg=KernelInfo(name=f"custom_addmul_kernel_{C.size}")).simplify()
return UOp.group(store_c, store_d).end(i).sink(arg=KernelInfo(name=f"custom_addmul_kernel_{C.numel()}")).simplify()
def custom_gemm(C:UOp, A:UOp, B:UOp) -> UOp:
assert A.shape[1] == B.shape[0]
@@ -291,10 +291,10 @@ class TestCustomKernel(unittest.TestCase):
def custom_add_with_tmp(o1:UOp, o2:UOp, A:UOp, B:UOp) -> UOp:
o1,o2,A,B = o1.flatten(), o2.flatten(), A.flatten(), B.flatten()
i = UOp.range(o1.size, 0)
i = UOp.range(o1.numel(), 0)
store_o1 = o1[i].store(A[i]+B[i])
store_o2 = o2[i].store(A[i]+B[i]+2)
return UOp.group(store_o1, store_o2).end(i).sink(arg=KernelInfo(name=f"add_with_tmp_{o1.size}")).simplify()
return UOp.group(store_o1, store_o2).end(i).sink(arg=KernelInfo(name=f"add_with_tmp_{o1.numel()}")).simplify()
from tinygrad import function
@function(precompile=True)
+203 -220
View File
@@ -2,13 +2,12 @@ import numpy as np
import functools, unittest, ctypes
from tinygrad.device import Device, Buffer
from tinygrad.tensor import Tensor, _to_np_dtype
from tinygrad.helpers import Context, dedup, from_mv
from tinygrad.tensor import Tensor
from tinygrad.helpers import Context, from_mv
from tinygrad.dtype import dtypes
from tinygrad.engine.jit import MultiGraphRunner
from tinygrad.engine.realize import BufferXfer, get_runner, CompiledRunner
from tinygrad.engine.schedule import ExecItem
from tinygrad.uop.ops import UOp, Ops
from tinygrad.schedule import linear_to_schedule
from tinygrad.uop.ops import UOp, Ops, buffers
from test.helpers import needs_second_gpu
@@ -17,77 +16,46 @@ Tensor.manual_seed(1337)
BUF_SIZE = 4096
RUN_CNT = 5
cached_prgs = {}
def helper_exec_op(device, outbuf, inbufs):
if (device, len(inbufs)) not in cached_prgs:
# cache AST by (device, num_inputs)
cached_asts: dict[tuple[str, int], UOp] = {}
def get_ast(device:str, num_inputs:int) -> UOp:
if (device, num_inputs) not in cached_asts:
with Context(DEBUG=0):
fst = [Tensor.randn(BUF_SIZE, dtype=dtypes.int).realize() for i in range(len(inbufs))]
fst = [Tensor.randn(BUF_SIZE, dtype=dtypes.int).realize() for _ in range(num_inputs)]
s = fst[0]
for i in range(1, len(inbufs)): s = s.bitwise_xor(fst[i])
for i in range(1, num_inputs): s = s.bitwise_xor(fst[i])
cached_asts[(device, num_inputs)] = s.schedule()[-1].ast
return cached_asts[(device, num_inputs)]
si = s.schedule()[-1]
prg = get_runner(device, si.ast)
cached_prgs[(device, len(inbufs))] = prg
return ExecItem(UOp(Ops.NOOP), [outbuf] + inbufs, prg=cached_prgs[(device, len(inbufs))])
def helper_copy_op(device, dest, src):
prg = BufferXfer(dest.nbytes, device, src.device)
return ExecItem(UOp(Ops.NOOP), [dest, src], prg=prg)
def helper_alloc_rawbuffer(device, fill=False):
rawbuf = Buffer(device, BUF_SIZE, dtypes.int).ensure_allocated()
def make_buffer(device, size=BUF_SIZE, fill=False):
buf = Buffer(device, size, dtypes.int).ensure_allocated()
if fill:
with Context(DEBUG=0):
data = np.random.randint(-10000, 10000, size=rawbuf.size, dtype=_to_np_dtype(rawbuf.dtype))
rawbuf.copyin(Tensor(data).realize().uop.base.realized.as_memoryview())
return rawbuf
buf.copyin(Tensor(np.random.randint(-10000, 10000, size=size, dtype=np.int32)).realize().uop.base.realized.as_memoryview())
return buf
def helper_create_offset_rawbuffer(base, offset=0):
x = Buffer(base.device, base.size-offset, base.dtype, base=base, offset=offset)
return x.ensure_allocated()
def helper_alloc_rawbuffer_sized(device, size, fill=False):
rawbuf = Buffer(device, size, dtypes.int).ensure_allocated()
if fill:
with Context(DEBUG=0):
data = np.random.randint(-10000, 10000, size=rawbuf.size, dtype=_to_np_dtype(rawbuf.dtype))
rawbuf.copyin(Tensor(data).realize().uop.base.realized.as_memoryview())
return rawbuf
def helper_make_view(base, offset_elems, size_elems):
def make_view(base, offset_elems, size_elems):
return Buffer(base.device, size_elems, base.dtype, base=base, offset=offset_elems * base.dtype.itemsize).ensure_allocated()
def helper_run_jit(jis, bufs, out_buffers):
for rawbuf in out_buffers:
mv = memoryview(bytearray(rawbuf.size * rawbuf.dtype.itemsize))
def get_buf_uop(buf:Buffer, cache:dict[Buffer,UOp]) -> UOp:
if buf not in cache:
cache[buf] = u = UOp.new_buffer(buf.device, buf.size, buf.dtype)
buffers[u] = buf
return cache[buf]
def make_graph(graph_cls, calls:list[UOp]):
linear = UOp(Ops.LINEAR, src=tuple(calls))
cf = UOp(Ops.CUSTOM_FUNCTION, dtypes.void, src=(linear,), arg="graph")
return graph_cls(cf, [])
def run_schedule(calls:list[UOp]):
for ei in linear_to_schedule(UOp(Ops.LINEAR, src=tuple(calls))): ei.lower().run({})
def zero_bufs(bufs):
for b in bufs:
mv = memoryview(bytearray(b.nbytes))
ctypes.memset(from_mv(mv), 0, len(mv))
rawbuf.copyin(mv)
for ei in jis: ei.run({}, jit=True)
return [rawbuf.as_memoryview() for rawbuf in bufs]
def helper_test_graphs(graph_impl, graphs, runs=RUN_CNT):
reg_ji = []
bufs = []
out_buffers = set()
for graph in graphs:
for ji in graph:
out_buffers.update([ji.bufs[i] for i in (ji.prg.p.outs if isinstance(ji.prg, CompiledRunner) else [0])])
bufs += ji.bufs
reg_ji.append(ji)
bufs = dedup(bufs)
ground_thruth_bufs = helper_run_jit(reg_ji, bufs, out_buffers)
ground_truth_np = [np.frombuffer(x, _to_np_dtype(bufs[i].dtype)) for i,x in enumerate(ground_thruth_bufs)]
# Build graphs
gr_ji = [ExecItem(UOp(Ops.NOOP), [], prg=graph_impl(None, None, graph)) for graph in graphs]
for _ in range(runs):
test_bufs = helper_run_jit(gr_ji, bufs, out_buffers)
test_bufs_np = [np.frombuffer(x, _to_np_dtype(bufs[i].dtype)) for i,x in enumerate(test_bufs)]
for i in range(len(ground_thruth_bufs)): np.testing.assert_equal(ground_truth_np[i], test_bufs_np[i])
b.copyin(mv)
@unittest.skipUnless(Device[Device.DEFAULT].graph is not None, "graph support required")
class TestGraph(unittest.TestCase):
@@ -101,236 +69,251 @@ class TestGraph(unittest.TestCase):
def test_order_2_writes_to_same_buf(self):
d0 = Device.DEFAULT
b0 = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(5)]
b = [make_buffer(d0, fill=True) for _ in range(5)]
c: dict[Buffer,UOp] = {}
graphs = [
[helper_exec_op(d0, b0[0], [b0[1], b0[2]]), helper_exec_op(d0, b0[0], [b0[3], b0[4]])]
calls = [
get_ast(d0, 2).call(get_buf_uop(b[0],c), get_buf_uop(b[1],c), get_buf_uop(b[2],c), metadata=()),
get_ast(d0, 2).call(get_buf_uop(b[0],c), get_buf_uop(b[3],c), get_buf_uop(b[4],c), metadata=()),
]
helper_test_graphs(Device[d0].graph, graphs)
zero_bufs([b[0]])
run_schedule(calls)
expected = [np.frombuffer(x.as_memoryview(), np.int32).copy() for x in b]
for _ in range(RUN_CNT):
zero_bufs([b[0]])
make_graph(Device[d0].graph, calls)([], {})
for i, buf in enumerate(b): np.testing.assert_equal(expected[i], np.frombuffer(buf.as_memoryview(), np.int32))
def test_order_read_write_same_buf(self):
d0 = Device.DEFAULT
b0 = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(5)]
b = [make_buffer(d0, fill=True) for _ in range(5)]
c: dict[Buffer,UOp] = {}
graphs = [
[helper_exec_op(d0, b0[0], [b0[1], b0[2]]), helper_exec_op(d0, b0[1], [b0[3], b0[4]])]
calls = [
get_ast(d0, 2).call(get_buf_uop(b[0],c), get_buf_uop(b[1],c), get_buf_uop(b[2],c), metadata=()),
get_ast(d0, 2).call(get_buf_uop(b[1],c), get_buf_uop(b[3],c), get_buf_uop(b[4],c), metadata=()),
]
helper_test_graphs(Device[d0].graph, graphs)
zero_bufs([b[0], b[1]])
run_schedule(calls)
expected = [np.frombuffer(x.as_memoryview(), np.int32).copy() for x in b]
for _ in range(RUN_CNT):
zero_bufs([b[0], b[1]])
make_graph(Device[d0].graph, calls)([], {})
for i, buf in enumerate(b): np.testing.assert_equal(expected[i], np.frombuffer(buf.as_memoryview(), np.int32))
def test_order_write_read_same_buf(self):
d0 = Device.DEFAULT
b0 = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(5)]
b = [make_buffer(d0, fill=True) for _ in range(5)]
c: dict[Buffer,UOp] = {}
graphs = [
[helper_exec_op(d0, b0[0], [b0[1], b0[2]]), helper_exec_op(d0, b0[1], [b0[0], b0[4]])]
calls = [
get_ast(d0, 2).call(get_buf_uop(b[0],c), get_buf_uop(b[1],c), get_buf_uop(b[2],c), metadata=()),
get_ast(d0, 2).call(get_buf_uop(b[1],c), get_buf_uop(b[0],c), get_buf_uop(b[4],c), metadata=()),
]
helper_test_graphs(Device[d0].graph, graphs)
zero_bufs([b[0], b[1]])
run_schedule(calls)
expected = [np.frombuffer(x.as_memoryview(), np.int32).copy() for x in b]
for _ in range(RUN_CNT):
zero_bufs([b[0], b[1]])
make_graph(Device[d0].graph, calls)([], {})
for i, buf in enumerate(b): np.testing.assert_equal(expected[i], np.frombuffer(buf.as_memoryview(), np.int32))
def test_order_copy_writed(self):
self.skip_if_not_multigraph()
d0 = Device.DEFAULT
b0 = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(4)]
b = [make_buffer(d0, fill=True) for _ in range(4)]
c: dict[Buffer,UOp] = {}
graphs = [
[helper_exec_op(d0, b0[0], [b0[1], b0[2]]), helper_copy_op(d0, b0[3], b0[0])]
calls = [
get_ast(d0, 2).call(get_buf_uop(b[0],c), get_buf_uop(b[1],c), get_buf_uop(b[2],c), metadata=()),
UOp(Ops.COPY).call(get_buf_uop(b[3],c), get_buf_uop(b[0],c), metadata=()),
]
helper_test_graphs(Device[d0].graph, graphs)
zero_bufs([b[0], b[3]])
run_schedule(calls)
expected = [np.frombuffer(x.as_memoryview(), np.int32).copy() for x in b]
for _ in range(RUN_CNT):
zero_bufs([b[0], b[3]])
make_graph(Device[d0].graph, calls)([], {})
for i, buf in enumerate(b): np.testing.assert_equal(expected[i], np.frombuffer(buf.as_memoryview(), np.int32))
def test_order_copy_then_read(self):
self.skip_if_not_multigraph()
d0 = Device.DEFAULT
b0 = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(4)]
b = [make_buffer(d0, fill=True) for _ in range(4)]
c: dict[Buffer,UOp] = {}
graphs = [
[helper_copy_op(d0, b0[1], b0[0]), helper_exec_op(d0, b0[3], [b0[1], b0[2]])]
calls = [
UOp(Ops.COPY).call(get_buf_uop(b[1],c), get_buf_uop(b[0],c), metadata=()),
get_ast(d0, 2).call(get_buf_uop(b[3],c), get_buf_uop(b[1],c), get_buf_uop(b[2],c), metadata=()),
]
helper_test_graphs(Device[d0].graph, graphs)
zero_bufs([b[1], b[3]])
run_schedule(calls)
expected = [np.frombuffer(x.as_memoryview(), np.int32).copy() for x in b]
for _ in range(RUN_CNT):
zero_bufs([b[1], b[3]])
make_graph(Device[d0].graph, calls)([], {})
for i, buf in enumerate(b): np.testing.assert_equal(expected[i], np.frombuffer(buf.as_memoryview(), np.int32))
def test_read_write_several_graphs(self):
d0 = Device.DEFAULT
b0 = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(8)]
b = [make_buffer(d0, fill=True) for _ in range(8)]
c: dict[Buffer,UOp] = {}
graphs = [
[helper_exec_op(d0, b0[3], [b0[1], b0[2]])],
[helper_exec_op(d0, b0[4], [b0[1], b0[3]])],
[helper_exec_op(d0, b0[5], [b0[4], b0[2]])]
]
calls1 = [get_ast(d0, 2).call(get_buf_uop(b[3],c), get_buf_uop(b[1],c), get_buf_uop(b[2],c), metadata=())]
calls2 = [get_ast(d0, 2).call(get_buf_uop(b[4],c), get_buf_uop(b[1],c), get_buf_uop(b[3],c), metadata=())]
calls3 = [get_ast(d0, 2).call(get_buf_uop(b[5],c), get_buf_uop(b[4],c), get_buf_uop(b[2],c), metadata=())]
helper_test_graphs(Device[d0].graph, graphs)
out = [b[3], b[4], b[5]]
zero_bufs(out)
run_schedule(calls1 + calls2 + calls3)
expected = [np.frombuffer(x.as_memoryview(), np.int32).copy() for x in b]
graphs = [
[helper_exec_op(d0, b0[3], [b0[1], b0[2]]), helper_exec_op(d0, b0[4], [b0[1], b0[2]]), helper_exec_op(d0, b0[5], [b0[1], b0[2]])],
[helper_exec_op(d0, b0[2], [b0[6], b0[7]])]
]
helper_test_graphs(Device[d0].graph, graphs)
for _ in range(RUN_CNT):
zero_bufs(out)
make_graph(Device[d0].graph, calls1)([], {})
make_graph(Device[d0].graph, calls2)([], {})
make_graph(Device[d0].graph, calls3)([], {})
for i, buf in enumerate(b): np.testing.assert_equal(expected[i], np.frombuffer(buf.as_memoryview(), np.int32))
@needs_second_gpu
def test_copies_2_devs(self):
self.skip_if_not_multigraph()
d0, d1 = Device.DEFAULT, f"{Device.DEFAULT}:1"
b0 = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(3)]
b1 = [helper_alloc_rawbuffer(d1, fill=True) for _ in range(1)]
b0 = [make_buffer(d0, fill=True) for _ in range(3)]
b1 = [make_buffer(d1, fill=True)]
c: dict[Buffer,UOp] = {}
graphs = [
[helper_copy_op(d0, b1[0], b0[0]), helper_exec_op(d0, b0[2], [b0[0], b0[1]])]
calls = [
UOp(Ops.COPY).call(get_buf_uop(b1[0],c), get_buf_uop(b0[0],c), metadata=()),
get_ast(d0, 2).call(get_buf_uop(b0[2],c), get_buf_uop(b0[0],c), get_buf_uop(b0[1],c), metadata=()),
]
helper_test_graphs(Device[d0].graph, graphs)
out = [b1[0], b0[2]]
zero_bufs(out)
run_schedule(calls)
expected = {buf: np.frombuffer(buf.as_memoryview(), np.int32).copy() for buf in b0 + b1}
@needs_second_gpu
def test_copies_after_graph_global(self):
self.skip_if_not_multigraph()
d0, d1, d2, d3 = Device.DEFAULT, f"{Device.DEFAULT}:1", f"{Device.DEFAULT}:2", f"{Device.DEFAULT}:3"
b0 = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(8)]
b1 = [helper_alloc_rawbuffer(d1, fill=True) for _ in range(6)]
b2 = [helper_alloc_rawbuffer(d2, fill=True) for _ in range(6)]
b3 = [helper_alloc_rawbuffer(d3, fill=True) for _ in range(6)]
graphs = [
[helper_exec_op(d0, b0[2], [b0[0], b0[1]]), helper_exec_op(d0, b0[3], [b0[0], b0[2]]), helper_exec_op(d0, b0[4], [b0[3], b0[2]]),
helper_exec_op(d0, b0[5], [b0[0], b0[2]]), helper_exec_op(d0, b0[6], [b0[1], b0[2]]), helper_exec_op(d0, b0[7], [b0[0], b0[2]])],
[helper_copy_op(d1, b0[2], b1[0])],
[helper_exec_op(d0, b0[2], [b0[0], b0[1]]), helper_exec_op(d0, b0[3], [b0[0], b0[2]]), helper_exec_op(d0, b0[4], [b0[3], b0[2]]),
helper_exec_op(d0, b0[5], [b0[0], b0[2]]), helper_exec_op(d0, b0[6], [b0[1], b0[2]]), helper_exec_op(d0, b0[7], [b0[0], b0[2]])],
[helper_copy_op(d3, b0[2], b3[0])],
]
helper_test_graphs(Device[d0].graph, graphs)
graphs = [
[helper_exec_op(d0, b0[2], [b0[0], b0[1]]), helper_exec_op(d0, b0[3], [b0[0], b0[2]]), helper_exec_op(d0, b0[4], [b0[3], b0[2]]),
helper_exec_op(d0, b0[5], [b0[0], b0[2]]), helper_copy_op(d0, b2[0], b0[2]), helper_copy_op(d0, b2[1], b0[5]),
helper_exec_op(d0, b0[7], [b0[0], b0[2]])],
[helper_copy_op(d1, b0[2], b1[0])],
[helper_exec_op(d0, b0[2], [b0[0], b0[1]])],
[helper_copy_op(d3, b0[2], b3[0])],
]
helper_test_graphs(Device[d0].graph, graphs)
graphs = [
[helper_exec_op(d0, b0[2], [b0[0], b0[1]]), helper_exec_op(d0, b0[3], [b0[0], b0[2]]), helper_exec_op(d0, b0[4], [b0[3], b0[2]]),
helper_exec_op(d0, b0[5], [b0[0], b0[2]]), helper_copy_op(d0, b2[0], b0[2]), helper_copy_op(d0, b2[1], b0[5]),
helper_exec_op(d0, b0[7], [b0[0], b0[2]])],
[helper_copy_op(d1, b0[5], b1[0])],
[helper_copy_op(d3, b0[5], b3[0])],
]
helper_test_graphs(Device[d0].graph, graphs)
graphs = [
[helper_copy_op(d1, b0[5], b1[0])],
[helper_copy_op(d3, b0[5], b3[0])],
]
helper_test_graphs(Device[d0].graph, graphs)
@needs_second_gpu
def test_graph_after_copies_devs(self):
self.skip_if_not_multigraph()
d0, d1, d2, d3 = Device.DEFAULT, f"{Device.DEFAULT}:1", f"{Device.DEFAULT}:2", f"{Device.DEFAULT}:3"
b0 = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(8)]
b1 = [helper_alloc_rawbuffer(d1, fill=True) for _ in range(1)]
b2 = [helper_alloc_rawbuffer(d2, fill=True) for _ in range(2)]
b3 = [helper_alloc_rawbuffer(d3, fill=True) for _ in range(2)]
graphs = [
[helper_copy_op(d1, b0[0], b1[0])],
[helper_copy_op(d2, b0[1], b2[0]), helper_copy_op(d3, b0[2], b3[0])],
[helper_exec_op(d0, b0[3], [b0[0], b0[2]]), helper_exec_op(d0, b0[4], [b0[3], b0[2]]),
helper_exec_op(d0, b0[5], [b0[0], b0[2]])],
]
helper_test_graphs(Device[d0].graph, graphs)
graphs = [
[helper_copy_op(d1, b0[0], b1[0])],
[helper_exec_op(d0, b0[2], [b0[0], b0[1]])],
[helper_copy_op(d2, b0[1], b2[0]), helper_copy_op(d3, b0[2], b3[0])],
[helper_exec_op(d0, b0[3], [b0[0], b0[2]]), helper_exec_op(d0, b0[4], [b0[3], b0[2]]),
helper_exec_op(d0, b0[5], [b0[0], b0[2]])],
]
helper_test_graphs(Device[d0].graph, graphs)
for _ in range(RUN_CNT):
zero_bufs(out)
make_graph(Device[d0].graph, calls)([], {})
for buf in b0 + b1: np.testing.assert_equal(expected[buf], np.frombuffer(buf.as_memoryview(), np.int32))
def test_graph_offset_bufs(self):
self.skip_if_not_multigraph()
d0 = Device.DEFAULT
if not hasattr(Device[d0].allocator, "_offset"): self.skipTest("device does not support _offset")
b0 = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(1)]
b0 += [helper_create_offset_rawbuffer(b0[0]), helper_create_offset_rawbuffer(b0[0])]
b0 = make_buffer(d0, fill=True)
b1 = make_view(b0, 0, b0.size)
b2 = make_view(b0, 0, b0.size)
c: dict[Buffer,UOp] = {}
graphs = [
[helper_copy_op(d0, b0[0], b0[2]), helper_exec_op(d0, b0[1], [b0[0], b0[2]])],
calls = [
UOp(Ops.COPY).call(get_buf_uop(b0,c), get_buf_uop(b2,c), metadata=()),
get_ast(d0, 2).call(get_buf_uop(b1,c), get_buf_uop(b0,c), get_buf_uop(b2,c), metadata=()),
]
helper_test_graphs(Device[d0].graph, graphs)
zero_bufs([b0])
run_schedule(calls)
expected = np.frombuffer(b0.as_memoryview(), np.int32).copy()
for _ in range(RUN_CNT):
zero_bufs([b0])
make_graph(Device[d0].graph, calls)([], {})
np.testing.assert_equal(expected, np.frombuffer(b0.as_memoryview(), np.int32))
def test_partial_write_preserves_write_dep(self):
self.skip_if_not_multigraph()
self.skip_if_no_offset()
d0 = Device.DEFAULT
base = helper_alloc_rawbuffer_sized(d0, BUF_SIZE * 2, fill=True)
copy_src_full = helper_alloc_rawbuffer_sized(d0, BUF_SIZE * 2, fill=True)
copy_src_lo = helper_alloc_rawbuffer(d0, fill=True)
v_lo = helper_make_view(base, 0, BUF_SIZE)
v_hi = helper_make_view(base, BUF_SIZE, BUF_SIZE)
a, c = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(2)]
base = make_buffer(d0, BUF_SIZE * 2, fill=True)
copy_src_full = make_buffer(d0, BUF_SIZE * 2, fill=True)
copy_src_lo = make_buffer(d0, fill=True)
v_lo, v_hi = make_view(base, 0, BUF_SIZE), make_view(base, BUF_SIZE, BUF_SIZE)
a, out = make_buffer(d0, fill=True), make_buffer(d0, fill=True)
c: dict[Buffer,UOp] = {}
graphs = [
[helper_copy_op(d0, base, copy_src_full), helper_copy_op(d0, v_lo, copy_src_lo), helper_exec_op(d0, c, [v_hi, a])]
calls = [
UOp(Ops.COPY).call(get_buf_uop(base,c), get_buf_uop(copy_src_full,c), metadata=()),
UOp(Ops.COPY).call(get_buf_uop(v_lo,c), get_buf_uop(copy_src_lo,c), metadata=()),
get_ast(d0, 2).call(get_buf_uop(out,c), get_buf_uop(v_hi,c), get_buf_uop(a,c), metadata=()),
]
helper_test_graphs(Device[d0].graph, graphs)
zero_bufs([base, out])
run_schedule(calls)
expected = {base: np.frombuffer(base.as_memoryview(), np.int32).copy(), out: np.frombuffer(out.as_memoryview(), np.int32).copy()}
for _ in range(RUN_CNT):
zero_bufs([base, out])
make_graph(Device[d0].graph, calls)([], {})
for buf in [base, out]: np.testing.assert_equal(expected[buf], np.frombuffer(buf.as_memoryview(), np.int32))
def test_partial_write_preserves_read_dep(self):
self.skip_if_not_multigraph()
self.skip_if_no_offset()
d0 = Device.DEFAULT
base = helper_alloc_rawbuffer_sized(d0, BUF_SIZE * 2, fill=True)
copy_dst = helper_alloc_rawbuffer_sized(d0, BUF_SIZE * 2, fill=True)
copy_src_lo = helper_alloc_rawbuffer(d0, fill=True)
v_lo = helper_make_view(base, 0, BUF_SIZE)
v_hi = helper_make_view(base, BUF_SIZE, BUF_SIZE)
a, b = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(2)]
base = make_buffer(d0, BUF_SIZE * 2, fill=True)
copy_dst = make_buffer(d0, BUF_SIZE * 2, fill=True)
copy_src_lo = make_buffer(d0, fill=True)
v_lo, v_hi = make_view(base, 0, BUF_SIZE), make_view(base, BUF_SIZE, BUF_SIZE)
a, b = make_buffer(d0, fill=True), make_buffer(d0, fill=True)
c: dict[Buffer,UOp] = {}
graphs = [
[helper_copy_op(d0, copy_dst, base), helper_copy_op(d0, v_lo, copy_src_lo), helper_exec_op(d0, v_hi, [a, b])]
calls = [
UOp(Ops.COPY).call(get_buf_uop(copy_dst,c), get_buf_uop(base,c), metadata=()),
UOp(Ops.COPY).call(get_buf_uop(v_lo,c), get_buf_uop(copy_src_lo,c), metadata=()),
get_ast(d0, 2).call(get_buf_uop(v_hi,c), get_buf_uop(a,c), get_buf_uop(b,c), metadata=()),
]
helper_test_graphs(Device[d0].graph, graphs)
zero_bufs([copy_dst, base])
run_schedule(calls)
expected = {copy_dst: np.frombuffer(copy_dst.as_memoryview(), np.int32).copy(), base: np.frombuffer(base.as_memoryview(), np.int32).copy()}
for _ in range(RUN_CNT):
zero_bufs([copy_dst, base])
make_graph(Device[d0].graph, calls)([], {})
for buf in [copy_dst, base]: np.testing.assert_equal(expected[buf], np.frombuffer(buf.as_memoryview(), np.int32))
def test_middle_write_splits_write_dep(self):
self.skip_if_not_multigraph()
self.skip_if_no_offset()
d0 = Device.DEFAULT
base = helper_alloc_rawbuffer_sized(d0, BUF_SIZE * 3, fill=True)
copy_src_full = helper_alloc_rawbuffer_sized(d0, BUF_SIZE * 3, fill=True)
copy_src_mid = helper_alloc_rawbuffer(d0, fill=True)
v_lo = helper_make_view(base, 0, BUF_SIZE)
v_mid = helper_make_view(base, BUF_SIZE, BUF_SIZE)
v_hi = helper_make_view(base, BUF_SIZE * 2, BUF_SIZE)
a, c, e = [helper_alloc_rawbuffer(d0, fill=True) for _ in range(3)]
base = make_buffer(d0, BUF_SIZE * 3, fill=True)
copy_src_full = make_buffer(d0, BUF_SIZE * 3, fill=True)
copy_src_mid = make_buffer(d0, fill=True)
v_lo, v_mid, v_hi = make_view(base, 0, BUF_SIZE), make_view(base, BUF_SIZE, BUF_SIZE), make_view(base, BUF_SIZE * 2, BUF_SIZE)
a, out1, out2 = make_buffer(d0, fill=True), make_buffer(d0, fill=True), make_buffer(d0, fill=True)
c: dict[Buffer,UOp] = {}
graphs = [
[helper_copy_op(d0, base, copy_src_full), helper_copy_op(d0, v_mid, copy_src_mid),
helper_exec_op(d0, c, [v_lo, a]), helper_exec_op(d0, e, [v_hi, a])]
calls = [
UOp(Ops.COPY).call(get_buf_uop(base,c), get_buf_uop(copy_src_full,c), metadata=()),
UOp(Ops.COPY).call(get_buf_uop(v_mid,c), get_buf_uop(copy_src_mid,c), metadata=()),
get_ast(d0, 2).call(get_buf_uop(out1,c), get_buf_uop(v_lo,c), get_buf_uop(a,c), metadata=()),
get_ast(d0, 2).call(get_buf_uop(out2,c), get_buf_uop(v_hi,c), get_buf_uop(a,c), metadata=()),
]
helper_test_graphs(Device[d0].graph, graphs)
outs = [base, out1, out2]
zero_bufs(outs)
run_schedule(calls)
expected = {buf: np.frombuffer(buf.as_memoryview(), np.int32).copy() for buf in outs}
for _ in range(RUN_CNT):
zero_bufs(outs)
make_graph(Device[d0].graph, calls)([], {})
for buf in outs: np.testing.assert_equal(expected[buf], np.frombuffer(buf.as_memoryview(), np.int32))
if __name__ == '__main__':
unittest.main()
+1 -1
View File
@@ -4,7 +4,7 @@ from tinygrad import Tensor, Device
from tinygrad.helpers import get_single_element
from tinygrad.codegen.opt import Opt, OptOps
from tinygrad.engine.realize import CompiledRunner, get_program
from tinygrad.engine.schedule import ExecItem
from tinygrad.schedule import ExecItem
class TestOptGemm(unittest.TestCase):
@classmethod
+1 -1
View File
@@ -6,7 +6,7 @@ from tinygrad import Tensor, Context, Device, dtypes
from tinygrad.uop.ops import Ops
from tinygrad.codegen.opt import Opt, OptOps
from tinygrad.engine.realize import CompiledRunner, get_program
from tinygrad.engine.schedule import ExecItem
from tinygrad.schedule import ExecItem
N = 512
+1 -1
View File
@@ -8,7 +8,7 @@ from tinygrad.device import Buffer, Device
from tinygrad.uop.ops import Ops, UOp, KernelInfo, AxisType
from tinygrad.renderer.cstyle import CStyleLanguage
from tinygrad.engine.realize import CompiledRunner, get_program, get_runner
from tinygrad.engine.schedule import ExecItem
from tinygrad.schedule import ExecItem
from tinygrad.device import is_dtype_supported
from tinygrad.codegen.opt import Opt, OptOps
from tinygrad.renderer.ptx import PTXRenderer
+1 -1
View File
@@ -1,6 +1,6 @@
import unittest
from tinygrad import Device, Tensor
from tinygrad.engine.schedule import create_schedule
from tinygrad.schedule import create_schedule
from tinygrad.runtime.ops_amd import AMDDevice
class TestAMD(unittest.TestCase):
+1 -1
View File
@@ -2,7 +2,7 @@ import time, unittest
from tinygrad.runtime.support.hip_comgr import compile_hip
from tinygrad import Tensor
from tinygrad.device import Device
from tinygrad.engine.schedule import create_schedule
from tinygrad.schedule import create_schedule
from tinygrad.codegen.opt.kernel import Kernel
class TestHIPCompileSpeed(unittest.TestCase):
+1 -1
View File
@@ -7,7 +7,7 @@ from tinygrad import GlobalCounters, Tensor, Device
from tinygrad.helpers import getenv
from tinygrad.nn.state import get_parameters
from tinygrad.engine.realize import capturing, run_schedule
from tinygrad.engine.schedule import linear_to_schedule
from tinygrad.schedule import linear_to_schedule
from tinygrad.tensor import _to_np_dtype
class CLCache:
+1 -1
View File
@@ -1,6 +1,6 @@
import gc
from tinygrad import Tensor, UOp, Device, nn
from tinygrad.engine.schedule import schedule_cache
from tinygrad.schedule import schedule_cache
from tinygrad.engine.realize import method_cache, get_program
from tinygrad.schedule.indexing import apply_movement_op, _apply_reshape
from tinygrad.uop.divandmod import fold_divmod_general
+2 -2
View File
@@ -5,7 +5,7 @@ from tinygrad.helpers import Context, getenv, from_mv
from tinygrad.dtype import dtypes
from tinygrad.tensor import Tensor, _to_np_dtype
from tinygrad.engine.realize import BufferXfer, get_runner
from tinygrad.engine.schedule import ExecItem
from tinygrad.schedule import ExecItem
from tinygrad.uop.ops import UOp, Ops
from tinygrad.engine.jit import apply_graph_to_jit
@@ -85,7 +85,7 @@ def run_jit(jis, all_buffers, input_buffers, var_vals):
with Context(DEBUG=0):
for rawbuf in all_buffers:
if rawbuf in input_buffers: continue
mv = memoryview(bytearray(rawbuf.size * rawbuf.dtype.itemsize))
mv = memoryview(bytearray(rawbuf.nbytes))
ctypes.memset(from_mv(mv), 0, len(mv))
rawbuf.copyin(mv)
+1
View File
@@ -43,6 +43,7 @@ class ProcessReplayWarning(Warning): pass
# *** replay the function and convert return values to string
def replay_get_program(p:ProgramSpec, ast:UOp, renderer:Renderer, opts:list[Opt]|None=None) -> tuple[str, str, tuple[Any, ...]]:
if ast.op is Ops.BEAM: ast = ast.src[0]
# the ast.arg is non None if we are inside of search.py
sink_arg = ast.arg or KernelInfo()
if opts is not None: sink_arg = replace(sink_arg, opts_to_apply=tuple(opts))
+6 -7
View File
@@ -4,7 +4,7 @@ Test with `pytest -n12 test/amd/`
`DEV=AMD:LLVM pytest -n12 test/amd/`
* dsl.py -- helpers for the autogen instruction classes in `__init__.py`. should be standalone with init
* test/mockgpu/amd/emu.py -- an emulator for RDNA that runs in tinygrad with `DEV=AMD MOCKGPU=1 PYTHON_REMU=1`
* test/mockgpu/amd/emu.py -- an emulator for RDNA that runs in tinygrad with `DEV=AMD MOCKGPU=1`
* generate.py -- extract assembly format + instruction pseudocode from AMD XML + PDF
* test/mockgpu/amd/pcode.py -- pseudocode to UOp transformation
* sqtt.py -- SQTT parser
@@ -20,20 +20,19 @@ test_llvm.py tests asm/disasm on the LLVM tests, confirming it behaves the same
tinygrad's dtype tests should pass with and without LLVM. they run in about 12 seconds.
`DEV=AMD PYTHON_REMU=1 MOCKGPU=1 pytest -n=12 test/backend/test_dtype_alu.py test/backend/test_dtype.py`
`DEV=AMD:LLVM PYTHON_REMU=1 MOCKGPU=1 pytest -n=12 test/backend/test_dtype_alu.py test/backend/test_dtype.py`
`DEV=AMD MOCKGPU=1 pytest -n=12 test/backend/test_dtype_alu.py test/backend/test_dtype.py`
`DEV=AMD:LLVM MOCKGPU=1 pytest -n=12 test/backend/test_dtype_alu.py test/backend/test_dtype.py`
The ops tests also pass, but they are very slow, so you should run them one at a time.
`SKIP_SLOW_TEST=1 DEV=AMD PYTHON_REMU=1 MOCKGPU=1 pytest -n=12 test/backend/test_ops.py`
`SKIP_SLOW_TEST=1 DEV=AMD:LLVM PYTHON_REMU=1 MOCKGPU=1 pytest -n=12 test/backend/test_ops.py`
`SKIP_SLOW_TEST=1 DEV=AMD MOCKGPU=1 pytest -n=12 test/backend/test_ops.py`
`SKIP_SLOW_TEST=1 DEV=AMD:LLVM MOCKGPU=1 pytest -n=12 test/backend/test_ops.py`
When something is caught by main tinygrad tests, a local regression test should be added to `test/amd`.
While working with tinygrad, you can dump the assembly with `DEBUG=7`. These tests all pass on real hardware
If a test is failing with `DEV=AMD PYTHON_REMU=1 MOCKGPU=1` it's because an instruction is emulated incorrectly.
If a test is failing with `DEV=AMD MOCKGPU=1` it's because an instruction is emulated incorrectly.
You can test without `MOCKGPU=1` to test on real hardware, if it works on real hardware there's a bug in the emulator.
IMPORTANT: if a test is failing in the emulator, it's an instruction bug. Use DEBUG=7, get the instructions, and debug.
Currently, only RDNA3 is well supported, but when finished, this will support RDNA3+RDNA4+CDNA in ~3000 lines.
Get line count with `cloc --by-file tinygrad/renderer/amd/*.py`
+9 -9
View File
@@ -1,7 +1,7 @@
import ctypes, time
from dataclasses import replace
from test.mockgpu.gpu import VirtGPU
from test.mockgpu.helpers import _try_dlopen_remu
from test.mockgpu.helpers import PythonRemu
from tinygrad.helpers import getbits, to_mv, getenv, DEV
from tinygrad.runtime.support import c
@@ -41,7 +41,7 @@ WAIT_REG_MEM_FUNCTION_EQ = 3 # ==
WAIT_REG_MEM_FUNCTION_NEQ = 4 # !=
WAIT_REG_MEM_FUNCTION_GEQ = 5 # >=
remu = _try_dlopen_remu()
remu = PythonRemu()
def create_sdma_packets():
# TODO: clean up this, if we want to keep it
@@ -212,13 +212,13 @@ class PM4Executor(AMDQueue):
scratch_size = wavesize * (16 if self.gpu.arch == "cdna" else 4) # per-thread scratch size in bytes
assert prg_sz > 0, "Invalid prg ptr (not found in mapped ranges)"
# Pass valid memory ranges, rsrc2, scratch_size, arch, and user data registers to Python emulator
if hasattr(remu, 'valid_mem_ranges'): remu.valid_mem_ranges = self.gpu.mapped_ranges
if hasattr(remu, 'rsrc2'): remu.rsrc2 = rsrc2
if hasattr(remu, 'scratch_size'): remu.scratch_size = scratch_size
if hasattr(remu, 'arch'): remu.arch = self.gpu.arch
if hasattr(remu, 'user_data'): remu.user_data = user_data
err = remu.run_asm(prg_addr, prg_sz, *gl, *lc, args_addr)
# Pass valid memory ranges, rsrc2, scratch_size, arch, and user data registers to the emulator
remu.valid_mem_ranges = self.gpu.mapped_ranges
remu.rsrc2 = rsrc2
remu.scratch_size = scratch_size
remu.arch = self.gpu.arch
remu.user_data = user_data
err = remu.run_asm(prg_addr, prg_sz, gl[0], gl[1], gl[2], lc[0], lc[1], lc[2], args_addr)
if err != 0: raise RuntimeError("remu does not support the new instruction introduced in this kernel")
def _exec_indirect_buffer(self, n):
+111 -24
View File
@@ -67,6 +67,7 @@ from tinygrad.runtime.autogen.amd.rdna4 import ins as ir4
from tinygrad.runtime.autogen.amd.cdna import ins as irc
from tinygrad.renderer.amd.dsl import VCC_LO, EXEC_LO, SCC, ttmp
from tinygrad.runtime.autogen.amd.common import Fmt, OpType
from test.amd.helpers import decode_dpp16
from test.mockgpu.amd.pcode import parse_block, _FUNCS, _set_bits, _val_to_bits
MASK32 = 0xFFFFFFFF
@@ -233,7 +234,6 @@ VOPD_TO_VOP2 = {
ir4.VOPDOp.V_DUAL_DOT2ACC_F32_F16: ir3.VOP2Op.V_DOT2ACC_F32_F16_E32,
}
def _wave_size(arch: str) -> int: return 64 if arch.startswith("cdna") else 32
WAVE_SIZE = 32 # default wave size for RDNA (exported for test_compare_emulators)
# Special registers stored after inline constants (256-259)
PC_LO_IDX, PC_HI_IDX, SCRATCH_STRIDE_IDX = 256, 257, 259
# SGPR buffer: 0-127 = SGPRs, 128-255 = inline constants, 256-259 = special registers
@@ -346,7 +346,7 @@ def parse_pcode(pcode: str, srcs: dict[str, UOp | int] | None = None) -> tuple[d
# TODO: pcode.py should tokenize full pcode string instead of line-by-line, then this hack can be removed
lines: list[str] = []
for l in raw_lines:
if lines and lines[-1].endswith('&&'): lines[-1] = lines[-1] + ' ' + l
if lines and re.search(r'(&&|\|\||[&|+\-*/^])\s*$', lines[-1]): lines[-1] = lines[-1] + ' ' + l
else: lines.append(l)
_, final, _ = parse_block(lines, 0, env, assigns=assigns)
sliced = set(d.split('[')[0] for d, _ in assigns if '[' in d)
@@ -639,11 +639,13 @@ class _Ctx:
src0_reg = (src0_off >= _c(256)).where(src0_off - _c(256), _c(0)) # VGPR index or 0
src1_off = self.inst_field(type(inst).src1) if hasattr(type(inst), 'src1') else None
src2_off = self.inst_field(type(inst).src2) if hasattr(type(inst), 'src2') else None
src1_reg = (src1_off >= _c(256)).where(src1_off - _c(256), src1_off) if src1_off is not None else _c(0)
src2_reg = (src2_off >= _c(256)).where(src2_off - _c(256), src2_off) if src2_off is not None else _c(0)
exec_val = self.rexec()
exec_lo = exec_val.cast(dtypes.uint32) if exec_val.dtype == dtypes.uint64 else exec_val
srcs = {
'SRC0': src0_reg, 'VDST': vdst_off, 'EXEC_LO': exec_lo, 'EXEC': exec_val if exec_val.dtype == dtypes.uint64 else exec_val.cast(dtypes.uint64),
'_vgpr': self.vgpr, '_wave_size': self.wave_size,
'_vgpr': self.vgpr, '_wave_size': self.wave_size, 'SRC1': src1_reg, 'SRC2': src2_reg,
'S0': self.rsrc_dyn(src0_off, _c(0, dtypes.int)) if 'WRITELANE' in op_name else src0_reg,
'S1': self.rsrc_dyn(src1_off, _c(0, dtypes.int)) if src1_off is not None else _c(0),
'S2': self.rsrc_dyn(src2_off, _c(0, dtypes.int)) if src2_off is not None else _c(0),
@@ -663,10 +665,11 @@ class _Ctx:
vcc_reg = sdst_reg if sdst_reg is not None else VCC_LO.offset
if 'VCC' not in srcs: srcs['VCC'] = self.rmask(_c(vcc_reg))
srcs.update({'EXEC': exec_mask, 'SCC': self.rsgpr_dyn(_c(SCC.offset)), 'laneId': lane, 'VDST': vdst_reg,
'ROUND_MODE': _c(0), 'ROUND_TOWARD_ZERO': _c(0), 'ROUND_NEAREST_EVEN': _c(0), '_vgpr': self.vgpr, '_wave_size': self.wave_size,
# CDNA SDWA byte/word select constants (E32 always uses BYTE0/WORD0 defaults)
'SDWA_SRC0_SEL': _c(0), 'BYTE0': _c(0), 'BYTE1': _c(1), 'BYTE2': _c(2), 'BYTE3': _c(3),
'WORD0': _c(0), 'WORD1': _c(1)}) # rounding mode and SDWA constants
'ROUND_MODE': _c(0), 'ROUND_TOWARD_ZERO': _c(0), 'ROUND_NEAREST_EVEN': _c(0), '_vgpr': self.vgpr, '_wave_size': self.wave_size,
'MAX_FLOAT_F32': UOp.const(dtypes.float32, 3.4028234663852886e38),
# CDNA SDWA byte/word select constants (E32 always uses BYTE0/WORD0 defaults)
'SDWA_SRC0_SEL': _c(0), 'BYTE0': _c(0), 'BYTE1': _c(1), 'BYTE2': _c(2), 'BYTE3': _c(3),
'WORD0': _c(0), 'WORD1': _c(1)}) # rounding mode and SDWA constants
_, assigns = parse_pcode(pcode, srcs)
# For integer ops with clamp, compute overflow using wide arithmetic
@@ -716,6 +719,10 @@ class _Ctx:
new_vcc = _set_lane_bit(old_vcc, lane, val, exec_mask)
raw_stores.extend([('vcc', s) for s in self.wmask(_c(VCC_LO.offset), new_vcc)])
elif dest.startswith('D0'):
dest_suffix = re.match(r'D0\.(\w+)', dest)
if dest_suffix is not None:
target_dt = {'u16': dtypes.uint16, 'i16': dtypes.int16, 'f16': dtypes.half}.get(dest_suffix.group(1))
if target_dt is not None and val.dtype != target_dt: val = val.cast(target_dt)
if (slice_match := re.match(r'D0\[(\d+)\s*:\s*(\d+)\]', dest)):
d0_hi_bit, d0_lo_bit = int(slice_match.group(1)), int(slice_match.group(2))
if d0_hi_bit != 31 or d0_lo_bit != 0:
@@ -728,7 +735,8 @@ class _Ctx:
# For integer ops with clamp, use pre-computed saturated value; for floats, clamp to [0,1]
if int_saturate is not None: val = int_saturate
elif clmp and val.dtype in (dtypes.float32, dtypes.half, dtypes.float64):
val = val.maximum(UOp.const(val.dtype, 0.0)).minimum(UOp.const(val.dtype, 1.0))
clamped = val.maximum(UOp.const(val.dtype, 0.0)).minimum(UOp.const(val.dtype, 1.0))
val = _FUNCS['isNAN'](val).where(UOp.const(val.dtype, 0.0), clamped)
if val.dtype in (dtypes.uint64, dtypes.int64, dtypes.float64):
lo, hi = _split64(val)
raw_stores.extend([('vgpr', self.wvgpr_dyn(vdst_reg, lane, lo, exec_mask)),
@@ -916,6 +924,49 @@ def _sdwa_write(old: UOp, val: UOp, dst_sel: UOp, dst_unused: UOp) -> UOp:
# For PAD and SEXT, unused bits are zero (PAD) or sign-extended (SEXT). For DWORD, just return val.
return dst_sel.eq(_c(6)).where(val, dst_unused.eq(_c(2)).where(preserved, placed))
def _dpp_quad_sel(quad_lane: UOp, sels: tuple[int, int, int, int]) -> UOp:
sel = _c(sels[0], dtypes.int)
for i, src in enumerate(sels[1:], start=1): sel = quad_lane.eq(_c(i, dtypes.int)).where(_c(src, dtypes.int), sel)
return sel
def _dpp16_ctrl(lane: UOp, dpp: int, row_mask: int, bank_mask: int, wave_size: int) -> tuple[UOp, UOp, UOp]:
"""Return (src_lane, row/bank enabled, in-bounds) for a DPP16 swizzle."""
lane_i = lane.cast(dtypes.int)
row_base, lane_in_row = lane_i & _c(~15, dtypes.int), lane_i & _c(15, dtypes.int)
row = lane_i // _c(16, dtypes.int)
bank = lane_in_row >> _c(2, dtypes.int)
enabled = (((_c(row_mask) >> row.cast(dtypes.uint32)) & _c(1)).ne(_c(0)) &
(((_c(bank_mask) >> bank.cast(dtypes.uint32)) & _c(1)).ne(_c(0))))
op, arg = decode_dpp16(dpp)
src_lane, valid = lane_i, UOp.const(dtypes.bool, True)
if op == 'quad_perm':
assert isinstance(arg, tuple)
src_lane = (lane_i & _c(~3, dtypes.int)) + _dpp_quad_sel(lane_i & _c(3, dtypes.int), arg)
else:
assert isinstance(arg, int)
if op == 'row_shl': src_lane, valid = row_base + lane_in_row + _c(arg, dtypes.int), lane_in_row <= _c(15 - arg, dtypes.int)
elif op == 'row_shr': src_lane, valid = row_base + lane_in_row - _c(arg, dtypes.int), lane_in_row >= _c(arg, dtypes.int)
elif op == 'row_ror': src_lane = row_base + ((lane_in_row - _c(arg, dtypes.int)) & _c(15, dtypes.int))
elif op == 'row_mirror': src_lane = row_base + (_c(15, dtypes.int) - lane_in_row)
elif op == 'row_half_mirror': src_lane = row_base + ((lane_in_row & _c(8, dtypes.int)) | (_c(7, dtypes.int) - (lane_in_row & _c(7, dtypes.int))))
elif op == 'row_bcast': src_lane = row_base
elif op == 'wave_shl': src_lane, valid = lane_i + _c(arg, dtypes.int), lane_i < _c(wave_size - arg, dtypes.int)
elif op == 'wave_rol': src_lane = (lane_i + _c(arg, dtypes.int)) % _c(wave_size, dtypes.int)
elif op == 'wave_shr': src_lane, valid = lane_i - _c(arg, dtypes.int), lane_i >= _c(arg, dtypes.int)
elif op == 'wave_ror': src_lane = (lane_i - _c(arg, dtypes.int)) % _c(wave_size, dtypes.int)
else: raise NotImplementedError(f"DPP16 control {dpp:#x} ({op}:{arg}) not implemented in emulator")
return src_lane, enabled, valid
def _load_dpp16_src0(ctx: _Ctx, inst, lane: UOp, fallback: UOp) -> UOp:
"""Load a DPP16-swizzled src0 value from vsrc0."""
src_lane, enabled, valid = _dpp16_ctrl(lane, getattr(inst, 'dpp', 0) or 0, getattr(inst, 'row_mask', 0xf) or 0xf,
getattr(inst, 'bank_mask', 0xf) or 0xf, ctx.wave_size)
safe_src_lane = (enabled & valid).where(src_lane, _c(0, dtypes.int))
swizzled = ctx.rvgpr_dyn(ctx.inst_field(type(inst).vsrc0), safe_src_lane)
invalid = UOp.const(fallback.dtype, 0) if getattr(inst, 'bc', 0) else fallback
return enabled.where(valid.where(swizzled, invalid), fallback)
def _compile_sdwa(inst: irc.VOP1_SDWA | irc.VOP2_SDWA | irc.VOP2_SDWA_SDST | irc.VOPC_SDWA_SDST, ctx: _Ctx) -> UOp:
"""Compile CDNA SDWA (Sub-Dword Access) VOP1/VOP2/VOPC instructions."""
is_vopc = isinstance(inst, irc.VOPC_SDWA_SDST)
@@ -999,33 +1050,43 @@ def _compile_sdwa(inst: irc.VOP1_SDWA | irc.VOP2_SDWA | irc.VOP2_SDWA_SDST | irc
return UOp.sink(UOp.sink(*stores).end(lane), *ctx.inc_pc())
return UOp.sink(*ctx.inc_pc())
def _compile_vop12(inst: ir3.VOP1 | ir3.VOP1_SDST | ir3.VOP2 | ir4.VOP1 | ir4.VOP1_SDST | ir4.VOP2 | irc.VOP1 | irc.VOP2, ctx: _Ctx) -> UOp:
def _compile_vop12(inst: ir3.VOP1 | ir3.VOP1_SDST | ir3.VOP1_DPP16 | ir3.VOP2 | ir3.VOP2_DPP16 |
ir4.VOP1 | ir4.VOP1_SDST | ir4.VOP1_DPP16 | ir4.VOP2 | ir4.VOP2_DPP16 |
irc.VOP1 | irc.VOP1_DPP16 | irc.VOP2 | irc.VOP2_DPP16, ctx: _Ctx) -> UOp:
op_name = _op_name(inst)
if op_name in ('V_READFIRSTLANE_B32_E32', 'V_PERMLANE64_B32_E32'): return ctx.compile_lane_pcode(inst.op, inst)
# v_accvgpr_mov_b32: ACCVGPR[vdst] = ACCVGPR[src0] (VOP1 encoding, no pcode)
if 'ACCVGPR_MOV' in op_name:
lane, exec_mask = ctx.range(), ctx.rexec()
vdst_reg = ctx.inst_field(type(inst).vdst) # VGPRField: raw ACCVGPR index (0-255)
src0_off = ctx.inst_field(type(inst).src0) # SrcField: raw 256 + ACCVGPR index
val = ctx.raccvgpr_dyn(src0_off - _c(256), lane)
acc_src0_off = ctx.inst_field(type(inst).src0) # SrcField: raw 256 + ACCVGPR index
val = ctx.raccvgpr_dyn(acc_src0_off - _c(256), lane)
return UOp.sink(ctx.waccvgpr_dyn(vdst_reg, lane, val, exec_mask).end(lane), *ctx.inc_pc())
lane, exec_mask, bits = ctx.range(), ctx.rexec(), inst.canonical_op_bits
literal = ctx.inst_field(type(inst).literal) if hasattr(type(inst), 'literal') else None # type: ignore[union-attr]
is_f64 = 'F64' in op_name and 'B64' not in op_name
is_float = any(x in op_name for x in ('F16', 'F32', 'F64'))
is_dpp16 = hasattr(type(inst), 'dpp') and hasattr(type(inst), 'vsrc0')
vdst_reg = ctx.inst_field(type(inst).vdst)
write_hi_half = bits['d'] == 16 and (vdst_reg >= _c(128))
if isinstance(write_hi_half, UOp): vdst_reg = write_hi_half.where(vdst_reg - _c(128), vdst_reg)
elif write_hi_half: vdst_reg -= 128
src0_off: UOp | None = None
if isinstance(inst, (ir3.VOP1, ir4.VOP1, irc.VOP1)):
# Handle VOP1 hi-half source operand (src0 >= v[128] for 16-bit ops)
src0_off = ctx.inst_field(type(inst).src0)
s0 = ctx.rsrc_dyn(src0_off, lane, bits['s0'], literal, is_f64)
if bits['s0'] == 16:
d0 = _cond_hi16(write_hi_half, ctx.rvgpr_dyn(vdst_reg, lane))
if is_dpp16:
s0 = _load_dpp16_src0(ctx, inst, lane, d0)
else:
src0_off = ctx.inst_field(type(inst).src0)
s0 = ctx.rsrc_dyn(src0_off, lane, bits['s0'], literal, is_f64)
if bits['s0'] == 16 and not is_dpp16:
src0_hi = src0_off >= _c(384)
# Only compute hi-half when src0_off >= 384, use guarded index to prevent OOB access
src0_reg = src0_hi.where(src0_off - _c(384), _c(0))
s0 = src0_hi.where(_hi16(ctx.rvgpr_dyn(src0_reg, lane)), s0)
d0 = _cond_hi16(write_hi_half, ctx.rvgpr_dyn(vdst_reg, lane))
if is_dpp16 and is_float:
s0 = _apply_src_mods(s0, 0, 1 if getattr(inst, 'src0_abs', 0) else 0, 1 if getattr(inst, 'src0_neg', 0) else 0, bits['s0'])
srcs:dict[str, UOp | int] = {'S0': s0, 'D0': d0}
else:
vsrc1_reg = ctx.inst_field(type(inst).vsrc1)
@@ -1038,13 +1099,19 @@ def _compile_vop12(inst: ir3.VOP1 | ir3.VOP1_SDST | ir3.VOP2 | ir4.VOP1 | ir4.VO
s1 = _cond_hi16(vsrc1_hi, ctx.rvgpr_dyn(vsrc1_actual, lane))
d0 = _cond_hi16(write_hi_half, ctx.rvgpr_dyn(vdst_reg, lane)) # FMAC/FMAMK hi-half dest needs hi-half accumulator
# Handle VOP2 hi-half src0 operand (src0 >= v[128] for 16-bit ops)
src0_off = ctx.inst_field(type(inst).src0)
s0 = ctx.rsrc_dyn(src0_off, lane, bits['s0'], literal, is_f64)
if bits['s0'] == 16:
if is_dpp16:
s0 = _load_dpp16_src0(ctx, inst, lane, d0)
else:
src0_off = ctx.inst_field(type(inst).src0)
s0 = ctx.rsrc_dyn(src0_off, lane, bits['s0'], literal, is_f64)
if bits['s0'] == 16 and not is_dpp16:
src0_hi = src0_off >= _c(384)
# Only compute hi-half when src0_off >= 384, use guarded index to prevent OOB access
src0_reg = src0_hi.where(src0_off - _c(384), _c(0))
s0 = src0_hi.where(_hi16(ctx.rvgpr_dyn(src0_reg, lane)), s0)
if is_dpp16 and is_float:
s0 = _apply_src_mods(s0, 0, 1 if getattr(inst, 'src0_abs', 0) else 0, 1 if getattr(inst, 'src0_neg', 0) else 0, bits['s0'])
s1 = _apply_src_mods(s1, 0, 1 if getattr(inst, 'src1_abs', 0) else 0, 1 if getattr(inst, 'src1_neg', 0) else 0, bits['s1'])
srcs = {'S0': s0, 'S1': s1, 'D0': d0}
# FMAAK_(DTYPE)_E32 series
if 'V_FMAA' in _op_name(inst) or 'V_FMAM' in _op_name(inst):
@@ -1052,10 +1119,11 @@ def _compile_vop12(inst: ir3.VOP1 | ir3.VOP1_SDST | ir3.VOP2 | ir4.VOP1 | ir4.VO
srcs['SIMM32'] = literal
return ctx.compile_vop_pcode(inst.op, srcs, lane, vdst_reg, exec_mask, opsel_dst_hi=write_hi_half, src0_off=src0_off)
def _compile_vopc(inst: ir3.VOPC|ir3.VOP3|ir4.VOPC|ir4.VOP3|irc.VOPC|irc.VOP3, ctx: _Ctx,
def _compile_vopc(inst: ir3.VOPC|ir3.VOPC_DPP16|ir3.VOP3|ir4.VOPC|ir4.VOPC_DPP16|ir4.VOP3|irc.VOPC|irc.VOP3, ctx: _Ctx,
opsel: int = 0, abs_bits: int = 0, neg_bits: int = 0) -> UOp:
exec_mask, op_name, bits = ctx.rexec(), _op_name(inst), inst.canonical_op_bits
is_cmpx, is_vopc = 'CMPX' in op_name, hasattr(inst, 'vsrc1') # is_vopc: e32 vs e64
is_dpp16 = hasattr(type(inst), 'dpp') and hasattr(type(inst), 'vsrc0')
# Handle both VOPC (vsrc1) and VOP3 (src1) instruction formats - read operands dynamically
if is_vopc:
@@ -1078,11 +1146,14 @@ def _compile_vopc(inst: ir3.VOPC|ir3.VOP3|ir4.VOPC|ir4.VOP3|irc.VOPC|irc.VOP3, c
is_float, is_f64, pcode = any(x in op_name for x in ('_F32', '_F64', '_F16')), '_F64' in op_name, get_pcode(inst.op)
def get_cmp_bit(lane) -> UOp:
lc = lane.cast(dtypes.int) if isinstance(lane, UOp) else _c(lane, dtypes.int)
s0 = ctx.rsrc_dyn(src0_off, lc, bits['s0'], literal, is_f64)
s0 = _load_dpp16_src0(ctx, inst, lc, _c(0)) if is_dpp16 else ctx.rsrc_dyn(src0_off, lc, bits['s0'], literal, is_f64)
s1 = _cond_hi16(vsrc1_hi, ctx.rsrc_dyn(src1_off, lc, bits['s1'], literal, is_f64)) if bits['s0'] == 16 \
else ctx.rsrc_dyn(src1_off, lc, bits['s1'], literal, is_f64)
if bits['s0'] == 16 and opsel: s0, s1 = _apply_opsel(s0, 0, opsel), _apply_opsel(s1, 1, opsel)
if is_float:
if is_dpp16:
s0 = _apply_src_mods(s0, 0, 1 if getattr(inst, 'src0_abs', 0) else 0, 1 if getattr(inst, 'src0_neg', 0) else 0, bits['s0'])
s1 = _apply_src_mods(s1, 0, 1 if getattr(inst, 'src1_abs', 0) else 0, 1 if getattr(inst, 'src1_neg', 0) else 0, bits['s1'])
s0 = _apply_src_mods(s0, 0, abs_bits, neg_bits, bits['s0'])
s1 = _apply_src_mods(s1, 1, abs_bits, neg_bits, bits['s1'])
for dest, val in parse_pcode(pcode, {'S0': s0, 'S1': s1, 'laneId': lc, 'D0': UOp.const(dtypes.uint64, 0)})[1]:
@@ -1177,6 +1248,19 @@ def _compile_vop3(inst: ir3.VOP3 | ir4.VOP3 | irc.VOP3, ctx: _Ctx) -> UOp:
opsel_dst_hi = bool(opsel & 0b1000) and bits['d'] == 16
return ctx.compile_vop_pcode(inst.op, srcs, lane, vdst_reg, exec_mask, opsel_dst_hi=opsel_dst_hi, clmp=getattr(inst, 'clmp', 0))
def _compile_vinterp(inst: ir3.VINTERP | ir4.VINTERP, ctx: _Ctx) -> UOp:
lane, exec_mask = ctx.range(), ctx.rexec()
inst_type = type(inst)
vdst_reg = ctx.inst_field(inst_type.vdst)
src0_off, src1_off, src2_off = ctx.inst_field(inst_type.src0), ctx.inst_field(inst_type.src1), ctx.inst_field(inst_type.src2)
src0_reg = (src0_off >= _c(256)).where(src0_off - _c(256), src0_off)
src2_reg = (src2_off >= _c(256)).where(src2_off - _c(256), src2_off)
srcs = {
'SRC0': src0_reg, 'SRC2': src2_reg,
'S0': ctx.rsrc_dyn(src0_off, lane), 'S1': ctx.rsrc_dyn(src1_off, lane), 'S2': ctx.rsrc_dyn(src2_off, lane),
}
return ctx.compile_vop_pcode(inst.op, srcs, lane, vdst_reg, exec_mask)
def _compile_vop3sd(inst: ir3.VOP3SD | ir4.VOP3SD | irc.VOP3SD, ctx: _Ctx) -> UOp:
exec_mask = ctx.rexec()
bits, pcode, ops = inst.canonical_op_bits, get_pcode(inst.op), inst.canonical_operands
@@ -1788,7 +1872,7 @@ def _compile_mem_op(inst: ir3.DS|ir3.FLAT|ir3.GLOBAL|ir3.SCRATCH|ir4.DS|ir4.VFLA
'DATA2': _u64(ctx.rvgpr_dyn(data1_reg, lane), ctx.rvgpr_dyn(data1_reg + _c(1), lane)) if has_data1 else UOp.const(dtypes.uint64, 0)}
# RDNA3 uses ADDR/OFFSET, RDNA4 uses vgpr_a/offset (lowercase) + CalcDsAddr function
return {'ADDR': addr, 'ADDR_BASE': addr, 'OFFSET': offset, 'OFFSET0': offset0, 'OFFSET1': offset1, '_lds': mem, 'laneId': lane,
'vgpr_a': ctx.rvgpr_dyn(addr_reg, lane), 'offset': offset, **data}
'vgpr_a': ctx.rvgpr_dyn(addr_reg, lane), 'offset': offset, 'offset0': offset0, 'offset1': offset1, **data}
active = _lane_active(exec_mask, lane)
# saddr < 124 means valid SGPR pair, otherwise use 0 (NULL means no saddr contribution)
use_saddr = (saddr_reg < _c(124)) if saddr_reg is not None else UOp.const(dtypes.bool, False)
@@ -1937,17 +2021,20 @@ def _compile_mubuf(inst: irc.MUBUF, ctx: _Ctx) -> UOp:
# Dispatch table: instruction type -> handler function
_INST_HANDLERS: dict[type, Callable[..., UOp]] = {
ir3.SOPP: _compile_sopp, ir3.SMEM: _compile_smem, ir3.SOP1: _compile_sop, ir3.SOP2: _compile_sop, ir3.SOPC: _compile_sop, ir3.SOPK: _compile_sop,
ir3.VOP1: _compile_vop12, ir3.VOP1_SDST: _compile_vop12, ir3.VOP2: _compile_vop12, ir3.VOPC: _compile_vopc, ir3.VOP3: _compile_vop3,
ir3.VOP1: _compile_vop12, ir3.VOP1_SDST: _compile_vop12, ir3.VOP1_DPP16: _compile_vop12, ir3.VOP2: _compile_vop12, ir3.VOP2_DPP16: _compile_vop12,
ir3.VOPC: _compile_vopc, ir3.VOPC_DPP16: _compile_vopc, ir3.VOP3: _compile_vop3, ir3.VINTERP: _compile_vinterp,
ir3.VOP3_SDST: _compile_vop3, ir3.VOP3SD: _compile_vop3sd, ir3.VOP3P: _compile_vop3p, ir3.VOPD: _compile_vopd,
ir3.DS: _compile_mem_op, ir3.FLAT: _compile_mem_op, ir3.GLOBAL: _compile_mem_op, ir3.SCRATCH: _compile_mem_op,
# RDNA4 instruction classes
ir4.SOPP: _compile_sopp, ir4.SMEM: _compile_smem, ir4.SOP1: _compile_sop, ir4.SOP2: _compile_sop, ir4.SOPC: _compile_sop, ir4.SOPK: _compile_sop,
ir4.VOP1: _compile_vop12, ir4.VOP1_SDST: _compile_vop12, ir4.VOP2: _compile_vop12, ir4.VOPC: _compile_vopc, ir4.VOP3: _compile_vop3,
ir4.VOP1: _compile_vop12, ir4.VOP1_SDST: _compile_vop12, ir4.VOP1_DPP16: _compile_vop12, ir4.VOP2: _compile_vop12, ir4.VOP2_DPP16: _compile_vop12,
ir4.VOPC: _compile_vopc, ir4.VOPC_DPP16: _compile_vopc, ir4.VOP3: _compile_vop3, ir4.VINTERP: _compile_vinterp,
ir4.VOP3_SDST: _compile_vop3, ir4.VOP3SD: _compile_vop3sd, ir4.VOP3P: _compile_vop3p, ir4.VOPD: _compile_vopd,
ir4.DS: _compile_mem_op, ir4.VFLAT: _compile_mem_op, ir4.VGLOBAL: _compile_mem_op, ir4.VSCRATCH: _compile_mem_op,
# CDNA instruction classes
irc.SOPP: _compile_sopp, irc.SMEM: _compile_smem, irc.SOP1: _compile_sop, irc.SOP2: _compile_sop, irc.SOPC: _compile_sop, irc.SOPK: _compile_sop,
irc.VOP1: _compile_vop12, irc.VOP2: _compile_vop12, irc.VOPC: _compile_vopc, irc.VOP3: _compile_vop3,
irc.VOP1: _compile_vop12, irc.VOP1_DPP16: _compile_vop12, irc.VOP2: _compile_vop12, irc.VOP2_DPP16: _compile_vop12,
irc.VOPC: _compile_vopc, irc.VOP3: _compile_vop3,
irc.VOP3_SDST: _compile_vop3, irc.VOP3SD: _compile_vop3sd, irc.VOP3P: _compile_vop3p,
irc.VOP1_SDWA: _compile_sdwa, irc.VOP2_SDWA: _compile_sdwa, irc.VOP2_SDWA_SDST: _compile_sdwa, irc.VOPC_SDWA_SDST: _compile_sdwa,
irc.DS: _compile_mem_op, irc.FLAT: _compile_mem_op, irc.GLOBAL: _compile_mem_op, irc.SCRATCH: _compile_mem_op,
+40 -19
View File
@@ -4,7 +4,7 @@ from tinygrad.dtype import dtypes
from tinygrad.uop.ops import Ops, UOp
from tinygrad.uop.decompositions import f2f
# Type alias for vars dict: stores UOps for variables and tuples for lambda definitions
# Type alias for vars dict: stores UOps and tuples for lambda definitions
VarVal = UOp | tuple[str, list[str], str]
def _const(dt, v): return UOp.const(dt, v)
@@ -50,6 +50,22 @@ def _extract_bits(val: UOp, hi: int, lo: int) -> UOp:
if result.dtype != target_dt: result = result.cast(target_dt)
return result
def _expr_bits(v: UOp) -> int:
if v.dtype == dtypes.bool: return 1
if v.op in (Ops.AND, Ops.XOR):
widths: list[int] = []
for src in v.src:
if src.op == Ops.CONST and isinstance(src.arg, int) and src.arg > 0 and (src.arg & (src.arg + 1)) == 0:
widths.append(src.arg.bit_length())
if widths: return max(widths)
return v.dtype.bitsize
def _countbits(v: UOp) -> UOp:
dt = dtypes.uint64 if _expr_bits(v) > 32 or v.dtype in (dtypes.uint64, dtypes.int64) else dtypes.uint32
vv, out = v.cast(dt), _u32(0)
for i in range(_expr_bits(v)): out = out + ((vv >> _const(dt, i)) & _const(dt, 1)).cast(dtypes.uint32)
return out
def _set_bit(old, pos, val):
mask = _u32(1) << pos
return (old & (mask ^ _u32(0xFFFFFFFF))) | ((val.cast(dtypes.uint32) & _u32(1)) << pos)
@@ -335,6 +351,7 @@ _FUNCS: dict[str, Callable[..., UOp]] = {
# System NOPs - these are scheduling hints, no effect on emulation
'MIN': lambda a, b: (a < b).where(a, b),
's_nop': lambda a: _u32(0),
'countbits': _countbits,
# Address calculation for memory operations
'CalcDsAddr': lambda a, o, *r: a.cast(dtypes.uint32) + o.cast(dtypes.uint32),
'CalcGlobalAddr': lambda v, s, *r: v.cast(dtypes.uint64) + s.cast(dtypes.uint64),
@@ -389,7 +406,7 @@ def tokenize(s: str) -> list[Token]:
if c.isspace():
i += 1
continue
if i + 1 < n and s[i:i+2] in ('+=', '-='):
if i + 1 < n and s[i:i+2] in ('+=', '-=', '|=', '&=', '^='):
tokens.append(Token('ASSIGN_OP', s[i:i+2]))
i += 2
continue
@@ -503,7 +520,7 @@ class Parser:
def unary(self) -> UOp:
if self.try_eat_val('~', 'OP'):
inner = self.unary()
return inner ^ _const(inner.dtype, (1 << (inner.dtype.itemsize * 8)) - 1)
return inner ^ _const(inner.dtype, (1 << _expr_bits(inner)) - 1)
if self.try_eat_val('!', 'OP'):
inner = self.unary()
return inner.eq(_const(inner.dtype, 0))
@@ -539,7 +556,10 @@ class Parser:
self.eat('COMMA')
lo = self.parse()
self.eat('RBRACE')
return (hi.cast(dt:=_BITS_DT.get((s:=lo.dtype.bitsize) * 2, dtypes.uint64)) << _const(dt, s)) | lo.cast(dt)
lo_bits, hi_bits = _expr_bits(lo), _expr_bits(hi)
total_bits = lo_bits + hi_bits
dt = _BITS_DT.get(total_bits, dtypes.uint32 if total_bits <= 32 else dtypes.uint64)
return (hi.cast(dt) << _const(dt, lo_bits)) | lo.cast(dt)
if self.at('NUM'):
num = self.eat('NUM').val
if self.try_eat('QUOTE'):
@@ -576,8 +596,8 @@ class Parser:
if name == 'OVERFLOW_F32': return _const(dtypes.uint32, 0x7F7FFFFF).bitcast(dtypes.float32)
if name == 'UNDERFLOW_F64': return _const(dtypes.uint64, 1).bitcast(dtypes.float64)
if name == 'OVERFLOW_F64': return _const(dtypes.uint64, 0x7FEFFFFFFFFFFFFF).bitcast(dtypes.float64)
if name == 'WAVE32': return _const(dtypes.bool, self.vars.get('_wave_size', 32) <= 32)
if name == 'WAVE64': return _const(dtypes.bool, self.vars.get('_wave_size', 32) > 32)
if name.lower() == 'wave32': return _const(dtypes.bool, self.vars.get('_wave_size', 32) <= 32)
if name.lower() == 'wave64': return _const(dtypes.bool, self.vars.get('_wave_size', 32) > 32)
if name == 'WAVE_MODE' and self.try_eat('DOT') and self.try_eat_val('IEEE', 'IDENT'): return _u32(1)
if self.try_eat('LBRACE'):
idx = self.eat('NUM').val
@@ -685,7 +705,7 @@ class Parser:
dt = dtypes.uint64 if base.dtype in (dtypes.uint64, dtypes.int64) else dtypes.uint32
base_cast = base.cast(dt) if base.dtype != dt else base
result = ((base_cast >> _const(dt, idx)) & _const(dt, 1))
return _cast_to(result, dt_suffix) if dt_suffix else result
return _cast_to(result, dt_suffix) if dt_suffix else result.cast(dtypes.bool)
if var_name:
idx_u32 = _to_u32(first)
elems = [(i, self.vars[f'{var_name}@{i}']) for i in range(256) if f'{var_name}@{i}' in self.vars]
@@ -699,7 +719,7 @@ class Parser:
dt = dtypes.uint64 if base.dtype in (dtypes.uint64, dtypes.int64) else dtypes.uint32
base_cast = base.cast(dt) if base.dtype != dt else base
result = (base_cast >> first.cast(dt)) & _const(dt, 1)
return _cast_to(result, dt_suffix) if dt_suffix else result
return _cast_to(result, dt_suffix) if dt_suffix else result.cast(dtypes.bool)
def _handle_brace_index(self, base) -> UOp:
self.eat('LBRACE')
@@ -845,7 +865,7 @@ class Parser:
hi = mem.index(safe_idx_hi, *gate)
combined = val.cast(dtypes.uint64) | (hi.cast(dtypes.uint64) << UOp.const(dtypes.uint64, 32))
val = is_unaligned.where((combined >> (byte_off.cast(dtypes.uint64) * UOp.const(dtypes.uint64, 8))).cast(dtypes.uint32), val)
return val
return _cast_to(val, dt)
def _coerce_cmp(self, l: UOp, r: UOp) -> tuple[UOp, UOp]:
if l.dtype != r.dtype:
@@ -1044,14 +1064,12 @@ def parse_block(lines: list[str], start: int, env: dict[str, VarVal], funcs: dic
elif j < len(toks) and toks[j].type == 'EQUALS': j += 1
rhs = parse_tokens(toks[j:], env, funcs)
if compound_op:
mem = env.get('_vmem') if '_vmem' in env else env.get('_lds')
if isinstance(mem, UOp):
adt = dtypes.uint64 if addr.dtype == dtypes.uint64 else dtypes.uint32
idx = (addr >> _const(adt, 2)).cast(dtypes.int)
old = mem.index(idx)
if dt in (dtypes.uint64, dtypes.int64, dtypes.float64):
old = old.cast(dtypes.uint64) | (mem.index(((addr + _const(adt, 4)) >> _const(adt, 2)).cast(dtypes.int)).cast(dtypes.uint64) << _u64(32))
rhs = (old + rhs) if compound_op == '+=' else (old - rhs)
old = Parser([Token('EOF', '')], env, funcs)._handle_mem_load(addr, dt)
if compound_op == '+=': rhs = old + rhs
elif compound_op == '-=': rhs = old - rhs
elif compound_op == '|=': rhs = old | rhs
elif compound_op == '&=': rhs = old & rhs
elif compound_op == '^=': rhs = old ^ rhs
if assigns is not None: assigns.append((f'MEM[{_tok_str(addr_toks)}].{dt_name}', (addr, rhs)))
i += 1
continue
@@ -1188,7 +1206,11 @@ def parse_block(lines: list[str], start: int, env: dict[str, VarVal], funcs: dic
old = block_assigns.get(var, env.get(var, _u32(0)))
rhs = parse_tokens(toks[assign_op+1:], env, funcs)
if rhs.dtype != old.dtype: rhs = rhs.cast(old.dtype)
block_assigns[var] = env[var] = (old + rhs) if toks[assign_op].val == '+=' else (old - rhs)
if toks[assign_op].val == '+=': block_assigns[var] = env[var] = old + rhs
elif toks[assign_op].val == '-=': block_assigns[var] = env[var] = old - rhs
elif toks[assign_op].val == '|=': block_assigns[var] = env[var] = old | rhs
elif toks[assign_op].val == '&=': block_assigns[var] = env[var] = old & rhs
elif toks[assign_op].val == '^=': block_assigns[var] = env[var] = old ^ rhs
i += 1
continue
@@ -1335,4 +1357,3 @@ def parse_block(lines: list[str], start: int, env: dict[str, VarVal], funcs: dic
def parse_expr(expr: str, env: dict[str, VarVal], funcs: dict | None = None) -> UOp:
return parse_tokens(tokenize(expr.strip().rstrip(';')), env, funcs)
+1 -19
View File
@@ -1,5 +1,4 @@
import ctypes, ctypes.util
from tinygrad.helpers import getenv
def _try_dlopen_gpuocelot():
GPUOCELOT_PATHS = [ctypes.util.find_library("gpuocelot")] if ctypes.util.find_library("gpuocelot") is not None else []
@@ -16,7 +15,7 @@ def _try_dlopen_gpuocelot():
return None
class PythonRemu:
"""Python RDNA3/RDNA4 emulator wrapper that matches the libremu.so interface."""
"""Python RDNA3/RDNA4 emulator wrapper used by mockgpu."""
valid_mem_ranges: set[tuple[int, int]] = set()
rsrc2: int = 0x19c # Default: USER_SGPR_COUNT=14, enable X and Y workgroup IDs
scratch_size: int = 0 # private_segment_fixed_size from kernel descriptor
@@ -26,20 +25,3 @@ class PythonRemu:
def run_asm(self, lib: int, lib_sz: int, gx: int, gy: int, gz: int, lx: int, ly: int, lz: int, args_ptr: int) -> int:
from test.mockgpu.amd.emu import run_asm
return run_asm(lib, lib_sz, gx, gy, gz, lx, ly, lz, args_ptr, self.rsrc2, self.scratch_size, self.arch, self.user_data)
def _try_dlopen_remu():
# Use Python emulator only if PYTHON_REMU=1
if int(getenv("PYTHON_REMU", "1")):
return PythonRemu()
REMU_PATHS = ["extra/remu/target/release/libremu.so", "libremu.so", "/usr/local/lib/libremu.so",
"extra/remu/target/release/libremu.dylib", "libremu.dylib", "/usr/local/lib/libremu.dylib", "/opt/homebrew/lib/libremu.dylib"]
for path in REMU_PATHS:
try:
remu = ctypes.CDLL(path)
remu.run_asm.restype = ctypes.c_int32
remu.run_asm.argtypes = [ctypes.c_void_p, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32,
ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_void_p]
except OSError: pass
else: return remu
print("Could not find libremu.so")
return None
+78 -89
View File
@@ -1,7 +1,6 @@
import ctypes, struct, subprocess, tempfile, unittest
from typing import Annotated
from tinygrad.helpers import OSX, WIN
from tinygrad.runtime.support.c import DLL, record, init_records
from tinygrad.runtime.support.c import DLL, record, Field
from tinygrad.runtime.support import c
from tinygrad.runtime.support.autogen import gen
@@ -14,10 +13,9 @@ class TestC(unittest.TestCase):
def test_struct_array_init(self):
@record
class Foo:
class Foo(c.Struct):
SIZE = 12
a: Annotated[ctypes.c_int * 3, 0]
init_records()
a = Field(ctypes.c_int * 3, 0)
f = Foo((1,2,3))
assert f.a[0] == 1
@@ -30,11 +28,10 @@ class TestC(unittest.TestCase):
def test_field_ranges(self):
@record
class Foo:
class Foo(c.Struct):
SIZE = 2
s: Annotated[ctypes.c_int8, 0]
u: Annotated[ctypes.c_uint8, 1]
init_records()
s = Field(ctypes.c_int8, 0)
u = Field(ctypes.c_uint8, 1)
f = Foo()
f.s = -1
@@ -45,10 +42,9 @@ class TestC(unittest.TestCase):
# this syntax is inherited from ctypes, but it seems a bit nonsensical?
def test_voidp_none(self):
@record
class Foo:
class Foo(c.Struct):
SIZE = 8
p: Annotated[ctypes.c_void_p, 0]
init_records()
p = Field(ctypes.c_void_p, 0)
f = Foo(None)
assert f.p is None
@@ -59,13 +55,12 @@ class TestC(unittest.TestCase):
def test_packed_struct(self):
@record
class Baz:
class Baz(c.Struct):
SIZE = 8
a: Annotated[ctypes.c_uint, 0, 30]
b: Annotated[ctypes.c_uint, 3, 30, 6]
c: Annotated[ctypes.c_uint, 7, 2, 4]
d: Annotated[ctypes.c_uint, 7, 2, 6]
init_records()
a = Field(ctypes.c_uint, 0, 30)
b = Field(ctypes.c_uint, 3, 30, 6)
c = Field(ctypes.c_uint, 7, 2, 4)
d = Field(ctypes.c_uint, 7, 2, 6)
b = Baz(0x3AAADEAD, 0xBEEF, 1, 0)
assert b.a == 0x3AAADEAD
@@ -81,13 +76,12 @@ class TestC(unittest.TestCase):
def test_packed_struct_interop(self):
@record
class Baz:
class Baz(c.Struct):
SIZE = 8
a: Annotated[ctypes.c_int, 0, 30]
b: Annotated[ctypes.c_int, 3, 30, 6]
c: Annotated[ctypes.c_int, 7, 2, 4]
d: Annotated[ctypes.c_int, 7, 2, 6]
init_records()
a = Field(ctypes.c_int, 0, 30)
b = Field(ctypes.c_int, 3, 30, 6)
c = Field(ctypes.c_int, 7, 2, 4)
d = Field(ctypes.c_int, 7, 2, 6)
src = '''
struct __attribute__((packed)) baz {
@@ -103,24 +97,23 @@ class TestC(unittest.TestCase):
'''
dll = self.compile(src)
b = Baz(0xAA000, 0x00BB0, 0, 1)
@dll.bind
@dll.bind(ctypes.c_int, Baz)
def test(x:Baz) -> ctypes.c_int: ...
self.assertEqual(test(b), b.a + b.b + b.c + b.d)
# https://github.com/python/cpython/issues/90914
def test_bitfield_interop(self):
@record
class Baz:
class Baz(c.Struct):
SIZE = 1
a: Annotated[ctypes.c_bool, 0, 1, 0]
b: Annotated[ctypes.c_bool, 0, 1, 1]
c: Annotated[ctypes.c_bool, 0, 1, 2]
d: Annotated[ctypes.c_bool, 0, 1, 3]
e: Annotated[ctypes.c_bool, 0, 1, 4]
f: Annotated[ctypes.c_bool, 0, 1, 5]
g: Annotated[ctypes.c_bool, 0, 1, 6]
h: Annotated[ctypes.c_bool, 0, 1, 7]
init_records()
a = Field(ctypes.c_bool, 0, 1, 0)
b = Field(ctypes.c_bool, 0, 1, 1)
c = Field(ctypes.c_bool, 0, 1, 2)
d = Field(ctypes.c_bool, 0, 1, 3)
e = Field(ctypes.c_bool, 0, 1, 4)
f = Field(ctypes.c_bool, 0, 1, 5)
g = Field(ctypes.c_bool, 0, 1, 6)
h = Field(ctypes.c_bool, 0, 1, 7)
src = '''#include <stdbool.h>
struct baz {
bool a:1, b:1, c:1, d:1, e:1, f:1, g:1, h:1;
@@ -131,23 +124,22 @@ class TestC(unittest.TestCase):
}
'''
dll = self.compile(src)
@dll.bind
@dll.bind(ctypes.c_int, Baz)
def test(x:Baz) -> ctypes.c_int: ...
for i in range(8): self.assertEqual(test(Baz(*(j==i for j in range(8)))), i==2)
def test_struct_interop(self):
@record
class Baz:
class Baz(c.Struct):
SIZE = 32
a: Annotated[ctypes.c_int, 0]
b: Annotated[ctypes.c_int, 4]
c: Annotated[ctypes.c_int, 8]
d: Annotated[ctypes.c_int, 12]
e: Annotated[ctypes.c_int, 16]
f: Annotated[ctypes.c_int, 20]
g: Annotated[ctypes.c_int, 24]
h: Annotated[ctypes.c_int, 28]
init_records()
a = Field(ctypes.c_int, 0)
b = Field(ctypes.c_int, 4)
c = Field(ctypes.c_int, 8)
d = Field(ctypes.c_int, 12)
e = Field(ctypes.c_int, 16)
f = Field(ctypes.c_int, 20)
g = Field(ctypes.c_int, 24)
h = Field(ctypes.c_int, 28)
src = '''#include <stdio.h>
struct baz {
int a, b, c, d, e, f, g, h;
@@ -158,16 +150,15 @@ class TestC(unittest.TestCase):
}
'''
dll = self.compile(src)
@dll.bind
@dll.bind(Baz, Baz)
def test(x:Baz) -> Baz: ...
self.assertEqual(bytes(test(Baz(*range(8)))), struct.pack("8i", *range(7, -1, -1)))
def test_aos_interop(self):
@record
class Item:
class Item(c.Struct):
SIZE = 4
val: Annotated[ctypes.c_int, 0]
init_records()
val = Field(ctypes.c_int, 0)
src = """
struct item { int val; };
int test(struct item arr[3]) {
@@ -177,16 +168,15 @@ class TestC(unittest.TestCase):
}
"""
dll = self.compile(src)
@dll.bind
@dll.bind(ctypes.c_int, Item * 3)
def test(arr:(Item * 3)) -> ctypes.c_int: ...
self.assertEqual(test((Item * 3)(Item(10), Item(20), Item(30))), 60)
def test_soa_interop(self):
@record
class Row:
class Row(c.Struct):
SIZE = 16
data: Annotated[ctypes.c_int * 3, 0]
init_records()
data = Field(ctypes.c_int * 3, 0)
src = """
struct row { int data[3]; };
struct row test(struct row x) {
@@ -194,7 +184,7 @@ class TestC(unittest.TestCase):
}
"""
dll = self.compile(src)
@dll.bind
@dll.bind(Row, Row)
def test(x:Row) -> Row: ...
r = test(Row((ctypes.c_int * 3)(10, 20, 30)))
self.assertIsInstance(r, Row)
@@ -204,10 +194,9 @@ class TestC(unittest.TestCase):
def test_soa_ptr_interop(self):
@record
class Row:
class Row(c.Struct):
SIZE = 8
data: Annotated[c.POINTER[ctypes.c_int], 0]
init_records()
data = Field(c.POINTER[ctypes.c_int], 0)
src = """
struct row { int *data; };
int test(struct row x) {
@@ -215,21 +204,20 @@ class TestC(unittest.TestCase):
}
"""
dll = self.compile(src)
@dll.bind
@dll.bind(ctypes.c_int, Row)
def test(x:Row) -> ctypes.c_int: ...
assert test(Row((ctypes.c_int * 3)(10, 20, 30))) == 60
def test_nested_struct_interop(self):
@record
class Inner:
class Inner(c.Struct):
SIZE = 4
a: Annotated[ctypes.c_int, 0]
a = Field(ctypes.c_int, 0)
@record
class Outer:
class Outer(c.Struct):
SIZE = 8
inner: Annotated[Inner, 0]
b: Annotated[ctypes.c_int, 4]
init_records()
inner = Field(Inner, 0)
b = Field(ctypes.c_int, 4)
src = """
struct i { int a; };
struct o { struct i i; int b; };
@@ -238,7 +226,7 @@ class TestC(unittest.TestCase):
}
"""
dll = self.compile(src)
@dll.bind
@dll.bind(Outer, Outer)
def test(x:Outer) -> Outer: ...
o = test(Outer(Inner(10), 20))
self.assertEqual(o.inner.a, 20)
@@ -246,11 +234,10 @@ class TestC(unittest.TestCase):
def test_struct_pointer_interop(self):
@record
class Foo:
class Foo(c.Struct):
SIZE = 8
a: Annotated[ctypes.c_int, 0]
b: Annotated[ctypes.c_int, 4]
init_records()
a = Field(ctypes.c_int, 0)
b = Field(ctypes.c_int, 4)
src = """
struct foo { int a, b; };
struct foo *test(struct foo *f) {
@@ -261,7 +248,7 @@ class TestC(unittest.TestCase):
}
"""
dll = self.compile(src)
@dll.bind
@dll.bind(ctypes.POINTER(Foo), ctypes.POINTER(Foo))
def test(f:ctypes.POINTER(Foo)) -> ctypes.POINTER(Foo): ...
inp = ctypes.pointer(Foo(10, 20))
out = test(inp)
@@ -273,16 +260,15 @@ class TestC(unittest.TestCase):
# Mimics how mesa.struct_lp_build_tgsi_params.mask is used
from tinygrad.runtime.support.c import POINTER
@record
class Inner:
class Inner(c.Struct):
SIZE = 8
value: Annotated[ctypes.c_int, 0]
flag: Annotated[ctypes.c_int, 4]
value = Field(ctypes.c_int, 0)
flag = Field(ctypes.c_int, 4)
@record
class Outer:
class Outer(c.Struct):
SIZE = 16
x: Annotated[ctypes.c_int, 0]
inner_ptr: Annotated[POINTER[Inner], 8]
init_records()
x = Field(ctypes.c_int, 0)
inner_ptr = Field(POINTER[Inner], 8)
src = """
struct inner { int value; int flag; };
@@ -292,7 +278,7 @@ class TestC(unittest.TestCase):
}
"""
dll = self.compile(src)
@dll.bind
@dll.bind(ctypes.c_int, ctypes.POINTER(Inner))
def test(p:POINTER[Inner]) -> ctypes.c_int: ...
inner = Inner(value=42, flag=10)
@@ -306,17 +292,16 @@ class TestC(unittest.TestCase):
# This causes the pointed-to object to be garbage collected, leading to use-after-free.
from tinygrad.runtime.support.c import POINTER
@record
class MaskContext:
class MaskContext(c.Struct):
SIZE = 16
value: Annotated[ctypes.c_int, 0]
initialized: Annotated[ctypes.c_int, 4]
ptr: Annotated[ctypes.c_void_p, 8]
value = Field(ctypes.c_int, 0)
initialized = Field(ctypes.c_int, 4)
ptr = Field(ctypes.c_void_p, 8)
@record
class Params:
class Params(c.Struct):
SIZE = 16
x: Annotated[ctypes.c_int, 0]
mask: Annotated[POINTER[MaskContext], 8]
init_records()
x = Field(ctypes.c_int, 0)
mask = Field(POINTER[MaskContext], 8)
src = """
struct mask_ctx { int value; int initialized; void *ptr; };
@@ -324,9 +309,9 @@ class TestC(unittest.TestCase):
int mask_end(struct mask_ctx *m) { return m->value + m->initialized; }
"""
dll = self.compile(src)
@dll.bind
@dll.bind(None, ctypes.POINTER(MaskContext), ctypes.c_int)
def mask_begin(m:POINTER[MaskContext], val:ctypes.c_int) -> None: ...
@dll.bind
@dll.bind(ctypes.c_int, ctypes.POINTER(MaskContext))
def mask_end(m:POINTER[MaskContext]) -> ctypes.c_int: ...
# When MaskContext() is created inline, it gets garbage collected after the pointer
@@ -444,6 +429,10 @@ typedef struct
self.assertTrue(hasattr(rect, 'height'))
self.assertTrue(hasattr(rect, 'color'))
p2 = Point(10, 20)
self.assertEqual(p2.x, 10)
self.assertEqual(p2.y, 20)
def test_struct_ordering(self):
namespace = self.run_gen("""
struct A;
+18 -4
View File
@@ -26,8 +26,17 @@ class TestDevice(unittest.TestCase):
@unittest.skipIf(Device.DEFAULT != "CPU", "only run on CPU")
def test_nonexistent_renderer(self):
with self.assertRaisesRegex(AssertionError, "No renderer"):
with self.assertRaisesRegex(RuntimeError, "has no renderer"):
with Context(DEV="CPU:TYPO"): Device[Device.DEFAULT].renderer
with self.assertRaisesRegex(RuntimeError, "did you mean: 'CLANGJIT'"):
with Context(DEV="CPU:CLANG"): Device[Device.DEFAULT].renderer
@unittest.skipIf(Device.DEFAULT != "AMD", "only run on AMD")
def test_nonexistent_iface(self):
result = subprocess.run(['python3', '-c', 'from tinygrad import Device; Device[Device.DEFAULT].iface'],
env={**os.environ, "DEV":"USA+AMD"}, capture_output=True)
self.assertNotEqual(result.returncode, 0)
self.assertIn(b"did you mean: 'USB'", result.stderr)
def test_lowercase_canonicalizes(self):
device = Device.DEFAULT
@@ -118,10 +127,11 @@ class TestDevVar(unittest.TestCase):
("AMD:LLVM:gfx1100", Target(device="AMD", renderer="LLVM", arch="gfx1100")), ("::gfx1100", Target(arch="gfx1100")),
("USB+", Target(interface="USB")), ("USB+AMD", Target(device="AMD", interface="USB")),
("PCI:0+AMD", Target(device="AMD", interface="PCI", indices="0")), (":0+AMD", Target(device="AMD", indices="0")),
("PCI:0,1+AMD", Target(device="AMD", interface="PCI", indices="0,1"))]:
("PCI:0,1+AMD", Target(device="AMD", interface="PCI", indices="0,1")),
("QCOM;USB+AMD", [Target(device="QCOM"), Target(device="AMD", interface="USB")])]:
with Context(DEV=d):
self.assertEqual(DEV.value, t)
self.assertEqual(str(DEV.value), d)
self.assertEqual(DEV.value, t if isinstance(t, list) else [t])
self.assertEqual(str(DEV), d)
def test_target(self):
with Context(DEV="CPU"): self.assertEqual(DEV.target("CPU"), Target("CPU"))
@@ -129,6 +139,10 @@ class TestDevVar(unittest.TestCase):
with Context(DEV=":LLVM"): self.assertEqual(DEV.target("CPU"), Target("CPU", "LLVM"))
with Context(DEV="AMD:LLVM"): self.assertEqual(DEV.target("CPU"), Target("CPU"))
with Context(DEV=""): self.assertEqual(DEV.target("CPU"), Target("CPU"))
with Context(DEV="QCOM:IR3;AMD:LLVM"):
self.assertEqual(DEV.target("QCOM"), Target("QCOM", "IR3"))
self.assertEqual(DEV.target("AMD"), Target("AMD", "LLVM"))
self.assertEqual(DEV.target("CPU"), Target("CPU"))
def test_dev_arch_override(self):
with Context(DEV="NULL:HIP:gfx1100"):
+12
View File
@@ -46,6 +46,18 @@ class TestLLMTokenizer(unittest.TestCase):
def test_llama_repeat(self): self._test_coding(self.llama_tok, "00000000000000000", [ 931, 931, 931, 931, 931, 410 ])
def test_llama_pat(self): self._test_coding(self.llama_tok, "today\n \n", [ 31213, 14211 ])
def test_tekken_from_gguf_kv(self):
kv = {
"tokenizer.ggml.tokens": ["<unk>", "<s>", "</s>", "[INST]", "[/INST]", "hello"],
"tokenizer.ggml.token_type": [3, 3, 3, 3, 3, 1],
"tokenizer.ggml.pre": "tekken",
}
tok = SimpleTokenizer.from_gguf_kv(kv)
self.assertEqual(tok.role("user"), [3])
self.assertEqual(tok.encode("hello"), [5])
self.assertEqual(tok.end_turn(2), [4])
self.assertEqual(tok.role("assistant"), [])
def test_stream_decoder(self):
"""stream_decoder buffers incomplete UTF-8: token 25677 has 3/4 of emoji, token 138 completes it."""
bs = [*range(33, 127), *range(161, 173), *range(174, 256)]
+1 -1
View File
@@ -1,7 +1,7 @@
import unittest
from tinygrad import dtypes
from tinygrad.uop.ops import UOp, Ops
from tinygrad.engine.memory import memory_plan_rewrite
from tinygrad.schedule.memory import memory_plan_rewrite
global_map = {}
held_bufs: set[UOp] = set()
+14
View File
@@ -1,6 +1,7 @@
import gc, unittest
from tinygrad import Tensor, GlobalCounters, dtypes
from tinygrad.engine.jit import TinyJit
from tinygrad.helpers import Context
class TestMultiRamUsage(unittest.TestCase):
def setUp(self):
@@ -139,6 +140,19 @@ class TestMultiRamUsage(unittest.TestCase):
mem_4 = run_layers(4)
self.assertEqual(mem_2, mem_4, f"graph memory should not grow with layers: 2 layers={mem_2}, 4 layers={mem_4}")
def test_allreduce_cast_dtype_memory(self):
N = 32
devices_2 = ("NULL:1", "NULL:2")
mem = {}
for allreduce_cast in (0, 1):
GlobalCounters.reset()
with Context(ALLREDUCE_CAST=allreduce_cast, SCACHE=0):
x = Tensor.empty((N, N), dtype=dtypes.bfloat16, device="NULL:1").shard(devices_2, axis=0)
x.sum(0).realize()
mem[allreduce_cast] = GlobalCounters.global_mem
# with ALLREDUCE_CAST, allreduce copies happen in bf16 (2 bytes) instead of fp32 (4 bytes)
self.assertLess(mem[1], mem[0])
class TestMultiAxis(unittest.TestCase):
def test_reshape_shard_invalid(self):
devices = ("NULL:0", "NULL:1")
+8 -1
View File
@@ -1,5 +1,5 @@
import unittest
from tinygrad import Tensor, Device
from tinygrad import Tensor, Device, Context
from tinygrad.engine.realize import get_program
from tinygrad.codegen.opt import Opt, OptOps
from test.external.process_replay.process_replay import replay_get_program
@@ -30,5 +30,12 @@ class TestProcessReplay(unittest.TestCase):
good, compare, _ = replay_get_program(p, self.ast, self.renderer, opts=opts)
self.assertEqual(good, compare)
@Context(BEAM=1)
def test_beam(self):
si = (Tensor.empty(N, N) @ Tensor.empty(N, N)).schedule()[-1]
p = get_program(si.ast, self.renderer)
good, compare, _ = replay_get_program(p, self.ast, self.renderer)
self.assertEqual(good, compare)
if __name__ == '__main__':
unittest.main(verbosity=2)
+31 -1
View File
@@ -1,7 +1,7 @@
# schedule tests that pass on NULL backend (no copyout needed)
import gc, unittest, time
from tinygrad import nn, dtypes, Device, Tensor
from tinygrad.uop.ops import UOp, Ops, GroupOp, UPat
from tinygrad.uop.ops import UOp, Ops, GroupOp, UPat, KernelInfo
from tinygrad.helpers import DEBUG, GlobalCounters, Context
from tinygrad.engine.realize import CompiledRunner, run_schedule
@@ -143,6 +143,36 @@ class TestSimpleSchedule(unittest.TestCase):
self.assertEqual(len(Tensor.schedule(a1, a2)), 1)
class TestSchedule(unittest.TestCase):
def test_create_schedule_handles_multi_kernel_after_and_after_deps(self):
def named_copy(name:str):
def fxn(out:UOp, src:UOp) -> UOp:
i = UOp.range(src.shape[0], 0)
return out[i].store(src[i]).end(i).sink(arg=KernelInfo(name=name))
return fxn
src = Tensor.zeros(4, dtype=dtypes.float).contiguous().realize()
dep = Tensor.zeros(4, dtype=dtypes.float).contiguous().realize()
out = Tensor.zeros(4, dtype=dtypes.float).contiguous().realize()
ones = Tensor.ones(4, dtype=dtypes.float).contiguous().realize()
twos = Tensor.full((4,), 2.0, dtype=dtypes.float).contiguous().realize()
threes = Tensor.full((4,), 3.0, dtype=dtypes.float).contiguous().realize()
ka = Tensor.custom_kernel(src, ones, fxn=named_copy("ka"))[0]
kb = Tensor.custom_kernel(src, twos, fxn=named_copy("kb"))[0]
src_after = Tensor(src.uop.after(*ka.uop.src[1:], *kb.uop.src[1:]))
kd = Tensor.custom_kernel(dep, threes, fxn=named_copy("kd"))[0]
kc = Tensor.custom_kernel(out, src_after, fxn=named_copy("kc"))[0]
out_after = Tensor(kc.uop.src[0].after(*kc.uop.src[1:], kd.uop))
schedule = out_after.schedule()
names = [si.ast.arg.name for si in schedule]
self.assertEqual(set(names), {"ka", "kb", "kc", "kd"})
self.assertEqual(names[-1], "kc")
self.assertLess(names.index("ka"), names.index("kc"))
self.assertLess(names.index("kb"), names.index("kc"))
self.assertLess(names.index("kd"), names.index("kc"))
@unittest.skipIf(Device.DEFAULT == "CPU", "devices must mismatch")
def test_error_on_device_mismatch(self):
a = Tensor.empty(10)
+1 -1
View File
@@ -1,7 +1,7 @@
import unittest
from tinygrad import Tensor, Variable, Context
from tinygrad.helpers import cpu_events
from tinygrad.engine.schedule import schedule_cache
from tinygrad.schedule import schedule_cache
def schedule_one():
Tensor([1]).schedule()
+11
View File
@@ -97,5 +97,16 @@ class TestSymbolicShrink(unittest.TestCase):
t = Tensor.rand(3, 5).shrink(((0, 2), (vi, vi+1)))
assert t.shape == (2, 1)
class TestSymbolicContiguousViewOffset(unittest.TestCase):
def test_shrink_from_start(self):
v = Variable("v", 1, 10).bind(5)
t = Tensor.rand(10).realize().shrink(((0, v),))
self.assertEqual(t.uop.contiguous_view_offset(), 0)
def test_shrink_with_offset(self):
v = Variable("v", 1, 7).bind(4)
t = Tensor.rand(10).realize().shrink(((3, 3+v),))
self.assertEqual(t.uop.contiguous_view_offset(), 3)
if __name__ == '__main__':
unittest.main()
+1 -1
View File
@@ -2,7 +2,7 @@ import unittest
from tinygrad import Tensor, dtypes
from tinygrad.tensor import _METADATA
from tinygrad.engine.realize import capturing
from tinygrad.engine.schedule import linear_to_schedule
from tinygrad.schedule import linear_to_schedule
from tinygrad.helpers import Context
@unittest.skip("tensor metadata is no longer supported")
+51 -59
View File
@@ -1,82 +1,74 @@
import math, unittest
from tinygrad import Tensor
# TODO: make all the expectedFailure cases pass — i.e. UOp.__getitem__ should produce the same UOp graph as
# Tensor.__getitem__ for every view-returning index pattern.
def _t(*shape):
return Tensor.arange(math.prod(shape)).reshape(*shape)
# Tensor().func().uop should be the same as UOp.func()
def _check(tc: unittest.TestCase, t: Tensor, fn):
tc.assertIs(fn(t).uop, fn(t.uop), f"\ntensor.uop = {fn(t).uop}\nuop = {fn(t.uop)}")
class TestTensorUOpGetitem(unittest.TestCase):
"""For each pattern, check that `Tensor(x)[idx].uop` equals `x.uop[idx]`."""
def _check(self, t: Tensor, idx):
via_tensor = t[idx].uop
via_uop = t.uop[idx]
self.assertIs(via_tensor, via_uop, f"\nidx={idx!r}\ntensor.uop = {via_tensor}\nuop[idx] = {via_uop}")
# ---- pure slice patterns ----
def test_slice_full(self): self._check(_t(4), slice(None))
def test_slice_positive(self): self._check(_t(8), slice(1, 5))
def test_slice_open_start(self): self._check(_t(8), slice(None, 5))
def test_slice_open_stop(self): self._check(_t(8), slice(3, None))
@unittest.expectedFailure
def test_slice_negative_start(self): self._check(_t(8), slice(-3, None))
@unittest.expectedFailure
def test_slice_negative_stop(self): self._check(_t(8), slice(None, -2))
@unittest.expectedFailure
def test_slice_both_negative(self): self._check(_t(8), slice(-5, -1))
def test_slice_full(self): _check(self, _t(4), lambda x: x[slice(None)])
def test_slice_positive(self): _check(self, _t(8), lambda x: x[1:5])
def test_slice_open_start(self): _check(self, _t(8), lambda x: x[:5])
def test_slice_open_stop(self): _check(self, _t(8), lambda x: x[3:])
def test_slice_negative_start(self): _check(self, _t(8), lambda x: x[-3:])
def test_slice_negative_stop(self): _check(self, _t(8), lambda x: x[:-2])
def test_slice_both_negative(self): _check(self, _t(8), lambda x: x[-5:-1])
# ---- slice with stride ----
@unittest.expectedFailure
def test_slice_stride(self): self._check(_t(6), slice(None, None, 2))
@unittest.expectedFailure
def test_slice_start_stop_stride(self): self._check(_t(6), slice(1, 5, 2))
@unittest.expectedFailure
def test_slice_reverse(self): self._check(_t(6), slice(None, None, -1))
@unittest.expectedFailure
def test_slice_singleton_negative_step(self): self._check(_t(8), slice(3, 2, -1))
def test_slice_stride(self): _check(self, _t(6), lambda x: x[::2])
def test_slice_start_stop_stride(self): _check(self, _t(6), lambda x: x[1:5:2])
def test_slice_reverse(self): _check(self, _t(6), lambda x: x[::-1])
def test_slice_singleton_negative_step(self): _check(self, _t(8), lambda x: x[3:2:-1])
# ---- empty / out-of-bounds slice ----
@unittest.expectedFailure
def test_slice_empty(self): self._check(_t(6), slice(3, 1))
@unittest.expectedFailure
def test_slice_oob_stop(self): self._check(_t(6), slice(0, 100))
def test_slice_empty(self): _check(self, _t(6), lambda x: x[3:1])
def test_slice_oob_stop(self): _check(self, _t(6), lambda x: x[0:100])
# ---- single int (reduces a dim) ----
@unittest.expectedFailure
def test_int_positive(self): self._check(_t(8), 3)
@unittest.expectedFailure
def test_int_negative(self): self._check(_t(8), -1)
def test_int_positive(self): _check(self, _t(8), lambda x: x[3])
def test_int_negative(self): _check(self, _t(8), lambda x: x[-1])
# ---- ellipsis ----
def test_ellipsis_only(self): self._check(_t(2, 3, 4), (Ellipsis,))
@unittest.expectedFailure
def test_ellipsis_then_int(self): self._check(_t(2, 3, 4), (Ellipsis, -1))
def test_ellipsis_then_slice(self): self._check(_t(2, 3, 4), (Ellipsis, slice(1, 3)))
@unittest.expectedFailure
def test_ellipsis_then_none(self): self._check(_t(2, 3), (Ellipsis, None))
def test_ellipsis_only(self): _check(self, _t(2, 3, 4), lambda x: x[...])
def test_ellipsis_then_int(self): _check(self, _t(2, 3, 4), lambda x: x[..., -1])
def test_ellipsis_then_slice(self): _check(self, _t(2, 3, 4), lambda x: x[..., 1:3])
def test_ellipsis_then_none(self): _check(self, _t(2, 3), lambda x: x[..., None])
# ---- None (unsqueeze) ----
@unittest.expectedFailure
def test_none_front(self): self._check(_t(4), (None,))
@unittest.expectedFailure
def test_none_back(self): self._check(_t(4), (slice(None), None))
@unittest.expectedFailure
def test_none_middle(self): self._check(_t(2, 3), (slice(None), None, slice(None)))
@unittest.expectedFailure
def test_multiple_none(self): self._check(_t(2, 3), (None, slice(None), None))
def test_none_front(self): _check(self, _t(4), lambda x: x[None])
def test_none_back(self): _check(self, _t(4), lambda x: x[:, None])
def test_none_middle(self): _check(self, _t(2, 3), lambda x: x[:, None, :])
def test_multiple_none(self): _check(self, _t(2, 3), lambda x: x[None, :, None])
# ---- mixed multi-dim ----
@unittest.expectedFailure
def test_int_then_slice(self): self._check(_t(2, 3), (1, slice(None)))
@unittest.expectedFailure
def test_multi_int(self): self._check(_t(2, 3, 4), (1, 2))
@unittest.expectedFailure
def test_mixed_slice_int(self): self._check(_t(2, 3, 4), (slice(0, 2), -1, slice(1, 3)))
def test_mixed_slice_slice(self): self._check(_t(3, 4, 5), (slice(1, 3), slice(None), slice(0, 2)))
@unittest.expectedFailure
def test_high_rank_combo(self): self._check(_t(4, 5, 6), (slice(1, 3), slice(None), -1, None))
def test_int_then_slice(self): _check(self, _t(2, 3), lambda x: x[1, :])
def test_multi_int(self): _check(self, _t(2, 3, 4), lambda x: x[1, 2])
def test_mixed_slice_int(self): _check(self, _t(2, 3, 4), lambda x: x[0:2, -1, 1:3])
def test_mixed_slice_slice(self): _check(self, _t(3, 4, 5), lambda x: x[1:3, :, 0:2])
def test_high_rank_combo(self): _check(self, _t(4, 5, 6), lambda x: x[1:3, :, -1, None])
class TestTensorUOpCumalu(unittest.TestCase):
def test_cumsum_1d(self): _check(self, _t(5), lambda x: x.cumsum())
def test_cumsum_2d(self): _check(self, _t(3, 4), lambda x: x.cumsum(1))
def test_cumsum_non_last(self): _check(self, _t(3, 4), lambda x: x.cumsum(0))
def test_cumsum_large(self): _check(self, _t(600), lambda x: x.cumsum()) # exercises _split_cumalu
def test_cumprod(self): _check(self, _t(4), lambda x: x.cumprod(0))
class TestTensorUOpCat(unittest.TestCase):
def test_cat_dim0(self): _check(self, _t(2, 3), lambda x: x.cat(x, dim=0))
def test_cat_dim1(self): _check(self, _t(2, 3), lambda x: x.cat(x, dim=1))
def test_cat_3tensors(self): _check(self, _t(2, 3), lambda x: x.cat(x, x, dim=0))
def test_cat_neg_dim(self): _check(self, _t(2, 3, 4), lambda x: x.cat(x, dim=-1))
class TestTensorUOpStack(unittest.TestCase):
def test_stack_dim0(self): _check(self, _t(2, 3), lambda x: x.stack(x, dim=0))
def test_stack_dim1(self): _check(self, _t(2, 3), lambda x: x.stack(x, dim=1))
def test_stack_3tensors(self): _check(self, _t(2, 3), lambda x: x.stack(x, x, dim=0))
def test_stack_new_last(self): _check(self, _t(2, 3), lambda x: x.stack(x, dim=-1))
if __name__ == "__main__":
unittest.main()
+21 -21
View File
@@ -10,7 +10,7 @@ from tinygrad.helpers import VIZ, cpu_profile, ProfilePointEvent, unwrap
from tinygrad.device import Buffer
from tinygrad.uop.ops import tracked_keys, tracked_ctxs, uop_fields, active_rewrites, active_group, _name_cnt, RewriteTrace
from tinygrad.viz.serve import get_rewrites, get_full_rewrite, uop_to_json
from tinygrad.viz.serve import load_rewrites, get_full_rewrite, uop_to_json, VizData
@track_rewrites(name=True)
def exec_rewrite(sink:UOp, pm_lst:list[PatternMatcher], names:None|list[str]=None) -> UOp:
@@ -21,19 +21,19 @@ def exec_rewrite(sink:UOp, pm_lst:list[PatternMatcher], names:None|list[str]=Non
# small container class for the viz server module
class VizTrace:
# loader init
def __init__(self): self._trace:RewriteTrace|None = None
def __init__(self): self._data:VizData|None = None
@property
def trace(self) -> RewriteTrace: return unwrap(self._trace)
def set_trace(self) -> None:
self._trace = RewriteTrace(tracked_keys.copy(), tracked_ctxs.copy(), uop_fields.copy())
import tinygrad.viz.serve as serve_module
serve_module.trace = self._trace
def data(self) -> VizData: return unwrap(self._data)
def set_data(self) -> None:
data = VizData(RewriteTrace(tracked_keys.copy(), tracked_ctxs.copy(), uop_fields.copy()))
load_rewrites(data)
self._data = data
# the API
def list_items(self) -> list[dict]: return get_rewrites(self.trace)
def list_items(self) -> list[dict]:
return self.data.ctxs
def get_details(self, rewrite_idx:int, step:int) -> Generator[dict, None, None]:
lst = self.list_items()
assert len(lst) > rewrite_idx, f"only loaded {len(lst)} traces, expecting at least {rewrite_idx}"
return get_full_rewrite(self.trace.rewrites[rewrite_idx][step])
assert len(self.data.trace.rewrites) > rewrite_idx, f"only loaded {len(self.data.trace.rewrites)} traces, expecting at least {rewrite_idx}"
return get_full_rewrite(self.data, self.data.trace.rewrites[rewrite_idx][step])
@contextlib.contextmanager
def save_viz():
@@ -52,7 +52,7 @@ def save_viz():
try:
yield viz
finally:
viz.set_trace()
viz.set_data()
TRACK_MATCH_STATS.value = prev_tms
PROFILE.value = prev_profile
VIZ.value = prev_viz
@@ -194,7 +194,7 @@ class TestViz(unittest.TestCase):
class TestStruct:
colored_field: str
a = UOp(Ops.CUSTOM, arg=TestStruct(colored("xyz", "magenta")+colored("12345", "blue")))
a2 = uop_to_json(a)[id(a)]
a2 = uop_to_json(VizData(), a)[id(a)]
self.assertEqual(ansistrip(a2["label"]), f"CUSTOM\n{TestStruct.__qualname__}(colored_field='xyz12345')")
def test_colored_label_multiline(self):
@@ -217,11 +217,11 @@ class TestViz(unittest.TestCase):
# use smaller stack limit for faster test (default is 250000)
with Context(REWRITE_STACK_LIMIT=100): self.assertRaises(RuntimeError, exec_rewrite, a, [pm])
graphs = flatten(x["graph"].values() for x in viz.get_details(0, 0))
self.assertEqual(graphs[0], uop_to_json(a)[id(a)])
self.assertEqual(graphs[1], uop_to_json(b)[id(b)])
self.assertEqual(graphs[0], uop_to_json(VizData(), a)[id(a)])
self.assertEqual(graphs[1], uop_to_json(VizData(), b)[id(b)])
# fallback to NOOP with the error message
nop = UOp(Ops.NOOP, arg="infinite loop in fixed_point_rewrite")
self.assertEqual(graphs[2], uop_to_json(nop)[id(nop)])
self.assertEqual(graphs[2], uop_to_json(VizData(), nop)[id(nop)])
def test_const_node_visibility(self):
with save_viz() as viz:
@@ -241,7 +241,7 @@ class TestViz(unittest.TestCase):
c = UOp.const(dtypes.float, 1.0, device="CPU", shape=(3,4)) # creates CONST->RESHAPE->EXPAND chain
a = UOp(Ops.DEFINE_VAR, dtypes.float, arg=("a", 0.0, 10.0))
alu = a + c
graph = uop_to_json(alu)
graph = uop_to_json(VizData(), alu)
# the RESHAPE and EXPAND nodes from the const should not appear in the graph
labels = {v["label"].split("\n")[0] for v in graph.values()}
self.assertNotIn("RESHAPE", labels)
@@ -335,7 +335,7 @@ class TestVizIntegration(unittest.TestCase):
prg = get_program(ast, Device[Device.DEFAULT].renderer)
lst = viz.list_items()
self.assertEqual(len(lst), 3)
self.assertEqual(lst[0]["name"], "Process 1 Buffer n1")
self.assertEqual(lst[0]["name"], "Callify 1 Buffer n1")
self.assertEqual(lst[1]["name"], "Schedule 1 Kernel n1")
self.assertEqual(lst[2]["name"], prg.name)
@@ -417,7 +417,7 @@ from tinygrad.device import ProfileDeviceEvent, ProfileGraphEvent, ProfileGraphE
from tinygrad.viz.serve import get_profile
from extra.viz.cli import decode_profile
def load_profile(lst:list[ProfileEvent]) -> dict: return decode_profile(get_profile(lst))
def load_profile(lst:list[ProfileEvent]) -> dict: return decode_profile(get_profile(VizData(), lst))
class TestVizProfiler(unittest.TestCase):
def test_transfer_uses_copy_device(self):
@@ -563,7 +563,7 @@ class TestVizProfiler(unittest.TestCase):
step = 10
n_events = 1_000
prof = [ProfileRangeEvent("CPU", name="k_test", st=decimal.Decimal(ts:=i*step), en=decimal.Decimal(ts)+step) for i in range(n_events)]
sz = len(get_profile(prof))
sz = len(get_profile(VizData(), prof))
self.assertLessEqual(sz/n_events, 26)
def test_calltrace(self):
@@ -586,7 +586,7 @@ class TestVizProfiler(unittest.TestCase):
step = decimal.Decimal(dur_mins*60*1e6//n_events)
prof = [ProfileRangeEvent("CPU", name="k_test", st=decimal.Decimal(ts:=i*step), en=decimal.Decimal(ts)+step) for i in range(n_events)]
with self.assertRaisesRegex(ValueError, "timestamp out of range"):
get_profile(prof)
get_profile(VizData(), prof)
def test_python_marker(self):
with save_viz():
+1 -1
View File
@@ -3,7 +3,7 @@ import unittest, math, time
from tinygrad import Tensor, Device, dtypes, Context
from tinygrad.uop.ops import UOp, Ops
from tinygrad.engine.realize import get_runner
from tinygrad.engine.schedule import ExecItem
from tinygrad.schedule import ExecItem
from tinygrad.engine.jit import TinyJit
import numpy as np
+24 -1
View File
@@ -1,5 +1,5 @@
import unittest
from tinygrad import Tensor
from tinygrad import Tensor, dtypes
from tinygrad.helpers import Context
from tinygrad.uop.ops import Ops
@@ -25,5 +25,28 @@ class TestRingAllReduce(unittest.TestCase):
out = t.sum(0)
self.assertListEqual(out.tolist(), [4]*N*100)
class TestAllreduceCast(unittest.TestCase):
def _get_copy_dtypes(self, dtype, allreduce_cast):
ds = tuple(f"CPU:{i}" for i in range(2))
with Context(ALLREDUCE_CAST=allreduce_cast, RING=0, SCACHE=0):
t = Tensor.empty(4, 4, dtype=dtype).shard(ds, axis=0)
schedules = t.sum(0).schedule_with_vars()[0]
return {si.bufs[0].dtype.scalar() for si in schedules if si.ast.op is Ops.COPY}
def test_allreduce_cast_bf16(self):
# with ALLREDUCE_CAST, allreduce copies stay in bfloat16 instead of promoting to float32
self.assertNotIn(dtypes.float, self._get_copy_dtypes(dtypes.bfloat16, allreduce_cast=1))
self.assertIn(dtypes.float, self._get_copy_dtypes(dtypes.bfloat16, allreduce_cast=0))
def test_allreduce_cast_half(self):
self.assertNotIn(dtypes.float, self._get_copy_dtypes(dtypes.half, allreduce_cast=1))
self.assertIn(dtypes.float, self._get_copy_dtypes(dtypes.half, allreduce_cast=0))
def test_allreduce_cast_float32_noop(self):
# float32 should not be affected by ALLREDUCE_CAST (no promotion happens)
dtypes_on = self._get_copy_dtypes(dtypes.float, allreduce_cast=1)
dtypes_off = self._get_copy_dtypes(dtypes.float, allreduce_cast=0)
self.assertEqual(dtypes_on, dtypes_off)
if __name__ == '__main__':
unittest.main()
+33
View File
@@ -947,5 +947,38 @@ class TestPartialAssignToSharedBuffer(unittest.TestCase):
for v, s in zip(views, shapes):
np.testing.assert_allclose(v.numpy(), np.ones(s))
class TestAfterCachePatterns(unittest.TestCase):
def test_double_store_after(self):
a = Tensor.zeros(10).contiguous()
b = Tensor.zeros(10).contiguous()
c = Tensor.ones(10).contiguous()
Tensor.realize(a, b, c)
a_store = a.uop.store(c.uop)
b_store = b.uop.store(c.uop)
with self.assertRaises(AssertionError):
a = Tensor(a.uop.after(a_store, b_store))
a.realize()
np.testing.assert_array_equal(a.numpy(), 1)
np.testing.assert_array_equal(b.numpy(), 1)
def test_double_store_after_different_sizes(self):
full = Tensor.zeros(2).contiguous()
head = Tensor.zeros(1).contiguous()
full_src = Tensor([1, 2], dtype=dtypes.float).contiguous()
head_src = Tensor([3], dtype=dtypes.float).contiguous()
Tensor.realize(full, head, full_src, head_src)
full_store = full.uop.store(full_src.uop)
head_store = head.uop.store(head_src.uop)
with self.assertRaises(AssertionError):
head = Tensor(head.uop.after(head_store, full_store))
head.realize()
np.testing.assert_array_equal(head.numpy(), [3])
np.testing.assert_array_equal(full.numpy(), [1, 2])
if __name__ == "__main__":
unittest.main()
+137 -1
View File
@@ -1,7 +1,10 @@
import unittest
import numpy as np
from tinygrad import Tensor, dtypes
from tinygrad.apps.llm import TransformerBlock, TransformerConfig, apply_rope as apply_rope_new, precompute_freqs_cis, pairwise_topk
from tinygrad.apps.llm import (
GatedDeltaNetBlock, SSMConfig, TransformerBlock, TransformerConfig,
apply_rope as apply_rope_new, precompute_freqs_cis, pairwise_topk,
)
def apply_rope(x:Tensor, start_pos:int):
B, H, T, Hd = x.shape
@@ -37,6 +40,139 @@ class TestAttention(unittest.TestCase):
expected = apply_rope_new(k[..., :rope_dim], block.freqs_cis[:seqlen]).cat(k[..., rope_dim:], dim=-1)
np.testing.assert_allclose(block.cache_kv[0, :, :, :seqlen, :].numpy(), expected.numpy(), rtol=1e-5, atol=1e-5)
class TestGatedDeltaNetBlock(unittest.TestCase):
def _tensor_linspace(self, start:float, stop:float, shape:tuple[int, ...]) -> Tensor:
return Tensor.linspace(start, stop, int(np.prod(shape)), dtype=dtypes.float32).reshape(*shape)
def _make_config(self, **kwargs):
return TransformerConfig(**({"num_blocks":1, "dim":4, "hidden_dim":8, "n_heads":1, "n_kv_heads":1,
"norm_eps":1e-5, "vocab_size":32, "head_dim":4, "rope_theta":10000.0,
"rope_dim":4, "v_head_dim":4, "max_context":4, "full_attention_interval":2,
"ssm":SSMConfig(conv_kernel=2, state_size=2, group_count=1, time_step_rank=1, inner_size=2)} | kwargs))
def _make_block(self, config:TransformerConfig) -> GatedDeltaNetBlock:
block = GatedDeltaNetBlock(config, config.ssm)
block.attn_norm.weight = self._tensor_linspace(0.8, 1.2, (config.dim,))
block.attn_qkv.weight = self._tensor_linspace(-0.15, 0.2, (block.conv_channels, config.dim))
block.attn_gate.weight = self._tensor_linspace(-0.1, 0.15, (config.ssm.inner_size, config.dim))
block.ssm_alpha.weight = self._tensor_linspace(-0.08, 0.12, (block.num_v_heads, config.dim))
block.ssm_beta.weight = self._tensor_linspace(-0.12, 0.07, (block.num_v_heads, config.dim))
block.ssm_conv1d["weight"] = self._tensor_linspace(-0.05, 0.05, (block.conv_channels, block.ssm_conv_kernel))
block.ssm_dt["bias"] = self._tensor_linspace(-0.1, 0.1, (block.num_v_heads,))
block.ssm_a = self._tensor_linspace(-0.1, -0.05, (block.num_v_heads,))
block.ssm_norm.weight = self._tensor_linspace(0.9, 1.1, (block.head_v_dim,))
block.ssm_out.weight = self._tensor_linspace(-0.2, 0.18, (config.dim, config.ssm.inner_size))
return block
def _run_attention(self, block:GatedDeltaNetBlock, x:Tensor, start_pos:int):
x_norm = block.attn_norm(x)
block._init_state(x_norm)
return block._attention(x_norm, start_pos).realize().numpy()
def _cache_views(self, block:GatedDeltaNetBlock) -> tuple[np.ndarray, np.ndarray]:
conv_flat = (block.ssm_conv_kernel - 1) * block.conv_channels
cache = block.delta_cache.numpy()
conv_state = cache[:, :conv_flat].reshape(cache.shape[0], block.ssm_conv_kernel - 1, block.conv_channels)
recurrent_state = cache[:, conv_flat:].reshape(cache.shape[0], block.num_v_heads, block.head_v_dim, block.head_v_dim)
return conv_state, recurrent_state
def _linear_np(self, x:np.ndarray, weight:np.ndarray) -> np.ndarray:
return x.astype(np.float32) @ weight.T.astype(np.float32)
def _rms_norm_np(self, x:np.ndarray, weight:np.ndarray, eps:float) -> np.ndarray:
x_float = x.astype(np.float32)
return (x_float / np.sqrt((x_float * x_float).mean(axis=-1, keepdims=True) + eps)) * weight.astype(np.float32)
def _normalize_np(self, x:np.ndarray, eps:float=1e-12) -> np.ndarray:
return x / np.maximum(np.sqrt((x * x).sum(axis=-1, keepdims=True)), eps)
def _softplus_np(self, x:np.ndarray) -> np.ndarray:
return np.log1p(np.exp(-np.abs(x))) + np.maximum(x, 0)
def _silu_np(self, x:np.ndarray) -> np.ndarray:
return x / (1.0 + np.exp(-x))
def _naive_attention(self, block:GatedDeltaNetBlock, x:Tensor):
x_np = x.numpy().astype(np.float32)
B, T, _ = x_np.shape
conv_state = np.zeros((B, block.ssm_conv_kernel - 1, block.conv_channels), dtype=np.float32)
recurrent_state = np.zeros((B, block.num_v_heads, block.head_v_dim, block.head_v_dim), dtype=np.float32)
conv_weight = block.ssm_conv1d["weight"].numpy().astype(np.float32).T[None, :, :]
qkv_weight = block.attn_qkv.weight.numpy().astype(np.float32)
gate_weight = block.attn_gate.weight.numpy().astype(np.float32)
alpha_weight = block.ssm_alpha.weight.numpy().astype(np.float32)
beta_weight = block.ssm_beta.weight.numpy().astype(np.float32)
out_weight = block.ssm_out.weight.numpy().astype(np.float32)
dt_bias = block.ssm_dt["bias"].numpy().astype(np.float32)
ssm_a = block.ssm_a.numpy().astype(np.float32)
attn_norm_weight = block.attn_norm.weight.numpy().astype(np.float32)
ssm_norm_weight = block.ssm_norm.weight.numpy().astype(np.float32)
outputs, conv_states, recurrent_states = [], [], []
for t in range(T):
x_norm = self._rms_norm_np(x_np[:, t:t+1, :], attn_norm_weight, block.attn_norm.eps)
x_half = x_norm.astype(np.float16)
out_gate = self._linear_np(x_half, gate_weight).reshape(B, 1, block.num_v_heads, block.head_v_dim)
beta = 1.0 / (1.0 + np.exp(-self._linear_np(x_half, beta_weight))).reshape(B, block.num_v_heads, 1, 1)
alpha = np.exp((self._softplus_np(self._linear_np(x_half, alpha_weight) + dt_bias)).reshape(B, block.num_v_heads, 1, 1) *
ssm_a.reshape(1, block.num_v_heads, 1, 1))
conv_window = np.concatenate([conv_state, self._linear_np(x_half, qkv_weight)], axis=1)
conv_out = self._silu_np((conv_window * conv_weight).sum(axis=1))
q, k, v = np.split(conv_out, [block.q_dim, 2 * block.q_dim], axis=-1)
q = self._normalize_np(q.reshape(B, block.num_k_heads, block.head_k_dim))
k = self._normalize_np(k.reshape(B, block.num_k_heads, block.head_k_dim))
v = v.reshape(B, block.num_v_heads, block.head_v_dim)
if block.num_v_heads != block.num_k_heads:
k_repeat = block.num_v_heads // block.num_k_heads
q = np.repeat(q[:, None, :, :], k_repeat, axis=1).reshape(B, block.num_v_heads, block.head_k_dim)
k = np.repeat(k[:, None, :, :], k_repeat, axis=1).reshape(B, block.num_v_heads, block.head_k_dim)
q, k, v = (q * (block.head_k_dim ** -0.5))[..., None], k[..., None], v[..., None]
recurrent_state = recurrent_state * alpha
recurrent_state = recurrent_state + np.matmul((v - np.matmul(recurrent_state, k)) * beta, np.swapaxes(k, -1, -2))
core_attn_out = np.matmul(recurrent_state, q).squeeze(-1).reshape(B, 1, block.num_v_heads, block.head_v_dim)
core_attn_out = self._rms_norm_np(core_attn_out, ssm_norm_weight, block.ssm_norm.eps)
out = self._linear_np((core_attn_out * self._silu_np(out_gate)).reshape(B, 1, -1).astype(np.float16), out_weight)
conv_state = conv_window[:, 1:, :]
outputs.append(out)
conv_states.append(conv_state.copy())
recurrent_states.append(recurrent_state.copy())
return outputs, conv_states, recurrent_states
def test_gatedeltanet_reference_and_reset(self):
config = self._make_config(max_context=3)
block = self._make_block(config)
x = Tensor.linspace(-1.0, 1.0, 3 * config.dim, dtype=dtypes.float32).reshape(1, 3, config.dim)
expected_outs, expected_conv, expected_recurrent = self._naive_attention(block, x)
for step in range(x.shape[1]):
out = self._run_attention(block, x[:, step:step+1], step)
conv_state, recurrent_state = self._cache_views(block)
np.testing.assert_allclose(out, expected_outs[step], rtol=1e-3, atol=1e-3,
err_msg=f"GatedDeltaNet output mismatch at step {step}")
np.testing.assert_allclose(conv_state, expected_conv[step], rtol=1e-3, atol=1e-3,
err_msg=f"GatedDeltaNet conv cache mismatch at step {step}")
np.testing.assert_allclose(recurrent_state, expected_recurrent[step], rtol=1e-3, atol=1e-3,
err_msg=f"GatedDeltaNet recurrent cache mismatch at step {step}")
warmup = Tensor.linspace(-0.5, 0.5, 2 * config.dim, dtype=dtypes.float32).reshape(1, 2, config.dim)
prompt = Tensor.linspace(0.75, -0.75, 2 * config.dim, dtype=dtypes.float32).reshape(1, 2, config.dim)
for i in range(warmup.shape[1]): self._run_attention(block, warmup[:, i:i+1], i)
Tensor.realize(*block._state_reset_ops())
expected_outs, expected_conv, expected_recurrent = self._naive_attention(block, prompt)
for step in range(prompt.shape[1]):
out = self._run_attention(block, prompt[:, step:step+1], step)
conv_state, recurrent_state = self._cache_views(block)
np.testing.assert_allclose(out, expected_outs[step], rtol=1e-3, atol=1e-3,
err_msg=f"GatedDeltaNet reset output mismatch at step {step}")
np.testing.assert_allclose(conv_state, expected_conv[step], rtol=1e-3, atol=1e-3,
err_msg=f"GatedDeltaNet reset conv cache mismatch at step {step}")
np.testing.assert_allclose(recurrent_state, expected_recurrent[step], rtol=1e-3, atol=1e-3,
err_msg=f"GatedDeltaNet reset recurrent cache mismatch at step {step}")
class TestPairwiseTopk(unittest.TestCase):
def test_basic_topk(self):
x = Tensor([[[1.0, 3.0, 2.0, 5.0, 4.0]]])
+3 -3
View File
@@ -418,8 +418,8 @@ class TestFunctionTuple(unittest.TestCase):
def test_custom_kernel_save_unused_output(self):
def my_kernel(C:UOp, D:UOp, A:UOp) -> UOp:
i = UOp.range(A.size, 0)
j = UOp.range(D.size, 1)
i = UOp.range(A.shape[0], 0)
j = UOp.range(D.shape[0], 1)
store_c = C[i].store(A[i] * 2.0).end(i)
store_d = D[j].store(A[j]).end(j)
return UOp.group(store_c, store_d).sink(arg=KernelInfo(name="my_kernel"))
@@ -444,7 +444,7 @@ class TestFunctionTuple(unittest.TestCase):
def test_custom_kernel_both_outputs_used(self):
def my_kernel(C:UOp, D:UOp, A:UOp) -> UOp:
i = UOp.range(A.size, 0)
i = UOp.range(A.shape[0], 0)
store_c = C[i].store(A[i] * 2.0)
store_d = D[i].store(A[i] * 3.0)
return UOp.group(store_c, store_d).end(i).sink(arg=KernelInfo(name="my_kernel"))
+1 -1
View File
@@ -1,7 +1,7 @@
import unittest
from unittest.mock import patch
from tinygrad import Tensor, UOp
from tinygrad.engine.schedule import schedule_cache
from tinygrad.schedule import schedule_cache
from tinygrad.apps.llm import Transformer, TransformerConfig
TEST_CONFIG = TransformerConfig(num_blocks=1, dim=64, hidden_dim=128, n_heads=2, n_kv_heads=2,
+1 -1
View File
@@ -2,7 +2,7 @@ import unittest
import functools
from tinygrad import Tensor, Variable, UOp
from tinygrad.uop.ops import KernelInfo
from tinygrad.engine.schedule import schedule_cache
from tinygrad.schedule import schedule_cache
def custom_set0_kernel(A:UOp, num:int) -> UOp:
return A[0].set(num).sink(arg=KernelInfo(f"custom_set0_{num}"))
+71 -253
View File
@@ -9,7 +9,7 @@ from tinygrad.viz.serve import TCPServerWithReuse, HTTPRequestHandler
class SimpleTokenizer:
def __init__(self, normal_tokens:dict[str, int], special_tokens:dict[str, int], preset:str="llama3"):
preset = {"qwen35":"qwen2","qwen35moe":"qwen2"}.get(preset, preset)
if preset not in ("llama3","llama-v3","llama-bpe","qwen2","olmo","kimi-k2","gemma4"): raise ValueError(f"Invalid tokenizer preset '{preset}'")
if preset not in ("llama3","llama-v3","llama-bpe","qwen2","olmo","kimi-k2","tekken"): raise ValueError(f"Invalid tokenizer preset '{preset}'")
# https://github.com/openai/gpt-2/blob/9b63575ef42771a015060c964af2c3da4cf7c8ab/src/encoder.py#L9
bs = [*range(33, 127), *range(161, 173), *range(174, 256)] # bytes that map to themselves
self._byte_decoder = {chr(b): b for b in bs} | {chr(256+i): b for i,b in enumerate(b for b in range(256) if b not in bs)}
@@ -22,11 +22,9 @@ class SimpleTokenizer:
f"[^\\r\\n{r_p_N}{r_p_L}]?[{r_p_L}]+|[{r_p_N}]{{1,3}}| ?[^{r_ws}{r_p_N}{r_p_L}]+[\\r\\n]*|[{r_ws}]*[\\r\\n]+|[{r_ws}]+(?![^{r_ws}])|[{r_ws}]+")
self._split_to_sentence = re.compile("|".join(re.escape(tok) for tok in special_tokens.keys()) if special_tokens else r"(?!)")
tok_bytes = (lambda tok: tok.replace("", " ").encode()) if preset == "gemma4" else (lambda tok: bytes(self._byte_decoder[c] for c in tok))
self._normal_tokens = {tok_bytes(tok): tid for tok, tid in normal_tokens.items()}
self._normal_tokens = {bytes(self._byte_decoder[c] for c in tok): tid for tok, tid in normal_tokens.items()}
self._special_tokens = special_tokens
self._tok2bytes = {tid: tok for tok, tid in self._normal_tokens.items()} | {
tid: (b'' if preset == "gemma4" else tok.encode()) for tok, tid in self._special_tokens.items()}
self._tok2bytes = {tid: tok for tok, tid in self._normal_tokens.items()} | {tid: tok.encode() for tok, tid in self._special_tokens.items()}
self.preset = preset
@staticmethod
@@ -34,9 +32,7 @@ class SimpleTokenizer:
# https://github.com/ggml-org/llama.cpp/blob/94933c8c2eeaa9a7983e3f6c08af76bd86724094/src/llama-vocab.cpp#L1818-L1820
vocab: typing.Iterable[tuple[str, int]] = ((tok, idx) for idx, tok in enumerate(kv["tokenizer.ggml.tokens"]))
normal_tokens, special_tokens = partition(vocab, lambda e: kv["tokenizer.ggml.token_type"][e[1]] == 1)
return SimpleTokenizer(
dict(normal_tokens), dict(special_tokens),
kv.get("tokenizer.ggml.pre") or kv.get("tokenizer.ggml.model", "llama3"))
return SimpleTokenizer(dict(normal_tokens), dict(special_tokens), kv["tokenizer.ggml.pre"])
def _encode_word(self, word:bytes) -> list[int]:
if (early_token:=self._normal_tokens.get(word)) is not None: return [early_token]
@@ -67,13 +63,16 @@ class SimpleTokenizer:
if self.preset == 'olmo': return self.encode("<|" + role + "|>\n") # OLMoE Instruct format
if self.preset == 'kimi-k2': return self.encode("<|im_" + role + "|>" + role + "<|im_middle|>")
if self.preset == 'qwen2': return self.encode("<|im_start|>" + role + "\n")
if self.preset == 'gemma4': return self.encode("<|turn>" + ("model" if role == "assistant" else role) + "\n")
if self.preset == 'tekken':
if role == 'user': return self.encode("[INST]")
if role == 'assistant': return []
raise ValueError(f"Unsupported role '{role}' for tokenizer preset '{self.preset}'")
return self.encode("<|start_header_id|>" + role + "<|end_header_id|>\n\n")
def end_turn(self, eos_id:int):
if self.preset == 'olmo': return self.encode("\n")
if self.preset == 'kimi-k2': return [eos_id]
if self.preset == 'qwen2': return [eos_id] + self.encode("\n")
if self.preset == 'gemma4': return self.encode("<turn|>\n")
if self.preset == 'tekken': return self.encode("[/INST]")
return [eos_id]
@functools.cache
@@ -96,27 +95,6 @@ def apply_rope(x:Tensor, freqs_cis:Tensor) -> Tensor:
x1, x2 = x.chunk(2, dim=-1)
return (x1 * cos - x2 * sin).cat(x2 * cos + x1 * sin, dim=-1)
class ScaledLinear:
def __init__(self, in_features:int, out_features:int):
self.weight = Tensor.zeros(out_features, in_features)
self.scale = Tensor.ones(in_features)
def __call__(self, x:Tensor) -> Tensor: return (x * self.scale) @ self.weight.transpose(-1, -2)
class ScaledExpertWeights(ExpertWeights):
def __init__(self, num_experts:int, in_features:int, out_features:int):
super().__init__(num_experts, in_features, out_features)
self.scale = Tensor.ones(num_experts)
class ScalarWeight:
def __init__(self): self.weight = Tensor.ones(1)
def rms_norm_no_weight(x:Tensor, eps:float) -> Tensor:
return x * (x.square().mean(axis=-1, keepdim=True) + eps).rsqrt()
def repeat_kv(x:Tensor, n_rep:int) -> Tensor:
return x if n_rep == 1 else x.unsqueeze(2).expand(
x.shape[0], x.shape[1], n_rep, x.shape[2], x.shape[3]).reshape(x.shape[0], x.shape[1] * n_rep, x.shape[2], x.shape[3])
def pairwise_topk(x: Tensor, k: int) -> tuple[Tensor, Tensor]:
n = x.shape[-1]
vals = Tensor.arange(n).reshape(1,1,n).cast(x.dtype).expand(x.shape)
@@ -137,17 +115,17 @@ class SSMConfig:
class TransformerConfig:
num_blocks: int
dim: int
hidden_dim: int|tuple[int, ...]
hidden_dim: int
n_heads: int
n_kv_heads: int|tuple[int, ...]
n_kv_heads: int
norm_eps: float
vocab_size: int
head_dim: int|tuple[int, ...]
rope_theta: float|tuple[float, ...]
head_dim: int
rope_theta: float
rope_dim: int
v_head_dim: int
max_context: int = 0
qk_norm: int|tuple[int, ...] = 0
qk_norm: int = 0
num_experts: int = 0
num_experts_per_tok: int = 0
norm_topk_prob: bool = False
@@ -160,66 +138,36 @@ class TransformerConfig:
leading_dense_blocks: int = 0
dense_hidden_dim: int = 0
routed_scaling_factor: float = 1.0
sliding_window: int = 0
sliding_window_pattern: tuple[bool, ...] = ()
per_layer_input_dim: int = 0
final_logit_softcap: float = 0.0
num_kv_shared_layers: int = 0
gemma4: bool = False
expert_hidden_dim: int = 0
class FFNBlock:
def __init__(self, config:TransformerConfig):
self.config = config
self.hidden_dim = config.hidden_dim
gemma_moe = config.gemma4 and config.num_experts > 0
# --- RMSNorms --------------------------------------------------------
self.attn_norm = nn.RMSNorm(config.dim, config.norm_eps)
self.ffn_norm = nn.RMSNorm(config.dim, config.norm_eps)
# --- feed-forward (MoE or dense) -------------------------------------
self.ffn_gate_inp: nn.Linear|ScaledLinear
self.ffn_down_exps: ExpertWeights|ScaledExpertWeights
if gemma_moe or config.num_experts == 0:
self.ffn_gate = nn.Linear(config.dim, self.hidden_dim, bias=False)
self.ffn_up = nn.Linear(config.dim, self.hidden_dim, bias=False)
self.ffn_down = nn.Linear(self.hidden_dim, config.dim, bias=False)
if gemma_moe:
self.ffn_gate_inp = ScaledLinear(config.dim, config.num_experts)
self.ffn_gate_up_exps = ExpertWeights(config.num_experts, config.dim, config.expert_hidden_dim * 2)
self.ffn_down_exps = ScaledExpertWeights(config.num_experts, config.expert_hidden_dim, config.dim)
self.post_ffw_norm_1 = nn.RMSNorm(config.dim, config.norm_eps)
self.pre_ffw_norm_2 = nn.RMSNorm(config.dim, config.norm_eps)
self.post_ffw_norm_2 = nn.RMSNorm(config.dim, config.norm_eps)
elif config.num_experts > 0:
if config.num_experts > 0:
self.ffn_gate_inp = nn.Linear(config.dim, config.num_experts, bias=False) # router
if config.kv_lora_rank > 0: self.exp_probs_b = {"bias": Tensor.zeros(config.num_experts)}
self.ffn_gate_exps = ExpertWeights(config.num_experts, config.dim, self.hidden_dim)
self.ffn_up_exps = ExpertWeights(config.num_experts, config.dim, self.hidden_dim)
self.ffn_down_exps = ExpertWeights(config.num_experts, self.hidden_dim, config.dim)
self.ffn_gate_exps = ExpertWeights(config.num_experts, config.dim, config.hidden_dim)
self.ffn_up_exps = ExpertWeights(config.num_experts, config.dim, config.hidden_dim)
self.ffn_down_exps = ExpertWeights(config.num_experts, config.hidden_dim, config.dim)
if config.shared_expert_dim > 0:
self.ffn_gate_shexp = nn.Linear(config.dim, config.shared_expert_dim, bias=False)
self.ffn_up_shexp = nn.Linear(config.dim, config.shared_expert_dim, bias=False)
self.ffn_down_shexp = nn.Linear(config.shared_expert_dim, config.dim, bias=False)
if config.shared_expert_gate: self.ffn_gate_inp_shexp = {"weight": Tensor.zeros(config.dim)}
else:
self.ffn_gate = nn.Linear(config.dim, config.hidden_dim, bias=False)
self.ffn_up = nn.Linear(config.dim, config.hidden_dim, bias=False)
self.ffn_down = nn.Linear(config.hidden_dim, config.dim, bias=False)
def _feed_forward(self, x:Tensor) -> Tensor:
h_norm = self.ffn_norm(x) if self.config.gemma4 else x
if self.config.gemma4 and self.config.num_experts > 0:
ffn_gate_inp = typing.cast(ScaledLinear, self.ffn_gate_inp)
ffn_down_exps = typing.cast(ScaledExpertWeights, self.ffn_down_exps)
dense = self.post_ffw_norm_1(self.ffn_down((self.ffn_gate(h_norm).gelu().contiguous()) * self.ffn_up(h_norm)))
router_probs = (
rms_norm_no_weight(x, self.config.norm_eps) * (self.config.dim ** -0.5) * ffn_gate_inp.scale
) @ ffn_gate_inp.weight.transpose(-1, -2)
vals, sel = pairwise_topk(router_probs.softmax(-1), self.config.num_experts_per_tok)
probs = vals / vals.sum(axis=-1, keepdim=True) * ffn_down_exps.scale[sel]
gate, up = self.ffn_gate_up_exps(sel, self.pre_ffw_norm_2(x).unsqueeze(2)).chunk(2, dim=-1)
return dense + self.post_ffw_norm_2((ffn_down_exps(sel, gate.gelu().contiguous() * up) * probs.unsqueeze(-1)).sum(axis=2))
if hasattr(self, 'ffn_gate_exps'):
h = h_norm.unsqueeze(2) # (B, T, 1, D) - add expert dim for broadcasting
logits = self.ffn_gate_inp(h_norm)
h = x.unsqueeze(2) # (B, T, 1, D) - add expert dim for broadcasting
logits = self.ffn_gate_inp(x)
if hasattr(self, 'exp_probs_b'):
probs = logits.sigmoid()
_, sel = pairwise_topk(probs + self.exp_probs_b["bias"], self.config.num_experts_per_tok)
@@ -232,13 +180,12 @@ class FFNBlock:
x_down = self.ffn_down_exps(sel, self.ffn_gate_exps(sel, h).silu() * self.ffn_up_exps(sel, h)) # (B, T, k, D)
out = (x_down * probs.unsqueeze(-1)).sum(axis=2) # (B, T, D)
if hasattr(self, 'ffn_gate_shexp'):
shexp = self.ffn_down_shexp(self.ffn_gate_shexp(h_norm).silu().contiguous() * self.ffn_up_shexp(h_norm))
if hasattr(self, 'ffn_gate_inp_shexp'): shexp = shexp * (h_norm * self.ffn_gate_inp_shexp["weight"]).sum(axis=-1, keepdim=True).sigmoid()
shexp = self.ffn_down_shexp(self.ffn_gate_shexp(x).silu().contiguous() * self.ffn_up_shexp(x))
if hasattr(self, 'ffn_gate_inp_shexp'): shexp = shexp * (x * self.ffn_gate_inp_shexp["weight"]).sum(axis=-1, keepdim=True).sigmoid()
out = out + shexp
return out
# TODO: remove the need for this contiguous
act = self.ffn_gate(h_norm).gelu() if self.config.gemma4 else self.ffn_gate(h_norm).silu()
return self.ffn_down(act.contiguous() * self.ffn_up(h_norm))
return self.ffn_down(self.ffn_gate(x).silu().contiguous() * self.ffn_up(x))
# given the token-prefix match, return how much cached state this block can still reuse
def _reusable_prefix_len(self, prefix_len:int, cached_len:int) -> int: return prefix_len
@@ -259,78 +206,29 @@ class FFNBlock:
class TransformerBlock(FFNBlock):
def __init__(self, config:TransformerConfig):
super().__init__(config)
self.head_dim = config.head_dim
self.rope_theta = config.rope_theta
self.qk_norm = config.qk_norm
self.n_kv_heads = config.n_kv_heads
self.is_sliding = config.sliding_window > 0 and bool(config.sliding_window_pattern) and config.sliding_window_pattern[0]
self.use_alternative_attention = config.gemma4 and config.num_experts > 0 and not self.is_sliding
self.store_full_length_kv = False
self.shared_kv_src_idx: int|None = None
self.full_kv_cache: Tensor|None = None
if not config.gemma4: assert config.v_head_dim == self.head_dim, "TransformerBlock requires v_head_dim == head_dim"
assert config.v_head_dim == config.head_dim, "TransformerBlock requires v_head_dim == head_dim"
# --- attention projections (all linear, bias-free) ------------------
q_proj_out = self.head_dim * config.n_heads * (2 if config.attn_output_gate else 1)
kv_proj_out = self.head_dim * self.n_kv_heads
q_proj_out = config.head_dim * config.n_heads * (2 if config.attn_output_gate else 1)
kv_proj_out = config.head_dim * config.n_kv_heads
self.attn_q = nn.Linear(config.dim, q_proj_out, bias=False)
self.attn_k = nn.Linear(config.dim, kv_proj_out, bias=False)
if not self.use_alternative_attention: self.attn_v = nn.Linear(config.dim, kv_proj_out, bias=False)
self.attn_output = nn.Linear(self.head_dim * config.n_heads, config.dim, bias=False)
if self.qk_norm: self.attn_q_norm, self.attn_k_norm = nn.RMSNorm(self.qk_norm, config.norm_eps), nn.RMSNorm(self.qk_norm, config.norm_eps)
if config.gemma4:
self.post_attention_norm = nn.RMSNorm(config.dim, config.norm_eps)
self.post_ffw_norm = nn.RMSNorm(config.dim, config.norm_eps)
self.layer_output_scale = ScalarWeight()
if config.per_layer_input_dim:
self.inp_gate = nn.Linear(config.dim, config.per_layer_input_dim, bias=False)
self.proj = nn.Linear(config.per_layer_input_dim, config.dim, bias=False)
self.post_norm = nn.RMSNorm(config.dim, config.norm_eps)
def _attention(self, x:Tensor, start_pos:int|UOp, shared_kv_cache:Tensor|None=None) -> Tensor:
if self.config.gemma4:
x_norm = self.attn_norm(x)
q, k = self.attn_q(x_norm), self.attn_k(x_norm)
if self.qk_norm and self.qk_norm != self.head_dim: q, k = self.attn_q_norm(q), self.attn_k_norm(k)
B, T, _ = x.shape
q = q.reshape(B, T, self.config.n_heads, self.head_dim).transpose(1, 2)
if self.qk_norm == self.head_dim: q = self.attn_q_norm(q)
q = apply_rope(q, self.freqs_cis[start_pos:start_pos+T])
if shared_kv_cache is not None:
k = shared_kv_cache[0, :, :, 0:start_pos+T, :]
v = shared_kv_cache[1, :, :, 0:start_pos+T, :]
else:
raw_k = k.reshape(B, T, self.n_kv_heads, self.head_dim)
k = raw_k.transpose(1, 2)
if self.qk_norm == self.head_dim: k = self.attn_k_norm(k)
raw_v = raw_k if self.use_alternative_attention else self.attn_v(x_norm).reshape(B, T, self.n_kv_heads, self.head_dim)
v = rms_norm_no_weight(raw_v, self.config.norm_eps).transpose(1, 2)
k = apply_rope(k, self.freqs_cis[start_pos:start_pos+T])
assigned_kv = Tensor(self.cache_kv.uop.after(self.cache_kv[:, :, :, start_pos:start_pos+T, :].uop.store(Tensor.stack(k, v).uop)))
if self.store_full_length_kv: self.full_kv_cache = assigned_kv
k = assigned_kv[0, :, :, 0:start_pos+T, :]
v = assigned_kv[1, :, :, 0:start_pos+T, :]
mask = None
if resolve(T != 1) or self.is_sliding:
mask = Tensor.full((1, 1, T, start_pos+T), float("-inf"), dtype=x.dtype, device=x.device).triu(start_pos+1)
if self.is_sliding:
mask = mask + Tensor.full((1, 1, T, start_pos+T), float("-inf"), dtype=x.dtype, device=x.device).tril(start_pos-self.config.sliding_window)
k, v = repeat_kv(k, self.config.n_heads // self.n_kv_heads), repeat_kv(v, self.config.n_heads // self.n_kv_heads)
return self.attn_output((((q @ k.transpose(-1, -2)) + (mask if mask is not None else 0)).softmax(-1) @ v).transpose(1, 2).reshape(B, T, -1))
self.attn_v = nn.Linear(config.dim, kv_proj_out, bias=False)
self.attn_output = nn.Linear(config.head_dim * config.n_heads, config.dim, bias=False)
if config.qk_norm: self.attn_q_norm, self.attn_k_norm = nn.RMSNorm(config.qk_norm, config.norm_eps), nn.RMSNorm(config.qk_norm, config.norm_eps)
def _attention(self, x:Tensor, start_pos:int|UOp) -> Tensor:
q, k, v = self.attn_q(x), self.attn_k(x), self.attn_v(x)
if self.qk_norm and self.qk_norm != self.head_dim: q, k = self.attn_q_norm(q), self.attn_k_norm(k)
if self.config.qk_norm and self.config.qk_norm != self.config.head_dim: q, k = self.attn_q_norm(q), self.attn_k_norm(k)
B, T, _ = x.shape
if self.config.attn_output_gate:
qg = q.reshape(B, T, self.config.n_heads, 2, self.head_dim)
q, gate = qg[:, :, :, 0, :], qg[:, :, :, 1, :].reshape(B, T, self.config.n_heads * self.head_dim)
q = q.reshape(B, T, self.config.n_heads, self.head_dim).transpose(1, 2) # (B,H,T,Hd)
k = k.reshape(B, T, self.n_kv_heads, self.head_dim).transpose(1, 2) # (B,KvH,T,Hd)
v = v.reshape(B, T, self.n_kv_heads, self.head_dim).transpose(1, 2) # (B,KvH,T,Hd)
if self.qk_norm == self.head_dim: q, k = self.attn_q_norm(q), self.attn_k_norm(k)
qg = q.reshape(B, T, self.config.n_heads, 2, self.config.head_dim)
q, gate = qg[:, :, :, 0, :], qg[:, :, :, 1, :].reshape(B, T, self.config.n_heads * self.config.head_dim)
q = q.reshape(B, T, self.config.n_heads, self.config.head_dim).transpose(1, 2) # (B,H,T,Hd)
k = k.reshape(B, T, self.config.n_kv_heads, self.config.head_dim).transpose(1, 2) # (B,KvH,T,Hd)
v = v.reshape(B, T, self.config.n_kv_heads, self.config.head_dim).transpose(1, 2) # (B,KvH,T,Hd)
if self.config.qk_norm == self.config.head_dim: q, k = self.attn_q_norm(q), self.attn_k_norm(k)
q = apply_rope(q[..., :self.config.rope_dim], self.freqs_cis[start_pos:start_pos+T]).cat(q[..., self.config.rope_dim:], dim=-1)
k = apply_rope(k[..., :self.config.rope_dim], self.freqs_cis[start_pos:start_pos+T]).cat(k[..., self.config.rope_dim:], dim=-1)
@@ -354,19 +252,8 @@ class TransformerBlock(FFNBlock):
def _init_state(self, x:Tensor):
if not hasattr(self, "cache_kv"):
# TODO: how is the dtype of this determined?
self.cache_kv = Tensor.empty(2, x.shape[0], self.n_kv_heads, self.config.max_context, self.head_dim, device=x.device)
self.freqs_cis = precompute_freqs_cis(self.head_dim if self.config.gemma4 else self.config.rope_dim, self.config.max_context, self.rope_theta)
def __call__(self, x: Tensor, start_pos: int|UOp, per_layer_input:Tensor|None=None, shared_kv_cache:Tensor|None=None):
if not self.config.gemma4: return super().__call__(x, start_pos)
self._init_state(x)
@function(precompile=True, allow_implicit=True)
def _run(x:Tensor, start_pos:int|UOp, per_layer_input:Tensor|None=None, shared_kv_cache:Tensor|None=None):
h = x + self.post_attention_norm(self._attention(x, start_pos, shared_kv_cache))
h = h + self.post_ffw_norm(self._feed_forward(h))
if per_layer_input is not None: h = h + self.post_norm(self.proj(self.inp_gate(h).gelu() * per_layer_input))
return (h * self.layer_output_scale.weight).contiguous()
return _run(x, start_pos, per_layer_input, shared_kv_cache)
self.cache_kv = Tensor.empty(2, x.shape[0], self.config.n_kv_heads, self.config.max_context, self.config.head_dim, device=x.device)
self.freqs_cis = precompute_freqs_cis(self.config.rope_dim, self.config.max_context, self.config.rope_theta)
class MLATransformerBlock(FFNBlock):
def __init__(self, config:TransformerConfig):
@@ -414,6 +301,7 @@ class GatedDeltaNetBlock(FFNBlock):
def __init__(self, config:TransformerConfig, ssm:SSMConfig):
super().__init__(config)
self.head_k_dim, self.num_k_heads, self.num_v_heads = ssm.state_size, ssm.group_count, ssm.time_step_rank
assert self.num_v_heads % self.num_k_heads == 0
self.head_v_dim, self.ssm_conv_kernel = ssm.inner_size // ssm.time_step_rank, ssm.conv_kernel
self.conv_channels, self.q_dim = ssm.inner_size + 2*ssm.group_count*ssm.state_size, ssm.state_size*ssm.group_count
self.attn_qkv, self.attn_gate = nn.Linear(config.dim, self.conv_channels, bias=False), nn.Linear(config.dim, ssm.inner_size, bias=False)
@@ -426,29 +314,36 @@ class GatedDeltaNetBlock(FFNBlock):
def _attention(self, x:Tensor, start_pos:int|UOp) -> Tensor:
B, T, _ = x.shape
assert T == 1, "GatedDeltaNetBlock currently only supports T=1"
# input processing
x = x.half()
out_gate = self.attn_gate(x).reshape(B, 1, self.num_v_heads, self.head_v_dim)
beta = self.ssm_beta(x).sigmoid().reshape(B, self.num_v_heads, 1, 1)
alpha = ((self.ssm_alpha(x).float() + self.ssm_dt["bias"]).softplus() * self.ssm_a).reshape(B, self.num_v_heads, 1, 1).exp()
# conv
conv_flat = (self.ssm_conv_kernel - 1) * self.conv_channels
ssm_flat = self.num_v_heads * self.head_v_dim * self.head_v_dim
conv_state = self.delta_cache[:, :conv_flat].reshape(B, self.ssm_conv_kernel - 1, self.conv_channels)
recurrent_state = self.delta_cache[:, conv_flat:conv_flat + ssm_flat].reshape(B, self.num_v_heads, self.head_v_dim, self.head_v_dim)
conv_window = conv_state.cat(self.attn_qkv(x), dim=1)
conv_out = (conv_window * self.ssm_conv1d["weight"].T.unsqueeze(0)).sum(1).silu()
# qkv
q, k, v = conv_out.split([self.q_dim, self.q_dim, self.conv_channels - 2*self.q_dim], dim=-1)
q, k = q.reshape(B, self.num_k_heads, self.head_k_dim).normalize(dim=-1), k.reshape(B, self.num_k_heads, self.head_k_dim).normalize(dim=-1)
q = q.reshape(B, self.num_k_heads, self.head_k_dim).normalize(dim=-1).repeat(1, self.num_v_heads//self.num_k_heads, 1)
k = k.reshape(B, self.num_k_heads, self.head_k_dim).normalize(dim=-1).repeat(1, self.num_v_heads//self.num_k_heads, 1)
v = v.reshape(B, self.num_v_heads, self.head_v_dim)
if self.num_v_heads != self.num_k_heads:
k_repeat = self.num_v_heads // self.num_k_heads
q = q.unsqueeze(1).expand(B, k_repeat, self.num_k_heads, self.head_k_dim).reshape(B, self.num_v_heads, self.head_k_dim)
k = k.unsqueeze(1).expand(B, k_repeat, self.num_k_heads, self.head_k_dim).reshape(B, self.num_v_heads, self.head_k_dim)
q, k, v = (q * self.head_k_dim**-0.5).unsqueeze(-1), k.unsqueeze(-1), v.unsqueeze(-1)
q, k, v = q.mul(self.head_k_dim**-0.5).unsqueeze(-1), k.unsqueeze(-1), v.unsqueeze(-1)
# recurrent
ssm_flat = self.num_v_heads * self.head_v_dim * self.head_v_dim
recurrent_state = self.delta_cache[:, conv_flat:conv_flat + ssm_flat].reshape(B, self.num_v_heads, self.head_v_dim, self.head_v_dim)
recurrent_state = recurrent_state * alpha
recurrent_state = recurrent_state + ((v - recurrent_state@k) * beta)@k.transpose(-1, -2)
new_cache = conv_window[:, 1:, :].reshape(B, -1).cat(recurrent_state.reshape(B, -1), dim=-1).contiguous()
assigned = self.delta_cache.uop.after(self.delta_cache.uop.store(new_cache.cast(self.delta_cache.dtype).uop))
cache_tensor = Tensor(assigned, device=self.delta_cache.device)
# final
final_state = cache_tensor[:, conv_flat:conv_flat + ssm_flat].reshape(B, self.num_v_heads, self.head_v_dim, self.head_v_dim)
core_attn_out = self.ssm_norm((final_state@q).squeeze(-1).reshape(B, 1, self.num_v_heads, self.head_v_dim))
return self.ssm_out((core_attn_out * out_gate.silu()).reshape(B, 1, -1).cast(x.dtype))
@@ -465,48 +360,15 @@ class GatedDeltaNetBlock(FFNBlock):
class Transformer:
def __init__(self, config:TransformerConfig):
dense_config = replace(config, num_experts=0, num_experts_per_tok=0, shared_expert_dim=0, hidden_dim=config.dense_hidden_dim or config.hidden_dim)
if config.ssm: config = replace(config, qk_norm=config.head_dim)
self.config = config
def layer_config(i:int) -> TransformerConfig:
return replace(
config,
hidden_dim=config.hidden_dim[i] if isinstance(config.hidden_dim, tuple) else config.hidden_dim,
n_kv_heads=config.n_kv_heads[i] if isinstance(config.n_kv_heads, tuple) else config.n_kv_heads,
head_dim=config.head_dim[i] if isinstance(config.head_dim, tuple) else config.head_dim,
rope_theta=config.rope_theta[i] if isinstance(config.rope_theta, tuple) else config.rope_theta,
qk_norm=config.qk_norm[i] if isinstance(config.qk_norm, tuple) else config.qk_norm,
sliding_window_pattern=(config.sliding_window_pattern[i],) if config.sliding_window_pattern else ())
if config.gemma4:
self.blk = [TransformerBlock(layer_config(i)) for i in range(config.num_blocks)]
else:
dense_config = replace(
config, num_experts=0, num_experts_per_tok=0, shared_expert_dim=0,
hidden_dim=config.dense_hidden_dim or config.hidden_dim)
block_cls = MLATransformerBlock if config.kv_lora_rank > 0 else TransformerBlock
self.blk:list[FFNBlock] = [GatedDeltaNetBlock(config, config.ssm) if config.ssm and (i+1) % config.full_attention_interval != 0 else
block_cls(dense_config if i < config.leading_dense_blocks else config) for i in range(config.num_blocks)]
block_cls = MLATransformerBlock if config.kv_lora_rank > 0 else TransformerBlock
self.blk:list[FFNBlock] = [GatedDeltaNetBlock(config, config.ssm) if config.ssm and (i+1) % config.full_attention_interval != 0 else
block_cls(dense_config if i < config.leading_dense_blocks else config) for i in range(config.num_blocks)]
self.token_embd = nn.Embedding(config.vocab_size, config.dim)
self.output_norm = nn.RMSNorm(config.dim, config.norm_eps)
self.output = nn.Linear(config.dim, config.vocab_size, bias=False)
if config.per_layer_input_dim:
self.per_layer_model_proj = nn.Linear(config.dim, config.num_blocks * config.per_layer_input_dim, bias=False)
self.per_layer_proj_norm = nn.RMSNorm(config.per_layer_input_dim, config.norm_eps)
self.per_layer_token_embd = nn.Embedding(config.vocab_size, config.num_blocks * config.per_layer_input_dim)
self.max_context = config.max_context
self.embed_scale = config.dim ** 0.5 if config.gemma4 else 1.0
self.per_layer_embed_scale = config.per_layer_input_dim ** 0.5 if config.per_layer_input_dim else 1.0
self.per_layer_input_scale = 2 ** -0.5
self.per_layer_model_projection_scale = config.dim ** -0.5 if config.gemma4 else 1.0
self.final_logit_softcap = config.final_logit_softcap
if config.num_kv_shared_layers:
first_shared = config.num_blocks - config.num_kv_shared_layers
last_of_type = {
False: max(i for i in range(first_shared) if not config.sliding_window_pattern[i]),
True: max(i for i in range(first_shared) if config.sliding_window_pattern[i])}
for idx, block in enumerate(self.blk[:first_shared]):
if bool(config.sliding_window_pattern) and idx == last_of_type[config.sliding_window_pattern[idx]]: block.store_full_length_kv = True
for idx, block in enumerate(self.blk[first_shared:], start=first_shared):
block.shared_kv_src_idx = last_of_type[config.sliding_window_pattern[idx]]
self.has_recurrent_block = any(isinstance(b, GatedDeltaNetBlock) for b in self.blk)
self._cached_tokens: list[int] = []
# we specialize the JIT for prefill and rollout
@@ -514,23 +376,9 @@ class Transformer:
self.rollout_jit = TinyJit(self.forward)
def forward(self, tokens:Tensor, start_pos:int|UOp, temperature:Tensor) -> Tensor:
x = self.token_embd(tokens).float() * self.embed_scale # (B, T, D)
if not self.config.gemma4:
for block in self.blk: x = block(x, start_pos)
else:
per_layer_inputs = None
if hasattr(self, 'per_layer_token_embd'):
B, T, _ = x.shape
per_layer_inputs = self.per_layer_proj_norm(
(self.per_layer_model_proj(x) * self.per_layer_model_projection_scale).reshape(B, T, len(self.blk), -1))
per_layer_inputs = (
per_layer_inputs + self.per_layer_token_embd(tokens).float().reshape(B, T, len(self.blk), -1) * self.per_layer_embed_scale
) * self.per_layer_input_scale
for i, block in enumerate(self.blk):
shared_kv_cache = self.blk[block.shared_kv_src_idx].full_kv_cache if block.shared_kv_src_idx is not None else None
x = block(x, start_pos, None if per_layer_inputs is None else per_layer_inputs[:,:,i,:], shared_kv_cache)
x = self.token_embd(tokens).float() # (B, T, D)
for block in self.blk: x = block(x, start_pos)
logits = self.output(self.output_norm(x))[:, -1, :]
if self.final_logit_softcap: logits = (logits / self.final_logit_softcap).tanh() * self.final_logit_softcap
# Gumbel-max trick: argmax(logits/temp - log(-log(uniform))) is equivalent to sampling from softmax(logits/temp)
return (logits / temperature.maximum(1e-12) - (Tensor.rand_like(logits).maximum(1e-12).log().neg()).log()).argmax(-1, keepdim=True)
@@ -572,36 +420,17 @@ class Transformer:
state_dict[name] = w.rearrange("n (h two) d -> n (two h) d", two=2).reshape(-1, w.shape[-1])
elif kv_lora_rank and 'attn_kv_a_mqa.weight' in name:
state_dict[name] = state_dict[name][:kv_lora_rank].cat(state_dict[name][kv_lora_rank:].rearrange("(h two) d -> (two h) d", two=2), dim=0)
hidden_dim = kv[f'{arch}.feed_forward_length'] if arch == 'gemma4' else \
kv.get(f'{arch}.expert_feed_forward_length', kv.get(f'{arch}.feed_forward_length', 0))
if arch == 'gemma4' and isinstance(hidden_dim, list): hidden_dim = tuple(hidden_dim)
if arch == 'gemma4':
sliding_window_pattern = tuple(kv[f'{arch}.attention.sliding_window_pattern'])
n_kv_heads = tuple(n_kv_heads) if isinstance(n_kv_heads, list) else n_kv_heads
head_dim = tuple(
kv[f'{arch}.attention.key_length_swa'] if is_sliding else kv[f'{arch}.attention.key_length']
for is_sliding in sliding_window_pattern)
rope_theta = tuple(
kv.get(f'{arch}.rope.freq_base_swa', kv[f'{arch}.rope.freq_base']) if is_sliding else kv[f'{arch}.rope.freq_base']
for is_sliding in sliding_window_pattern)
else:
sliding_window_pattern = ()
rope_theta = kv[f'{arch}.rope.freq_base']
config = TransformerConfig(
num_blocks=kv[f'{arch}.block_count'], dim=kv[f'{arch}.embedding_length'],
hidden_dim=hidden_dim,
hidden_dim=kv.get(f'{arch}.expert_feed_forward_length', kv.get(f'{arch}.feed_forward_length', 0)),
n_heads=n_heads, n_kv_heads=n_kv_heads, norm_eps=kv[f'{arch}.attention.layer_norm_rms_epsilon'],
vocab_size=len(kv['tokenizer.ggml.tokens']),
head_dim=head_dim,
rope_theta=rope_theta,
rope_theta=kv[f'{arch}.rope.freq_base'],
rope_dim=rope_dim,
v_head_dim=kv.get(
f'{arch}.attention.value_length_mla',
kv.get(f'{arch}.attention.value_length', head_dim if isinstance(head_dim, int) else head_dim[0])),
v_head_dim=kv.get(f'{arch}.attention.value_length_mla', kv.get(f'{arch}.attention.value_length', head_dim)),
max_context=max_context,
qk_norm=head_dim if arch == 'gemma4' else (
int(state_dict['blk.0.attn_q_norm.weight'].shape[0]) if 'blk.0.attn_q_norm.weight' in state_dict else 0),
qk_norm=int(state_dict['blk.0.attn_q_norm.weight'].shape[0]) if 'blk.0.attn_q_norm.weight' in state_dict else 0,
num_experts=kv.get(f'{arch}.expert_count', 0), num_experts_per_tok=kv.get(f'{arch}.expert_used_count', 0),
norm_topk_prob=kv.get(f'{arch}.expert_weights_norm', arch in ('qwen3moe', 'qwen35moe')),
kv_lora_rank=kv_lora_rank,
@@ -611,17 +440,8 @@ class Transformer:
kv.get(f'{arch}.expert_shared_count', 0) * kv.get(f'{arch}.expert_feed_forward_length', 0)),
shared_expert_gate=f"blk.{kv.get(f'{arch}.leading_dense_block_count', 0)}.ffn_gate_inp_shexp.weight" in state_dict,
dense_hidden_dim=kv.get(f'{arch}.feed_forward_length', 0) if kv.get(f'{arch}.leading_dense_block_count', 0) else 0,
routed_scaling_factor=kv.get(f'{arch}.expert_weights_scale', 1.0),
full_attention_interval=kv.get(f'{arch}.full_attention_interval', 0),
attn_output_gate=arch in ('qwen35', 'qwen35moe'),
ssm=ssm,
sliding_window=kv.get(f'{arch}.attention.sliding_window', 0),
sliding_window_pattern=sliding_window_pattern,
per_layer_input_dim=kv.get(f'{arch}.embedding_length_per_layer_input', 0),
final_logit_softcap=kv.get(f'{arch}.final_logit_softcapping', 0.0),
num_kv_shared_layers=kv.get(f'{arch}.attention.shared_kv_layers', 0),
gemma4=arch == 'gemma4',
expert_hidden_dim=kv.get(f'{arch}.expert_feed_forward_length', 0))
routed_scaling_factor=kv.get(f'{arch}.expert_weights_scale', 1.0), attn_output_gate=arch in ('qwen35', 'qwen35moe'), ssm=ssm,
full_attention_interval=kv.get(f'{arch}.full_attention_interval', 0))
model = Transformer(config)
nn.state.load_state_dict(model, state_dict, verbose=False, consume=True, realize=False) # NOTE: rope_freqs.weight (32,) is unused
# NOTE: without this contiguous, it unpacks the weights from the model every time. we shouldn't need this, but for now it's faster
@@ -671,8 +491,6 @@ models = {
"qwen3.5:9b": "https://huggingface.co/unsloth/Qwen3.5-9B-GGUF/resolve/main/Qwen3.5-9B-Q4_K_M.gguf",
"qwen3.5:27b": "https://huggingface.co/unsloth/Qwen3.5-27B-GGUF/resolve/main/Qwen3.5-27B-Q4_K_M.gguf",
"qwen3.5:35b-a3b": "https://huggingface.co/unsloth/Qwen3.5-35B-A3B-GGUF/resolve/main/Qwen3.5-35B-A3B-Q4_K_M.gguf",
"gemma4:e2b-q4": "https://huggingface.co/unsloth/gemma-4-E2B-it-GGUF/resolve/main/gemma-4-E2B-it-Q4_K_M.gguf",
"gemma4:26b-a4b-q4": "https://huggingface.co/unsloth/gemma-4-26B-A4B-it-GGUF/resolve/main/gemma-4-26B-A4B-it-UD-Q4_K_M.gguf",
"olmoe": "https://huggingface.co/allenai/OLMoE-1B-7B-0924-Instruct-GGUF/resolve/main/olmoe-1b-7b-0924-instruct-q4_k_m.gguf",
"moonlight": "https://huggingface.co/gabriellarson/Moonlight-16B-A3B-Instruct-GGUF/resolve/main/Moonlight-16B-A3B-Instruct-Q4_K_M.gguf",
}
@@ -65,7 +65,7 @@ def _make_buffer_view(src:UOp) -> UOp|None:
if (offset := src.contiguous_view_offset()) is None: return None
buf = src.base
if buf.op is Ops.BUFFER_VIEW: offset, buf = offset + buf.arg[1], buf.src[0]
return UOp(Ops.BUFFER_VIEW, src.dtype, (buf,), (src.size, offset)).reshape(src.shape)
return UOp(Ops.BUFFER_VIEW, src.dtype, (buf,), (src.numel(), offset)).reshape(src.shape)
def contiguous_mops_to_view(c:UOp, src:UOp):
"""CONTIGUOUS(MOPS(BUFFER)) → CONTIGUOUS(BUFFER_VIEW) when movement ops collapse to a contiguous range."""
@@ -94,13 +94,13 @@ def contiguous_mops_to_view(c:UOp, src:UOp):
if (view := _make_buffer_view(src)) is None: return None
return view.contiguous(tag=c.tag)
def transform_precompiled_call(c:UOp) -> UOp|None:
def transform_precompiled_function(c:UOp) -> UOp|None:
if not c.arg.precompile: return None
if c.src[0].op is Ops.SINK: return None
assert c.src[0].op is Ops.TUPLE, f"expected TUPLE body for precompiled call, got {c.src[0].op}"
assert c.src[0].op is Ops.TUPLE, f"expected TUPLE body for precompiled function, got {c.src[0].op}"
input_buffers = tuple(x.contiguous() if x.op not in {Ops.AFTER, Ops.BIND} else x for x in c.src[1:])
# add the outputs to the call
# add the outputs to the function
srcs = c.src[0].src
resolved = [c.gettuple(i) for i in range(len(srcs))]
outs = tuple(_buffer_like(r) for r in resolved)
@@ -108,7 +108,7 @@ def transform_precompiled_call(c:UOp) -> UOp|None:
fxn = UOp.sink(*[t.after(t.store(s)) for t,s in zip(targets, srcs)])
# create the new thing for the big graph
new_call = c.replace(src=(fxn, *input_buffers, *outs), tag=None)
new_call = c.replace(op=Ops.CALL, src=(fxn, *input_buffers, *outs), tag=None)
rets = tuple(o.after(new_call) for o in outs)
# if the CALL has symbolic shapes, shrink the max-sized output to the actual symbolic shape
@@ -119,8 +119,8 @@ def transform_precompiled_call(c:UOp) -> UOp|None:
# NOTE: adding rules to here is bad. these all need to run before the schedule cache
pm_early_transform_tensor_graph = PatternMatcher([
# transform precompiled CALLs
(UPat(Ops.CALL, name="c"), transform_precompiled_call),
# transform precompiled FUNCTIONs -> CALLs
(UPat(Ops.FUNCTION, name="c"), transform_precompiled_function),
# resolve TUPLE+GETTUPLE (for precompiled calls)
(UPat(Ops.GETTUPLE, src=(UPat(Ops.TUPLE, name="t"),), name="g"), lambda g,t: t.src[g.arg]),
@@ -178,7 +178,7 @@ pm_replace_buf = PatternMatcher([
(UPat(Ops.BIND, src=(UPat(Ops.DEFINE_VAR), UPat(Ops.CONST)), name="b"), replace_input_buffer),
])
@track_rewrites(lambda _,ret: f"Process {pluralize('Buffer', len(ret[1]))}")
@track_rewrites(lambda _,ret: f"Callify {pluralize('Buffer', len(ret[1]))}")
def transform_to_call(big_sink:UOp) -> tuple[UOp, dict[UOp, UOp]]:
if VIZ: graph_rewrite(big_sink, PatternMatcher([]), name="View Tensor Graph")
# uop list is a list in the original_sink graph and we can map to the tags later
+3 -4
View File
@@ -5,7 +5,7 @@ from typing import Any, Generic, TypeVar, Iterator, Generator, TYPE_CHECKING
import importlib, inspect, functools, pathlib, os, platform, contextlib, sys, re, atexit, pickle, decimal
from tinygrad.helpers import BENCHMARKS, CI, OSX, LRU, getenv, diskcache_get, diskcache_put, DEBUG, GlobalCounters, flat_mv, PROFILE, temp, colored
from tinygrad.helpers import Context, CCACHE, ALLOW_DEVICE_USAGE, MAX_BUFFER_SIZE, cpu_events, ProfileEvent, ProfilePointEvent, suppress_finalizing
from tinygrad.helpers import select_first_inited, DEV, EMULATED_DTYPES, IMAGE, FLOAT16, TracingKey, size_to_str, Target
from tinygrad.helpers import select_by_name, select_first_inited, DEV, EMULATED_DTYPES, IMAGE, FLOAT16, TracingKey, size_to_str, Target
from tinygrad.dtype import DType, PtrDType, dtypes, _to_np_dtype
if TYPE_CHECKING: from tinygrad.renderer import Renderer
@@ -292,9 +292,8 @@ class Compiled:
assert (rn:=next((self._renderer_name(r) for r in self.renderers if getenv(f"{self.device}_{self._renderer_name(r)}")), None)) is None, \
f"{self.device}_{rn}=1 is deprecated, use DEV={self.device}:{rn} or {self.device}_CC={rn} instead"
t = DEV.target(self.device.split(':')[0], **({"arch":self.arch} if self.arch else {}))
renderers = [r for r in self.renderers if self._renderer_name(r) == t.renderer] if t.renderer else self.renderers
assert renderers, f"No renderer for {self.device} " + (f"matches request {t.renderer!r}" if t.renderer else "is available")
return select_first_inited(renderers, f"No renderer for {self.device} is available", self.cached_renderer, target=t)
return select_first_inited(select_by_name(self.renderers, self._renderer_name, t.renderer, f"{self.device} has no renderer {t.renderer!r}"),
f"No renderer for {self.device} is available", self.cached_renderer, target=t)
def synchronize(self):
"""
+2 -2
View File
@@ -6,8 +6,8 @@ from tinygrad.device import Buffer, Compiled, Device, MultiBuffer
from tinygrad.dtype import DType, dtypes
from tinygrad.uop.ops import UOp, PatternMatcher, Variable, sym_infer, Ops, buffers, track_rewrites, graph_rewrite
from tinygrad.engine.realize import ExecItem, capturing, BufferCopy, BufferXfer, EncDec, CompiledRunner, Runner, Estimates
from tinygrad.engine.memory import memory_plan_rewrite, _collect_bufs
from tinygrad.engine.schedule import linear_to_schedule
from tinygrad.schedule.memory import memory_plan_rewrite, _collect_bufs
from tinygrad.schedule import linear_to_schedule
from tinygrad.nn.state import get_parameters
from tinygrad.schedule.rangeify import mop_cleanup
from dataclasses import dataclass
-175
View File
@@ -1,175 +0,0 @@
import time, inspect
from typing import cast
from collections import deque
from tinygrad.uop.ops import UOp, Ops, buffers, UOpMetaClass, track_rewrites, graph_rewrite, gate_kernel_sink, KernelInfo
from tinygrad.uop.spec import type_verify, tensor_spec
from tinygrad.device import Buffer, MultiBuffer
from tinygrad.helpers import DEBUG, cpu_profile, TracingKey, SPEC, pluralize, SCACHE, BASEDIR, flatten, BEAM
from tinygrad.engine.realize import ExecItem
# **** schedule linearizer
# unwrap VIEW/CAST/etc to find the actual data source (kernel output, buffer, or multi-device op)
def _unwrap_src(s: UOp) -> UOp:
while len(s.src) and s.op not in {Ops.AFTER, Ops.BUFFER, Ops.PARAM, Ops.MSELECT, Ops.MSTACK, Ops.BIND}: s = s.src[0]
return s
def create_schedule(sched_sink:UOp) -> UOp:
with cpu_profile(TracingKey("toposort sched_sink")):
# build kernel dependency graph: edges from producer kernel to consumer kernels
children: dict[UOp, list[UOp]] = {}
in_degree: dict[UOp, int] = {}
for u in sched_sink.toposort(gate_kernel_sink):
if u.op is not Ops.AFTER: continue
k = u.src[1]
if k.op is Ops.STORE: continue # skip unprocessed STORE+AFTER inside precompiled CALL bodies
assert k.op in {Ops.CALL, Ops.END}, f"AFTER src[1] should be CALL or END, not {k.op}"
in_degree.setdefault(k, 0)
if k.op is Ops.END: assert k.src[0].op is Ops.CALL, f"END src[0] should be KERNEL, not {k.src[0].op}"
# WAR deps from rangeify are stored in AFTER src[2:]
kernel_deps = k.src[0].src[1:] if k.op is Ops.END else k.src[1:]
for s in kernel_deps + u.src[2:]:
match (s := _unwrap_src(s)).op:
case Ops.AFTER:
children.setdefault(s.src[1], []).append(k)
in_degree[k] += 1
case Ops.MSELECT | Ops.MSTACK:
for ss in s.src:
if ss.op is Ops.MSELECT: ss = ss.src[0]
if ss.op not in {Ops.BUFFER, Ops.PARAM}:
assert ss.op is Ops.AFTER, f"ss.op is not AFTER, it's {ss.op}"
children.setdefault(ss.src[1], []).append(k)
in_degree[k] += 1
case Ops.BUFFER | Ops.PARAM | Ops.BIND:
pass # BUFFER/PARAM is already realized, BIND is a bound variable (not a buffer dependency)
case _:
raise RuntimeError(f"input to kernel must be AFTER, BUFFER, PARAM, MSELECT, MSTACK, or BIND, not {s.op}")
with cpu_profile(TracingKey("linearize schedule")):
queue: deque[UOp] = deque(k for k,v in in_degree.items() if v == 0)
linearized: list[UOp] = []
while len(queue):
rk = queue.popleft()
if rk.op is Ops.LINEAR:
linearized.extend(rk.src)
else:
k = rk.src[0] if rk.op is Ops.END else rk
assert k.op is Ops.CALL, f"unexpected op in queue: {k.op}"
buf_uops = tuple(_unwrap_src(s).buf_uop for s in k.src[1:] if s.op is not Ops.BIND)
linearized.append(k.src[0].call(*buf_uops, metadata=k.arg.metadata))
for x in children.get(rk, []):
in_degree[x] -= 1
if in_degree[x] == 0: queue.append(x)
return UOp(Ops.LINEAR, src=tuple(linearized))
def linear_to_schedule(linear:UOp) -> list[ExecItem]:
"""Convert a LINEAR UOp to a list of ExecItems."""
schedule: list[ExecItem] = []
for si in linear.src:
ast, buf_uops = si.src[0], si.src[1:]
# create subbuffers if needed
if ast.op is Ops.BUFFER_VIEW:
base = buf_uops[1].buffer
assert isinstance(base, Buffer), "base can't be MultiBuffer"
buffers[buf_uops[0]] = base.view(buf_uops[0].arg, ast.dtype, ast.arg[1]*base.dtype.itemsize)
# wrap SINK with BEAM UOp when beam search is enabled
if ast.op is Ops.SINK and BEAM >= 1: ast = UOp(Ops.BEAM, src=(ast,), arg=BEAM.value)
ubufs = [b.buffer for b in buf_uops if b.op is not Ops.BIND]
metadata = si.arg.metadata
if ast.op is Ops.CUSTOM_FUNCTION and ast.arg == "graph":
schedule.append(ExecItem(ast, flatten([b.bufs if isinstance(b, MultiBuffer) else [b] for b in ubufs]), metadata))
elif any(isinstance(x, MultiBuffer) for x in ubufs):
assert all(isinstance(x, MultiBuffer) for x in ubufs), "kernel must all be multibuffer"
dnums = [x for x in ast.variables() if x.expr == '_device_num']
for j, bufs in enumerate(zip(*[x.bufs for x in cast(tuple[MultiBuffer, ...], ubufs)])):
schedule.append(ExecItem(ast, list(bufs), metadata, {dnums[0].expr:j} if len(dnums) else {}))
else:
schedule.append(ExecItem(ast, cast(list[Buffer|None], ubufs), metadata))
return schedule
from tinygrad.engine.memory import memory_plan_rewrite
from tinygrad.engine.realize import capturing
from tinygrad.schedule.rangeify import get_kernel_graph
from tinygrad.helpers import CAPTURING
from tinygrad.uop.ops import PatternMatcher, UPat
def create_new_buffer(ctx:tuple[dict[UOp, UOp], tuple[UOp, ...]], b:UOp):
if (ret:=ctx[0].get(b, None)) is None: ctx[0][b] = ret = UOp.new_buffer(b.device, b.arg, b.dtype)
return ret
pm_post_sched_cache = PatternMatcher([
(UPat(Ops.PARAM, name="x"), lambda ctx,x: ctx[1][x.arg]),
# create new BUFFERs for LUNIQUE BUFFERs from rangeify
(UPat(Ops.BUFFER, src=(UPat(Ops.LUNIQUE), UPat(Ops.DEVICE)), name="b"), create_new_buffer),
])
pm_resolve_linear_call = PatternMatcher([
# call LINEAR is resolved here
(UPat(Ops.CALL, src=(UPat(Ops.LINEAR),), name="linear_call", allow_any_len=True), lambda linear_call:
graph_rewrite(linear_call.src[0], pm_post_sched_cache, ctx=({}, linear_call.src[1:]), walk=True, name="params to buffers")),
# LINEAR on LINEAR
(UPat(Ops.LINEAR, custom_early_reject={Ops.LINEAR}, name="x"),
lambda x: x.replace(src=tuple(flatten(x.src if x.op is Ops.LINEAR else (x,) for x in x.src)))),
])
schedule_cache: dict[bytes, UOp] = {}
# ctx is just for DEBUG on inner
def lower_sink_to_linear(function:UOp) -> UOp|None:
st = time.perf_counter()
if isinstance(function.arg, KernelInfo): return None
cache_key = function.key
if not SCACHE or (sc_ret:=schedule_cache.get(cache_key, None)) is None:
if SPEC: type_verify(function, tensor_spec)
# support recursive CALLs
linear = create_schedule(get_kernel_graph(function))
if SCACHE: schedule_cache[cache_key] = linear
else:
# schedule cache hit
linear = sc_ret
if (DEBUG >= 1 and len(linear.src) > 1) or DEBUG >= 3:
for frm in inspect.stack():
if frm.filename == "<string>": continue
if frm.filename.startswith(str(BASEDIR / "apps")): break
if not frm.filename.startswith(str(BASEDIR)) and not frm.filename.endswith("/contextlib.py"): break
else:
frm = None
print(f"scheduled {len(linear.src):5d} kernels in {(time.perf_counter()-st)*1000:8.2f} ms"+\
f" | {' cache hit' if SCACHE and sc_ret is not None else 'CACHE MISS'} {cache_key.hex()[:8]}"+\
f" | {len(UOpMetaClass.ucache):7d} uops in cache"+("" if frm is None else f" | {frm.filename}:{frm.lineno}"))
return linear
pm_schedule = PatternMatcher([
(UPat(Ops.SINK, name="function"), lower_sink_to_linear),
])
@track_rewrites(lambda _,ret: f"Schedule {pluralize('Kernel', len(ret[0]))}")
def complete_create_schedule_with_vars(big_sink:UOp) -> tuple[list[ExecItem], dict[str, int]]:
# big_sink srcs are all the Tensors
linear_call = graph_rewrite(big_sink, pm_schedule, name="schedule to linear", enter_calls=True)
# this recursively resolves the linear_call and allocates buffers
linear = graph_rewrite(linear_call, pm_resolve_linear_call, name="resolve linear call")
# vars used in the schedule
used_vars = set().union(*[{v.expr for v in si.src[0].variables()} for si in linear.src])
# get var_vals
var_vals: dict[str, int] = {}
for b in big_sink.src[1:]:
if b.op is Ops.BIND:
nm = b.src[0].expr
if nm not in used_vars: continue
val = b.src[1].arg
if var_vals.get(nm, val) != val: raise RuntimeError(f"bind mismatch on {nm}, {var_vals[nm]} != {val}")
var_vals[nm] = val
# jit captures this schedule, no need to execute.
if len(capturing) and CAPTURING:
capturing[0].add_linear(linear, var_vals)
return [], var_vals
held_bufs = ({b for b in linear_call.src[1:] if b.op is Ops.BUFFER} if linear_call.op is Ops.CALL else set())
linear = memory_plan_rewrite(linear, held_bufs)
# convert LINEAR to ExecItems
schedule: list[ExecItem] = linear_to_schedule(linear)
return schedule, var_vals
+4 -4
View File
@@ -95,15 +95,15 @@ def compute_gradient(root:UOp, root_grad:UOp, targets:set[UOp]) -> dict[UOp, UOp
if t0 not in grads or grads[t0].op is Ops.NOOP: continue
# GETTUPLE: accumulate gradient into a TUPLE UOp on the CALL, process when we hit the CALL
if t0.op is Ops.GETTUPLE:
k = t0.src[0] # the CALL
assert k.op is Ops.CALL and k.src[0].op is Ops.TUPLE
k = t0.src[0] # the FUNCTION
assert k.op is Ops.FUNCTION and k.src[0].op is Ops.TUPLE
n_outputs = len(k.src[0].src)
prev = grads[k].src if k in grads else tuple(UOp(Ops.NOOP) for _ in range(n_outputs))
grads[k] = UOp.maketuple(*(prev[i] + grads[t0] if i == t0.arg and prev[i].op is not Ops.NOOP else
grads[t0] if i == t0.arg else prev[i] for i in range(n_outputs)))
continue
# CALL: pass needed param set so backward only computes required gradients
if t0.op is Ops.CALL:
# FUNCTION: pass needed param set so backward only computes required gradients
if t0.op is Ops.FUNCTION:
needed = {i for i, arg in enumerate(t0.src[1:]) if arg in targets or in_target_path.get(arg, False)}
lgrads:tuple[UOp|None, ...]|None = call_gradient(grads[t0], t0, needed)
else:
+17 -16
View File
@@ -3,7 +3,7 @@ import time
START_TIME = time.perf_counter()
import os, functools, platform, re, contextlib, operator, hashlib, pickle, sqlite3, tempfile, pathlib, string, ctypes, sys, gzip, getpass, gc
from collections import defaultdict
import subprocess, shutil, math, types, copyreg, inspect, importlib, decimal, itertools
import subprocess, shutil, math, types, copyreg, inspect, importlib, decimal, itertools, difflib
from dataclasses import dataclass, field, replace
from typing import ClassVar, Iterable, Any, TypeVar, Callable, Sequence, TypeGuard, Iterator, Generic, Generator, cast, overload
@@ -121,6 +121,11 @@ def suppress_finalizing(func):
if not getattr(sys, 'is_finalizing', lambda: True)(): raise # re-raise if not finalizing
return wrapper
def select_by_name(candidates:Sequence[T], get_name:Callable[...,str], query:str, err_msg:str) -> list[T]:
if len(ret:=[c for c in candidates if not query or get_name(c) == query]) == 0:
raise RuntimeError(err_msg + (f", did you mean: {m[0]!r}?" if (m:=difflib.get_close_matches(query, map(get_name, candidates))) else ""))
return ret
def select_first_inited(candidates:Sequence[Callable[...,T]], err_msg:str, cache:dict|None=None, **kwargs):
excs = []
for typ in candidates:
@@ -130,7 +135,7 @@ def select_first_inited(candidates:Sequence[Callable[...,T]], err_msg:str, cache
if cache is not None: cache[typ] = x
return x
except Exception as e: excs.append(e)
raise excs[0] if len(excs) == 1 else ExceptionGroup(err_msg, excs)
raise excs[0] if len(excs) == 1 else ExceptionGroup(err_msg + " is available", excs)
def pluralize(st:str, cnt:int): return f"{cnt} {st}"+('' if cnt == 1 else 's')
@@ -202,20 +207,19 @@ class Target:
def replacedefault(self, **kwargs) -> Target: return replace(self, **{k:v for k,v in kwargs.items() if not getattr(self, k)})
class _DEV(ContextVar):
_value = Target()
_value: list[Target] = [Target()]
@property
def value(self) -> Target: return self._value
def value(self) -> list[Target]: return self._value
@value.setter
def value(self, v:str|Target): self._value = v if isinstance(v, Target) else Target.parse(v)
def __getattr__(self, k): return getattr(self.value, k)
def value(self, v:str|Target|list[Target]):
self._value = v if isinstance(v, list) else [v] if isinstance(v, Target) else [Target.parse(t) for t in v.split(';')]
def __repr__(self) -> str: return ";".join([repr(t) for t in self._value])
def __getattr__(self, k): return getattr(self._value[0], k)
# get target for device string, kwargs are passed if not already specified
def target(self, dev:str, **kwargs) -> Target:
t = self.value.replacedefault(**kwargs) if self.device == dev or not self.device else Target(device=dev, **kwargs)
# TODO: remove this once DEV supports secondary targets
if (cv:=ContextVar._cache.get(f"{dev}_CC", None)) is not None and cv.value:
assert not t.renderer, f"renderer set in DEV and {dev}_CC"
return replace(t, renderer=cv.value.upper())
return replace(t, device=dev)
assert (v:=getenv(k:=f"{dev}_CC", "")) == "", \
f"{k}={v} is deprecated, use DEV='{';'.join([repr(t) for t in self._value if t.device != dev] + [f'{dev}:{v}'])}' instead"
return replace(next((t for t in self._value if not t.device or t.device == dev), Target(device=dev)).replacedefault(**kwargs), device=dev)
DEV, DEBUG, BEAM, NOOPT = _DEV("DEV", ""), ContextVar("DEBUG", 0), ContextVar("BEAM", 0), ContextVar("NOOPT", 0)
IMAGE, FLOAT16, OPENPILOT_HACKS = ContextVar("IMAGE", 0), ContextVar("FLOAT16", 0), ContextVar("OPENPILOT_HACKS", 0)
@@ -224,7 +228,7 @@ WINO, CAPTURING, TRACEMETA = ContextVar("WINO", 0), ContextVar("CAPTURING", 1),
USE_TC, TC_SELECT, TC_OPT, AMX = ContextVar("TC", 1), ContextVar("TC_SELECT", -1), ContextVar("TC_OPT", 0), ContextVar("AMX", 0)
TRANSCENDENTAL, NOLOCALS = ContextVar("TRANSCENDENTAL", 1), ContextVar("NOLOCALS", 0)
SPLIT_REDUCEOP, NO_MEMORY_PLANNER, LRU = ContextVar("SPLIT_REDUCEOP", 1), ContextVar("NO_MEMORY_PLANNER", 0), ContextVar("LRU", 1)
RING, ALL2ALL = ContextVar("RING", 1), ContextVar("ALL2ALL", 0)
RING, ALL2ALL, ALLREDUCE_CAST = ContextVar("RING", 1), ContextVar("ALL2ALL", 0), ContextVar("ALLREDUCE_CAST", 1)
CACHELEVEL, IGNORE_BEAM_CACHE, DEVECTORIZE = ContextVar("CACHELEVEL", 2), ContextVar("IGNORE_BEAM_CACHE", 0), ContextVar("DEVECTORIZE", 1)
VALIDATE_WITH_CPU, DISABLE_FAST_IDIV = ContextVar("VALIDATE_WITH_CPU", 0), ContextVar("DISABLE_FAST_IDIV", 0)
CORRECT_DIVMOD_FOLDING, FUSE_OPTIM = ContextVar("CORRECT_DIVMOD_FOLDING", 0), ContextVar("FUSE_OPTIM", 0)
@@ -233,10 +237,7 @@ MAX_KERNEL_BUFFERS = ContextVar("MAX_KERNEL_BUFFERS", 0)
EMULATED_DTYPES = ContextVar("EMULATED_DTYPES", "")
CAPTURE_PROCESS_REPLAY = ContextVar("CAPTURE_PROCESS_REPLAY", 0)
CPU_COUNT = ContextVar("CPU_COUNT", max(1, len(os.sched_getaffinity(0)) if hasattr(os, "sched_getaffinity") else (os.cpu_count() or 1)))
# Compilers
CPU_CC, NV_CC, CUDA_CC, NULL_CC = ContextVar("CPU_CC", ""), ContextVar("NV_CC", ""), ContextVar("CUDA_CC", ""), ContextVar("NULL_CC", "")
NULL_ALLOW_COPYOUT = ContextVar("NULL_ALLOW_COPYOUT", 0)
AMD_CC, QCOM_CC = ContextVar("AMD_CC", ""), ContextVar("QCOM_CC", "")
# VIZ implies PROFILE, but you can run PROFILE without VIZ
VIZ = ContextVar("VIZ", 0)
PROFILE = ContextVar("PROFILE", abs(VIZ.value))
+98 -3
View File
@@ -1,15 +1,26 @@
import functools
import functools, itertools
from typing import Self, Sequence, Literal, get_args
from tinygrad.mixin.elementwise import ElementwiseMixin
from tinygrad.mixin.movement import MovementMixin
from tinygrad.mixin.reduce import ReduceMixin
from tinygrad.uop.ops import _broadcast_shape, resolve
from tinygrad.uop import Ops
from tinygrad.uop.ops import _broadcast_shape, resolve, smax, smin, identity_element
from tinygrad.dtype import DTypeLike, dtypes, least_upper_dtype, sum_acc_dtype, to_dtype
from tinygrad.helpers import argfix, prod
from tinygrad.helpers import argfix, flatten, prod, round_up
ReductionStr = Literal["mean", "sum", "none"]
class OpMixin(ElementwiseMixin, ReduceMixin):
def _pad_constant(self, pX, value:float) -> Self:
# shrink first for negative pads, then pad with only non-negative values
pX = tuple((0, 0) if p is None else p for p in pX)
has_neg = not all(resolve(p >= 0) for p in flatten(pX))
X = self.shrink(tuple((-smin(pB,0),smin(pA+s,s)) for (pB,pA),s in zip(pX, self.shape))) if has_neg else self
pads = tuple((smax(pB,0), smax(pA,0)) for pB,pA in pX) if has_neg else pX
if value == 0: return MovementMixin.pad(X, pads)
return MovementMixin.pad(X, pads) + MovementMixin.pad(X.ones_like(), pads).cast(dtypes.bool).where(0, value)
def _broadcasted(self, y, reverse=False) -> tuple[Self, Self]:
if not isinstance(y, type(self)): y = self.ufix(y)
x, y = (self, y) if not reverse else (y, self)
@@ -249,6 +260,90 @@ class OpMixin(ElementwiseMixin, ReduceMixin):
m = self.max(axis=axis, keepdim=True)
return (self - m).exp().sum(axis=axis, keepdim=keepdim).log() + (m if keepdim else m.squeeze(axis))
def cat(self, *args:Self, dim:int=0) -> Self:
"""
Concatenates self with other tensors in `args` along an axis specified by `dim`.
All tensors must have the same shape except in the concatenating dimension.
```python exec="true" source="above" session="tensor" result="python"
t0, t1, t2 = Tensor([[1, 2]]), Tensor([[3, 4]]), Tensor([[5, 6]])
print(t0.cat(t1, t2, dim=0).numpy())
```
```python exec="true" source="above" session="tensor" result="python"
print(t0.cat(t1, t2, dim=1).numpy())
```
"""
dim = self._resolve_dim(dim)
for arg in args: assert arg.ndim==self.ndim and all(ti==ai for i,(ti,ai) in enumerate(zip(self.shape, arg.shape)) if i!=dim)
tensors = [self, *args]
dim_cumsum = list(itertools.accumulate([t.shape[dim] for t in tensors], initial=0))
padded = [t.pad(tuple((dim_cumsum[i], dim_cumsum[-1]-dim_cumsum[i+1]) if j==dim else None for j in range(t.ndim))) for i,t in enumerate(tensors)]
return padded[0].usum(*padded[1:])
def stack(self, *args:Self, dim:int=0) -> Self:
"""
Concatenates self with other tensors in `args` along a new dimension specified by `dim`.
```python exec="true" source="above" session="tensor" result="python"
t0, t1, t2 = Tensor([1, 2]), Tensor([3, 4]), Tensor([5, 6])
print(t0.stack(t1, t2, dim=0).numpy())
```
```python exec="true" source="above" session="tensor" result="python"
print(t0.stack(t1, t2, dim=1).numpy())
```
"""
# checks for shapes and number of dimensions delegated to cat
unsqueezed = [t.unsqueeze(dim) for t in argfix(self, *args)]
return unsqueezed[0].cat(*unsqueezed[1:], dim=dim)
def _cumalu(self, axis:int, op:Ops) -> Self:
assert self.shape[axis] != 0 and op in (Ops.ADD, Ops.MAX, Ops.MUL)
pads = (None,)*(self.ndim-1) + ((self.shape[axis]-1, 0),)
pooled = self.transpose(axis,-1)._pad_constant(pads, identity_element(op, self.dtype))._pool((self.shape[axis],))
return getattr(pooled, {Ops.ADD: "sum", Ops.MAX: "max", Ops.MUL: "prod"}[op])(-1).transpose(axis, -1)
def _split_cumalu(self, axis:int, op:Ops) -> Self:
axis = self._resolve_dim(axis)
if self.ndim == 0 or 0 in self.shape: return self
# TODO: someday the optimizer will find this on its own
# for now this is a two stage cumsum
SPLIT = 256
value = identity_element(op, self.dtype)
if not isinstance(s:=self.shape[axis], int) or s <= SPLIT*2: return self._cumalu(axis, op)
ret = self.transpose(axis,-1)._pad_constant((None,)*(self.ndim-1)+((round_up(s,SPLIT)-s,0),), value).unflatten(-1,(-1,SPLIT))._cumalu(-1, op)
base = ret[..., -1]._cumalu(-1, op)._pad_constant((None,)*(ret.ndim-2) + ((1, -1),), value)
base = base.unsqueeze(-1).expand(*base.shape, ret.shape[-1])
def fix(x: Self) -> Self: return x.flatten(start_dim=-2)[..., -s:].transpose(axis,-1)
return getattr(fix(ret), {Ops.ADD: "add", Ops.MAX: "maximum", Ops.MUL: "mul"}[op])(fix(base))
def cumsum(self, axis:int=0) -> Self:
"""
Computes the cumulative sum of the tensor along the specified `axis`.
```python exec="true" source="above" session="tensor" result="python"
t = Tensor.ones(2, 3)
print(t.numpy())
```
```python exec="true" source="above" session="tensor" result="python"
print(t.cumsum(1).numpy())
```
"""
return self._split_cumalu(axis, Ops.ADD)
def cumprod(self, axis:int) -> Self:
"""
Computes the cumulative product of the elements of the tensor along the specified `axis`.
```python exec="true" source="above" session="tensor" result="python"
t = Tensor.arange(1, 7).reshape(2, 3)
print(t.numpy())
```
```python exec="true" source="above" session="tensor" result="python"
print(t.cumprod(axis=0).numpy())
```
"""
return self._split_cumalu(axis, Ops.MUL)
# ***** functional nn ops *****
def linear(self, weight:Self, bias:Self|None=None, dtype:DTypeLike|None=None) -> Self:
+51 -1
View File
@@ -2,7 +2,7 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Self, Sequence
from tinygrad.uop import Ops
from tinygrad.helpers import prod, argfix, argsort, flatten, dedup, make_tuple, ceildiv
from tinygrad.helpers import prod, argfix, argsort, flatten, dedup, make_tuple, ceildiv, round_up, all_int
from tinygrad.uop.ops import resolve, smax, _align_left, _broadcast_shape
if TYPE_CHECKING:
@@ -56,6 +56,56 @@ class MovementMixin:
raise IndexError(f"{dim=} out of range {[-max(1, total), max(1, total) - 1]}")
return dim + total if dim < 0 else dim
def _parse_view_index(self, index, size: sint) -> dict:
# parses a single slice/int/None/sint index into {boundary, stride, size, collapse_dim}
from tinygrad.uop.ops import UOp, sint
match index:
case None: return {"size":1, "boundary":(0,1), "stride":1, "collapse_dim":False}
case int() | UOp(): # sint
if resolve(index >= size, False) or resolve(index < -size, False): raise IndexError(f"{index=} is out of bounds with {size=}")
# TODO: is this right for (negative) symbolic?
b = index if resolve(index >= 0, False) else index + size
return {"size":size, "boundary":(b, b+1), "stride":1, "collapse_dim":True}
case slice():
if not all(s is None or isinstance(s, sint) for s in (index.start, index.stop, index.step)):
raise TypeError(f"slice {index=} is not supported")
if resolve(index.step == 0, False): raise ValueError(f"{index=} cannot have 0 as step")
start, stop = 0 if index.start is None else index.start, size if index.stop is None else index.stop
step = 1 if index.step is None else index.step
if all_int((start, stop, step)):
# handle int slicing (resolve negative bounds, clamp, stride)
*bound, stride = index.indices(int(size.vmax) if isinstance(size, UOp) else size)
bound = [0, 0] if stride * (bound[1] - bound[0]) < 0 else ([bound[1]+1, bound[0]+1] if stride < 0 else bound)
return {"size":ceildiv(bound[1]-bound[0], abs(stride)), "boundary":tuple(bound), "stride":stride, "collapse_dim":False}
if resolve(step == 1, False) and resolve((stop-start) >= 0, False):
return {"size":stop-start, "boundary":(start, stop), "stride":step, "collapse_dim":False}
raise TypeError(f"slice {index=} is not supported")
case _: raise IndexError(f"{type(index).__name__} indexing is not supported")
def _apply_view_ops(self, mops:list) -> Self:
# applies shrink + flip + stride from a list of parsed view indices
# flip negative strides
x = self.shrink(tuple(m["boundary"] for m in mops)).flip(tuple(i for i, m in enumerate(mops) if m["stride"] < 0))
strides = tuple(abs(m["stride"]) for m in mops)
# apply stride
if any(st != 1 for st in strides):
if not all_int(x.shape): raise RuntimeError("symbolic shape not supported")
x = x.pad_to(tuple(round_up(s, st) for s, st in zip(x.shape, strides)))
x = x.reshape(tuple(flatten((s // st, st) for s, st in zip(x.shape, strides))))
x = x.shrink_to(tuple(flatten((s, 1) for s in x.shape[::2]))).reshape(x.shape[::2])
return x
def __getitem__(self, indices) -> Self:
# wrap single index into a list
if (isinstance(indices, list) and all_int(indices)) or not isinstance(indices, (tuple, list)): indices = [indices]
indices_parsed, dim = [], 0
for index in self._normalize_indices(list(indices)):
indices_parsed.append({**self._parse_view_index(index, 1 if index is None else self.shape[dim]), "index":index})
if index is not None: dim += 1
x = self._apply_view_ops(mops) if (mops := [p for p in indices_parsed if p["index"] is not None]) else self
# dim injection from None (size 1) and dim collapse from int indices
return x.reshape(tuple(p["size"] for p in indices_parsed if not p["collapse_dim"]))
def _broadcast_to(self, new_shape: tuple[sint, ...]) -> Self:
if self.shape == new_shape:
return self
+11 -8
View File
@@ -32,11 +32,13 @@ _FORMATS: dict[str, list[type[Inst]]] | None = None
def _load_formats() -> dict[str, list[type[Inst]]]:
global _FORMATS
if _FORMATS is not None: return _FORMATS
from tinygrad.runtime.autogen.amd.rdna3.ins import (VOP1, VOP1_SDST, VOP1_LIT, VOP2, VOP2_LIT, VOP3, VOP3_SDST, VOP3SD, VOP3P, VOPC, VOPD,
VINTERP, SOP1, SOP1_LIT, SOP2, SOP2_LIT, SOPC, SOPK, SOPK_LIT, SOPP, SMEM, DS, FLAT, GLOBAL, SCRATCH)
from tinygrad.runtime.autogen.amd.rdna4.ins import (VOP1 as R4_VOP1, VOP1_SDST as R4_VOP1_SDST, VOP1_LIT as R4_VOP1_LIT,
VOP2 as R4_VOP2, VOP2_LIT as R4_VOP2_LIT, VOP3 as R4_VOP3, VOP3_SDST as R4_VOP3_SDST, VOP3SD as R4_VOP3SD, VOP3P as R4_VOP3P,
VOPC as R4_VOPC, VOPD as R4_VOPD, VINTERP as R4_VINTERP, SOP1 as R4_SOP1, SOP1_LIT as R4_SOP1_LIT,
from tinygrad.runtime.autogen.amd.rdna3.ins import (VOP1, VOP1_SDST, VOP1_DPP16, VOP1_LIT, VOP2, VOP2_DPP16, VOP2_LIT, VOP3, VOP3_SDST,
VOP3SD, VOP3P, VOPC, VOPC_DPP16, VOPD, VINTERP, SOP1, SOP1_LIT, SOP2, SOP2_LIT, SOPC, SOPK, SOPK_LIT, SOPP, SMEM, DS, FLAT, GLOBAL,
SCRATCH)
from tinygrad.runtime.autogen.amd.rdna4.ins import (VOP1 as R4_VOP1, VOP1_SDST as R4_VOP1_SDST, VOP1_DPP16 as R4_VOP1_DPP16,
VOP1_LIT as R4_VOP1_LIT, VOP2 as R4_VOP2, VOP2_DPP16 as R4_VOP2_DPP16, VOP2_LIT as R4_VOP2_LIT, VOP3 as R4_VOP3,
VOP3_SDST as R4_VOP3_SDST, VOP3SD as R4_VOP3SD, VOP3P as R4_VOP3P, VOPC as R4_VOPC, VOPC_DPP16 as R4_VOPC_DPP16,
VOPD as R4_VOPD, VINTERP as R4_VINTERP, SOP1 as R4_SOP1, SOP1_LIT as R4_SOP1_LIT,
SOP2 as R4_SOP2, SOP2_LIT as R4_SOP2_LIT, SOPC as R4_SOPC, SOPC_LIT as R4_SOPC_LIT,
SOPK as R4_SOPK, SOPK_LIT as R4_SOPK_LIT, SOPP as R4_SOPP,
SMEM as R4_SMEM, DS as R4_DS, VFLAT as R4_FLAT, VGLOBAL as R4_GLOBAL, VSCRATCH as R4_SCRATCH)
@@ -50,10 +52,11 @@ def _load_formats() -> dict[str, list[type[Inst]]]:
# Order: base before _LIT (base matches regular ops, _LIT catches lit-only ops excluded from base)
_FORMATS = {
"rdna3": [VOPD, VOP3P, VINTERP, VOP3SD, VOP3_SDST, VOP3, DS, GLOBAL, SCRATCH, FLAT, SMEM,
SOP1, SOP1_LIT, SOP2, SOP2_LIT, SOPC, SOPK, SOPK_LIT, SOPP, VOPC, VOP1_SDST, VOP1, VOP1_LIT, VOP2, VOP2_LIT],
SOP1, SOP1_LIT, SOP2, SOP2_LIT, SOPC, SOPK, SOPK_LIT, SOPP, VOPC_DPP16, VOPC, VOP1_SDST, VOP1_DPP16, VOP1, VOP1_LIT,
VOP2_DPP16, VOP2, VOP2_LIT],
"rdna4": [R4_VOPD, R4_VOP3P, R4_VINTERP, R4_VOP3SD, R4_VOP3_SDST, R4_VOP3, R4_DS, R4_GLOBAL, R4_SCRATCH, R4_FLAT, R4_SMEM,
R4_SOP1, R4_SOP1_LIT, R4_SOPC, R4_SOPC_LIT, R4_SOPP, R4_SOPK, R4_SOPK_LIT, R4_VOPC, R4_VOP1_SDST, R4_VOP1, R4_VOP1_LIT,
R4_SOP2, R4_SOP2_LIT, R4_VOP2, R4_VOP2_LIT],
R4_SOP1, R4_SOP1_LIT, R4_SOPC, R4_SOPC_LIT, R4_SOPP, R4_SOPK, R4_SOPK_LIT, R4_VOPC_DPP16, R4_VOPC, R4_VOP1_SDST,
R4_VOP1_DPP16, R4_VOP1, R4_VOP1_LIT, R4_SOP2, R4_SOP2_LIT, R4_VOP2_DPP16, R4_VOP2, R4_VOP2_LIT],
"cdna": [C_VOP3PX2, C_VOP3P_MFMA, C_VOP3P, C_VOP3SD, C_VOP3_SDST, C_VOP3, C_DS, C_GLOBAL, C_SCRATCH, C_FLAT, C_MUBUF, C_SMEM,
C_SOP1, C_SOPC, C_SOPP, C_SOPK, C_SOPK_LIT, C_VOPC_SDWA_SDST, C_VOPC,
C_VOP1_DPP16, C_VOP1_SDWA, C_VOP1, C_VOP2_DPP16, C_VOP2_SDWA, C_SOP2, C_VOP2, C_VOP2_LIT],
+2 -2
View File
@@ -127,7 +127,7 @@ def __getattr__(nm):
return load("rocprof", "['rocprof-trace-decoder', p:='/usr/local/lib/rocprof-trace-decoder.so', p.replace('so','dylib')]",
[f"{{}}/include/{s}.h" for s in ["rocprof_trace_decoder", "trace_decoder_instrument", "trace_decoder_types"]],
srcs="https://github.com/ROCm/rocprof-trace-decoder/archive/dd0485100971522cc4cd8ae136bdda431061a04d.tar.gz")
case "mesa": return load("mesa", "([] if CPU_CC.value == 'LVP' or DEV.renderer == 'LVP' else ['tinymesa']) + ['tinymesa_cpu']", [
case "mesa": return load("mesa", "([] if DEV.renderer == 'LVP' else ['tinymesa']) + ['tinymesa_cpu']", [
*[f"{{}}/src/compiler/nir/{s}.h" for s in ["nir", "nir_builder", "nir_shader_compiler_options", "nir_serialize"]], "{}/gen/nir_intrinsics.h",
*[f"{{}}/src/nouveau/{s}.h" for s in ["headers/nv_device_info", "compiler/nak"]],
*[f"{{}}/src/gallium/auxiliary/gallivm/lp_bld{s}.h" for s in ["", "_passmgr", "_misc", "_type", "_init", "_nir", "_struct", "_jit_types",
@@ -146,7 +146,7 @@ def __getattr__(nm):
*[f"python3 src/compiler/{s}_h.py > gen/{s.split('/')[-1]}.h" for s in ["nir/nir_opcodes", "nir/nir_builder_opcodes"]],
*[f"python3 src/compiler/nir/nir_{s}_h.py --outdir gen" for s in ["intrinsics", "intrinsics_indices"]]]), cwd=path, shell=True, check=True),
srcs="https://gitlab.freedesktop.org/mesa/mesa/-/archive/mesa-25.2.7/mesa-25.2.7.tar.gz",
prolog=["from tinygrad.helpers import CPU_CC, DEV", "import gzip, base64"],
prolog=["from tinygrad.helpers import DEV", "import gzip, base64"],
epilog=lambda path: [system(f"{root}/extra/mesa/lvp_nir_options.sh {path}")])
case "libclang":
return load("libclang", clang_lib,
File diff suppressed because one or more lines are too long
+34 -131
View File
@@ -1,139 +1,42 @@
# mypy: disable-error-code="empty-body"
from __future__ import annotations
import ctypes
from typing import Annotated, Literal, TypeAlias
from typing import Literal, TypeAlias
from tinygrad.runtime.support.c import _IO, _IOW, _IOR, _IOWR
from tinygrad.runtime.support import c
class union_PM4_MES_TYPE_3_HEADER(c.Struct): SIZE = 0
class enum_mes_set_resources_queue_type_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
queue_type__mes_set_resources__kernel_interface_queue_kiq = enum_mes_set_resources_queue_type_enum.define('queue_type__mes_set_resources__kernel_interface_queue_kiq', 0)
queue_type__mes_set_resources__hsa_interface_queue_hiq = enum_mes_set_resources_queue_type_enum.define('queue_type__mes_set_resources__hsa_interface_queue_hiq', 1)
queue_type__mes_set_resources__hsa_debug_interface_queue = enum_mes_set_resources_queue_type_enum.define('queue_type__mes_set_resources__hsa_debug_interface_queue', 4)
class struct_pm4_mes_set_resources(c.Struct): SIZE = 0
class struct_pm4_mes_runlist(c.Struct): SIZE = 0
class struct_pm4_mes_map_process(c.Struct): SIZE = 0
class struct_PM4_MES_MAP_PROCESS_VM(c.Struct): SIZE = 0
class enum_mes_map_queues_queue_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
queue_sel__mes_map_queues__map_to_specified_queue_slots_vi = enum_mes_map_queues_queue_sel_enum.define('queue_sel__mes_map_queues__map_to_specified_queue_slots_vi', 0)
queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi = enum_mes_map_queues_queue_sel_enum.define('queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi', 1)
class enum_mes_map_queues_queue_type_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
queue_type__mes_map_queues__normal_compute_vi = enum_mes_map_queues_queue_type_enum.define('queue_type__mes_map_queues__normal_compute_vi', 0)
queue_type__mes_map_queues__debug_interface_queue_vi = enum_mes_map_queues_queue_type_enum.define('queue_type__mes_map_queues__debug_interface_queue_vi', 1)
queue_type__mes_map_queues__normal_latency_static_queue_vi = enum_mes_map_queues_queue_type_enum.define('queue_type__mes_map_queues__normal_latency_static_queue_vi', 2)
queue_type__mes_map_queues__low_latency_static_queue_vi = enum_mes_map_queues_queue_type_enum.define('queue_type__mes_map_queues__low_latency_static_queue_vi', 3)
class enum_mes_map_queues_engine_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
engine_sel__mes_map_queues__compute_vi = enum_mes_map_queues_engine_sel_enum.define('engine_sel__mes_map_queues__compute_vi', 0)
engine_sel__mes_map_queues__sdma0_vi = enum_mes_map_queues_engine_sel_enum.define('engine_sel__mes_map_queues__sdma0_vi', 2)
engine_sel__mes_map_queues__sdma1_vi = enum_mes_map_queues_engine_sel_enum.define('engine_sel__mes_map_queues__sdma1_vi', 3)
class enum_mes_map_queues_extended_engine_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
extended_engine_sel__mes_map_queues__legacy_engine_sel = enum_mes_map_queues_extended_engine_sel_enum.define('extended_engine_sel__mes_map_queues__legacy_engine_sel', 0)
extended_engine_sel__mes_map_queues__sdma0_to_7_sel = enum_mes_map_queues_extended_engine_sel_enum.define('extended_engine_sel__mes_map_queues__sdma0_to_7_sel', 1)
extended_engine_sel__mes_map_queues__sdma8_to_15_sel = enum_mes_map_queues_extended_engine_sel_enum.define('extended_engine_sel__mes_map_queues__sdma8_to_15_sel', 2)
class struct_pm4_mes_map_queues(c.Struct): SIZE = 0
class enum_mes_query_status_interrupt_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
interrupt_sel__mes_query_status__completion_status = enum_mes_query_status_interrupt_sel_enum.define('interrupt_sel__mes_query_status__completion_status', 0)
interrupt_sel__mes_query_status__process_status = enum_mes_query_status_interrupt_sel_enum.define('interrupt_sel__mes_query_status__process_status', 1)
interrupt_sel__mes_query_status__queue_status = enum_mes_query_status_interrupt_sel_enum.define('interrupt_sel__mes_query_status__queue_status', 2)
class enum_mes_query_status_command_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
command__mes_query_status__interrupt_only = enum_mes_query_status_command_enum.define('command__mes_query_status__interrupt_only', 0)
command__mes_query_status__fence_only_immediate = enum_mes_query_status_command_enum.define('command__mes_query_status__fence_only_immediate', 1)
command__mes_query_status__fence_only_after_write_ack = enum_mes_query_status_command_enum.define('command__mes_query_status__fence_only_after_write_ack', 2)
command__mes_query_status__fence_wait_for_write_ack_send_interrupt = enum_mes_query_status_command_enum.define('command__mes_query_status__fence_wait_for_write_ack_send_interrupt', 3)
class enum_mes_query_status_engine_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
engine_sel__mes_query_status__compute = enum_mes_query_status_engine_sel_enum.define('engine_sel__mes_query_status__compute', 0)
engine_sel__mes_query_status__sdma0_queue = enum_mes_query_status_engine_sel_enum.define('engine_sel__mes_query_status__sdma0_queue', 2)
engine_sel__mes_query_status__sdma1_queue = enum_mes_query_status_engine_sel_enum.define('engine_sel__mes_query_status__sdma1_queue', 3)
class struct_pm4_mes_query_status(c.Struct): SIZE = 0
class enum_mes_unmap_queues_action_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
action__mes_unmap_queues__preempt_queues = enum_mes_unmap_queues_action_enum.define('action__mes_unmap_queues__preempt_queues', 0)
action__mes_unmap_queues__reset_queues = enum_mes_unmap_queues_action_enum.define('action__mes_unmap_queues__reset_queues', 1)
action__mes_unmap_queues__disable_process_queues = enum_mes_unmap_queues_action_enum.define('action__mes_unmap_queues__disable_process_queues', 2)
action__mes_unmap_queues__reserved = enum_mes_unmap_queues_action_enum.define('action__mes_unmap_queues__reserved', 3)
class enum_mes_unmap_queues_queue_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
queue_sel__mes_unmap_queues__perform_request_on_specified_queues = enum_mes_unmap_queues_queue_sel_enum.define('queue_sel__mes_unmap_queues__perform_request_on_specified_queues', 0)
queue_sel__mes_unmap_queues__perform_request_on_pasid_queues = enum_mes_unmap_queues_queue_sel_enum.define('queue_sel__mes_unmap_queues__perform_request_on_pasid_queues', 1)
queue_sel__mes_unmap_queues__unmap_all_queues = enum_mes_unmap_queues_queue_sel_enum.define('queue_sel__mes_unmap_queues__unmap_all_queues', 2)
queue_sel__mes_unmap_queues__unmap_all_non_static_queues = enum_mes_unmap_queues_queue_sel_enum.define('queue_sel__mes_unmap_queues__unmap_all_non_static_queues', 3)
class enum_mes_unmap_queues_engine_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
engine_sel__mes_unmap_queues__compute = enum_mes_unmap_queues_engine_sel_enum.define('engine_sel__mes_unmap_queues__compute', 0)
engine_sel__mes_unmap_queues__sdma0 = enum_mes_unmap_queues_engine_sel_enum.define('engine_sel__mes_unmap_queues__sdma0', 2)
engine_sel__mes_unmap_queues__sdmal = enum_mes_unmap_queues_engine_sel_enum.define('engine_sel__mes_unmap_queues__sdmal', 3)
class enum_mes_unmap_queues_extended_engine_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
extended_engine_sel__mes_unmap_queues__legacy_engine_sel = enum_mes_unmap_queues_extended_engine_sel_enum.define('extended_engine_sel__mes_unmap_queues__legacy_engine_sel', 0)
extended_engine_sel__mes_unmap_queues__sdma0_to_7_sel = enum_mes_unmap_queues_extended_engine_sel_enum.define('extended_engine_sel__mes_unmap_queues__sdma0_to_7_sel', 1)
class struct_pm4_mes_unmap_queues(c.Struct): SIZE = 0
class enum_mec_release_mem_event_index_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
event_index__mec_release_mem__end_of_pipe = enum_mec_release_mem_event_index_enum.define('event_index__mec_release_mem__end_of_pipe', 5)
event_index__mec_release_mem__shader_done = enum_mec_release_mem_event_index_enum.define('event_index__mec_release_mem__shader_done', 6)
class enum_mec_release_mem_cache_policy_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
cache_policy__mec_release_mem__lru = enum_mec_release_mem_cache_policy_enum.define('cache_policy__mec_release_mem__lru', 0)
cache_policy__mec_release_mem__stream = enum_mec_release_mem_cache_policy_enum.define('cache_policy__mec_release_mem__stream', 1)
class enum_mec_release_mem_pq_exe_status_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
pq_exe_status__mec_release_mem__default = enum_mec_release_mem_pq_exe_status_enum.define('pq_exe_status__mec_release_mem__default', 0)
pq_exe_status__mec_release_mem__phase_update = enum_mec_release_mem_pq_exe_status_enum.define('pq_exe_status__mec_release_mem__phase_update', 1)
class enum_mec_release_mem_dst_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
dst_sel__mec_release_mem__memory_controller = enum_mec_release_mem_dst_sel_enum.define('dst_sel__mec_release_mem__memory_controller', 0)
dst_sel__mec_release_mem__tc_l2 = enum_mec_release_mem_dst_sel_enum.define('dst_sel__mec_release_mem__tc_l2', 1)
dst_sel__mec_release_mem__queue_write_pointer_register = enum_mec_release_mem_dst_sel_enum.define('dst_sel__mec_release_mem__queue_write_pointer_register', 2)
dst_sel__mec_release_mem__queue_write_pointer_poll_mask_bit = enum_mec_release_mem_dst_sel_enum.define('dst_sel__mec_release_mem__queue_write_pointer_poll_mask_bit', 3)
class enum_mec_release_mem_int_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
int_sel__mec_release_mem__none = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__none', 0)
int_sel__mec_release_mem__send_interrupt_only = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__send_interrupt_only', 1)
int_sel__mec_release_mem__send_interrupt_after_write_confirm = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__send_interrupt_after_write_confirm', 2)
int_sel__mec_release_mem__send_data_after_write_confirm = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__send_data_after_write_confirm', 3)
int_sel__mec_release_mem__unconditionally_send_int_ctxid = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__unconditionally_send_int_ctxid', 4)
int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_32_bit_compare = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_32_bit_compare', 5)
int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_64_bit_compare = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_64_bit_compare', 6)
class enum_mec_release_mem_data_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
data_sel__mec_release_mem__none = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__none', 0)
data_sel__mec_release_mem__send_32_bit_low = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__send_32_bit_low', 1)
data_sel__mec_release_mem__send_64_bit_data = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__send_64_bit_data', 2)
data_sel__mec_release_mem__send_gpu_clock_counter = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__send_gpu_clock_counter', 3)
data_sel__mec_release_mem__send_cp_perfcounter_hi_lo = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__send_cp_perfcounter_hi_lo', 4)
data_sel__mec_release_mem__store_gds_data_to_memory = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__store_gds_data_to_memory', 5)
class struct_pm4_mec_release_mem(c.Struct): SIZE = 0
class enum_WRITE_DATA_dst_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
dst_sel___write_data__mem_mapped_register = enum_WRITE_DATA_dst_sel_enum.define('dst_sel___write_data__mem_mapped_register', 0)
dst_sel___write_data__tc_l2 = enum_WRITE_DATA_dst_sel_enum.define('dst_sel___write_data__tc_l2', 2)
dst_sel___write_data__gds = enum_WRITE_DATA_dst_sel_enum.define('dst_sel___write_data__gds', 3)
dst_sel___write_data__memory = enum_WRITE_DATA_dst_sel_enum.define('dst_sel___write_data__memory', 5)
dst_sel___write_data__memory_mapped_adc_persistent_state = enum_WRITE_DATA_dst_sel_enum.define('dst_sel___write_data__memory_mapped_adc_persistent_state', 6)
class enum_WRITE_DATA_addr_incr_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
addr_incr___write_data__increment_address = enum_WRITE_DATA_addr_incr_enum.define('addr_incr___write_data__increment_address', 0)
addr_incr___write_data__do_not_increment_address = enum_WRITE_DATA_addr_incr_enum.define('addr_incr___write_data__do_not_increment_address', 1)
class enum_WRITE_DATA_wr_confirm_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
wr_confirm___write_data__do_not_wait_for_write_confirmation = enum_WRITE_DATA_wr_confirm_enum.define('wr_confirm___write_data__do_not_wait_for_write_confirmation', 0)
wr_confirm___write_data__wait_for_write_confirmation = enum_WRITE_DATA_wr_confirm_enum.define('wr_confirm___write_data__wait_for_write_confirmation', 1)
class enum_WRITE_DATA_cache_policy_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
cache_policy___write_data__lru = enum_WRITE_DATA_cache_policy_enum.define('cache_policy___write_data__lru', 0)
cache_policy___write_data__stream = enum_WRITE_DATA_cache_policy_enum.define('cache_policy___write_data__stream', 1)
class struct_pm4_mec_write_data_mmio(c.Struct): SIZE = 0
class _anonenum0(Annotated[int, ctypes.c_uint32], c.Enum): pass
CACHE_FLUSH_AND_INV_TS_EVENT = _anonenum0.define('CACHE_FLUSH_AND_INV_TS_EVENT', 20)
c.init_records()
class union_PM4_MES_TYPE_3_HEADER(c.Struct): pass
enum_mes_set_resources_queue_type_enum: dict[int, str] = {(queue_type__mes_set_resources__kernel_interface_queue_kiq:=0): 'queue_type__mes_set_resources__kernel_interface_queue_kiq', (queue_type__mes_set_resources__hsa_interface_queue_hiq:=1): 'queue_type__mes_set_resources__hsa_interface_queue_hiq', (queue_type__mes_set_resources__hsa_debug_interface_queue:=4): 'queue_type__mes_set_resources__hsa_debug_interface_queue'}
class struct_pm4_mes_set_resources(c.Struct): pass
class struct_pm4_mes_runlist(c.Struct): pass
class struct_pm4_mes_map_process(c.Struct): pass
class struct_PM4_MES_MAP_PROCESS_VM(c.Struct): pass
enum_mes_map_queues_queue_sel_enum: dict[int, str] = {(queue_sel__mes_map_queues__map_to_specified_queue_slots_vi:=0): 'queue_sel__mes_map_queues__map_to_specified_queue_slots_vi', (queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi:=1): 'queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi'}
enum_mes_map_queues_queue_type_enum: dict[int, str] = {(queue_type__mes_map_queues__normal_compute_vi:=0): 'queue_type__mes_map_queues__normal_compute_vi', (queue_type__mes_map_queues__debug_interface_queue_vi:=1): 'queue_type__mes_map_queues__debug_interface_queue_vi', (queue_type__mes_map_queues__normal_latency_static_queue_vi:=2): 'queue_type__mes_map_queues__normal_latency_static_queue_vi', (queue_type__mes_map_queues__low_latency_static_queue_vi:=3): 'queue_type__mes_map_queues__low_latency_static_queue_vi'}
enum_mes_map_queues_engine_sel_enum: dict[int, str] = {(engine_sel__mes_map_queues__compute_vi:=0): 'engine_sel__mes_map_queues__compute_vi', (engine_sel__mes_map_queues__sdma0_vi:=2): 'engine_sel__mes_map_queues__sdma0_vi', (engine_sel__mes_map_queues__sdma1_vi:=3): 'engine_sel__mes_map_queues__sdma1_vi'}
enum_mes_map_queues_extended_engine_sel_enum: dict[int, str] = {(extended_engine_sel__mes_map_queues__legacy_engine_sel:=0): 'extended_engine_sel__mes_map_queues__legacy_engine_sel', (extended_engine_sel__mes_map_queues__sdma0_to_7_sel:=1): 'extended_engine_sel__mes_map_queues__sdma0_to_7_sel', (extended_engine_sel__mes_map_queues__sdma8_to_15_sel:=2): 'extended_engine_sel__mes_map_queues__sdma8_to_15_sel'}
class struct_pm4_mes_map_queues(c.Struct): pass
enum_mes_query_status_interrupt_sel_enum: dict[int, str] = {(interrupt_sel__mes_query_status__completion_status:=0): 'interrupt_sel__mes_query_status__completion_status', (interrupt_sel__mes_query_status__process_status:=1): 'interrupt_sel__mes_query_status__process_status', (interrupt_sel__mes_query_status__queue_status:=2): 'interrupt_sel__mes_query_status__queue_status'}
enum_mes_query_status_command_enum: dict[int, str] = {(command__mes_query_status__interrupt_only:=0): 'command__mes_query_status__interrupt_only', (command__mes_query_status__fence_only_immediate:=1): 'command__mes_query_status__fence_only_immediate', (command__mes_query_status__fence_only_after_write_ack:=2): 'command__mes_query_status__fence_only_after_write_ack', (command__mes_query_status__fence_wait_for_write_ack_send_interrupt:=3): 'command__mes_query_status__fence_wait_for_write_ack_send_interrupt'}
enum_mes_query_status_engine_sel_enum: dict[int, str] = {(engine_sel__mes_query_status__compute:=0): 'engine_sel__mes_query_status__compute', (engine_sel__mes_query_status__sdma0_queue:=2): 'engine_sel__mes_query_status__sdma0_queue', (engine_sel__mes_query_status__sdma1_queue:=3): 'engine_sel__mes_query_status__sdma1_queue'}
class struct_pm4_mes_query_status(c.Struct): pass
enum_mes_unmap_queues_action_enum: dict[int, str] = {(action__mes_unmap_queues__preempt_queues:=0): 'action__mes_unmap_queues__preempt_queues', (action__mes_unmap_queues__reset_queues:=1): 'action__mes_unmap_queues__reset_queues', (action__mes_unmap_queues__disable_process_queues:=2): 'action__mes_unmap_queues__disable_process_queues', (action__mes_unmap_queues__reserved:=3): 'action__mes_unmap_queues__reserved'}
enum_mes_unmap_queues_queue_sel_enum: dict[int, str] = {(queue_sel__mes_unmap_queues__perform_request_on_specified_queues:=0): 'queue_sel__mes_unmap_queues__perform_request_on_specified_queues', (queue_sel__mes_unmap_queues__perform_request_on_pasid_queues:=1): 'queue_sel__mes_unmap_queues__perform_request_on_pasid_queues', (queue_sel__mes_unmap_queues__unmap_all_queues:=2): 'queue_sel__mes_unmap_queues__unmap_all_queues', (queue_sel__mes_unmap_queues__unmap_all_non_static_queues:=3): 'queue_sel__mes_unmap_queues__unmap_all_non_static_queues'}
enum_mes_unmap_queues_engine_sel_enum: dict[int, str] = {(engine_sel__mes_unmap_queues__compute:=0): 'engine_sel__mes_unmap_queues__compute', (engine_sel__mes_unmap_queues__sdma0:=2): 'engine_sel__mes_unmap_queues__sdma0', (engine_sel__mes_unmap_queues__sdmal:=3): 'engine_sel__mes_unmap_queues__sdmal'}
enum_mes_unmap_queues_extended_engine_sel_enum: dict[int, str] = {(extended_engine_sel__mes_unmap_queues__legacy_engine_sel:=0): 'extended_engine_sel__mes_unmap_queues__legacy_engine_sel', (extended_engine_sel__mes_unmap_queues__sdma0_to_7_sel:=1): 'extended_engine_sel__mes_unmap_queues__sdma0_to_7_sel'}
class struct_pm4_mes_unmap_queues(c.Struct): pass
enum_mec_release_mem_event_index_enum: dict[int, str] = {(event_index__mec_release_mem__end_of_pipe:=5): 'event_index__mec_release_mem__end_of_pipe', (event_index__mec_release_mem__shader_done:=6): 'event_index__mec_release_mem__shader_done'}
enum_mec_release_mem_cache_policy_enum: dict[int, str] = {(cache_policy__mec_release_mem__lru:=0): 'cache_policy__mec_release_mem__lru', (cache_policy__mec_release_mem__stream:=1): 'cache_policy__mec_release_mem__stream'}
enum_mec_release_mem_pq_exe_status_enum: dict[int, str] = {(pq_exe_status__mec_release_mem__default:=0): 'pq_exe_status__mec_release_mem__default', (pq_exe_status__mec_release_mem__phase_update:=1): 'pq_exe_status__mec_release_mem__phase_update'}
enum_mec_release_mem_dst_sel_enum: dict[int, str] = {(dst_sel__mec_release_mem__memory_controller:=0): 'dst_sel__mec_release_mem__memory_controller', (dst_sel__mec_release_mem__tc_l2:=1): 'dst_sel__mec_release_mem__tc_l2', (dst_sel__mec_release_mem__queue_write_pointer_register:=2): 'dst_sel__mec_release_mem__queue_write_pointer_register', (dst_sel__mec_release_mem__queue_write_pointer_poll_mask_bit:=3): 'dst_sel__mec_release_mem__queue_write_pointer_poll_mask_bit'}
enum_mec_release_mem_int_sel_enum: dict[int, str] = {(int_sel__mec_release_mem__none:=0): 'int_sel__mec_release_mem__none', (int_sel__mec_release_mem__send_interrupt_only:=1): 'int_sel__mec_release_mem__send_interrupt_only', (int_sel__mec_release_mem__send_interrupt_after_write_confirm:=2): 'int_sel__mec_release_mem__send_interrupt_after_write_confirm', (int_sel__mec_release_mem__send_data_after_write_confirm:=3): 'int_sel__mec_release_mem__send_data_after_write_confirm', (int_sel__mec_release_mem__unconditionally_send_int_ctxid:=4): 'int_sel__mec_release_mem__unconditionally_send_int_ctxid', (int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_32_bit_compare:=5): 'int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_32_bit_compare', (int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_64_bit_compare:=6): 'int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_64_bit_compare'}
enum_mec_release_mem_data_sel_enum: dict[int, str] = {(data_sel__mec_release_mem__none:=0): 'data_sel__mec_release_mem__none', (data_sel__mec_release_mem__send_32_bit_low:=1): 'data_sel__mec_release_mem__send_32_bit_low', (data_sel__mec_release_mem__send_64_bit_data:=2): 'data_sel__mec_release_mem__send_64_bit_data', (data_sel__mec_release_mem__send_gpu_clock_counter:=3): 'data_sel__mec_release_mem__send_gpu_clock_counter', (data_sel__mec_release_mem__send_cp_perfcounter_hi_lo:=4): 'data_sel__mec_release_mem__send_cp_perfcounter_hi_lo', (data_sel__mec_release_mem__store_gds_data_to_memory:=5): 'data_sel__mec_release_mem__store_gds_data_to_memory'}
class struct_pm4_mec_release_mem(c.Struct): pass
enum_WRITE_DATA_dst_sel_enum: dict[int, str] = {(dst_sel___write_data__mem_mapped_register:=0): 'dst_sel___write_data__mem_mapped_register', (dst_sel___write_data__tc_l2:=2): 'dst_sel___write_data__tc_l2', (dst_sel___write_data__gds:=3): 'dst_sel___write_data__gds', (dst_sel___write_data__memory:=5): 'dst_sel___write_data__memory', (dst_sel___write_data__memory_mapped_adc_persistent_state:=6): 'dst_sel___write_data__memory_mapped_adc_persistent_state'}
enum_WRITE_DATA_addr_incr_enum: dict[int, str] = {(addr_incr___write_data__increment_address:=0): 'addr_incr___write_data__increment_address', (addr_incr___write_data__do_not_increment_address:=1): 'addr_incr___write_data__do_not_increment_address'}
enum_WRITE_DATA_wr_confirm_enum: dict[int, str] = {(wr_confirm___write_data__do_not_wait_for_write_confirmation:=0): 'wr_confirm___write_data__do_not_wait_for_write_confirmation', (wr_confirm___write_data__wait_for_write_confirmation:=1): 'wr_confirm___write_data__wait_for_write_confirmation'}
enum_WRITE_DATA_cache_policy_enum: dict[int, str] = {(cache_policy___write_data__lru:=0): 'cache_policy___write_data__lru', (cache_policy___write_data__stream:=1): 'cache_policy___write_data__stream'}
class struct_pm4_mec_write_data_mmio(c.Struct): pass
_anonenum0: dict[int, str] = {(CACHE_FLUSH_AND_INV_TS_EVENT:=20): 'CACHE_FLUSH_AND_INV_TS_EVENT'}
PACKET_TYPE0 = 0 # type: ignore
PACKET_TYPE1 = 1 # type: ignore
PACKET_TYPE2 = 2 # type: ignore
+34 -131
View File
@@ -1,139 +1,42 @@
# mypy: disable-error-code="empty-body"
from __future__ import annotations
import ctypes
from typing import Annotated, Literal, TypeAlias
from typing import Literal, TypeAlias
from tinygrad.runtime.support.c import _IO, _IOW, _IOR, _IOWR
from tinygrad.runtime.support import c
class union_PM4_MES_TYPE_3_HEADER(c.Struct): SIZE = 0
class enum_mes_set_resources_queue_type_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
queue_type__mes_set_resources__kernel_interface_queue_kiq = enum_mes_set_resources_queue_type_enum.define('queue_type__mes_set_resources__kernel_interface_queue_kiq', 0)
queue_type__mes_set_resources__hsa_interface_queue_hiq = enum_mes_set_resources_queue_type_enum.define('queue_type__mes_set_resources__hsa_interface_queue_hiq', 1)
queue_type__mes_set_resources__hsa_debug_interface_queue = enum_mes_set_resources_queue_type_enum.define('queue_type__mes_set_resources__hsa_debug_interface_queue', 4)
class struct_pm4_mes_set_resources(c.Struct): SIZE = 0
class struct_pm4_mes_runlist(c.Struct): SIZE = 0
class struct_pm4_mes_map_process(c.Struct): SIZE = 0
class struct_PM4_MES_MAP_PROCESS_VM(c.Struct): SIZE = 0
class enum_mes_map_queues_queue_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
queue_sel__mes_map_queues__map_to_specified_queue_slots_vi = enum_mes_map_queues_queue_sel_enum.define('queue_sel__mes_map_queues__map_to_specified_queue_slots_vi', 0)
queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi = enum_mes_map_queues_queue_sel_enum.define('queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi', 1)
class enum_mes_map_queues_queue_type_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
queue_type__mes_map_queues__normal_compute_vi = enum_mes_map_queues_queue_type_enum.define('queue_type__mes_map_queues__normal_compute_vi', 0)
queue_type__mes_map_queues__debug_interface_queue_vi = enum_mes_map_queues_queue_type_enum.define('queue_type__mes_map_queues__debug_interface_queue_vi', 1)
queue_type__mes_map_queues__normal_latency_static_queue_vi = enum_mes_map_queues_queue_type_enum.define('queue_type__mes_map_queues__normal_latency_static_queue_vi', 2)
queue_type__mes_map_queues__low_latency_static_queue_vi = enum_mes_map_queues_queue_type_enum.define('queue_type__mes_map_queues__low_latency_static_queue_vi', 3)
class enum_mes_map_queues_engine_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
engine_sel__mes_map_queues__compute_vi = enum_mes_map_queues_engine_sel_enum.define('engine_sel__mes_map_queues__compute_vi', 0)
engine_sel__mes_map_queues__sdma0_vi = enum_mes_map_queues_engine_sel_enum.define('engine_sel__mes_map_queues__sdma0_vi', 2)
engine_sel__mes_map_queues__sdma1_vi = enum_mes_map_queues_engine_sel_enum.define('engine_sel__mes_map_queues__sdma1_vi', 3)
class enum_mes_map_queues_extended_engine_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
extended_engine_sel__mes_map_queues__legacy_engine_sel = enum_mes_map_queues_extended_engine_sel_enum.define('extended_engine_sel__mes_map_queues__legacy_engine_sel', 0)
extended_engine_sel__mes_map_queues__sdma0_to_7_sel = enum_mes_map_queues_extended_engine_sel_enum.define('extended_engine_sel__mes_map_queues__sdma0_to_7_sel', 1)
extended_engine_sel__mes_map_queues__sdma8_to_15_sel = enum_mes_map_queues_extended_engine_sel_enum.define('extended_engine_sel__mes_map_queues__sdma8_to_15_sel', 2)
class struct_pm4_mes_map_queues(c.Struct): SIZE = 0
class enum_mes_query_status_interrupt_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
interrupt_sel__mes_query_status__completion_status = enum_mes_query_status_interrupt_sel_enum.define('interrupt_sel__mes_query_status__completion_status', 0)
interrupt_sel__mes_query_status__process_status = enum_mes_query_status_interrupt_sel_enum.define('interrupt_sel__mes_query_status__process_status', 1)
interrupt_sel__mes_query_status__queue_status = enum_mes_query_status_interrupt_sel_enum.define('interrupt_sel__mes_query_status__queue_status', 2)
class enum_mes_query_status_command_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
command__mes_query_status__interrupt_only = enum_mes_query_status_command_enum.define('command__mes_query_status__interrupt_only', 0)
command__mes_query_status__fence_only_immediate = enum_mes_query_status_command_enum.define('command__mes_query_status__fence_only_immediate', 1)
command__mes_query_status__fence_only_after_write_ack = enum_mes_query_status_command_enum.define('command__mes_query_status__fence_only_after_write_ack', 2)
command__mes_query_status__fence_wait_for_write_ack_send_interrupt = enum_mes_query_status_command_enum.define('command__mes_query_status__fence_wait_for_write_ack_send_interrupt', 3)
class enum_mes_query_status_engine_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
engine_sel__mes_query_status__compute = enum_mes_query_status_engine_sel_enum.define('engine_sel__mes_query_status__compute', 0)
engine_sel__mes_query_status__sdma0_queue = enum_mes_query_status_engine_sel_enum.define('engine_sel__mes_query_status__sdma0_queue', 2)
engine_sel__mes_query_status__sdma1_queue = enum_mes_query_status_engine_sel_enum.define('engine_sel__mes_query_status__sdma1_queue', 3)
class struct_pm4_mes_query_status(c.Struct): SIZE = 0
class enum_mes_unmap_queues_action_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
action__mes_unmap_queues__preempt_queues = enum_mes_unmap_queues_action_enum.define('action__mes_unmap_queues__preempt_queues', 0)
action__mes_unmap_queues__reset_queues = enum_mes_unmap_queues_action_enum.define('action__mes_unmap_queues__reset_queues', 1)
action__mes_unmap_queues__disable_process_queues = enum_mes_unmap_queues_action_enum.define('action__mes_unmap_queues__disable_process_queues', 2)
action__mes_unmap_queues__reserved = enum_mes_unmap_queues_action_enum.define('action__mes_unmap_queues__reserved', 3)
class enum_mes_unmap_queues_queue_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
queue_sel__mes_unmap_queues__perform_request_on_specified_queues = enum_mes_unmap_queues_queue_sel_enum.define('queue_sel__mes_unmap_queues__perform_request_on_specified_queues', 0)
queue_sel__mes_unmap_queues__perform_request_on_pasid_queues = enum_mes_unmap_queues_queue_sel_enum.define('queue_sel__mes_unmap_queues__perform_request_on_pasid_queues', 1)
queue_sel__mes_unmap_queues__unmap_all_queues = enum_mes_unmap_queues_queue_sel_enum.define('queue_sel__mes_unmap_queues__unmap_all_queues', 2)
queue_sel__mes_unmap_queues__unmap_all_non_static_queues = enum_mes_unmap_queues_queue_sel_enum.define('queue_sel__mes_unmap_queues__unmap_all_non_static_queues', 3)
class enum_mes_unmap_queues_engine_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
engine_sel__mes_unmap_queues__compute = enum_mes_unmap_queues_engine_sel_enum.define('engine_sel__mes_unmap_queues__compute', 0)
engine_sel__mes_unmap_queues__sdma0 = enum_mes_unmap_queues_engine_sel_enum.define('engine_sel__mes_unmap_queues__sdma0', 2)
engine_sel__mes_unmap_queues__sdmal = enum_mes_unmap_queues_engine_sel_enum.define('engine_sel__mes_unmap_queues__sdmal', 3)
class enum_mes_unmap_queues_extended_engine_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
extended_engine_sel__mes_unmap_queues__legacy_engine_sel = enum_mes_unmap_queues_extended_engine_sel_enum.define('extended_engine_sel__mes_unmap_queues__legacy_engine_sel', 0)
extended_engine_sel__mes_unmap_queues__sdma0_to_7_sel = enum_mes_unmap_queues_extended_engine_sel_enum.define('extended_engine_sel__mes_unmap_queues__sdma0_to_7_sel', 1)
class struct_pm4_mes_unmap_queues(c.Struct): SIZE = 0
class enum_mec_release_mem_event_index_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
event_index__mec_release_mem__end_of_pipe = enum_mec_release_mem_event_index_enum.define('event_index__mec_release_mem__end_of_pipe', 5)
event_index__mec_release_mem__shader_done = enum_mec_release_mem_event_index_enum.define('event_index__mec_release_mem__shader_done', 6)
class enum_mec_release_mem_cache_policy_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
cache_policy__mec_release_mem__lru = enum_mec_release_mem_cache_policy_enum.define('cache_policy__mec_release_mem__lru', 0)
cache_policy__mec_release_mem__stream = enum_mec_release_mem_cache_policy_enum.define('cache_policy__mec_release_mem__stream', 1)
class enum_mec_release_mem_pq_exe_status_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
pq_exe_status__mec_release_mem__default = enum_mec_release_mem_pq_exe_status_enum.define('pq_exe_status__mec_release_mem__default', 0)
pq_exe_status__mec_release_mem__phase_update = enum_mec_release_mem_pq_exe_status_enum.define('pq_exe_status__mec_release_mem__phase_update', 1)
class enum_mec_release_mem_dst_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
dst_sel__mec_release_mem__memory_controller = enum_mec_release_mem_dst_sel_enum.define('dst_sel__mec_release_mem__memory_controller', 0)
dst_sel__mec_release_mem__tc_l2 = enum_mec_release_mem_dst_sel_enum.define('dst_sel__mec_release_mem__tc_l2', 1)
dst_sel__mec_release_mem__queue_write_pointer_register = enum_mec_release_mem_dst_sel_enum.define('dst_sel__mec_release_mem__queue_write_pointer_register', 2)
dst_sel__mec_release_mem__queue_write_pointer_poll_mask_bit = enum_mec_release_mem_dst_sel_enum.define('dst_sel__mec_release_mem__queue_write_pointer_poll_mask_bit', 3)
class enum_mec_release_mem_int_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
int_sel__mec_release_mem__none = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__none', 0)
int_sel__mec_release_mem__send_interrupt_only = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__send_interrupt_only', 1)
int_sel__mec_release_mem__send_interrupt_after_write_confirm = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__send_interrupt_after_write_confirm', 2)
int_sel__mec_release_mem__send_data_after_write_confirm = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__send_data_after_write_confirm', 3)
int_sel__mec_release_mem__unconditionally_send_int_ctxid = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__unconditionally_send_int_ctxid', 4)
int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_32_bit_compare = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_32_bit_compare', 5)
int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_64_bit_compare = enum_mec_release_mem_int_sel_enum.define('int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_64_bit_compare', 6)
class enum_mec_release_mem_data_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
data_sel__mec_release_mem__none = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__none', 0)
data_sel__mec_release_mem__send_32_bit_low = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__send_32_bit_low', 1)
data_sel__mec_release_mem__send_64_bit_data = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__send_64_bit_data', 2)
data_sel__mec_release_mem__send_gpu_clock_counter = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__send_gpu_clock_counter', 3)
data_sel__mec_release_mem__send_cp_perfcounter_hi_lo = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__send_cp_perfcounter_hi_lo', 4)
data_sel__mec_release_mem__store_gds_data_to_memory = enum_mec_release_mem_data_sel_enum.define('data_sel__mec_release_mem__store_gds_data_to_memory', 5)
class struct_pm4_mec_release_mem(c.Struct): SIZE = 0
class enum_WRITE_DATA_dst_sel_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
dst_sel___write_data__mem_mapped_register = enum_WRITE_DATA_dst_sel_enum.define('dst_sel___write_data__mem_mapped_register', 0)
dst_sel___write_data__tc_l2 = enum_WRITE_DATA_dst_sel_enum.define('dst_sel___write_data__tc_l2', 2)
dst_sel___write_data__gds = enum_WRITE_DATA_dst_sel_enum.define('dst_sel___write_data__gds', 3)
dst_sel___write_data__memory = enum_WRITE_DATA_dst_sel_enum.define('dst_sel___write_data__memory', 5)
dst_sel___write_data__memory_mapped_adc_persistent_state = enum_WRITE_DATA_dst_sel_enum.define('dst_sel___write_data__memory_mapped_adc_persistent_state', 6)
class enum_WRITE_DATA_addr_incr_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
addr_incr___write_data__increment_address = enum_WRITE_DATA_addr_incr_enum.define('addr_incr___write_data__increment_address', 0)
addr_incr___write_data__do_not_increment_address = enum_WRITE_DATA_addr_incr_enum.define('addr_incr___write_data__do_not_increment_address', 1)
class enum_WRITE_DATA_wr_confirm_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
wr_confirm___write_data__do_not_wait_for_write_confirmation = enum_WRITE_DATA_wr_confirm_enum.define('wr_confirm___write_data__do_not_wait_for_write_confirmation', 0)
wr_confirm___write_data__wait_for_write_confirmation = enum_WRITE_DATA_wr_confirm_enum.define('wr_confirm___write_data__wait_for_write_confirmation', 1)
class enum_WRITE_DATA_cache_policy_enum(Annotated[int, ctypes.c_uint32], c.Enum): pass
cache_policy___write_data__lru = enum_WRITE_DATA_cache_policy_enum.define('cache_policy___write_data__lru', 0)
cache_policy___write_data__stream = enum_WRITE_DATA_cache_policy_enum.define('cache_policy___write_data__stream', 1)
class struct_pm4_mec_write_data_mmio(c.Struct): SIZE = 0
class _anonenum0(Annotated[int, ctypes.c_uint32], c.Enum): pass
CACHE_FLUSH_AND_INV_TS_EVENT = _anonenum0.define('CACHE_FLUSH_AND_INV_TS_EVENT', 20)
c.init_records()
class union_PM4_MES_TYPE_3_HEADER(c.Struct): pass
enum_mes_set_resources_queue_type_enum: dict[int, str] = {(queue_type__mes_set_resources__kernel_interface_queue_kiq:=0): 'queue_type__mes_set_resources__kernel_interface_queue_kiq', (queue_type__mes_set_resources__hsa_interface_queue_hiq:=1): 'queue_type__mes_set_resources__hsa_interface_queue_hiq', (queue_type__mes_set_resources__hsa_debug_interface_queue:=4): 'queue_type__mes_set_resources__hsa_debug_interface_queue'}
class struct_pm4_mes_set_resources(c.Struct): pass
class struct_pm4_mes_runlist(c.Struct): pass
class struct_pm4_mes_map_process(c.Struct): pass
class struct_PM4_MES_MAP_PROCESS_VM(c.Struct): pass
enum_mes_map_queues_queue_sel_enum: dict[int, str] = {(queue_sel__mes_map_queues__map_to_specified_queue_slots_vi:=0): 'queue_sel__mes_map_queues__map_to_specified_queue_slots_vi', (queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi:=1): 'queue_sel__mes_map_queues__map_to_hws_determined_queue_slots_vi'}
enum_mes_map_queues_queue_type_enum: dict[int, str] = {(queue_type__mes_map_queues__normal_compute_vi:=0): 'queue_type__mes_map_queues__normal_compute_vi', (queue_type__mes_map_queues__debug_interface_queue_vi:=1): 'queue_type__mes_map_queues__debug_interface_queue_vi', (queue_type__mes_map_queues__normal_latency_static_queue_vi:=2): 'queue_type__mes_map_queues__normal_latency_static_queue_vi', (queue_type__mes_map_queues__low_latency_static_queue_vi:=3): 'queue_type__mes_map_queues__low_latency_static_queue_vi'}
enum_mes_map_queues_engine_sel_enum: dict[int, str] = {(engine_sel__mes_map_queues__compute_vi:=0): 'engine_sel__mes_map_queues__compute_vi', (engine_sel__mes_map_queues__sdma0_vi:=2): 'engine_sel__mes_map_queues__sdma0_vi', (engine_sel__mes_map_queues__sdma1_vi:=3): 'engine_sel__mes_map_queues__sdma1_vi'}
enum_mes_map_queues_extended_engine_sel_enum: dict[int, str] = {(extended_engine_sel__mes_map_queues__legacy_engine_sel:=0): 'extended_engine_sel__mes_map_queues__legacy_engine_sel', (extended_engine_sel__mes_map_queues__sdma0_to_7_sel:=1): 'extended_engine_sel__mes_map_queues__sdma0_to_7_sel', (extended_engine_sel__mes_map_queues__sdma8_to_15_sel:=2): 'extended_engine_sel__mes_map_queues__sdma8_to_15_sel'}
class struct_pm4_mes_map_queues(c.Struct): pass
enum_mes_query_status_interrupt_sel_enum: dict[int, str] = {(interrupt_sel__mes_query_status__completion_status:=0): 'interrupt_sel__mes_query_status__completion_status', (interrupt_sel__mes_query_status__process_status:=1): 'interrupt_sel__mes_query_status__process_status', (interrupt_sel__mes_query_status__queue_status:=2): 'interrupt_sel__mes_query_status__queue_status'}
enum_mes_query_status_command_enum: dict[int, str] = {(command__mes_query_status__interrupt_only:=0): 'command__mes_query_status__interrupt_only', (command__mes_query_status__fence_only_immediate:=1): 'command__mes_query_status__fence_only_immediate', (command__mes_query_status__fence_only_after_write_ack:=2): 'command__mes_query_status__fence_only_after_write_ack', (command__mes_query_status__fence_wait_for_write_ack_send_interrupt:=3): 'command__mes_query_status__fence_wait_for_write_ack_send_interrupt'}
enum_mes_query_status_engine_sel_enum: dict[int, str] = {(engine_sel__mes_query_status__compute:=0): 'engine_sel__mes_query_status__compute', (engine_sel__mes_query_status__sdma0_queue:=2): 'engine_sel__mes_query_status__sdma0_queue', (engine_sel__mes_query_status__sdma1_queue:=3): 'engine_sel__mes_query_status__sdma1_queue'}
class struct_pm4_mes_query_status(c.Struct): pass
enum_mes_unmap_queues_action_enum: dict[int, str] = {(action__mes_unmap_queues__preempt_queues:=0): 'action__mes_unmap_queues__preempt_queues', (action__mes_unmap_queues__reset_queues:=1): 'action__mes_unmap_queues__reset_queues', (action__mes_unmap_queues__disable_process_queues:=2): 'action__mes_unmap_queues__disable_process_queues', (action__mes_unmap_queues__reserved:=3): 'action__mes_unmap_queues__reserved'}
enum_mes_unmap_queues_queue_sel_enum: dict[int, str] = {(queue_sel__mes_unmap_queues__perform_request_on_specified_queues:=0): 'queue_sel__mes_unmap_queues__perform_request_on_specified_queues', (queue_sel__mes_unmap_queues__perform_request_on_pasid_queues:=1): 'queue_sel__mes_unmap_queues__perform_request_on_pasid_queues', (queue_sel__mes_unmap_queues__unmap_all_queues:=2): 'queue_sel__mes_unmap_queues__unmap_all_queues', (queue_sel__mes_unmap_queues__unmap_all_non_static_queues:=3): 'queue_sel__mes_unmap_queues__unmap_all_non_static_queues'}
enum_mes_unmap_queues_engine_sel_enum: dict[int, str] = {(engine_sel__mes_unmap_queues__compute:=0): 'engine_sel__mes_unmap_queues__compute', (engine_sel__mes_unmap_queues__sdma0:=2): 'engine_sel__mes_unmap_queues__sdma0', (engine_sel__mes_unmap_queues__sdmal:=3): 'engine_sel__mes_unmap_queues__sdmal'}
enum_mes_unmap_queues_extended_engine_sel_enum: dict[int, str] = {(extended_engine_sel__mes_unmap_queues__legacy_engine_sel:=0): 'extended_engine_sel__mes_unmap_queues__legacy_engine_sel', (extended_engine_sel__mes_unmap_queues__sdma0_to_7_sel:=1): 'extended_engine_sel__mes_unmap_queues__sdma0_to_7_sel'}
class struct_pm4_mes_unmap_queues(c.Struct): pass
enum_mec_release_mem_event_index_enum: dict[int, str] = {(event_index__mec_release_mem__end_of_pipe:=5): 'event_index__mec_release_mem__end_of_pipe', (event_index__mec_release_mem__shader_done:=6): 'event_index__mec_release_mem__shader_done'}
enum_mec_release_mem_cache_policy_enum: dict[int, str] = {(cache_policy__mec_release_mem__lru:=0): 'cache_policy__mec_release_mem__lru', (cache_policy__mec_release_mem__stream:=1): 'cache_policy__mec_release_mem__stream'}
enum_mec_release_mem_pq_exe_status_enum: dict[int, str] = {(pq_exe_status__mec_release_mem__default:=0): 'pq_exe_status__mec_release_mem__default', (pq_exe_status__mec_release_mem__phase_update:=1): 'pq_exe_status__mec_release_mem__phase_update'}
enum_mec_release_mem_dst_sel_enum: dict[int, str] = {(dst_sel__mec_release_mem__memory_controller:=0): 'dst_sel__mec_release_mem__memory_controller', (dst_sel__mec_release_mem__tc_l2:=1): 'dst_sel__mec_release_mem__tc_l2', (dst_sel__mec_release_mem__queue_write_pointer_register:=2): 'dst_sel__mec_release_mem__queue_write_pointer_register', (dst_sel__mec_release_mem__queue_write_pointer_poll_mask_bit:=3): 'dst_sel__mec_release_mem__queue_write_pointer_poll_mask_bit'}
enum_mec_release_mem_int_sel_enum: dict[int, str] = {(int_sel__mec_release_mem__none:=0): 'int_sel__mec_release_mem__none', (int_sel__mec_release_mem__send_interrupt_only:=1): 'int_sel__mec_release_mem__send_interrupt_only', (int_sel__mec_release_mem__send_interrupt_after_write_confirm:=2): 'int_sel__mec_release_mem__send_interrupt_after_write_confirm', (int_sel__mec_release_mem__send_data_after_write_confirm:=3): 'int_sel__mec_release_mem__send_data_after_write_confirm', (int_sel__mec_release_mem__unconditionally_send_int_ctxid:=4): 'int_sel__mec_release_mem__unconditionally_send_int_ctxid', (int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_32_bit_compare:=5): 'int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_32_bit_compare', (int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_64_bit_compare:=6): 'int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_64_bit_compare'}
enum_mec_release_mem_data_sel_enum: dict[int, str] = {(data_sel__mec_release_mem__none:=0): 'data_sel__mec_release_mem__none', (data_sel__mec_release_mem__send_32_bit_low:=1): 'data_sel__mec_release_mem__send_32_bit_low', (data_sel__mec_release_mem__send_64_bit_data:=2): 'data_sel__mec_release_mem__send_64_bit_data', (data_sel__mec_release_mem__send_gpu_clock_counter:=3): 'data_sel__mec_release_mem__send_gpu_clock_counter', (data_sel__mec_release_mem__send_cp_perfcounter_hi_lo:=4): 'data_sel__mec_release_mem__send_cp_perfcounter_hi_lo', (data_sel__mec_release_mem__store_gds_data_to_memory:=5): 'data_sel__mec_release_mem__store_gds_data_to_memory'}
class struct_pm4_mec_release_mem(c.Struct): pass
enum_WRITE_DATA_dst_sel_enum: dict[int, str] = {(dst_sel___write_data__mem_mapped_register:=0): 'dst_sel___write_data__mem_mapped_register', (dst_sel___write_data__tc_l2:=2): 'dst_sel___write_data__tc_l2', (dst_sel___write_data__gds:=3): 'dst_sel___write_data__gds', (dst_sel___write_data__memory:=5): 'dst_sel___write_data__memory', (dst_sel___write_data__memory_mapped_adc_persistent_state:=6): 'dst_sel___write_data__memory_mapped_adc_persistent_state'}
enum_WRITE_DATA_addr_incr_enum: dict[int, str] = {(addr_incr___write_data__increment_address:=0): 'addr_incr___write_data__increment_address', (addr_incr___write_data__do_not_increment_address:=1): 'addr_incr___write_data__do_not_increment_address'}
enum_WRITE_DATA_wr_confirm_enum: dict[int, str] = {(wr_confirm___write_data__do_not_wait_for_write_confirmation:=0): 'wr_confirm___write_data__do_not_wait_for_write_confirmation', (wr_confirm___write_data__wait_for_write_confirmation:=1): 'wr_confirm___write_data__wait_for_write_confirmation'}
enum_WRITE_DATA_cache_policy_enum: dict[int, str] = {(cache_policy___write_data__lru:=0): 'cache_policy___write_data__lru', (cache_policy___write_data__stream:=1): 'cache_policy___write_data__stream'}
class struct_pm4_mec_write_data_mmio(c.Struct): pass
_anonenum0: dict[int, str] = {(CACHE_FLUSH_AND_INV_TS_EVENT:=20): 'CACHE_FLUSH_AND_INV_TS_EVENT'}
GFX9_NUM_GFX_RINGS = 1 # type: ignore
GFX9_NUM_COMPUTE_RINGS = 8 # type: ignore
PACKET_TYPE0 = 0 # type: ignore
+308 -246
View File
@@ -1,453 +1,515 @@
# mypy: disable-error-code="empty-body"
from __future__ import annotations
import ctypes
from typing import Annotated, Literal, TypeAlias
from typing import Literal, TypeAlias
from tinygrad.runtime.support.c import _IO, _IOW, _IOR, _IOWR
from tinygrad.runtime.support import c
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG(c.Struct):
SIZE = 28
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION, 0]
COUNT_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION, 4]
PARAMETER_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION, 8]
SRC_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION, 12]
SRC_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION, 16]
DST_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION, 20]
DST_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION, 24]
HEADER_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION
COUNT_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION
PARAMETER_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION
SRC_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION
SRC_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION
DST_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION
DST_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
extra_info: Annotated[Annotated[int, ctypes.c_uint32], 2, 16, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
extra_info: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('extra_info', ctypes.c_uint32, 2, 16, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION(c.Struct):
SIZE = 4
count: Annotated[Annotated[int, ctypes.c_uint32], 0, 22, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 10, 6]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
count: int
reserved_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION.register_fields([('count', ctypes.c_uint32, 0, 22, 0), ('reserved_0', ctypes.c_uint32, 2, 10, 6), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION(c.Struct):
SIZE = 4
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
dst_swap: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 2, 6, 2]
src_swap: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 6, 2]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
reserved_0: int
dst_swap: int
reserved_1: int
src_swap: int
reserved_2: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION.register_fields([('reserved_0', ctypes.c_uint32, 0, 16, 0), ('dst_swap', ctypes.c_uint32, 2, 2, 0), ('reserved_1', ctypes.c_uint32, 2, 6, 2), ('src_swap', ctypes.c_uint32, 3, 2, 0), ('reserved_2', ctypes.c_uint32, 3, 6, 2), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION(c.Struct):
SIZE = 4
src_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_31_0: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION.register_fields([('src_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION(c.Struct):
SIZE = 4
src_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_63_32: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION.register_fields([('src_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION(c.Struct):
SIZE = 4
dst_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_31_0: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION.register_fields([('dst_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_5_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION(c.Struct):
SIZE = 4
dst_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_6_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_63_32: int
DW_6_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION.register_fields([('dst_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_6_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION, 0), ('COUNT_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION, 4), ('PARAMETER_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION, 8), ('SRC_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION, 12), ('SRC_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION, 16), ('DST_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION, 20), ('DST_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION, 24)])
rocr_AMD_SDMA_PKT_COPY_LINEAR: TypeAlias = rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG(c.Struct):
SIZE = 52
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION, 0]
SRC_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION, 4]
SRC_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION, 8]
SRC_PARAMETER_1_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION, 12]
SRC_PARAMETER_2_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION, 16]
SRC_PARAMETER_3_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION, 20]
DST_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION, 24]
DST_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION, 28]
DST_PARAMETER_1_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION, 32]
DST_PARAMETER_2_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION, 36]
DST_PARAMETER_3_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION, 40]
RECT_PARAMETER_1_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION, 44]
RECT_PARAMETER_2_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION, 48]
HEADER_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION
SRC_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION
SRC_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION
SRC_PARAMETER_1_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION
SRC_PARAMETER_2_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION
SRC_PARAMETER_3_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION
DST_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION
DST_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION
DST_PARAMETER_1_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION
DST_PARAMETER_2_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION
DST_PARAMETER_3_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION
RECT_PARAMETER_1_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION
RECT_PARAMETER_2_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved: Annotated[Annotated[int, ctypes.c_uint32], 2, 13, 0]
element: Annotated[Annotated[int, ctypes.c_uint32], 3, 3, 5]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved: int
element: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved', ctypes.c_uint32, 2, 13, 0), ('element', ctypes.c_uint32, 3, 3, 5), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION(c.Struct):
SIZE = 4
src_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION.register_fields([('src_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION(c.Struct):
SIZE = 4
src_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION.register_fields([('src_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION(c.Struct):
SIZE = 4
src_offset_x: Annotated[Annotated[int, ctypes.c_uint32], 0, 14, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 6]
src_offset_y: Annotated[Annotated[int, ctypes.c_uint32], 2, 14, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_offset_x: int
reserved_1: int
src_offset_y: int
reserved_2: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION.register_fields([('src_offset_x', ctypes.c_uint32, 0, 14, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 6), ('src_offset_y', ctypes.c_uint32, 2, 14, 0), ('reserved_2', ctypes.c_uint32, 3, 2, 6), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION(c.Struct):
SIZE = 4
src_offset_z: Annotated[Annotated[int, ctypes.c_uint32], 0, 11, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 3]
src_pitch: Annotated[Annotated[int, ctypes.c_uint32], 1, 19, 5]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_offset_z: int
reserved_1: int
src_pitch: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION.register_fields([('src_offset_z', ctypes.c_uint32, 0, 11, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 3), ('src_pitch', ctypes.c_uint32, 1, 19, 5), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION(c.Struct):
SIZE = 4
src_slice_pitch: Annotated[Annotated[int, ctypes.c_uint32], 0, 28, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_slice_pitch: int
reserved_1: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION.register_fields([('src_slice_pitch', ctypes.c_uint32, 0, 28, 0), ('reserved_1', ctypes.c_uint32, 3, 4, 4), ('DW_5_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION(c.Struct):
SIZE = 4
dst_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_6_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_31_0: int
DW_6_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION.register_fields([('dst_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_6_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION(c.Struct):
SIZE = 4
dst_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_7_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_63_32: int
DW_7_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION.register_fields([('dst_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_7_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION(c.Struct):
SIZE = 4
dst_offset_x: Annotated[Annotated[int, ctypes.c_uint32], 0, 14, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 6]
dst_offset_y: Annotated[Annotated[int, ctypes.c_uint32], 2, 14, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_8_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_offset_x: int
reserved_1: int
dst_offset_y: int
reserved_2: int
DW_8_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION.register_fields([('dst_offset_x', ctypes.c_uint32, 0, 14, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 6), ('dst_offset_y', ctypes.c_uint32, 2, 14, 0), ('reserved_2', ctypes.c_uint32, 3, 2, 6), ('DW_8_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION(c.Struct):
SIZE = 4
dst_offset_z: Annotated[Annotated[int, ctypes.c_uint32], 0, 11, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 3]
dst_pitch: Annotated[Annotated[int, ctypes.c_uint32], 1, 19, 5]
DW_9_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_offset_z: int
reserved_1: int
dst_pitch: int
DW_9_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION.register_fields([('dst_offset_z', ctypes.c_uint32, 0, 11, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 3), ('dst_pitch', ctypes.c_uint32, 1, 19, 5), ('DW_9_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION(c.Struct):
SIZE = 4
dst_slice_pitch: Annotated[Annotated[int, ctypes.c_uint32], 0, 28, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_10_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_slice_pitch: int
reserved_1: int
DW_10_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION.register_fields([('dst_slice_pitch', ctypes.c_uint32, 0, 28, 0), ('reserved_1', ctypes.c_uint32, 3, 4, 4), ('DW_10_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION(c.Struct):
SIZE = 4
rect_x: Annotated[Annotated[int, ctypes.c_uint32], 0, 14, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 6]
rect_y: Annotated[Annotated[int, ctypes.c_uint32], 2, 14, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_11_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
rect_x: int
reserved_1: int
rect_y: int
reserved_2: int
DW_11_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION.register_fields([('rect_x', ctypes.c_uint32, 0, 14, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 6), ('rect_y', ctypes.c_uint32, 2, 14, 0), ('reserved_2', ctypes.c_uint32, 3, 2, 6), ('DW_11_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION(c.Struct):
SIZE = 4
rect_z: Annotated[Annotated[int, ctypes.c_uint32], 0, 11, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 5, 3]
dst_swap: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 2, 6, 2]
src_swap: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 0]
reserved_3: Annotated[Annotated[int, ctypes.c_uint32], 3, 6, 2]
DW_12_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
rect_z: int
reserved_1: int
dst_swap: int
reserved_2: int
src_swap: int
reserved_3: int
DW_12_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION.register_fields([('rect_z', ctypes.c_uint32, 0, 11, 0), ('reserved_1', ctypes.c_uint32, 1, 5, 3), ('dst_swap', ctypes.c_uint32, 2, 2, 0), ('reserved_2', ctypes.c_uint32, 2, 6, 2), ('src_swap', ctypes.c_uint32, 3, 2, 0), ('reserved_3', ctypes.c_uint32, 3, 6, 2), ('DW_12_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION, 0), ('SRC_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION, 4), ('SRC_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION, 8), ('SRC_PARAMETER_1_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION, 12), ('SRC_PARAMETER_2_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION, 16), ('SRC_PARAMETER_3_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION, 20), ('DST_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION, 24), ('DST_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION, 28), ('DST_PARAMETER_1_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION, 32), ('DST_PARAMETER_2_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION, 36), ('DST_PARAMETER_3_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION, 40), ('RECT_PARAMETER_1_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION, 44), ('RECT_PARAMETER_2_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION, 48)])
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT: TypeAlias = rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG(c.Struct):
SIZE = 20
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION, 0]
DST_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION, 4]
DST_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION, 8]
DATA_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION, 12]
COUNT_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION, 16]
HEADER_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION
DST_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION
DST_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION
DATA_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION
COUNT_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
sw: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 12, 2]
fillsize: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
sw: int
reserved_0: int
fillsize: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('sw', ctypes.c_uint32, 2, 2, 0), ('reserved_0', ctypes.c_uint32, 2, 12, 2), ('fillsize', ctypes.c_uint32, 3, 2, 6), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION(c.Struct):
SIZE = 4
dst_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION.register_fields([('dst_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION(c.Struct):
SIZE = 4
dst_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION.register_fields([('dst_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION(c.Struct):
SIZE = 4
src_data_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_data_31_0: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION.register_fields([('src_data_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION(c.Struct):
SIZE = 4
count: Annotated[Annotated[int, ctypes.c_uint32], 0, 22, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 10, 6]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
count: int
reserved_0: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION.register_fields([('count', ctypes.c_uint32, 0, 22, 0), ('reserved_0', ctypes.c_uint32, 2, 10, 6), ('DW_4_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION, 0), ('DST_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION, 4), ('DST_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION, 8), ('DATA_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION, 12), ('COUNT_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION, 16)])
rocr_AMD_SDMA_PKT_CONSTANT_FILL: TypeAlias = rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG(c.Struct):
SIZE = 16
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION, 8]
DATA_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION, 12]
HEADER_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION
DATA_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
mtype: Annotated[Annotated[int, ctypes.c_uint32], 2, 3, 0]
gcc: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 3]
sys: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 4]
pad1: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 5]
snp: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 6]
gpa: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 7]
l2_policy: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 3, 6, 2]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
mtype: int
gcc: int
sys: int
pad1: int
snp: int
gpa: int
l2_policy: int
reserved_0: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('mtype', ctypes.c_uint32, 2, 3, 0), ('gcc', ctypes.c_uint32, 2, 1, 3), ('sys', ctypes.c_uint32, 2, 1, 4), ('pad1', ctypes.c_uint32, 2, 1, 5), ('snp', ctypes.c_uint32, 2, 1, 6), ('gpa', ctypes.c_uint32, 2, 1, 7), ('l2_policy', ctypes.c_uint32, 3, 2, 0), ('reserved_0', ctypes.c_uint32, 3, 6, 2), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION(c.Struct):
SIZE = 4
data: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
data: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION.register_fields([('data', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_FENCE_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION, 8), ('DATA_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION, 12)])
rocr_AMD_SDMA_PKT_FENCE: TypeAlias = rocr_AMD_SDMA_PKT_FENCE_TAG
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG(c.Struct):
SIZE = 24
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION, 8]
VALUE_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION, 12]
MASK_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION, 16]
DW5_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION, 20]
HEADER_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION
VALUE_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION
MASK_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION
DW5_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 10, 0]
hdp_flush: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 2]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 3]
func: Annotated[Annotated[int, ctypes.c_uint32], 3, 3, 4]
mem_poll: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 7]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved_0: int
hdp_flush: int
reserved_1: int
func: int
mem_poll: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved_0', ctypes.c_uint32, 2, 10, 0), ('hdp_flush', ctypes.c_uint32, 3, 1, 2), ('reserved_1', ctypes.c_uint32, 3, 1, 3), ('func', ctypes.c_uint32, 3, 3, 4), ('mem_poll', ctypes.c_uint32, 3, 1, 7), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION(c.Struct):
SIZE = 4
value: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
value: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION.register_fields([('value', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION(c.Struct):
SIZE = 4
mask: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
mask: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION.register_fields([('mask', ctypes.c_uint32, 0, 32, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION(c.Struct):
SIZE = 4
interval: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
retry_count: Annotated[Annotated[int, ctypes.c_uint32], 2, 12, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
interval: int
retry_count: int
reserved_0: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION.register_fields([('interval', ctypes.c_uint32, 0, 16, 0), ('retry_count', ctypes.c_uint32, 2, 12, 0), ('reserved_0', ctypes.c_uint32, 3, 4, 4), ('DW_5_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION, 8), ('VALUE_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION, 12), ('MASK_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION, 16), ('DW5_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION, 20)])
rocr_AMD_SDMA_PKT_POLL_REGMEM: TypeAlias = rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG(c.Struct):
SIZE = 32
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION, 8]
SRC_DATA_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION, 12]
SRC_DATA_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION, 16]
CMP_DATA_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION, 20]
CMP_DATA_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION, 24]
LOOP_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION, 28]
HEADER_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION
SRC_DATA_LO_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION
SRC_DATA_HI_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION
CMP_DATA_LO_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION
CMP_DATA_HI_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION
LOOP_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
l: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 8, 1]
operation: Annotated[Annotated[int, ctypes.c_uint32], 3, 7, 1]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
l: int
reserved_0: int
operation: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('l', ctypes.c_uint32, 2, 1, 0), ('reserved_0', ctypes.c_uint32, 2, 8, 1), ('operation', ctypes.c_uint32, 3, 7, 1), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION(c.Struct):
SIZE = 4
src_data_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_data_31_0: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION.register_fields([('src_data_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION(c.Struct):
SIZE = 4
src_data_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_data_63_32: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION.register_fields([('src_data_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION(c.Struct):
SIZE = 4
cmp_data_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
cmp_data_31_0: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION.register_fields([('cmp_data_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_5_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION(c.Struct):
SIZE = 4
cmp_data_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_6_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
cmp_data_63_32: int
DW_6_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION.register_fields([('cmp_data_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_6_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION(c.Struct):
SIZE = 4
loop_interval: Annotated[Annotated[int, ctypes.c_uint32], 0, 13, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 1, 19, 5]
DW_7_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
loop_interval: int
reserved_0: int
DW_7_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION.register_fields([('loop_interval', ctypes.c_uint32, 0, 13, 0), ('reserved_0', ctypes.c_uint32, 1, 19, 5), ('DW_7_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_ATOMIC_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION, 8), ('SRC_DATA_LO_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION, 12), ('SRC_DATA_HI_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION, 16), ('CMP_DATA_LO_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION, 20), ('CMP_DATA_HI_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION, 24), ('LOOP_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION, 28)])
rocr_AMD_SDMA_PKT_ATOMIC: TypeAlias = rocr_AMD_SDMA_PKT_ATOMIC_TAG
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG(c.Struct):
SIZE = 12
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION, 8]
HEADER_UNION: rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 16, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved_0: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved_0', ctypes.c_uint32, 2, 16, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION, 8)])
rocr_AMD_SDMA_PKT_TIMESTAMP: TypeAlias = rocr_AMD_SDMA_PKT_TIMESTAMP_TAG
@c.record
class rocr_AMD_SDMA_PKT_TRAP_TAG(c.Struct):
SIZE = 8
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION, 0]
INT_CONTEXT_UNION: Annotated[rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION, 4]
HEADER_UNION: rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION
INT_CONTEXT_UNION: rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION
@c.record
class rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 16, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved_0: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved_0', ctypes.c_uint32, 2, 16, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION(c.Struct):
SIZE = 4
int_ctx: Annotated[Annotated[int, ctypes.c_uint32], 0, 28, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
int_ctx: int
reserved_1: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION.register_fields([('int_ctx', ctypes.c_uint32, 0, 28, 0), ('reserved_1', ctypes.c_uint32, 3, 4, 4), ('DW_1_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_TRAP_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION, 0), ('INT_CONTEXT_UNION', rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION, 4)])
rocr_AMD_SDMA_PKT_TRAP: TypeAlias = rocr_AMD_SDMA_PKT_TRAP_TAG
@c.record
class rocr_AMD_SDMA_PKT_HDP_FLUSH_TAG(c.Struct):
SIZE = 24
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 4]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 8]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 12]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 16]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 20]
DW_0_DATA: int
DW_1_DATA: int
DW_2_DATA: int
DW_3_DATA: int
DW_4_DATA: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_HDP_FLUSH_TAG.register_fields([('DW_0_DATA', ctypes.c_uint32, 0), ('DW_1_DATA', ctypes.c_uint32, 4), ('DW_2_DATA', ctypes.c_uint32, 8), ('DW_3_DATA', ctypes.c_uint32, 12), ('DW_4_DATA', ctypes.c_uint32, 16), ('DW_5_DATA', ctypes.c_uint32, 20)])
rocr_AMD_SDMA_PKT_HDP_FLUSH: TypeAlias = rocr_AMD_SDMA_PKT_HDP_FLUSH_TAG
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG(c.Struct):
SIZE = 20
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION, 0]
WORD1_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION, 4]
WORD2_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION, 8]
WORD3_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION, 12]
WORD4_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION, 16]
HEADER_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION
WORD1_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION
WORD2_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION
WORD3_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION
WORD4_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION(c.Struct):
SIZE = 4
BaseVA_LO: Annotated[Annotated[int, ctypes.c_uint32], 0, 25, 7]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
BaseVA_LO: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION.register_fields([('BaseVA_LO', ctypes.c_uint32, 0, 25, 7), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION(c.Struct):
SIZE = 4
BaseVA_HI: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
GCR_CONTROL_GLI_INV: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
GCR_CONTROL_GL1_RANGE: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 2]
GCR_CONTROL_GLM_WB: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 4]
GCR_CONTROL_GLM_INV: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 5]
GCR_CONTROL_GLK_WB: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 6]
GCR_CONTROL_GLK_INV: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 7]
GCR_CONTROL_GLV_INV: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 0]
GCR_CONTROL_GL1_INV: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 1]
GCR_CONTROL_GL2_US: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 2]
GCR_CONTROL_GL2_RANGE: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 3]
GCR_CONTROL_GL2_DISCARD: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 5]
GCR_CONTROL_GL2_INV: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 6]
GCR_CONTROL_GL2_WB: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 7]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
BaseVA_HI: int
GCR_CONTROL_GLI_INV: int
GCR_CONTROL_GL1_RANGE: int
GCR_CONTROL_GLM_WB: int
GCR_CONTROL_GLM_INV: int
GCR_CONTROL_GLK_WB: int
GCR_CONTROL_GLK_INV: int
GCR_CONTROL_GLV_INV: int
GCR_CONTROL_GL1_INV: int
GCR_CONTROL_GL2_US: int
GCR_CONTROL_GL2_RANGE: int
GCR_CONTROL_GL2_DISCARD: int
GCR_CONTROL_GL2_INV: int
GCR_CONTROL_GL2_WB: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION.register_fields([('BaseVA_HI', ctypes.c_uint32, 0, 16, 0), ('GCR_CONTROL_GLI_INV', ctypes.c_uint32, 2, 2, 0), ('GCR_CONTROL_GL1_RANGE', ctypes.c_uint32, 2, 2, 2), ('GCR_CONTROL_GLM_WB', ctypes.c_uint32, 2, 1, 4), ('GCR_CONTROL_GLM_INV', ctypes.c_uint32, 2, 1, 5), ('GCR_CONTROL_GLK_WB', ctypes.c_uint32, 2, 1, 6), ('GCR_CONTROL_GLK_INV', ctypes.c_uint32, 2, 1, 7), ('GCR_CONTROL_GLV_INV', ctypes.c_uint32, 3, 1, 0), ('GCR_CONTROL_GL1_INV', ctypes.c_uint32, 3, 1, 1), ('GCR_CONTROL_GL2_US', ctypes.c_uint32, 3, 1, 2), ('GCR_CONTROL_GL2_RANGE', ctypes.c_uint32, 3, 2, 3), ('GCR_CONTROL_GL2_DISCARD', ctypes.c_uint32, 3, 1, 5), ('GCR_CONTROL_GL2_INV', ctypes.c_uint32, 3, 1, 6), ('GCR_CONTROL_GL2_WB', ctypes.c_uint32, 3, 1, 7), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION(c.Struct):
SIZE = 4
GCR_CONTROL_RANGE_IS_PA: Annotated[Annotated[int, ctypes.c_uint32], 0, 1, 0]
GCR_CONTROL_SEQ: Annotated[Annotated[int, ctypes.c_uint32], 0, 2, 1]
LimitVA_LO: Annotated[Annotated[int, ctypes.c_uint32], 0, 25, 7]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
GCR_CONTROL_RANGE_IS_PA: int
GCR_CONTROL_SEQ: int
LimitVA_LO: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION.register_fields([('GCR_CONTROL_RANGE_IS_PA', ctypes.c_uint32, 0, 1, 0), ('GCR_CONTROL_SEQ', ctypes.c_uint32, 0, 2, 1), ('LimitVA_LO', ctypes.c_uint32, 0, 25, 7), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION(c.Struct):
SIZE = 4
LimitVA_HI: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
VMID: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
LimitVA_HI: int
VMID: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION.register_fields([('LimitVA_HI', ctypes.c_uint32, 0, 16, 0), ('VMID', ctypes.c_uint32, 3, 4, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_GCR_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION, 0), ('WORD1_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION, 4), ('WORD2_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION, 8), ('WORD3_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION, 12), ('WORD4_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION, 16)])
rocr_AMD_SDMA_PKT_GCR: TypeAlias = rocr_AMD_SDMA_PKT_GCR_TAG
c.init_records()
SDMA_OP_COPY = 1 # type: ignore
SDMA_OP_FENCE = 5 # type: ignore
SDMA_OP_TRAP = 6 # type: ignore
+308 -246
View File
@@ -1,453 +1,515 @@
# mypy: disable-error-code="empty-body"
from __future__ import annotations
import ctypes
from typing import Annotated, Literal, TypeAlias
from typing import Literal, TypeAlias
from tinygrad.runtime.support.c import _IO, _IOW, _IOR, _IOWR
from tinygrad.runtime.support import c
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG(c.Struct):
SIZE = 28
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION, 0]
COUNT_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION, 4]
PARAMETER_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION, 8]
SRC_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION, 12]
SRC_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION, 16]
DST_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION, 20]
DST_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION, 24]
HEADER_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION
COUNT_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION
PARAMETER_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION
SRC_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION
SRC_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION
DST_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION
DST_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
extra_info: Annotated[Annotated[int, ctypes.c_uint32], 2, 16, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
extra_info: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('extra_info', ctypes.c_uint32, 2, 16, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION(c.Struct):
SIZE = 4
count: Annotated[Annotated[int, ctypes.c_uint32], 0, 22, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 10, 6]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
count: int
reserved_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION.register_fields([('count', ctypes.c_uint32, 0, 22, 0), ('reserved_0', ctypes.c_uint32, 2, 10, 6), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION(c.Struct):
SIZE = 4
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
dst_swap: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 2, 6, 2]
src_swap: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 6, 2]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
reserved_0: int
dst_swap: int
reserved_1: int
src_swap: int
reserved_2: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION.register_fields([('reserved_0', ctypes.c_uint32, 0, 16, 0), ('dst_swap', ctypes.c_uint32, 2, 2, 0), ('reserved_1', ctypes.c_uint32, 2, 6, 2), ('src_swap', ctypes.c_uint32, 3, 2, 0), ('reserved_2', ctypes.c_uint32, 3, 6, 2), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION(c.Struct):
SIZE = 4
src_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_31_0: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION.register_fields([('src_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION(c.Struct):
SIZE = 4
src_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_63_32: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION.register_fields([('src_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION(c.Struct):
SIZE = 4
dst_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_31_0: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION.register_fields([('dst_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_5_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION(c.Struct):
SIZE = 4
dst_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_6_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_63_32: int
DW_6_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION.register_fields([('dst_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_6_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION, 0), ('COUNT_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION, 4), ('PARAMETER_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION, 8), ('SRC_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION, 12), ('SRC_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION, 16), ('DST_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION, 20), ('DST_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION, 24)])
rocr_AMD_SDMA_PKT_COPY_LINEAR: TypeAlias = rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG(c.Struct):
SIZE = 52
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION, 0]
SRC_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION, 4]
SRC_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION, 8]
SRC_PARAMETER_1_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION, 12]
SRC_PARAMETER_2_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION, 16]
SRC_PARAMETER_3_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION, 20]
DST_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION, 24]
DST_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION, 28]
DST_PARAMETER_1_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION, 32]
DST_PARAMETER_2_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION, 36]
DST_PARAMETER_3_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION, 40]
RECT_PARAMETER_1_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION, 44]
RECT_PARAMETER_2_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION, 48]
HEADER_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION
SRC_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION
SRC_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION
SRC_PARAMETER_1_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION
SRC_PARAMETER_2_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION
SRC_PARAMETER_3_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION
DST_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION
DST_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION
DST_PARAMETER_1_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION
DST_PARAMETER_2_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION
DST_PARAMETER_3_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION
RECT_PARAMETER_1_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION
RECT_PARAMETER_2_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved: Annotated[Annotated[int, ctypes.c_uint32], 2, 13, 0]
element: Annotated[Annotated[int, ctypes.c_uint32], 3, 3, 5]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved: int
element: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved', ctypes.c_uint32, 2, 13, 0), ('element', ctypes.c_uint32, 3, 3, 5), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION(c.Struct):
SIZE = 4
src_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION.register_fields([('src_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION(c.Struct):
SIZE = 4
src_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION.register_fields([('src_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION(c.Struct):
SIZE = 4
src_offset_x: Annotated[Annotated[int, ctypes.c_uint32], 0, 14, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 6]
src_offset_y: Annotated[Annotated[int, ctypes.c_uint32], 2, 14, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_offset_x: int
reserved_1: int
src_offset_y: int
reserved_2: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION.register_fields([('src_offset_x', ctypes.c_uint32, 0, 14, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 6), ('src_offset_y', ctypes.c_uint32, 2, 14, 0), ('reserved_2', ctypes.c_uint32, 3, 2, 6), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION(c.Struct):
SIZE = 4
src_offset_z: Annotated[Annotated[int, ctypes.c_uint32], 0, 11, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 3]
src_pitch: Annotated[Annotated[int, ctypes.c_uint32], 1, 19, 5]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_offset_z: int
reserved_1: int
src_pitch: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION.register_fields([('src_offset_z', ctypes.c_uint32, 0, 11, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 3), ('src_pitch', ctypes.c_uint32, 1, 19, 5), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION(c.Struct):
SIZE = 4
src_slice_pitch: Annotated[Annotated[int, ctypes.c_uint32], 0, 28, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_slice_pitch: int
reserved_1: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION.register_fields([('src_slice_pitch', ctypes.c_uint32, 0, 28, 0), ('reserved_1', ctypes.c_uint32, 3, 4, 4), ('DW_5_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION(c.Struct):
SIZE = 4
dst_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_6_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_31_0: int
DW_6_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION.register_fields([('dst_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_6_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION(c.Struct):
SIZE = 4
dst_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_7_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_63_32: int
DW_7_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION.register_fields([('dst_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_7_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION(c.Struct):
SIZE = 4
dst_offset_x: Annotated[Annotated[int, ctypes.c_uint32], 0, 14, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 6]
dst_offset_y: Annotated[Annotated[int, ctypes.c_uint32], 2, 14, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_8_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_offset_x: int
reserved_1: int
dst_offset_y: int
reserved_2: int
DW_8_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION.register_fields([('dst_offset_x', ctypes.c_uint32, 0, 14, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 6), ('dst_offset_y', ctypes.c_uint32, 2, 14, 0), ('reserved_2', ctypes.c_uint32, 3, 2, 6), ('DW_8_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION(c.Struct):
SIZE = 4
dst_offset_z: Annotated[Annotated[int, ctypes.c_uint32], 0, 11, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 3]
dst_pitch: Annotated[Annotated[int, ctypes.c_uint32], 1, 19, 5]
DW_9_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_offset_z: int
reserved_1: int
dst_pitch: int
DW_9_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION.register_fields([('dst_offset_z', ctypes.c_uint32, 0, 11, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 3), ('dst_pitch', ctypes.c_uint32, 1, 19, 5), ('DW_9_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION(c.Struct):
SIZE = 4
dst_slice_pitch: Annotated[Annotated[int, ctypes.c_uint32], 0, 28, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_10_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_slice_pitch: int
reserved_1: int
DW_10_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION.register_fields([('dst_slice_pitch', ctypes.c_uint32, 0, 28, 0), ('reserved_1', ctypes.c_uint32, 3, 4, 4), ('DW_10_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION(c.Struct):
SIZE = 4
rect_x: Annotated[Annotated[int, ctypes.c_uint32], 0, 14, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 6]
rect_y: Annotated[Annotated[int, ctypes.c_uint32], 2, 14, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_11_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
rect_x: int
reserved_1: int
rect_y: int
reserved_2: int
DW_11_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION.register_fields([('rect_x', ctypes.c_uint32, 0, 14, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 6), ('rect_y', ctypes.c_uint32, 2, 14, 0), ('reserved_2', ctypes.c_uint32, 3, 2, 6), ('DW_11_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION(c.Struct):
SIZE = 4
rect_z: Annotated[Annotated[int, ctypes.c_uint32], 0, 11, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 5, 3]
dst_swap: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 2, 6, 2]
src_swap: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 0]
reserved_3: Annotated[Annotated[int, ctypes.c_uint32], 3, 6, 2]
DW_12_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
rect_z: int
reserved_1: int
dst_swap: int
reserved_2: int
src_swap: int
reserved_3: int
DW_12_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION.register_fields([('rect_z', ctypes.c_uint32, 0, 11, 0), ('reserved_1', ctypes.c_uint32, 1, 5, 3), ('dst_swap', ctypes.c_uint32, 2, 2, 0), ('reserved_2', ctypes.c_uint32, 2, 6, 2), ('src_swap', ctypes.c_uint32, 3, 2, 0), ('reserved_3', ctypes.c_uint32, 3, 6, 2), ('DW_12_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION, 0), ('SRC_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION, 4), ('SRC_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION, 8), ('SRC_PARAMETER_1_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION, 12), ('SRC_PARAMETER_2_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION, 16), ('SRC_PARAMETER_3_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION, 20), ('DST_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION, 24), ('DST_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION, 28), ('DST_PARAMETER_1_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION, 32), ('DST_PARAMETER_2_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION, 36), ('DST_PARAMETER_3_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION, 40), ('RECT_PARAMETER_1_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION, 44), ('RECT_PARAMETER_2_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION, 48)])
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT: TypeAlias = rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG(c.Struct):
SIZE = 20
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION, 0]
DST_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION, 4]
DST_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION, 8]
DATA_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION, 12]
COUNT_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION, 16]
HEADER_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION
DST_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION
DST_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION
DATA_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION
COUNT_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
sw: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 12, 2]
fillsize: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
sw: int
reserved_0: int
fillsize: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('sw', ctypes.c_uint32, 2, 2, 0), ('reserved_0', ctypes.c_uint32, 2, 12, 2), ('fillsize', ctypes.c_uint32, 3, 2, 6), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION(c.Struct):
SIZE = 4
dst_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION.register_fields([('dst_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION(c.Struct):
SIZE = 4
dst_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION.register_fields([('dst_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION(c.Struct):
SIZE = 4
src_data_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_data_31_0: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION.register_fields([('src_data_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION(c.Struct):
SIZE = 4
count: Annotated[Annotated[int, ctypes.c_uint32], 0, 22, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 10, 6]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
count: int
reserved_0: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION.register_fields([('count', ctypes.c_uint32, 0, 22, 0), ('reserved_0', ctypes.c_uint32, 2, 10, 6), ('DW_4_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION, 0), ('DST_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION, 4), ('DST_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION, 8), ('DATA_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION, 12), ('COUNT_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION, 16)])
rocr_AMD_SDMA_PKT_CONSTANT_FILL: TypeAlias = rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG(c.Struct):
SIZE = 16
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION, 8]
DATA_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION, 12]
HEADER_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION
DATA_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
mtype: Annotated[Annotated[int, ctypes.c_uint32], 2, 3, 0]
gcc: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 3]
sys: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 4]
pad1: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 5]
snp: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 6]
gpa: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 7]
l2_policy: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 3, 6, 2]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
mtype: int
gcc: int
sys: int
pad1: int
snp: int
gpa: int
l2_policy: int
reserved_0: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('mtype', ctypes.c_uint32, 2, 3, 0), ('gcc', ctypes.c_uint32, 2, 1, 3), ('sys', ctypes.c_uint32, 2, 1, 4), ('pad1', ctypes.c_uint32, 2, 1, 5), ('snp', ctypes.c_uint32, 2, 1, 6), ('gpa', ctypes.c_uint32, 2, 1, 7), ('l2_policy', ctypes.c_uint32, 3, 2, 0), ('reserved_0', ctypes.c_uint32, 3, 6, 2), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION(c.Struct):
SIZE = 4
data: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
data: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION.register_fields([('data', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_FENCE_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION, 8), ('DATA_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION, 12)])
rocr_AMD_SDMA_PKT_FENCE: TypeAlias = rocr_AMD_SDMA_PKT_FENCE_TAG
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG(c.Struct):
SIZE = 24
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION, 8]
VALUE_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION, 12]
MASK_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION, 16]
DW5_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION, 20]
HEADER_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION
VALUE_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION
MASK_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION
DW5_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 10, 0]
hdp_flush: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 2]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 3]
func: Annotated[Annotated[int, ctypes.c_uint32], 3, 3, 4]
mem_poll: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 7]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved_0: int
hdp_flush: int
reserved_1: int
func: int
mem_poll: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved_0', ctypes.c_uint32, 2, 10, 0), ('hdp_flush', ctypes.c_uint32, 3, 1, 2), ('reserved_1', ctypes.c_uint32, 3, 1, 3), ('func', ctypes.c_uint32, 3, 3, 4), ('mem_poll', ctypes.c_uint32, 3, 1, 7), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION(c.Struct):
SIZE = 4
value: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
value: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION.register_fields([('value', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION(c.Struct):
SIZE = 4
mask: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
mask: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION.register_fields([('mask', ctypes.c_uint32, 0, 32, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION(c.Struct):
SIZE = 4
interval: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
retry_count: Annotated[Annotated[int, ctypes.c_uint32], 2, 12, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
interval: int
retry_count: int
reserved_0: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION.register_fields([('interval', ctypes.c_uint32, 0, 16, 0), ('retry_count', ctypes.c_uint32, 2, 12, 0), ('reserved_0', ctypes.c_uint32, 3, 4, 4), ('DW_5_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION, 8), ('VALUE_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION, 12), ('MASK_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION, 16), ('DW5_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION, 20)])
rocr_AMD_SDMA_PKT_POLL_REGMEM: TypeAlias = rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG(c.Struct):
SIZE = 32
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION, 8]
SRC_DATA_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION, 12]
SRC_DATA_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION, 16]
CMP_DATA_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION, 20]
CMP_DATA_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION, 24]
LOOP_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION, 28]
HEADER_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION
SRC_DATA_LO_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION
SRC_DATA_HI_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION
CMP_DATA_LO_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION
CMP_DATA_HI_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION
LOOP_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
l: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 8, 1]
operation: Annotated[Annotated[int, ctypes.c_uint32], 3, 7, 1]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
l: int
reserved_0: int
operation: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('l', ctypes.c_uint32, 2, 1, 0), ('reserved_0', ctypes.c_uint32, 2, 8, 1), ('operation', ctypes.c_uint32, 3, 7, 1), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION(c.Struct):
SIZE = 4
src_data_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_data_31_0: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION.register_fields([('src_data_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION(c.Struct):
SIZE = 4
src_data_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_data_63_32: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION.register_fields([('src_data_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION(c.Struct):
SIZE = 4
cmp_data_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
cmp_data_31_0: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION.register_fields([('cmp_data_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_5_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION(c.Struct):
SIZE = 4
cmp_data_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_6_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
cmp_data_63_32: int
DW_6_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION.register_fields([('cmp_data_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_6_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION(c.Struct):
SIZE = 4
loop_interval: Annotated[Annotated[int, ctypes.c_uint32], 0, 13, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 1, 19, 5]
DW_7_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
loop_interval: int
reserved_0: int
DW_7_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION.register_fields([('loop_interval', ctypes.c_uint32, 0, 13, 0), ('reserved_0', ctypes.c_uint32, 1, 19, 5), ('DW_7_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_ATOMIC_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION, 8), ('SRC_DATA_LO_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION, 12), ('SRC_DATA_HI_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION, 16), ('CMP_DATA_LO_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION, 20), ('CMP_DATA_HI_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION, 24), ('LOOP_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION, 28)])
rocr_AMD_SDMA_PKT_ATOMIC: TypeAlias = rocr_AMD_SDMA_PKT_ATOMIC_TAG
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG(c.Struct):
SIZE = 12
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION, 8]
HEADER_UNION: rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 16, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved_0: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved_0', ctypes.c_uint32, 2, 16, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION, 8)])
rocr_AMD_SDMA_PKT_TIMESTAMP: TypeAlias = rocr_AMD_SDMA_PKT_TIMESTAMP_TAG
@c.record
class rocr_AMD_SDMA_PKT_TRAP_TAG(c.Struct):
SIZE = 8
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION, 0]
INT_CONTEXT_UNION: Annotated[rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION, 4]
HEADER_UNION: rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION
INT_CONTEXT_UNION: rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION
@c.record
class rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 16, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved_0: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved_0', ctypes.c_uint32, 2, 16, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION(c.Struct):
SIZE = 4
int_ctx: Annotated[Annotated[int, ctypes.c_uint32], 0, 28, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
int_ctx: int
reserved_1: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION.register_fields([('int_ctx', ctypes.c_uint32, 0, 28, 0), ('reserved_1', ctypes.c_uint32, 3, 4, 4), ('DW_1_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_TRAP_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION, 0), ('INT_CONTEXT_UNION', rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION, 4)])
rocr_AMD_SDMA_PKT_TRAP: TypeAlias = rocr_AMD_SDMA_PKT_TRAP_TAG
@c.record
class rocr_AMD_SDMA_PKT_HDP_FLUSH_TAG(c.Struct):
SIZE = 24
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 4]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 8]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 12]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 16]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 20]
DW_0_DATA: int
DW_1_DATA: int
DW_2_DATA: int
DW_3_DATA: int
DW_4_DATA: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_HDP_FLUSH_TAG.register_fields([('DW_0_DATA', ctypes.c_uint32, 0), ('DW_1_DATA', ctypes.c_uint32, 4), ('DW_2_DATA', ctypes.c_uint32, 8), ('DW_3_DATA', ctypes.c_uint32, 12), ('DW_4_DATA', ctypes.c_uint32, 16), ('DW_5_DATA', ctypes.c_uint32, 20)])
rocr_AMD_SDMA_PKT_HDP_FLUSH: TypeAlias = rocr_AMD_SDMA_PKT_HDP_FLUSH_TAG
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG(c.Struct):
SIZE = 20
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION, 0]
WORD1_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION, 4]
WORD2_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION, 8]
WORD3_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION, 12]
WORD4_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION, 16]
HEADER_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION
WORD1_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION
WORD2_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION
WORD3_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION
WORD4_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION(c.Struct):
SIZE = 4
BaseVA_LO: Annotated[Annotated[int, ctypes.c_uint32], 0, 25, 7]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
BaseVA_LO: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION.register_fields([('BaseVA_LO', ctypes.c_uint32, 0, 25, 7), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION(c.Struct):
SIZE = 4
BaseVA_HI: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
GCR_CONTROL_GLI_INV: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
GCR_CONTROL_GL1_RANGE: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 2]
GCR_CONTROL_GLM_WB: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 4]
GCR_CONTROL_GLM_INV: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 5]
GCR_CONTROL_GLK_WB: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 6]
GCR_CONTROL_GLK_INV: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 7]
GCR_CONTROL_GLV_INV: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 0]
GCR_CONTROL_GL1_INV: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 1]
GCR_CONTROL_GL2_US: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 2]
GCR_CONTROL_GL2_RANGE: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 3]
GCR_CONTROL_GL2_DISCARD: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 5]
GCR_CONTROL_GL2_INV: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 6]
GCR_CONTROL_GL2_WB: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 7]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
BaseVA_HI: int
GCR_CONTROL_GLI_INV: int
GCR_CONTROL_GL1_RANGE: int
GCR_CONTROL_GLM_WB: int
GCR_CONTROL_GLM_INV: int
GCR_CONTROL_GLK_WB: int
GCR_CONTROL_GLK_INV: int
GCR_CONTROL_GLV_INV: int
GCR_CONTROL_GL1_INV: int
GCR_CONTROL_GL2_US: int
GCR_CONTROL_GL2_RANGE: int
GCR_CONTROL_GL2_DISCARD: int
GCR_CONTROL_GL2_INV: int
GCR_CONTROL_GL2_WB: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION.register_fields([('BaseVA_HI', ctypes.c_uint32, 0, 16, 0), ('GCR_CONTROL_GLI_INV', ctypes.c_uint32, 2, 2, 0), ('GCR_CONTROL_GL1_RANGE', ctypes.c_uint32, 2, 2, 2), ('GCR_CONTROL_GLM_WB', ctypes.c_uint32, 2, 1, 4), ('GCR_CONTROL_GLM_INV', ctypes.c_uint32, 2, 1, 5), ('GCR_CONTROL_GLK_WB', ctypes.c_uint32, 2, 1, 6), ('GCR_CONTROL_GLK_INV', ctypes.c_uint32, 2, 1, 7), ('GCR_CONTROL_GLV_INV', ctypes.c_uint32, 3, 1, 0), ('GCR_CONTROL_GL1_INV', ctypes.c_uint32, 3, 1, 1), ('GCR_CONTROL_GL2_US', ctypes.c_uint32, 3, 1, 2), ('GCR_CONTROL_GL2_RANGE', ctypes.c_uint32, 3, 2, 3), ('GCR_CONTROL_GL2_DISCARD', ctypes.c_uint32, 3, 1, 5), ('GCR_CONTROL_GL2_INV', ctypes.c_uint32, 3, 1, 6), ('GCR_CONTROL_GL2_WB', ctypes.c_uint32, 3, 1, 7), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION(c.Struct):
SIZE = 4
GCR_CONTROL_RANGE_IS_PA: Annotated[Annotated[int, ctypes.c_uint32], 0, 1, 0]
GCR_CONTROL_SEQ: Annotated[Annotated[int, ctypes.c_uint32], 0, 2, 1]
LimitVA_LO: Annotated[Annotated[int, ctypes.c_uint32], 0, 25, 7]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
GCR_CONTROL_RANGE_IS_PA: int
GCR_CONTROL_SEQ: int
LimitVA_LO: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION.register_fields([('GCR_CONTROL_RANGE_IS_PA', ctypes.c_uint32, 0, 1, 0), ('GCR_CONTROL_SEQ', ctypes.c_uint32, 0, 2, 1), ('LimitVA_LO', ctypes.c_uint32, 0, 25, 7), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION(c.Struct):
SIZE = 4
LimitVA_HI: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
VMID: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
LimitVA_HI: int
VMID: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION.register_fields([('LimitVA_HI', ctypes.c_uint32, 0, 16, 0), ('VMID', ctypes.c_uint32, 3, 4, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_GCR_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION, 0), ('WORD1_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION, 4), ('WORD2_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION, 8), ('WORD3_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION, 12), ('WORD4_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION, 16)])
rocr_AMD_SDMA_PKT_GCR: TypeAlias = rocr_AMD_SDMA_PKT_GCR_TAG
c.init_records()
SDMA_OP_COPY = 1 # type: ignore
SDMA_OP_FENCE = 5 # type: ignore
SDMA_OP_TRAP = 6 # type: ignore
+308 -246
View File
@@ -1,453 +1,515 @@
# mypy: disable-error-code="empty-body"
from __future__ import annotations
import ctypes
from typing import Annotated, Literal, TypeAlias
from typing import Literal, TypeAlias
from tinygrad.runtime.support.c import _IO, _IOW, _IOR, _IOWR
from tinygrad.runtime.support import c
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG(c.Struct):
SIZE = 28
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION, 0]
COUNT_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION, 4]
PARAMETER_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION, 8]
SRC_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION, 12]
SRC_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION, 16]
DST_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION, 20]
DST_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION, 24]
HEADER_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION
COUNT_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION
PARAMETER_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION
SRC_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION
SRC_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION
DST_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION
DST_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
extra_info: Annotated[Annotated[int, ctypes.c_uint32], 2, 16, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
extra_info: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('extra_info', ctypes.c_uint32, 2, 16, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION(c.Struct):
SIZE = 4
count: Annotated[Annotated[int, ctypes.c_uint32], 0, 22, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 10, 6]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
count: int
reserved_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION.register_fields([('count', ctypes.c_uint32, 0, 22, 0), ('reserved_0', ctypes.c_uint32, 2, 10, 6), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION(c.Struct):
SIZE = 4
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
dst_swap: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 2, 6, 2]
src_swap: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 6, 2]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
reserved_0: int
dst_swap: int
reserved_1: int
src_swap: int
reserved_2: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION.register_fields([('reserved_0', ctypes.c_uint32, 0, 16, 0), ('dst_swap', ctypes.c_uint32, 2, 2, 0), ('reserved_1', ctypes.c_uint32, 2, 6, 2), ('src_swap', ctypes.c_uint32, 3, 2, 0), ('reserved_2', ctypes.c_uint32, 3, 6, 2), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION(c.Struct):
SIZE = 4
src_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_31_0: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION.register_fields([('src_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION(c.Struct):
SIZE = 4
src_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_63_32: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION.register_fields([('src_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION(c.Struct):
SIZE = 4
dst_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_31_0: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION.register_fields([('dst_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_5_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION(c.Struct):
SIZE = 4
dst_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_6_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_63_32: int
DW_6_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION.register_fields([('dst_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_6_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_HEADER_UNION, 0), ('COUNT_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_COUNT_UNION, 4), ('PARAMETER_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_PARAMETER_UNION, 8), ('SRC_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_LO_UNION, 12), ('SRC_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_SRC_ADDR_HI_UNION, 16), ('DST_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_LO_UNION, 20), ('DST_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG_DST_ADDR_HI_UNION, 24)])
rocr_AMD_SDMA_PKT_COPY_LINEAR: TypeAlias = rocr_AMD_SDMA_PKT_COPY_LINEAR_TAG
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG(c.Struct):
SIZE = 52
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION, 0]
SRC_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION, 4]
SRC_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION, 8]
SRC_PARAMETER_1_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION, 12]
SRC_PARAMETER_2_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION, 16]
SRC_PARAMETER_3_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION, 20]
DST_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION, 24]
DST_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION, 28]
DST_PARAMETER_1_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION, 32]
DST_PARAMETER_2_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION, 36]
DST_PARAMETER_3_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION, 40]
RECT_PARAMETER_1_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION, 44]
RECT_PARAMETER_2_UNION: Annotated[rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION, 48]
HEADER_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION
SRC_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION
SRC_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION
SRC_PARAMETER_1_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION
SRC_PARAMETER_2_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION
SRC_PARAMETER_3_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION
DST_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION
DST_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION
DST_PARAMETER_1_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION
DST_PARAMETER_2_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION
DST_PARAMETER_3_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION
RECT_PARAMETER_1_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION
RECT_PARAMETER_2_UNION: rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved: Annotated[Annotated[int, ctypes.c_uint32], 2, 13, 0]
element: Annotated[Annotated[int, ctypes.c_uint32], 3, 3, 5]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved: int
element: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved', ctypes.c_uint32, 2, 13, 0), ('element', ctypes.c_uint32, 3, 3, 5), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION(c.Struct):
SIZE = 4
src_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION.register_fields([('src_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION(c.Struct):
SIZE = 4
src_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION.register_fields([('src_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION(c.Struct):
SIZE = 4
src_offset_x: Annotated[Annotated[int, ctypes.c_uint32], 0, 14, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 6]
src_offset_y: Annotated[Annotated[int, ctypes.c_uint32], 2, 14, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_offset_x: int
reserved_1: int
src_offset_y: int
reserved_2: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION.register_fields([('src_offset_x', ctypes.c_uint32, 0, 14, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 6), ('src_offset_y', ctypes.c_uint32, 2, 14, 0), ('reserved_2', ctypes.c_uint32, 3, 2, 6), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION(c.Struct):
SIZE = 4
src_offset_z: Annotated[Annotated[int, ctypes.c_uint32], 0, 11, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 3]
src_pitch: Annotated[Annotated[int, ctypes.c_uint32], 1, 19, 5]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_offset_z: int
reserved_1: int
src_pitch: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION.register_fields([('src_offset_z', ctypes.c_uint32, 0, 11, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 3), ('src_pitch', ctypes.c_uint32, 1, 19, 5), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION(c.Struct):
SIZE = 4
src_slice_pitch: Annotated[Annotated[int, ctypes.c_uint32], 0, 28, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_slice_pitch: int
reserved_1: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION.register_fields([('src_slice_pitch', ctypes.c_uint32, 0, 28, 0), ('reserved_1', ctypes.c_uint32, 3, 4, 4), ('DW_5_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION(c.Struct):
SIZE = 4
dst_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_6_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_31_0: int
DW_6_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION.register_fields([('dst_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_6_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION(c.Struct):
SIZE = 4
dst_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_7_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_63_32: int
DW_7_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION.register_fields([('dst_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_7_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION(c.Struct):
SIZE = 4
dst_offset_x: Annotated[Annotated[int, ctypes.c_uint32], 0, 14, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 6]
dst_offset_y: Annotated[Annotated[int, ctypes.c_uint32], 2, 14, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_8_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_offset_x: int
reserved_1: int
dst_offset_y: int
reserved_2: int
DW_8_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION.register_fields([('dst_offset_x', ctypes.c_uint32, 0, 14, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 6), ('dst_offset_y', ctypes.c_uint32, 2, 14, 0), ('reserved_2', ctypes.c_uint32, 3, 2, 6), ('DW_8_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION(c.Struct):
SIZE = 4
dst_offset_z: Annotated[Annotated[int, ctypes.c_uint32], 0, 11, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 3]
dst_pitch: Annotated[Annotated[int, ctypes.c_uint32], 1, 19, 5]
DW_9_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_offset_z: int
reserved_1: int
dst_pitch: int
DW_9_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION.register_fields([('dst_offset_z', ctypes.c_uint32, 0, 11, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 3), ('dst_pitch', ctypes.c_uint32, 1, 19, 5), ('DW_9_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION(c.Struct):
SIZE = 4
dst_slice_pitch: Annotated[Annotated[int, ctypes.c_uint32], 0, 28, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_10_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_slice_pitch: int
reserved_1: int
DW_10_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION.register_fields([('dst_slice_pitch', ctypes.c_uint32, 0, 28, 0), ('reserved_1', ctypes.c_uint32, 3, 4, 4), ('DW_10_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION(c.Struct):
SIZE = 4
rect_x: Annotated[Annotated[int, ctypes.c_uint32], 0, 14, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 2, 6]
rect_y: Annotated[Annotated[int, ctypes.c_uint32], 2, 14, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_11_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
rect_x: int
reserved_1: int
rect_y: int
reserved_2: int
DW_11_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION.register_fields([('rect_x', ctypes.c_uint32, 0, 14, 0), ('reserved_1', ctypes.c_uint32, 1, 2, 6), ('rect_y', ctypes.c_uint32, 2, 14, 0), ('reserved_2', ctypes.c_uint32, 3, 2, 6), ('DW_11_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION(c.Struct):
SIZE = 4
rect_z: Annotated[Annotated[int, ctypes.c_uint32], 0, 11, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 1, 5, 3]
dst_swap: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
reserved_2: Annotated[Annotated[int, ctypes.c_uint32], 2, 6, 2]
src_swap: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 0]
reserved_3: Annotated[Annotated[int, ctypes.c_uint32], 3, 6, 2]
DW_12_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
rect_z: int
reserved_1: int
dst_swap: int
reserved_2: int
src_swap: int
reserved_3: int
DW_12_DATA: int
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION.register_fields([('rect_z', ctypes.c_uint32, 0, 11, 0), ('reserved_1', ctypes.c_uint32, 1, 5, 3), ('dst_swap', ctypes.c_uint32, 2, 2, 0), ('reserved_2', ctypes.c_uint32, 2, 6, 2), ('src_swap', ctypes.c_uint32, 3, 2, 0), ('reserved_3', ctypes.c_uint32, 3, 6, 2), ('DW_12_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_HEADER_UNION, 0), ('SRC_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_LO_UNION, 4), ('SRC_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_ADDR_HI_UNION, 8), ('SRC_PARAMETER_1_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_1_UNION, 12), ('SRC_PARAMETER_2_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_2_UNION, 16), ('SRC_PARAMETER_3_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_SRC_PARAMETER_3_UNION, 20), ('DST_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_LO_UNION, 24), ('DST_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_ADDR_HI_UNION, 28), ('DST_PARAMETER_1_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_1_UNION, 32), ('DST_PARAMETER_2_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_2_UNION, 36), ('DST_PARAMETER_3_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_DST_PARAMETER_3_UNION, 40), ('RECT_PARAMETER_1_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_1_UNION, 44), ('RECT_PARAMETER_2_UNION', rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG_RECT_PARAMETER_2_UNION, 48)])
rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT: TypeAlias = rocr_AMD_SDMA_PKT_COPY_LINEAR_RECT_TAG
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG(c.Struct):
SIZE = 20
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION, 0]
DST_ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION, 4]
DST_ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION, 8]
DATA_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION, 12]
COUNT_UNION: Annotated[rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION, 16]
HEADER_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION
DST_ADDR_LO_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION
DST_ADDR_HI_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION
DATA_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION
COUNT_UNION: rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
sw: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 12, 2]
fillsize: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 6]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
sw: int
reserved_0: int
fillsize: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('sw', ctypes.c_uint32, 2, 2, 0), ('reserved_0', ctypes.c_uint32, 2, 12, 2), ('fillsize', ctypes.c_uint32, 3, 2, 6), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION(c.Struct):
SIZE = 4
dst_addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION.register_fields([('dst_addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION(c.Struct):
SIZE = 4
dst_addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
dst_addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION.register_fields([('dst_addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION(c.Struct):
SIZE = 4
src_data_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_data_31_0: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION.register_fields([('src_data_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION(c.Struct):
SIZE = 4
count: Annotated[Annotated[int, ctypes.c_uint32], 0, 22, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 10, 6]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
count: int
reserved_0: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION.register_fields([('count', ctypes.c_uint32, 0, 22, 0), ('reserved_0', ctypes.c_uint32, 2, 10, 6), ('DW_4_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_HEADER_UNION, 0), ('DST_ADDR_LO_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_LO_UNION, 4), ('DST_ADDR_HI_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DST_ADDR_HI_UNION, 8), ('DATA_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_DATA_UNION, 12), ('COUNT_UNION', rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG_COUNT_UNION, 16)])
rocr_AMD_SDMA_PKT_CONSTANT_FILL: TypeAlias = rocr_AMD_SDMA_PKT_CONSTANT_FILL_TAG
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG(c.Struct):
SIZE = 16
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION, 8]
DATA_UNION: Annotated[rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION, 12]
HEADER_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION
DATA_UNION: rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
mtype: Annotated[Annotated[int, ctypes.c_uint32], 2, 3, 0]
gcc: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 3]
sys: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 4]
pad1: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 5]
snp: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 6]
gpa: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 7]
l2_policy: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 3, 6, 2]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
mtype: int
gcc: int
sys: int
pad1: int
snp: int
gpa: int
l2_policy: int
reserved_0: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('mtype', ctypes.c_uint32, 2, 3, 0), ('gcc', ctypes.c_uint32, 2, 1, 3), ('sys', ctypes.c_uint32, 2, 1, 4), ('pad1', ctypes.c_uint32, 2, 1, 5), ('snp', ctypes.c_uint32, 2, 1, 6), ('gpa', ctypes.c_uint32, 2, 1, 7), ('l2_policy', ctypes.c_uint32, 3, 2, 0), ('reserved_0', ctypes.c_uint32, 3, 6, 2), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION(c.Struct):
SIZE = 4
data: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
data: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION.register_fields([('data', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_FENCE_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_ADDR_HI_UNION, 8), ('DATA_UNION', rocr_AMD_SDMA_PKT_FENCE_TAG_DATA_UNION, 12)])
rocr_AMD_SDMA_PKT_FENCE: TypeAlias = rocr_AMD_SDMA_PKT_FENCE_TAG
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG(c.Struct):
SIZE = 24
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION, 8]
VALUE_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION, 12]
MASK_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION, 16]
DW5_UNION: Annotated[rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION, 20]
HEADER_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION
VALUE_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION
MASK_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION
DW5_UNION: rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 10, 0]
hdp_flush: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 2]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 3]
func: Annotated[Annotated[int, ctypes.c_uint32], 3, 3, 4]
mem_poll: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 7]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved_0: int
hdp_flush: int
reserved_1: int
func: int
mem_poll: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved_0', ctypes.c_uint32, 2, 10, 0), ('hdp_flush', ctypes.c_uint32, 3, 1, 2), ('reserved_1', ctypes.c_uint32, 3, 1, 3), ('func', ctypes.c_uint32, 3, 3, 4), ('mem_poll', ctypes.c_uint32, 3, 1, 7), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION(c.Struct):
SIZE = 4
value: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
value: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION.register_fields([('value', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION(c.Struct):
SIZE = 4
mask: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
mask: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION.register_fields([('mask', ctypes.c_uint32, 0, 32, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION(c.Struct):
SIZE = 4
interval: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
retry_count: Annotated[Annotated[int, ctypes.c_uint32], 2, 12, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
interval: int
retry_count: int
reserved_0: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION.register_fields([('interval', ctypes.c_uint32, 0, 16, 0), ('retry_count', ctypes.c_uint32, 2, 12, 0), ('reserved_0', ctypes.c_uint32, 3, 4, 4), ('DW_5_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_ADDR_HI_UNION, 8), ('VALUE_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_VALUE_UNION, 12), ('MASK_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_MASK_UNION, 16), ('DW5_UNION', rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG_DW5_UNION, 20)])
rocr_AMD_SDMA_PKT_POLL_REGMEM: TypeAlias = rocr_AMD_SDMA_PKT_POLL_REGMEM_TAG
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG(c.Struct):
SIZE = 32
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION, 8]
SRC_DATA_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION, 12]
SRC_DATA_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION, 16]
CMP_DATA_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION, 20]
CMP_DATA_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION, 24]
LOOP_UNION: Annotated[rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION, 28]
HEADER_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION
SRC_DATA_LO_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION
SRC_DATA_HI_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION
CMP_DATA_LO_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION
CMP_DATA_HI_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION
LOOP_UNION: rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
l: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 8, 1]
operation: Annotated[Annotated[int, ctypes.c_uint32], 3, 7, 1]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
l: int
reserved_0: int
operation: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('l', ctypes.c_uint32, 2, 1, 0), ('reserved_0', ctypes.c_uint32, 2, 8, 1), ('operation', ctypes.c_uint32, 3, 7, 1), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION(c.Struct):
SIZE = 4
src_data_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_data_31_0: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION.register_fields([('src_data_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION(c.Struct):
SIZE = 4
src_data_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
src_data_63_32: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION.register_fields([('src_data_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION(c.Struct):
SIZE = 4
cmp_data_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
cmp_data_31_0: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION.register_fields([('cmp_data_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_5_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION(c.Struct):
SIZE = 4
cmp_data_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_6_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
cmp_data_63_32: int
DW_6_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION.register_fields([('cmp_data_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_6_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION(c.Struct):
SIZE = 4
loop_interval: Annotated[Annotated[int, ctypes.c_uint32], 0, 13, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 1, 19, 5]
DW_7_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
loop_interval: int
reserved_0: int
DW_7_DATA: int
rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION.register_fields([('loop_interval', ctypes.c_uint32, 0, 13, 0), ('reserved_0', ctypes.c_uint32, 1, 19, 5), ('DW_7_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_ATOMIC_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_ADDR_HI_UNION, 8), ('SRC_DATA_LO_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_LO_UNION, 12), ('SRC_DATA_HI_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_SRC_DATA_HI_UNION, 16), ('CMP_DATA_LO_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_LO_UNION, 20), ('CMP_DATA_HI_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_CMP_DATA_HI_UNION, 24), ('LOOP_UNION', rocr_AMD_SDMA_PKT_ATOMIC_TAG_LOOP_UNION, 28)])
rocr_AMD_SDMA_PKT_ATOMIC: TypeAlias = rocr_AMD_SDMA_PKT_ATOMIC_TAG
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG(c.Struct):
SIZE = 12
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION, 0]
ADDR_LO_UNION: Annotated[rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION, 4]
ADDR_HI_UNION: Annotated[rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION, 8]
HEADER_UNION: rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION
ADDR_LO_UNION: rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION
ADDR_HI_UNION: rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 16, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved_0: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved_0', ctypes.c_uint32, 2, 16, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION(c.Struct):
SIZE = 4
addr_31_0: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_31_0: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION.register_fields([('addr_31_0', ctypes.c_uint32, 0, 32, 0), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION(c.Struct):
SIZE = 4
addr_63_32: Annotated[Annotated[int, ctypes.c_uint32], 0, 32, 0]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
addr_63_32: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION.register_fields([('addr_63_32', ctypes.c_uint32, 0, 32, 0), ('DW_2_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_TIMESTAMP_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_HEADER_UNION, 0), ('ADDR_LO_UNION', rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_LO_UNION, 4), ('ADDR_HI_UNION', rocr_AMD_SDMA_PKT_TIMESTAMP_TAG_ADDR_HI_UNION, 8)])
rocr_AMD_SDMA_PKT_TIMESTAMP: TypeAlias = rocr_AMD_SDMA_PKT_TIMESTAMP_TAG
@c.record
class rocr_AMD_SDMA_PKT_TRAP_TAG(c.Struct):
SIZE = 8
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION, 0]
INT_CONTEXT_UNION: Annotated[rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION, 4]
HEADER_UNION: rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION
INT_CONTEXT_UNION: rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION
@c.record
class rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
reserved_0: Annotated[Annotated[int, ctypes.c_uint32], 2, 16, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
reserved_0: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('reserved_0', ctypes.c_uint32, 2, 16, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION(c.Struct):
SIZE = 4
int_ctx: Annotated[Annotated[int, ctypes.c_uint32], 0, 28, 0]
reserved_1: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 4]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
int_ctx: int
reserved_1: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION.register_fields([('int_ctx', ctypes.c_uint32, 0, 28, 0), ('reserved_1', ctypes.c_uint32, 3, 4, 4), ('DW_1_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_TRAP_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_TRAP_TAG_HEADER_UNION, 0), ('INT_CONTEXT_UNION', rocr_AMD_SDMA_PKT_TRAP_TAG_INT_CONTEXT_UNION, 4)])
rocr_AMD_SDMA_PKT_TRAP: TypeAlias = rocr_AMD_SDMA_PKT_TRAP_TAG
@c.record
class rocr_AMD_SDMA_PKT_HDP_FLUSH_TAG(c.Struct):
SIZE = 24
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 4]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 8]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 12]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 16]
DW_5_DATA: Annotated[Annotated[int, ctypes.c_uint32], 20]
DW_0_DATA: int
DW_1_DATA: int
DW_2_DATA: int
DW_3_DATA: int
DW_4_DATA: int
DW_5_DATA: int
rocr_AMD_SDMA_PKT_HDP_FLUSH_TAG.register_fields([('DW_0_DATA', ctypes.c_uint32, 0), ('DW_1_DATA', ctypes.c_uint32, 4), ('DW_2_DATA', ctypes.c_uint32, 8), ('DW_3_DATA', ctypes.c_uint32, 12), ('DW_4_DATA', ctypes.c_uint32, 16), ('DW_5_DATA', ctypes.c_uint32, 20)])
rocr_AMD_SDMA_PKT_HDP_FLUSH: TypeAlias = rocr_AMD_SDMA_PKT_HDP_FLUSH_TAG
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG(c.Struct):
SIZE = 20
HEADER_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION, 0]
WORD1_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION, 4]
WORD2_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION, 8]
WORD3_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION, 12]
WORD4_UNION: Annotated[rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION, 16]
HEADER_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION
WORD1_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION
WORD2_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION
WORD3_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION
WORD4_UNION: rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION(c.Struct):
SIZE = 4
op: Annotated[Annotated[int, ctypes.c_uint32], 0, 8, 0]
sub_op: Annotated[Annotated[int, ctypes.c_uint32], 1, 8, 0]
DW_0_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
op: int
sub_op: int
DW_0_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION.register_fields([('op', ctypes.c_uint32, 0, 8, 0), ('sub_op', ctypes.c_uint32, 1, 8, 0), ('DW_0_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION(c.Struct):
SIZE = 4
BaseVA_LO: Annotated[Annotated[int, ctypes.c_uint32], 0, 25, 7]
DW_1_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
BaseVA_LO: int
DW_1_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION.register_fields([('BaseVA_LO', ctypes.c_uint32, 0, 25, 7), ('DW_1_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION(c.Struct):
SIZE = 4
BaseVA_HI: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
GCR_CONTROL_GLI_INV: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 0]
GCR_CONTROL_GL1_RANGE: Annotated[Annotated[int, ctypes.c_uint32], 2, 2, 2]
GCR_CONTROL_GLM_WB: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 4]
GCR_CONTROL_GLM_INV: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 5]
GCR_CONTROL_GLK_WB: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 6]
GCR_CONTROL_GLK_INV: Annotated[Annotated[int, ctypes.c_uint32], 2, 1, 7]
GCR_CONTROL_GLV_INV: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 0]
GCR_CONTROL_GL1_INV: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 1]
GCR_CONTROL_GL2_US: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 2]
GCR_CONTROL_GL2_RANGE: Annotated[Annotated[int, ctypes.c_uint32], 3, 2, 3]
GCR_CONTROL_GL2_DISCARD: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 5]
GCR_CONTROL_GL2_INV: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 6]
GCR_CONTROL_GL2_WB: Annotated[Annotated[int, ctypes.c_uint32], 3, 1, 7]
DW_2_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
BaseVA_HI: int
GCR_CONTROL_GLI_INV: int
GCR_CONTROL_GL1_RANGE: int
GCR_CONTROL_GLM_WB: int
GCR_CONTROL_GLM_INV: int
GCR_CONTROL_GLK_WB: int
GCR_CONTROL_GLK_INV: int
GCR_CONTROL_GLV_INV: int
GCR_CONTROL_GL1_INV: int
GCR_CONTROL_GL2_US: int
GCR_CONTROL_GL2_RANGE: int
GCR_CONTROL_GL2_DISCARD: int
GCR_CONTROL_GL2_INV: int
GCR_CONTROL_GL2_WB: int
DW_2_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION.register_fields([('BaseVA_HI', ctypes.c_uint32, 0, 16, 0), ('GCR_CONTROL_GLI_INV', ctypes.c_uint32, 2, 2, 0), ('GCR_CONTROL_GL1_RANGE', ctypes.c_uint32, 2, 2, 2), ('GCR_CONTROL_GLM_WB', ctypes.c_uint32, 2, 1, 4), ('GCR_CONTROL_GLM_INV', ctypes.c_uint32, 2, 1, 5), ('GCR_CONTROL_GLK_WB', ctypes.c_uint32, 2, 1, 6), ('GCR_CONTROL_GLK_INV', ctypes.c_uint32, 2, 1, 7), ('GCR_CONTROL_GLV_INV', ctypes.c_uint32, 3, 1, 0), ('GCR_CONTROL_GL1_INV', ctypes.c_uint32, 3, 1, 1), ('GCR_CONTROL_GL2_US', ctypes.c_uint32, 3, 1, 2), ('GCR_CONTROL_GL2_RANGE', ctypes.c_uint32, 3, 2, 3), ('GCR_CONTROL_GL2_DISCARD', ctypes.c_uint32, 3, 1, 5), ('GCR_CONTROL_GL2_INV', ctypes.c_uint32, 3, 1, 6), ('GCR_CONTROL_GL2_WB', ctypes.c_uint32, 3, 1, 7), ('DW_2_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION(c.Struct):
SIZE = 4
GCR_CONTROL_RANGE_IS_PA: Annotated[Annotated[int, ctypes.c_uint32], 0, 1, 0]
GCR_CONTROL_SEQ: Annotated[Annotated[int, ctypes.c_uint32], 0, 2, 1]
LimitVA_LO: Annotated[Annotated[int, ctypes.c_uint32], 0, 25, 7]
DW_3_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
GCR_CONTROL_RANGE_IS_PA: int
GCR_CONTROL_SEQ: int
LimitVA_LO: int
DW_3_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION.register_fields([('GCR_CONTROL_RANGE_IS_PA', ctypes.c_uint32, 0, 1, 0), ('GCR_CONTROL_SEQ', ctypes.c_uint32, 0, 2, 1), ('LimitVA_LO', ctypes.c_uint32, 0, 25, 7), ('DW_3_DATA', ctypes.c_uint32, 0)])
@c.record
class rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION(c.Struct):
SIZE = 4
LimitVA_HI: Annotated[Annotated[int, ctypes.c_uint32], 0, 16, 0]
VMID: Annotated[Annotated[int, ctypes.c_uint32], 3, 4, 0]
DW_4_DATA: Annotated[Annotated[int, ctypes.c_uint32], 0]
LimitVA_HI: int
VMID: int
DW_4_DATA: int
rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION.register_fields([('LimitVA_HI', ctypes.c_uint32, 0, 16, 0), ('VMID', ctypes.c_uint32, 3, 4, 0), ('DW_4_DATA', ctypes.c_uint32, 0)])
rocr_AMD_SDMA_PKT_GCR_TAG.register_fields([('HEADER_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_HEADER_UNION, 0), ('WORD1_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD1_UNION, 4), ('WORD2_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD2_UNION, 8), ('WORD3_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD3_UNION, 12), ('WORD4_UNION', rocr_AMD_SDMA_PKT_GCR_TAG_WORD4_UNION, 16)])
rocr_AMD_SDMA_PKT_GCR: TypeAlias = rocr_AMD_SDMA_PKT_GCR_TAG
c.init_records()
SDMA_OP_COPY = 1 # type: ignore
SDMA_OP_FENCE = 5 # type: ignore
SDMA_OP_TRAP = 6 # type: ignore
File diff suppressed because one or more lines are too long
+264 -567
View File
@@ -1,647 +1,344 @@
# mypy: disable-error-code="empty-body"
from __future__ import annotations
import ctypes
from typing import Annotated, Literal, TypeAlias
from typing import Literal, TypeAlias
from tinygrad.runtime.support.c import _IO, _IOW, _IOR, _IOWR
from tinygrad.runtime.support import c
PPSMC_Result: TypeAlias = Annotated[int, ctypes.c_uint32]
PPSMC_MSG: TypeAlias = Annotated[int, ctypes.c_uint32]
class FEATURE_LIST_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
FEATURE_DATA_CALCULATION = FEATURE_LIST_e.define('FEATURE_DATA_CALCULATION', 0)
FEATURE_DPM_FCLK = FEATURE_LIST_e.define('FEATURE_DPM_FCLK', 1)
FEATURE_DPM_GFXCLK = FEATURE_LIST_e.define('FEATURE_DPM_GFXCLK', 2)
FEATURE_DPM_LCLK = FEATURE_LIST_e.define('FEATURE_DPM_LCLK', 3)
FEATURE_DPM_SOCCLK = FEATURE_LIST_e.define('FEATURE_DPM_SOCCLK', 4)
FEATURE_DPM_UCLK = FEATURE_LIST_e.define('FEATURE_DPM_UCLK', 5)
FEATURE_DPM_VCN = FEATURE_LIST_e.define('FEATURE_DPM_VCN', 6)
FEATURE_DPM_XGMI = FEATURE_LIST_e.define('FEATURE_DPM_XGMI', 7)
FEATURE_DS_FCLK = FEATURE_LIST_e.define('FEATURE_DS_FCLK', 8)
FEATURE_DS_GFXCLK = FEATURE_LIST_e.define('FEATURE_DS_GFXCLK', 9)
FEATURE_DS_LCLK = FEATURE_LIST_e.define('FEATURE_DS_LCLK', 10)
FEATURE_DS_MP0CLK = FEATURE_LIST_e.define('FEATURE_DS_MP0CLK', 11)
FEATURE_DS_MP1CLK = FEATURE_LIST_e.define('FEATURE_DS_MP1CLK', 12)
FEATURE_DS_MPIOCLK = FEATURE_LIST_e.define('FEATURE_DS_MPIOCLK', 13)
FEATURE_DS_SOCCLK = FEATURE_LIST_e.define('FEATURE_DS_SOCCLK', 14)
FEATURE_DS_VCN = FEATURE_LIST_e.define('FEATURE_DS_VCN', 15)
FEATURE_APCC_DFLL = FEATURE_LIST_e.define('FEATURE_APCC_DFLL', 16)
FEATURE_APCC_PLUS = FEATURE_LIST_e.define('FEATURE_APCC_PLUS', 17)
FEATURE_PPT = FEATURE_LIST_e.define('FEATURE_PPT', 18)
FEATURE_TDC = FEATURE_LIST_e.define('FEATURE_TDC', 19)
FEATURE_THERMAL = FEATURE_LIST_e.define('FEATURE_THERMAL', 20)
FEATURE_SOC_PCC = FEATURE_LIST_e.define('FEATURE_SOC_PCC', 21)
FEATURE_PROCHOT = FEATURE_LIST_e.define('FEATURE_PROCHOT', 22)
FEATURE_FDD_AID_HBM = FEATURE_LIST_e.define('FEATURE_FDD_AID_HBM', 23)
FEATURE_FDD_AID_SOC = FEATURE_LIST_e.define('FEATURE_FDD_AID_SOC', 24)
FEATURE_FDD_XCD_EDC = FEATURE_LIST_e.define('FEATURE_FDD_XCD_EDC', 25)
FEATURE_FDD_XCD_XVMIN = FEATURE_LIST_e.define('FEATURE_FDD_XCD_XVMIN', 26)
FEATURE_FW_CTF = FEATURE_LIST_e.define('FEATURE_FW_CTF', 27)
FEATURE_SMU_CG = FEATURE_LIST_e.define('FEATURE_SMU_CG', 28)
FEATURE_PSI7 = FEATURE_LIST_e.define('FEATURE_PSI7', 29)
FEATURE_XGMI_PER_LINK_PWR_DOWN = FEATURE_LIST_e.define('FEATURE_XGMI_PER_LINK_PWR_DOWN', 30)
FEATURE_SOC_DC_RTC = FEATURE_LIST_e.define('FEATURE_SOC_DC_RTC', 31)
FEATURE_GFX_DC_RTC = FEATURE_LIST_e.define('FEATURE_GFX_DC_RTC', 32)
FEATURE_DVM_MIN_PSM = FEATURE_LIST_e.define('FEATURE_DVM_MIN_PSM', 33)
FEATURE_PRC = FEATURE_LIST_e.define('FEATURE_PRC', 34)
FEATURE_PSM_SQ_THROTTLER = FEATURE_LIST_e.define('FEATURE_PSM_SQ_THROTTLER', 35)
FEATURE_PIT = FEATURE_LIST_e.define('FEATURE_PIT', 36)
FEATURE_DVO = FEATURE_LIST_e.define('FEATURE_DVO', 37)
FEATURE_XVMINORPSM_CLKSTOP_DS = FEATURE_LIST_e.define('FEATURE_XVMINORPSM_CLKSTOP_DS', 38)
FEATURE_GLOBAL_DPM = FEATURE_LIST_e.define('FEATURE_GLOBAL_DPM', 39)
FEATURE_HROM_EN = FEATURE_LIST_e.define('FEATURE_HROM_EN', 40)
NUM_FEATURES = FEATURE_LIST_e.define('NUM_FEATURES', 41)
class PCIE_LINK_SPEED_INDEX_TABLE_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
PCIE_LINK_SPEED_INDEX_TABLE_RESERVED = PCIE_LINK_SPEED_INDEX_TABLE_e.define('PCIE_LINK_SPEED_INDEX_TABLE_RESERVED', 0)
PCIE_LINK_SPEED_INDEX_TABLE_GEN1 = PCIE_LINK_SPEED_INDEX_TABLE_e.define('PCIE_LINK_SPEED_INDEX_TABLE_GEN1', 1)
PCIE_LINK_SPEED_INDEX_TABLE_GEN2 = PCIE_LINK_SPEED_INDEX_TABLE_e.define('PCIE_LINK_SPEED_INDEX_TABLE_GEN2', 2)
PCIE_LINK_SPEED_INDEX_TABLE_GEN3 = PCIE_LINK_SPEED_INDEX_TABLE_e.define('PCIE_LINK_SPEED_INDEX_TABLE_GEN3', 3)
PCIE_LINK_SPEED_INDEX_TABLE_GEN4 = PCIE_LINK_SPEED_INDEX_TABLE_e.define('PCIE_LINK_SPEED_INDEX_TABLE_GEN4', 4)
PCIE_LINK_SPEED_INDEX_TABLE_GEN5 = PCIE_LINK_SPEED_INDEX_TABLE_e.define('PCIE_LINK_SPEED_INDEX_TABLE_GEN5', 5)
PCIE_LINK_SPEED_INDEX_TABLE_COUNT = PCIE_LINK_SPEED_INDEX_TABLE_e.define('PCIE_LINK_SPEED_INDEX_TABLE_COUNT', 6)
class GFX_GUARDBAND_OFFSET_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
GFX_GUARDBAND_OFFSET_0 = GFX_GUARDBAND_OFFSET_e.define('GFX_GUARDBAND_OFFSET_0', 0)
GFX_GUARDBAND_OFFSET_1 = GFX_GUARDBAND_OFFSET_e.define('GFX_GUARDBAND_OFFSET_1', 1)
GFX_GUARDBAND_OFFSET_2 = GFX_GUARDBAND_OFFSET_e.define('GFX_GUARDBAND_OFFSET_2', 2)
GFX_GUARDBAND_OFFSET_3 = GFX_GUARDBAND_OFFSET_e.define('GFX_GUARDBAND_OFFSET_3', 3)
GFX_GUARDBAND_OFFSET_4 = GFX_GUARDBAND_OFFSET_e.define('GFX_GUARDBAND_OFFSET_4', 4)
GFX_GUARDBAND_OFFSET_5 = GFX_GUARDBAND_OFFSET_e.define('GFX_GUARDBAND_OFFSET_5', 5)
GFX_GUARDBAND_OFFSET_6 = GFX_GUARDBAND_OFFSET_e.define('GFX_GUARDBAND_OFFSET_6', 6)
GFX_GUARDBAND_OFFSET_7 = GFX_GUARDBAND_OFFSET_e.define('GFX_GUARDBAND_OFFSET_7', 7)
GFX_GUARDBAND_OFFSET_COUNT = GFX_GUARDBAND_OFFSET_e.define('GFX_GUARDBAND_OFFSET_COUNT', 8)
class GFX_DVM_MARGIN_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
GFX_DVM_MARGINHI_0 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINHI_0', 0)
GFX_DVM_MARGINHI_1 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINHI_1', 1)
GFX_DVM_MARGINHI_2 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINHI_2', 2)
GFX_DVM_MARGINHI_3 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINHI_3', 3)
GFX_DVM_MARGINHI_4 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINHI_4', 4)
GFX_DVM_MARGINHI_5 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINHI_5', 5)
GFX_DVM_MARGINHI_6 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINHI_6', 6)
GFX_DVM_MARGINHI_7 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINHI_7', 7)
GFX_DVM_MARGINLO_0 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINLO_0', 8)
GFX_DVM_MARGINLO_1 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINLO_1', 9)
GFX_DVM_MARGINLO_2 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINLO_2', 10)
GFX_DVM_MARGINLO_3 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINLO_3', 11)
GFX_DVM_MARGINLO_4 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINLO_4', 12)
GFX_DVM_MARGINLO_5 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINLO_5', 13)
GFX_DVM_MARGINLO_6 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINLO_6', 14)
GFX_DVM_MARGINLO_7 = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGINLO_7', 15)
GFX_DVM_MARGIN_COUNT = GFX_DVM_MARGIN_e.define('GFX_DVM_MARGIN_COUNT', 16)
class SYSTEM_TEMP_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
SYSTEM_TEMP_UBB_FPGA = SYSTEM_TEMP_e.define('SYSTEM_TEMP_UBB_FPGA', 0)
SYSTEM_TEMP_UBB_FRONT = SYSTEM_TEMP_e.define('SYSTEM_TEMP_UBB_FRONT', 1)
SYSTEM_TEMP_UBB_BACK = SYSTEM_TEMP_e.define('SYSTEM_TEMP_UBB_BACK', 2)
SYSTEM_TEMP_UBB_OAM7 = SYSTEM_TEMP_e.define('SYSTEM_TEMP_UBB_OAM7', 3)
SYSTEM_TEMP_UBB_IBC = SYSTEM_TEMP_e.define('SYSTEM_TEMP_UBB_IBC', 4)
SYSTEM_TEMP_UBB_UFPGA = SYSTEM_TEMP_e.define('SYSTEM_TEMP_UBB_UFPGA', 5)
SYSTEM_TEMP_UBB_OAM1 = SYSTEM_TEMP_e.define('SYSTEM_TEMP_UBB_OAM1', 6)
SYSTEM_TEMP_OAM_0_1_HSC = SYSTEM_TEMP_e.define('SYSTEM_TEMP_OAM_0_1_HSC', 7)
SYSTEM_TEMP_OAM_2_3_HSC = SYSTEM_TEMP_e.define('SYSTEM_TEMP_OAM_2_3_HSC', 8)
SYSTEM_TEMP_OAM_4_5_HSC = SYSTEM_TEMP_e.define('SYSTEM_TEMP_OAM_4_5_HSC', 9)
SYSTEM_TEMP_OAM_6_7_HSC = SYSTEM_TEMP_e.define('SYSTEM_TEMP_OAM_6_7_HSC', 10)
SYSTEM_TEMP_UBB_FPGA_0V72_VR = SYSTEM_TEMP_e.define('SYSTEM_TEMP_UBB_FPGA_0V72_VR', 11)
SYSTEM_TEMP_UBB_FPGA_3V3_VR = SYSTEM_TEMP_e.define('SYSTEM_TEMP_UBB_FPGA_3V3_VR', 12)
SYSTEM_TEMP_RETIMER_0_1_2_3_1V2_VR = SYSTEM_TEMP_e.define('SYSTEM_TEMP_RETIMER_0_1_2_3_1V2_VR', 13)
SYSTEM_TEMP_RETIMER_4_5_6_7_1V2_VR = SYSTEM_TEMP_e.define('SYSTEM_TEMP_RETIMER_4_5_6_7_1V2_VR', 14)
SYSTEM_TEMP_RETIMER_0_1_0V9_VR = SYSTEM_TEMP_e.define('SYSTEM_TEMP_RETIMER_0_1_0V9_VR', 15)
SYSTEM_TEMP_RETIMER_4_5_0V9_VR = SYSTEM_TEMP_e.define('SYSTEM_TEMP_RETIMER_4_5_0V9_VR', 16)
SYSTEM_TEMP_RETIMER_2_3_0V9_VR = SYSTEM_TEMP_e.define('SYSTEM_TEMP_RETIMER_2_3_0V9_VR', 17)
SYSTEM_TEMP_RETIMER_6_7_0V9_VR = SYSTEM_TEMP_e.define('SYSTEM_TEMP_RETIMER_6_7_0V9_VR', 18)
SYSTEM_TEMP_OAM_0_1_2_3_3V3_VR = SYSTEM_TEMP_e.define('SYSTEM_TEMP_OAM_0_1_2_3_3V3_VR', 19)
SYSTEM_TEMP_OAM_4_5_6_7_3V3_VR = SYSTEM_TEMP_e.define('SYSTEM_TEMP_OAM_4_5_6_7_3V3_VR', 20)
SYSTEM_TEMP_IBC_HSC = SYSTEM_TEMP_e.define('SYSTEM_TEMP_IBC_HSC', 21)
SYSTEM_TEMP_IBC = SYSTEM_TEMP_e.define('SYSTEM_TEMP_IBC', 22)
SYSTEM_TEMP_MAX_ENTRIES = SYSTEM_TEMP_e.define('SYSTEM_TEMP_MAX_ENTRIES', 32)
class NODE_TEMP_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
NODE_TEMP_RETIMER = NODE_TEMP_e.define('NODE_TEMP_RETIMER', 0)
NODE_TEMP_IBC_TEMP = NODE_TEMP_e.define('NODE_TEMP_IBC_TEMP', 1)
NODE_TEMP_IBC_2_TEMP = NODE_TEMP_e.define('NODE_TEMP_IBC_2_TEMP', 2)
NODE_TEMP_VDD18_VR_TEMP = NODE_TEMP_e.define('NODE_TEMP_VDD18_VR_TEMP', 3)
NODE_TEMP_04_HBM_B_VR_TEMP = NODE_TEMP_e.define('NODE_TEMP_04_HBM_B_VR_TEMP', 4)
NODE_TEMP_04_HBM_D_VR_TEMP = NODE_TEMP_e.define('NODE_TEMP_04_HBM_D_VR_TEMP', 5)
NODE_TEMP_MAX_TEMP_ENTRIES = NODE_TEMP_e.define('NODE_TEMP_MAX_TEMP_ENTRIES', 12)
class SVI_TEMP_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
SVI_VDDCR_VDD0_TEMP = SVI_TEMP_e.define('SVI_VDDCR_VDD0_TEMP', 0)
SVI_VDDCR_VDD1_TEMP = SVI_TEMP_e.define('SVI_VDDCR_VDD1_TEMP', 1)
SVI_VDDCR_VDD2_TEMP = SVI_TEMP_e.define('SVI_VDDCR_VDD2_TEMP', 2)
SVI_VDDCR_VDD3_TEMP = SVI_TEMP_e.define('SVI_VDDCR_VDD3_TEMP', 3)
SVI_VDDCR_SOC_A_TEMP = SVI_TEMP_e.define('SVI_VDDCR_SOC_A_TEMP', 4)
SVI_VDDCR_SOC_C_TEMP = SVI_TEMP_e.define('SVI_VDDCR_SOC_C_TEMP', 5)
SVI_VDDCR_SOCIO_A_TEMP = SVI_TEMP_e.define('SVI_VDDCR_SOCIO_A_TEMP', 6)
SVI_VDDCR_SOCIO_C_TEMP = SVI_TEMP_e.define('SVI_VDDCR_SOCIO_C_TEMP', 7)
SVI_VDD_085_HBM_TEMP = SVI_TEMP_e.define('SVI_VDD_085_HBM_TEMP', 8)
SVI_VDDCR_11_HBM_B_TEMP = SVI_TEMP_e.define('SVI_VDDCR_11_HBM_B_TEMP', 9)
SVI_VDDCR_11_HBM_D_TEMP = SVI_TEMP_e.define('SVI_VDDCR_11_HBM_D_TEMP', 10)
SVI_VDD_USR_TEMP = SVI_TEMP_e.define('SVI_VDD_USR_TEMP', 11)
SVI_VDDIO_11_E32_TEMP = SVI_TEMP_e.define('SVI_VDDIO_11_E32_TEMP', 12)
SVI_MAX_TEMP_ENTRIES = SVI_TEMP_e.define('SVI_MAX_TEMP_ENTRIES', 13)
PPSMC_Result: TypeAlias = ctypes.c_uint32
PPSMC_MSG: TypeAlias = ctypes.c_uint32
FEATURE_LIST_e: dict[int, str] = {(FEATURE_DATA_CALCULATION:=0): 'FEATURE_DATA_CALCULATION', (FEATURE_DPM_FCLK:=1): 'FEATURE_DPM_FCLK', (FEATURE_DPM_GFXCLK:=2): 'FEATURE_DPM_GFXCLK', (FEATURE_DPM_LCLK:=3): 'FEATURE_DPM_LCLK', (FEATURE_DPM_SOCCLK:=4): 'FEATURE_DPM_SOCCLK', (FEATURE_DPM_UCLK:=5): 'FEATURE_DPM_UCLK', (FEATURE_DPM_VCN:=6): 'FEATURE_DPM_VCN', (FEATURE_DPM_XGMI:=7): 'FEATURE_DPM_XGMI', (FEATURE_DS_FCLK:=8): 'FEATURE_DS_FCLK', (FEATURE_DS_GFXCLK:=9): 'FEATURE_DS_GFXCLK', (FEATURE_DS_LCLK:=10): 'FEATURE_DS_LCLK', (FEATURE_DS_MP0CLK:=11): 'FEATURE_DS_MP0CLK', (FEATURE_DS_MP1CLK:=12): 'FEATURE_DS_MP1CLK', (FEATURE_DS_MPIOCLK:=13): 'FEATURE_DS_MPIOCLK', (FEATURE_DS_SOCCLK:=14): 'FEATURE_DS_SOCCLK', (FEATURE_DS_VCN:=15): 'FEATURE_DS_VCN', (FEATURE_APCC_DFLL:=16): 'FEATURE_APCC_DFLL', (FEATURE_APCC_PLUS:=17): 'FEATURE_APCC_PLUS', (FEATURE_PPT:=18): 'FEATURE_PPT', (FEATURE_TDC:=19): 'FEATURE_TDC', (FEATURE_THERMAL:=20): 'FEATURE_THERMAL', (FEATURE_SOC_PCC:=21): 'FEATURE_SOC_PCC', (FEATURE_PROCHOT:=22): 'FEATURE_PROCHOT', (FEATURE_FDD_AID_HBM:=23): 'FEATURE_FDD_AID_HBM', (FEATURE_FDD_AID_SOC:=24): 'FEATURE_FDD_AID_SOC', (FEATURE_FDD_XCD_EDC:=25): 'FEATURE_FDD_XCD_EDC', (FEATURE_FDD_XCD_XVMIN:=26): 'FEATURE_FDD_XCD_XVMIN', (FEATURE_FW_CTF:=27): 'FEATURE_FW_CTF', (FEATURE_SMU_CG:=28): 'FEATURE_SMU_CG', (FEATURE_PSI7:=29): 'FEATURE_PSI7', (FEATURE_XGMI_PER_LINK_PWR_DOWN:=30): 'FEATURE_XGMI_PER_LINK_PWR_DOWN', (FEATURE_SOC_DC_RTC:=31): 'FEATURE_SOC_DC_RTC', (FEATURE_GFX_DC_RTC:=32): 'FEATURE_GFX_DC_RTC', (FEATURE_DVM_MIN_PSM:=33): 'FEATURE_DVM_MIN_PSM', (FEATURE_PRC:=34): 'FEATURE_PRC', (FEATURE_PSM_SQ_THROTTLER:=35): 'FEATURE_PSM_SQ_THROTTLER', (FEATURE_PIT:=36): 'FEATURE_PIT', (FEATURE_DVO:=37): 'FEATURE_DVO', (FEATURE_XVMINORPSM_CLKSTOP_DS:=38): 'FEATURE_XVMINORPSM_CLKSTOP_DS', (FEATURE_GLOBAL_DPM:=39): 'FEATURE_GLOBAL_DPM', (FEATURE_HROM_EN:=40): 'FEATURE_HROM_EN', (NUM_FEATURES:=41): 'NUM_FEATURES'}
PCIE_LINK_SPEED_INDEX_TABLE_e: dict[int, str] = {(PCIE_LINK_SPEED_INDEX_TABLE_RESERVED:=0): 'PCIE_LINK_SPEED_INDEX_TABLE_RESERVED', (PCIE_LINK_SPEED_INDEX_TABLE_GEN1:=1): 'PCIE_LINK_SPEED_INDEX_TABLE_GEN1', (PCIE_LINK_SPEED_INDEX_TABLE_GEN2:=2): 'PCIE_LINK_SPEED_INDEX_TABLE_GEN2', (PCIE_LINK_SPEED_INDEX_TABLE_GEN3:=3): 'PCIE_LINK_SPEED_INDEX_TABLE_GEN3', (PCIE_LINK_SPEED_INDEX_TABLE_GEN4:=4): 'PCIE_LINK_SPEED_INDEX_TABLE_GEN4', (PCIE_LINK_SPEED_INDEX_TABLE_GEN5:=5): 'PCIE_LINK_SPEED_INDEX_TABLE_GEN5', (PCIE_LINK_SPEED_INDEX_TABLE_COUNT:=6): 'PCIE_LINK_SPEED_INDEX_TABLE_COUNT'}
GFX_GUARDBAND_OFFSET_e: dict[int, str] = {(GFX_GUARDBAND_OFFSET_0:=0): 'GFX_GUARDBAND_OFFSET_0', (GFX_GUARDBAND_OFFSET_1:=1): 'GFX_GUARDBAND_OFFSET_1', (GFX_GUARDBAND_OFFSET_2:=2): 'GFX_GUARDBAND_OFFSET_2', (GFX_GUARDBAND_OFFSET_3:=3): 'GFX_GUARDBAND_OFFSET_3', (GFX_GUARDBAND_OFFSET_4:=4): 'GFX_GUARDBAND_OFFSET_4', (GFX_GUARDBAND_OFFSET_5:=5): 'GFX_GUARDBAND_OFFSET_5', (GFX_GUARDBAND_OFFSET_6:=6): 'GFX_GUARDBAND_OFFSET_6', (GFX_GUARDBAND_OFFSET_7:=7): 'GFX_GUARDBAND_OFFSET_7', (GFX_GUARDBAND_OFFSET_COUNT:=8): 'GFX_GUARDBAND_OFFSET_COUNT'}
GFX_DVM_MARGIN_e: dict[int, str] = {(GFX_DVM_MARGINHI_0:=0): 'GFX_DVM_MARGINHI_0', (GFX_DVM_MARGINHI_1:=1): 'GFX_DVM_MARGINHI_1', (GFX_DVM_MARGINHI_2:=2): 'GFX_DVM_MARGINHI_2', (GFX_DVM_MARGINHI_3:=3): 'GFX_DVM_MARGINHI_3', (GFX_DVM_MARGINHI_4:=4): 'GFX_DVM_MARGINHI_4', (GFX_DVM_MARGINHI_5:=5): 'GFX_DVM_MARGINHI_5', (GFX_DVM_MARGINHI_6:=6): 'GFX_DVM_MARGINHI_6', (GFX_DVM_MARGINHI_7:=7): 'GFX_DVM_MARGINHI_7', (GFX_DVM_MARGINLO_0:=8): 'GFX_DVM_MARGINLO_0', (GFX_DVM_MARGINLO_1:=9): 'GFX_DVM_MARGINLO_1', (GFX_DVM_MARGINLO_2:=10): 'GFX_DVM_MARGINLO_2', (GFX_DVM_MARGINLO_3:=11): 'GFX_DVM_MARGINLO_3', (GFX_DVM_MARGINLO_4:=12): 'GFX_DVM_MARGINLO_4', (GFX_DVM_MARGINLO_5:=13): 'GFX_DVM_MARGINLO_5', (GFX_DVM_MARGINLO_6:=14): 'GFX_DVM_MARGINLO_6', (GFX_DVM_MARGINLO_7:=15): 'GFX_DVM_MARGINLO_7', (GFX_DVM_MARGIN_COUNT:=16): 'GFX_DVM_MARGIN_COUNT'}
SYSTEM_TEMP_e: dict[int, str] = {(SYSTEM_TEMP_UBB_FPGA:=0): 'SYSTEM_TEMP_UBB_FPGA', (SYSTEM_TEMP_UBB_FRONT:=1): 'SYSTEM_TEMP_UBB_FRONT', (SYSTEM_TEMP_UBB_BACK:=2): 'SYSTEM_TEMP_UBB_BACK', (SYSTEM_TEMP_UBB_OAM7:=3): 'SYSTEM_TEMP_UBB_OAM7', (SYSTEM_TEMP_UBB_IBC:=4): 'SYSTEM_TEMP_UBB_IBC', (SYSTEM_TEMP_UBB_UFPGA:=5): 'SYSTEM_TEMP_UBB_UFPGA', (SYSTEM_TEMP_UBB_OAM1:=6): 'SYSTEM_TEMP_UBB_OAM1', (SYSTEM_TEMP_OAM_0_1_HSC:=7): 'SYSTEM_TEMP_OAM_0_1_HSC', (SYSTEM_TEMP_OAM_2_3_HSC:=8): 'SYSTEM_TEMP_OAM_2_3_HSC', (SYSTEM_TEMP_OAM_4_5_HSC:=9): 'SYSTEM_TEMP_OAM_4_5_HSC', (SYSTEM_TEMP_OAM_6_7_HSC:=10): 'SYSTEM_TEMP_OAM_6_7_HSC', (SYSTEM_TEMP_UBB_FPGA_0V72_VR:=11): 'SYSTEM_TEMP_UBB_FPGA_0V72_VR', (SYSTEM_TEMP_UBB_FPGA_3V3_VR:=12): 'SYSTEM_TEMP_UBB_FPGA_3V3_VR', (SYSTEM_TEMP_RETIMER_0_1_2_3_1V2_VR:=13): 'SYSTEM_TEMP_RETIMER_0_1_2_3_1V2_VR', (SYSTEM_TEMP_RETIMER_4_5_6_7_1V2_VR:=14): 'SYSTEM_TEMP_RETIMER_4_5_6_7_1V2_VR', (SYSTEM_TEMP_RETIMER_0_1_0V9_VR:=15): 'SYSTEM_TEMP_RETIMER_0_1_0V9_VR', (SYSTEM_TEMP_RETIMER_4_5_0V9_VR:=16): 'SYSTEM_TEMP_RETIMER_4_5_0V9_VR', (SYSTEM_TEMP_RETIMER_2_3_0V9_VR:=17): 'SYSTEM_TEMP_RETIMER_2_3_0V9_VR', (SYSTEM_TEMP_RETIMER_6_7_0V9_VR:=18): 'SYSTEM_TEMP_RETIMER_6_7_0V9_VR', (SYSTEM_TEMP_OAM_0_1_2_3_3V3_VR:=19): 'SYSTEM_TEMP_OAM_0_1_2_3_3V3_VR', (SYSTEM_TEMP_OAM_4_5_6_7_3V3_VR:=20): 'SYSTEM_TEMP_OAM_4_5_6_7_3V3_VR', (SYSTEM_TEMP_IBC_HSC:=21): 'SYSTEM_TEMP_IBC_HSC', (SYSTEM_TEMP_IBC:=22): 'SYSTEM_TEMP_IBC', (SYSTEM_TEMP_MAX_ENTRIES:=32): 'SYSTEM_TEMP_MAX_ENTRIES'}
NODE_TEMP_e: dict[int, str] = {(NODE_TEMP_RETIMER:=0): 'NODE_TEMP_RETIMER', (NODE_TEMP_IBC_TEMP:=1): 'NODE_TEMP_IBC_TEMP', (NODE_TEMP_IBC_2_TEMP:=2): 'NODE_TEMP_IBC_2_TEMP', (NODE_TEMP_VDD18_VR_TEMP:=3): 'NODE_TEMP_VDD18_VR_TEMP', (NODE_TEMP_04_HBM_B_VR_TEMP:=4): 'NODE_TEMP_04_HBM_B_VR_TEMP', (NODE_TEMP_04_HBM_D_VR_TEMP:=5): 'NODE_TEMP_04_HBM_D_VR_TEMP', (NODE_TEMP_MAX_TEMP_ENTRIES:=12): 'NODE_TEMP_MAX_TEMP_ENTRIES'}
SVI_TEMP_e: dict[int, str] = {(SVI_VDDCR_VDD0_TEMP:=0): 'SVI_VDDCR_VDD0_TEMP', (SVI_VDDCR_VDD1_TEMP:=1): 'SVI_VDDCR_VDD1_TEMP', (SVI_VDDCR_VDD2_TEMP:=2): 'SVI_VDDCR_VDD2_TEMP', (SVI_VDDCR_VDD3_TEMP:=3): 'SVI_VDDCR_VDD3_TEMP', (SVI_VDDCR_SOC_A_TEMP:=4): 'SVI_VDDCR_SOC_A_TEMP', (SVI_VDDCR_SOC_C_TEMP:=5): 'SVI_VDDCR_SOC_C_TEMP', (SVI_VDDCR_SOCIO_A_TEMP:=6): 'SVI_VDDCR_SOCIO_A_TEMP', (SVI_VDDCR_SOCIO_C_TEMP:=7): 'SVI_VDDCR_SOCIO_C_TEMP', (SVI_VDD_085_HBM_TEMP:=8): 'SVI_VDD_085_HBM_TEMP', (SVI_VDDCR_11_HBM_B_TEMP:=9): 'SVI_VDDCR_11_HBM_B_TEMP', (SVI_VDDCR_11_HBM_D_TEMP:=10): 'SVI_VDDCR_11_HBM_D_TEMP', (SVI_VDD_USR_TEMP:=11): 'SVI_VDD_USR_TEMP', (SVI_VDDIO_11_E32_TEMP:=12): 'SVI_VDDIO_11_E32_TEMP', (SVI_MAX_TEMP_ENTRIES:=13): 'SVI_MAX_TEMP_ENTRIES'}
@c.record
class MetricsTable_t(c.Struct):
SIZE = 1284
AccumulationCounter: Annotated[uint64_t, 0]
MaxSocketTemperature: Annotated[uint32_t, 8]
MaxVrTemperature: Annotated[uint32_t, 12]
MaxHbmTemperature: Annotated[uint32_t, 16]
MaxSocketTemperatureAcc: Annotated[uint64_t, 20]
MaxVrTemperatureAcc: Annotated[uint64_t, 28]
MaxHbmTemperatureAcc: Annotated[uint64_t, 36]
SocketPowerLimit: Annotated[uint32_t, 44]
SocketPower: Annotated[uint32_t, 48]
Timestamp: Annotated[uint64_t, 52]
SocketEnergyAcc: Annotated[uint64_t, 60]
XcdEnergyAcc: Annotated[uint64_t, 68]
AidEnergyAcc: Annotated[uint64_t, 76]
HbmEnergyAcc: Annotated[uint64_t, 84]
GfxclkFrequencyLimit: Annotated[uint32_t, 92]
FclkFrequency: Annotated[uint32_t, 96]
UclkFrequency: Annotated[uint32_t, 100]
SocclkFrequency: Annotated[c.Array[uint32_t, Literal[4]], 104]
VclkFrequency: Annotated[c.Array[uint32_t, Literal[4]], 120]
DclkFrequency: Annotated[c.Array[uint32_t, Literal[4]], 136]
LclkFrequency: Annotated[c.Array[uint32_t, Literal[4]], 152]
GfxclkFrequencyAcc: Annotated[c.Array[uint64_t, Literal[8]], 168]
MaxLclkDpmRange: Annotated[uint32_t, 232]
MinLclkDpmRange: Annotated[uint32_t, 236]
XgmiWidth: Annotated[uint32_t, 240]
XgmiBitrate: Annotated[uint32_t, 244]
XgmiReadBandwidthAcc: Annotated[c.Array[uint64_t, Literal[8]], 248]
XgmiWriteBandwidthAcc: Annotated[c.Array[uint64_t, Literal[8]], 312]
SocketGfxBusy: Annotated[uint32_t, 376]
DramBandwidthUtilization: Annotated[uint32_t, 380]
SocketGfxBusyAcc: Annotated[uint64_t, 384]
DramBandwidthAcc: Annotated[uint64_t, 392]
MaxDramBandwidth: Annotated[uint32_t, 400]
DramBandwidthUtilizationAcc: Annotated[uint64_t, 404]
PcieBandwidthAcc: Annotated[c.Array[uint64_t, Literal[4]], 412]
ProchotResidencyAcc: Annotated[uint32_t, 444]
PptResidencyAcc: Annotated[uint32_t, 448]
SocketThmResidencyAcc: Annotated[uint32_t, 452]
VrThmResidencyAcc: Annotated[uint32_t, 456]
HbmThmResidencyAcc: Annotated[uint32_t, 460]
GfxLockXCDMak: Annotated[uint32_t, 464]
GfxclkFrequency: Annotated[c.Array[uint32_t, Literal[8]], 468]
XgmiReadDataSizeAcc: Annotated[c.Array[uint64_t, Literal[8]], 500]
XgmiWriteDataSizeAcc: Annotated[c.Array[uint64_t, Literal[8]], 564]
PcieBandwidth: Annotated[c.Array[uint32_t, Literal[4]], 628]
PCIeL0ToRecoveryCountAcc: Annotated[uint32_t, 644]
PCIenReplayAAcc: Annotated[uint32_t, 648]
PCIenReplayARolloverCountAcc: Annotated[uint32_t, 652]
PCIeNAKSentCountAcc: Annotated[uint32_t, 656]
PCIeNAKReceivedCountAcc: Annotated[uint32_t, 660]
VcnBusy: Annotated[c.Array[uint32_t, Literal[4]], 664]
JpegBusy: Annotated[c.Array[uint32_t, Literal[40]], 680]
PCIeLinkSpeed: Annotated[uint32_t, 840]
PCIeLinkWidth: Annotated[uint32_t, 844]
GfxBusy: Annotated[c.Array[uint32_t, Literal[8]], 848]
GfxBusyAcc: Annotated[c.Array[uint64_t, Literal[8]], 880]
PCIeOtherEndRecoveryAcc: Annotated[uint32_t, 944]
GfxclkBelowHostLimitPptAcc: Annotated[c.Array[uint64_t, Literal[8]], 948]
GfxclkBelowHostLimitThmAcc: Annotated[c.Array[uint64_t, Literal[8]], 1012]
GfxclkBelowHostLimitTotalAcc: Annotated[c.Array[uint64_t, Literal[8]], 1076]
GfxclkLowUtilizationAcc: Annotated[c.Array[uint64_t, Literal[8]], 1140]
AidTemperature: Annotated[c.Array[uint32_t, Literal[4]], 1204]
XcdTemperature: Annotated[c.Array[uint32_t, Literal[8]], 1220]
HbmTemperature: Annotated[c.Array[uint32_t, Literal[8]], 1252]
uint64_t: TypeAlias = Annotated[int, ctypes.c_uint64]
uint32_t: TypeAlias = Annotated[int, ctypes.c_uint32]
AccumulationCounter: int
MaxSocketTemperature: int
MaxVrTemperature: int
MaxHbmTemperature: int
MaxSocketTemperatureAcc: int
MaxVrTemperatureAcc: int
MaxHbmTemperatureAcc: int
SocketPowerLimit: int
SocketPower: int
Timestamp: int
SocketEnergyAcc: int
XcdEnergyAcc: int
AidEnergyAcc: int
HbmEnergyAcc: int
GfxclkFrequencyLimit: int
FclkFrequency: int
UclkFrequency: int
SocclkFrequency: c.Array[ctypes.c_uint32, Literal[4]]
VclkFrequency: c.Array[ctypes.c_uint32, Literal[4]]
DclkFrequency: c.Array[ctypes.c_uint32, Literal[4]]
LclkFrequency: c.Array[ctypes.c_uint32, Literal[4]]
GfxclkFrequencyAcc: c.Array[ctypes.c_uint64, Literal[8]]
MaxLclkDpmRange: int
MinLclkDpmRange: int
XgmiWidth: int
XgmiBitrate: int
XgmiReadBandwidthAcc: c.Array[ctypes.c_uint64, Literal[8]]
XgmiWriteBandwidthAcc: c.Array[ctypes.c_uint64, Literal[8]]
SocketGfxBusy: int
DramBandwidthUtilization: int
SocketGfxBusyAcc: int
DramBandwidthAcc: int
MaxDramBandwidth: int
DramBandwidthUtilizationAcc: int
PcieBandwidthAcc: c.Array[ctypes.c_uint64, Literal[4]]
ProchotResidencyAcc: int
PptResidencyAcc: int
SocketThmResidencyAcc: int
VrThmResidencyAcc: int
HbmThmResidencyAcc: int
GfxLockXCDMak: int
GfxclkFrequency: c.Array[ctypes.c_uint32, Literal[8]]
XgmiReadDataSizeAcc: c.Array[ctypes.c_uint64, Literal[8]]
XgmiWriteDataSizeAcc: c.Array[ctypes.c_uint64, Literal[8]]
PcieBandwidth: c.Array[ctypes.c_uint32, Literal[4]]
PCIeL0ToRecoveryCountAcc: int
PCIenReplayAAcc: int
PCIenReplayARolloverCountAcc: int
PCIeNAKSentCountAcc: int
PCIeNAKReceivedCountAcc: int
VcnBusy: c.Array[ctypes.c_uint32, Literal[4]]
JpegBusy: c.Array[ctypes.c_uint32, Literal[40]]
PCIeLinkSpeed: int
PCIeLinkWidth: int
GfxBusy: c.Array[ctypes.c_uint32, Literal[8]]
GfxBusyAcc: c.Array[ctypes.c_uint64, Literal[8]]
PCIeOtherEndRecoveryAcc: int
GfxclkBelowHostLimitPptAcc: c.Array[ctypes.c_uint64, Literal[8]]
GfxclkBelowHostLimitThmAcc: c.Array[ctypes.c_uint64, Literal[8]]
GfxclkBelowHostLimitTotalAcc: c.Array[ctypes.c_uint64, Literal[8]]
GfxclkLowUtilizationAcc: c.Array[ctypes.c_uint64, Literal[8]]
AidTemperature: c.Array[ctypes.c_uint32, Literal[4]]
XcdTemperature: c.Array[ctypes.c_uint32, Literal[8]]
HbmTemperature: c.Array[ctypes.c_uint32, Literal[8]]
uint64_t: TypeAlias = ctypes.c_uint64
uint32_t: TypeAlias = ctypes.c_uint32
MetricsTable_t.register_fields([('AccumulationCounter', uint64_t, 0), ('MaxSocketTemperature', uint32_t, 8), ('MaxVrTemperature', uint32_t, 12), ('MaxHbmTemperature', uint32_t, 16), ('MaxSocketTemperatureAcc', uint64_t, 20), ('MaxVrTemperatureAcc', uint64_t, 28), ('MaxHbmTemperatureAcc', uint64_t, 36), ('SocketPowerLimit', uint32_t, 44), ('SocketPower', uint32_t, 48), ('Timestamp', uint64_t, 52), ('SocketEnergyAcc', uint64_t, 60), ('XcdEnergyAcc', uint64_t, 68), ('AidEnergyAcc', uint64_t, 76), ('HbmEnergyAcc', uint64_t, 84), ('GfxclkFrequencyLimit', uint32_t, 92), ('FclkFrequency', uint32_t, 96), ('UclkFrequency', uint32_t, 100), ('SocclkFrequency', c.Array[uint32_t, Literal[4]], 104), ('VclkFrequency', c.Array[uint32_t, Literal[4]], 120), ('DclkFrequency', c.Array[uint32_t, Literal[4]], 136), ('LclkFrequency', c.Array[uint32_t, Literal[4]], 152), ('GfxclkFrequencyAcc', c.Array[uint64_t, Literal[8]], 168), ('MaxLclkDpmRange', uint32_t, 232), ('MinLclkDpmRange', uint32_t, 236), ('XgmiWidth', uint32_t, 240), ('XgmiBitrate', uint32_t, 244), ('XgmiReadBandwidthAcc', c.Array[uint64_t, Literal[8]], 248), ('XgmiWriteBandwidthAcc', c.Array[uint64_t, Literal[8]], 312), ('SocketGfxBusy', uint32_t, 376), ('DramBandwidthUtilization', uint32_t, 380), ('SocketGfxBusyAcc', uint64_t, 384), ('DramBandwidthAcc', uint64_t, 392), ('MaxDramBandwidth', uint32_t, 400), ('DramBandwidthUtilizationAcc', uint64_t, 404), ('PcieBandwidthAcc', c.Array[uint64_t, Literal[4]], 412), ('ProchotResidencyAcc', uint32_t, 444), ('PptResidencyAcc', uint32_t, 448), ('SocketThmResidencyAcc', uint32_t, 452), ('VrThmResidencyAcc', uint32_t, 456), ('HbmThmResidencyAcc', uint32_t, 460), ('GfxLockXCDMak', uint32_t, 464), ('GfxclkFrequency', c.Array[uint32_t, Literal[8]], 468), ('XgmiReadDataSizeAcc', c.Array[uint64_t, Literal[8]], 500), ('XgmiWriteDataSizeAcc', c.Array[uint64_t, Literal[8]], 564), ('PcieBandwidth', c.Array[uint32_t, Literal[4]], 628), ('PCIeL0ToRecoveryCountAcc', uint32_t, 644), ('PCIenReplayAAcc', uint32_t, 648), ('PCIenReplayARolloverCountAcc', uint32_t, 652), ('PCIeNAKSentCountAcc', uint32_t, 656), ('PCIeNAKReceivedCountAcc', uint32_t, 660), ('VcnBusy', c.Array[uint32_t, Literal[4]], 664), ('JpegBusy', c.Array[uint32_t, Literal[40]], 680), ('PCIeLinkSpeed', uint32_t, 840), ('PCIeLinkWidth', uint32_t, 844), ('GfxBusy', c.Array[uint32_t, Literal[8]], 848), ('GfxBusyAcc', c.Array[uint64_t, Literal[8]], 880), ('PCIeOtherEndRecoveryAcc', uint32_t, 944), ('GfxclkBelowHostLimitPptAcc', c.Array[uint64_t, Literal[8]], 948), ('GfxclkBelowHostLimitThmAcc', c.Array[uint64_t, Literal[8]], 1012), ('GfxclkBelowHostLimitTotalAcc', c.Array[uint64_t, Literal[8]], 1076), ('GfxclkLowUtilizationAcc', c.Array[uint64_t, Literal[8]], 1140), ('AidTemperature', c.Array[uint32_t, Literal[4]], 1204), ('XcdTemperature', c.Array[uint32_t, Literal[8]], 1220), ('HbmTemperature', c.Array[uint32_t, Literal[8]], 1252)])
@c.record
class SystemMetricsTable_t(c.Struct):
SIZE = 152
AccumulationCounter: Annotated[uint64_t, 0]
LabelVersion: Annotated[uint16_t, 8]
NodeIdentifier: Annotated[uint16_t, 10]
SystemTemperatures: Annotated[c.Array[int16_t, Literal[32]], 12]
NodeTemperatures: Annotated[c.Array[int16_t, Literal[12]], 76]
VrTemperatures: Annotated[c.Array[int16_t, Literal[13]], 100]
spare: Annotated[c.Array[int16_t, Literal[7]], 126]
NodePowerLimit: Annotated[uint32_t, 140]
NodePower: Annotated[uint32_t, 144]
GlobalPPTResidencyAcc: Annotated[uint32_t, 148]
uint16_t: TypeAlias = Annotated[int, ctypes.c_uint16]
int16_t: TypeAlias = Annotated[int, ctypes.c_int16]
AccumulationCounter: int
LabelVersion: int
NodeIdentifier: int
SystemTemperatures: c.Array[ctypes.c_int16, Literal[32]]
NodeTemperatures: c.Array[ctypes.c_int16, Literal[12]]
VrTemperatures: c.Array[ctypes.c_int16, Literal[13]]
spare: c.Array[ctypes.c_int16, Literal[7]]
NodePowerLimit: int
NodePower: int
GlobalPPTResidencyAcc: int
uint16_t: TypeAlias = ctypes.c_uint16
int16_t: TypeAlias = ctypes.c_int16
SystemMetricsTable_t.register_fields([('AccumulationCounter', uint64_t, 0), ('LabelVersion', uint16_t, 8), ('NodeIdentifier', uint16_t, 10), ('SystemTemperatures', c.Array[int16_t, Literal[32]], 12), ('NodeTemperatures', c.Array[int16_t, Literal[12]], 76), ('VrTemperatures', c.Array[int16_t, Literal[13]], 100), ('spare', c.Array[int16_t, Literal[7]], 126), ('NodePowerLimit', uint32_t, 140), ('NodePower', uint32_t, 144), ('GlobalPPTResidencyAcc', uint32_t, 148)])
@c.record
class VfMetricsTable_t(c.Struct):
SIZE = 56
AccumulationCounter: Annotated[uint32_t, 0]
InstGfxclk_TargFreq: Annotated[uint32_t, 4]
AccGfxclk_TargFreq: Annotated[uint64_t, 8]
AccGfxRsmuDpm_Busy: Annotated[uint64_t, 16]
AccGfxclkBelowHostLimitPpt: Annotated[uint64_t, 24]
AccGfxclkBelowHostLimitThm: Annotated[uint64_t, 32]
AccGfxclkBelowHostLimitTotal: Annotated[uint64_t, 40]
AccGfxclkLowUtilization: Annotated[uint64_t, 48]
AccumulationCounter: int
InstGfxclk_TargFreq: int
AccGfxclk_TargFreq: int
AccGfxRsmuDpm_Busy: int
AccGfxclkBelowHostLimitPpt: int
AccGfxclkBelowHostLimitThm: int
AccGfxclkBelowHostLimitTotal: int
AccGfxclkLowUtilization: int
VfMetricsTable_t.register_fields([('AccumulationCounter', uint32_t, 0), ('InstGfxclk_TargFreq', uint32_t, 4), ('AccGfxclk_TargFreq', uint64_t, 8), ('AccGfxRsmuDpm_Busy', uint64_t, 16), ('AccGfxclkBelowHostLimitPpt', uint64_t, 24), ('AccGfxclkBelowHostLimitThm', uint64_t, 32), ('AccGfxclkBelowHostLimitTotal', uint64_t, 40), ('AccGfxclkLowUtilization', uint64_t, 48)])
@c.record
class FRUProductInfo_t(c.Struct):
SIZE = 168
ModelNumber: Annotated[c.Array[uint8_t, Literal[20]], 0]
Name: Annotated[c.Array[uint8_t, Literal[64]], 20]
Serial: Annotated[c.Array[uint8_t, Literal[20]], 84]
ManufacturerName: Annotated[c.Array[uint8_t, Literal[32]], 104]
FruId: Annotated[c.Array[uint8_t, Literal[32]], 136]
uint8_t: TypeAlias = Annotated[int, ctypes.c_ubyte]
ModelNumber: c.Array[ctypes.c_ubyte, Literal[20]]
Name: c.Array[ctypes.c_ubyte, Literal[64]]
Serial: c.Array[ctypes.c_ubyte, Literal[20]]
ManufacturerName: c.Array[ctypes.c_ubyte, Literal[32]]
FruId: c.Array[ctypes.c_ubyte, Literal[32]]
uint8_t: TypeAlias = ctypes.c_ubyte
FRUProductInfo_t.register_fields([('ModelNumber', c.Array[uint8_t, Literal[20]], 0), ('Name', c.Array[uint8_t, Literal[64]], 20), ('Serial', c.Array[uint8_t, Literal[20]], 84), ('ManufacturerName', c.Array[uint8_t, Literal[32]], 104), ('FruId', c.Array[uint8_t, Literal[32]], 136)])
@c.record
class StaticMetricsTable_t(c.Struct):
SIZE = 408
ProductInfo: Annotated[FRUProductInfo_t, 0]
MaxSocketPowerLimit: Annotated[uint32_t, 168]
MaxGfxclkFrequency: Annotated[uint32_t, 172]
MinGfxclkFrequency: Annotated[uint32_t, 176]
FclkFrequencyTable: Annotated[c.Array[uint32_t, Literal[4]], 180]
UclkFrequencyTable: Annotated[c.Array[uint32_t, Literal[4]], 196]
SocclkFrequencyTable: Annotated[c.Array[uint32_t, Literal[4]], 212]
VclkFrequencyTable: Annotated[c.Array[uint32_t, Literal[4]], 228]
DclkFrequencyTable: Annotated[c.Array[uint32_t, Literal[4]], 244]
LclkFrequencyTable: Annotated[c.Array[uint32_t, Literal[4]], 260]
PublicSerialNumber_AID: Annotated[c.Array[uint64_t, Literal[4]], 276]
PublicSerialNumber_XCD: Annotated[c.Array[uint64_t, Literal[8]], 308]
MaxXgmiWidth: Annotated[uint32_t, 372]
MaxXgmiBitrate: Annotated[uint32_t, 376]
InputTelemetryVoltageInmV: Annotated[uint32_t, 380]
pldmVersion: Annotated[c.Array[uint32_t, Literal[2]], 384]
MaxNodePowerLimit: Annotated[uint32_t, 392]
PPT1Max: Annotated[uint32_t, 396]
PPT1Min: Annotated[uint32_t, 400]
PPT1Default: Annotated[uint32_t, 404]
class I2cControllerPort_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
I2C_CONTROLLER_PORT_0 = I2cControllerPort_e.define('I2C_CONTROLLER_PORT_0', 0)
I2C_CONTROLLER_PORT_1 = I2cControllerPort_e.define('I2C_CONTROLLER_PORT_1', 1)
I2C_CONTROLLER_PORT_COUNT = I2cControllerPort_e.define('I2C_CONTROLLER_PORT_COUNT', 2)
class I2cSpeed_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
UNSUPPORTED_1 = I2cSpeed_e.define('UNSUPPORTED_1', 0)
I2C_SPEED_STANDARD_100K = I2cSpeed_e.define('I2C_SPEED_STANDARD_100K', 1)
I2C_SPEED_FAST_400K = I2cSpeed_e.define('I2C_SPEED_FAST_400K', 2)
I2C_SPEED_FAST_PLUS_1M = I2cSpeed_e.define('I2C_SPEED_FAST_PLUS_1M', 3)
UNSUPPORTED_2 = I2cSpeed_e.define('UNSUPPORTED_2', 4)
UNSUPPORTED_3 = I2cSpeed_e.define('UNSUPPORTED_3', 5)
I2C_SPEED_COUNT = I2cSpeed_e.define('I2C_SPEED_COUNT', 6)
class I2cCmdType_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
I2C_CMD_READ = I2cCmdType_e.define('I2C_CMD_READ', 0)
I2C_CMD_WRITE = I2cCmdType_e.define('I2C_CMD_WRITE', 1)
I2C_CMD_COUNT = I2cCmdType_e.define('I2C_CMD_COUNT', 2)
class ERR_CODE_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
CODE_DAGB0 = ERR_CODE_e.define('CODE_DAGB0', 0)
CODE_EA0 = ERR_CODE_e.define('CODE_EA0', 5)
CODE_UTCL2_ROUTER = ERR_CODE_e.define('CODE_UTCL2_ROUTER', 10)
CODE_VML2 = ERR_CODE_e.define('CODE_VML2', 11)
CODE_VML2_WALKER = ERR_CODE_e.define('CODE_VML2_WALKER', 12)
CODE_MMCANE = ERR_CODE_e.define('CODE_MMCANE', 13)
CODE_VIDD = ERR_CODE_e.define('CODE_VIDD', 14)
CODE_VIDV = ERR_CODE_e.define('CODE_VIDV', 15)
CODE_JPEG0S = ERR_CODE_e.define('CODE_JPEG0S', 16)
CODE_JPEG0D = ERR_CODE_e.define('CODE_JPEG0D', 17)
CODE_JPEG1S = ERR_CODE_e.define('CODE_JPEG1S', 18)
CODE_JPEG1D = ERR_CODE_e.define('CODE_JPEG1D', 19)
CODE_JPEG2S = ERR_CODE_e.define('CODE_JPEG2S', 20)
CODE_JPEG2D = ERR_CODE_e.define('CODE_JPEG2D', 21)
CODE_JPEG3S = ERR_CODE_e.define('CODE_JPEG3S', 22)
CODE_JPEG3D = ERR_CODE_e.define('CODE_JPEG3D', 23)
CODE_JPEG4S = ERR_CODE_e.define('CODE_JPEG4S', 24)
CODE_JPEG4D = ERR_CODE_e.define('CODE_JPEG4D', 25)
CODE_JPEG5S = ERR_CODE_e.define('CODE_JPEG5S', 26)
CODE_JPEG5D = ERR_CODE_e.define('CODE_JPEG5D', 27)
CODE_JPEG6S = ERR_CODE_e.define('CODE_JPEG6S', 28)
CODE_JPEG6D = ERR_CODE_e.define('CODE_JPEG6D', 29)
CODE_JPEG7S = ERR_CODE_e.define('CODE_JPEG7S', 30)
CODE_JPEG7D = ERR_CODE_e.define('CODE_JPEG7D', 31)
CODE_MMSCHD = ERR_CODE_e.define('CODE_MMSCHD', 32)
CODE_SDMA0 = ERR_CODE_e.define('CODE_SDMA0', 33)
CODE_SDMA1 = ERR_CODE_e.define('CODE_SDMA1', 34)
CODE_SDMA2 = ERR_CODE_e.define('CODE_SDMA2', 35)
CODE_SDMA3 = ERR_CODE_e.define('CODE_SDMA3', 36)
CODE_HDP = ERR_CODE_e.define('CODE_HDP', 37)
CODE_ATHUB = ERR_CODE_e.define('CODE_ATHUB', 38)
CODE_IH = ERR_CODE_e.define('CODE_IH', 39)
CODE_XHUB_POISON = ERR_CODE_e.define('CODE_XHUB_POISON', 40)
CODE_SMN_SLVERR = ERR_CODE_e.define('CODE_SMN_SLVERR', 40)
CODE_WDT = ERR_CODE_e.define('CODE_WDT', 41)
CODE_UNKNOWN = ERR_CODE_e.define('CODE_UNKNOWN', 42)
CODE_COUNT = ERR_CODE_e.define('CODE_COUNT', 43)
class GC_ERROR_CODE_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
SH_FED_CODE = GC_ERROR_CODE_e.define('SH_FED_CODE', 0)
GCEA_CODE = GC_ERROR_CODE_e.define('GCEA_CODE', 1)
SQ_CODE = GC_ERROR_CODE_e.define('SQ_CODE', 2)
LDS_CODE = GC_ERROR_CODE_e.define('LDS_CODE', 3)
GDS_CODE = GC_ERROR_CODE_e.define('GDS_CODE', 4)
SP0_CODE = GC_ERROR_CODE_e.define('SP0_CODE', 5)
SP1_CODE = GC_ERROR_CODE_e.define('SP1_CODE', 6)
TCC_CODE = GC_ERROR_CODE_e.define('TCC_CODE', 7)
TCA_CODE = GC_ERROR_CODE_e.define('TCA_CODE', 8)
TCX_CODE = GC_ERROR_CODE_e.define('TCX_CODE', 9)
CPC_CODE = GC_ERROR_CODE_e.define('CPC_CODE', 10)
CPF_CODE = GC_ERROR_CODE_e.define('CPF_CODE', 11)
CPG_CODE = GC_ERROR_CODE_e.define('CPG_CODE', 12)
SPI_CODE = GC_ERROR_CODE_e.define('SPI_CODE', 13)
RLC_CODE = GC_ERROR_CODE_e.define('RLC_CODE', 14)
SQC_CODE = GC_ERROR_CODE_e.define('SQC_CODE', 15)
TA_CODE = GC_ERROR_CODE_e.define('TA_CODE', 16)
TD_CODE = GC_ERROR_CODE_e.define('TD_CODE', 17)
TCP_CODE = GC_ERROR_CODE_e.define('TCP_CODE', 18)
TCI_CODE = GC_ERROR_CODE_e.define('TCI_CODE', 19)
GC_ROUTER_CODE = GC_ERROR_CODE_e.define('GC_ROUTER_CODE', 20)
VML2_CODE = GC_ERROR_CODE_e.define('VML2_CODE', 21)
VML2_WALKER_CODE = GC_ERROR_CODE_e.define('VML2_WALKER_CODE', 22)
ATCL2_CODE = GC_ERROR_CODE_e.define('ATCL2_CODE', 23)
GC_CANE_CODE = GC_ERROR_CODE_e.define('GC_CANE_CODE', 24)
MP5_CODE_SMN_SLVERR = GC_ERROR_CODE_e.define('MP5_CODE_SMN_SLVERR', 40)
MP5_CODE_UNKNOWN = GC_ERROR_CODE_e.define('MP5_CODE_UNKNOWN', 42)
ProductInfo: FRUProductInfo_t
MaxSocketPowerLimit: int
MaxGfxclkFrequency: int
MinGfxclkFrequency: int
FclkFrequencyTable: c.Array[ctypes.c_uint32, Literal[4]]
UclkFrequencyTable: c.Array[ctypes.c_uint32, Literal[4]]
SocclkFrequencyTable: c.Array[ctypes.c_uint32, Literal[4]]
VclkFrequencyTable: c.Array[ctypes.c_uint32, Literal[4]]
DclkFrequencyTable: c.Array[ctypes.c_uint32, Literal[4]]
LclkFrequencyTable: c.Array[ctypes.c_uint32, Literal[4]]
PublicSerialNumber_AID: c.Array[ctypes.c_uint64, Literal[4]]
PublicSerialNumber_XCD: c.Array[ctypes.c_uint64, Literal[8]]
MaxXgmiWidth: int
MaxXgmiBitrate: int
InputTelemetryVoltageInmV: int
pldmVersion: c.Array[ctypes.c_uint32, Literal[2]]
MaxNodePowerLimit: int
PPT1Max: int
PPT1Min: int
PPT1Default: int
StaticMetricsTable_t.register_fields([('ProductInfo', FRUProductInfo_t, 0), ('MaxSocketPowerLimit', uint32_t, 168), ('MaxGfxclkFrequency', uint32_t, 172), ('MinGfxclkFrequency', uint32_t, 176), ('FclkFrequencyTable', c.Array[uint32_t, Literal[4]], 180), ('UclkFrequencyTable', c.Array[uint32_t, Literal[4]], 196), ('SocclkFrequencyTable', c.Array[uint32_t, Literal[4]], 212), ('VclkFrequencyTable', c.Array[uint32_t, Literal[4]], 228), ('DclkFrequencyTable', c.Array[uint32_t, Literal[4]], 244), ('LclkFrequencyTable', c.Array[uint32_t, Literal[4]], 260), ('PublicSerialNumber_AID', c.Array[uint64_t, Literal[4]], 276), ('PublicSerialNumber_XCD', c.Array[uint64_t, Literal[8]], 308), ('MaxXgmiWidth', uint32_t, 372), ('MaxXgmiBitrate', uint32_t, 376), ('InputTelemetryVoltageInmV', uint32_t, 380), ('pldmVersion', c.Array[uint32_t, Literal[2]], 384), ('MaxNodePowerLimit', uint32_t, 392), ('PPT1Max', uint32_t, 396), ('PPT1Min', uint32_t, 400), ('PPT1Default', uint32_t, 404)])
I2cControllerPort_e: dict[int, str] = {(I2C_CONTROLLER_PORT_0:=0): 'I2C_CONTROLLER_PORT_0', (I2C_CONTROLLER_PORT_1:=1): 'I2C_CONTROLLER_PORT_1', (I2C_CONTROLLER_PORT_COUNT:=2): 'I2C_CONTROLLER_PORT_COUNT'}
I2cSpeed_e: dict[int, str] = {(UNSUPPORTED_1:=0): 'UNSUPPORTED_1', (I2C_SPEED_STANDARD_100K:=1): 'I2C_SPEED_STANDARD_100K', (I2C_SPEED_FAST_400K:=2): 'I2C_SPEED_FAST_400K', (I2C_SPEED_FAST_PLUS_1M:=3): 'I2C_SPEED_FAST_PLUS_1M', (UNSUPPORTED_2:=4): 'UNSUPPORTED_2', (UNSUPPORTED_3:=5): 'UNSUPPORTED_3', (I2C_SPEED_COUNT:=6): 'I2C_SPEED_COUNT'}
I2cCmdType_e: dict[int, str] = {(I2C_CMD_READ:=0): 'I2C_CMD_READ', (I2C_CMD_WRITE:=1): 'I2C_CMD_WRITE', (I2C_CMD_COUNT:=2): 'I2C_CMD_COUNT'}
ERR_CODE_e: dict[int, str] = {(CODE_DAGB0:=0): 'CODE_DAGB0', (CODE_EA0:=5): 'CODE_EA0', (CODE_UTCL2_ROUTER:=10): 'CODE_UTCL2_ROUTER', (CODE_VML2:=11): 'CODE_VML2', (CODE_VML2_WALKER:=12): 'CODE_VML2_WALKER', (CODE_MMCANE:=13): 'CODE_MMCANE', (CODE_VIDD:=14): 'CODE_VIDD', (CODE_VIDV:=15): 'CODE_VIDV', (CODE_JPEG0S:=16): 'CODE_JPEG0S', (CODE_JPEG0D:=17): 'CODE_JPEG0D', (CODE_JPEG1S:=18): 'CODE_JPEG1S', (CODE_JPEG1D:=19): 'CODE_JPEG1D', (CODE_JPEG2S:=20): 'CODE_JPEG2S', (CODE_JPEG2D:=21): 'CODE_JPEG2D', (CODE_JPEG3S:=22): 'CODE_JPEG3S', (CODE_JPEG3D:=23): 'CODE_JPEG3D', (CODE_JPEG4S:=24): 'CODE_JPEG4S', (CODE_JPEG4D:=25): 'CODE_JPEG4D', (CODE_JPEG5S:=26): 'CODE_JPEG5S', (CODE_JPEG5D:=27): 'CODE_JPEG5D', (CODE_JPEG6S:=28): 'CODE_JPEG6S', (CODE_JPEG6D:=29): 'CODE_JPEG6D', (CODE_JPEG7S:=30): 'CODE_JPEG7S', (CODE_JPEG7D:=31): 'CODE_JPEG7D', (CODE_MMSCHD:=32): 'CODE_MMSCHD', (CODE_SDMA0:=33): 'CODE_SDMA0', (CODE_SDMA1:=34): 'CODE_SDMA1', (CODE_SDMA2:=35): 'CODE_SDMA2', (CODE_SDMA3:=36): 'CODE_SDMA3', (CODE_HDP:=37): 'CODE_HDP', (CODE_ATHUB:=38): 'CODE_ATHUB', (CODE_IH:=39): 'CODE_IH', (CODE_XHUB_POISON:=40): 'CODE_XHUB_POISON', (CODE_SMN_SLVERR:=40): 'CODE_SMN_SLVERR', (CODE_WDT:=41): 'CODE_WDT', (CODE_UNKNOWN:=42): 'CODE_UNKNOWN', (CODE_COUNT:=43): 'CODE_COUNT'}
GC_ERROR_CODE_e: dict[int, str] = {(SH_FED_CODE:=0): 'SH_FED_CODE', (GCEA_CODE:=1): 'GCEA_CODE', (SQ_CODE:=2): 'SQ_CODE', (LDS_CODE:=3): 'LDS_CODE', (GDS_CODE:=4): 'GDS_CODE', (SP0_CODE:=5): 'SP0_CODE', (SP1_CODE:=6): 'SP1_CODE', (TCC_CODE:=7): 'TCC_CODE', (TCA_CODE:=8): 'TCA_CODE', (TCX_CODE:=9): 'TCX_CODE', (CPC_CODE:=10): 'CPC_CODE', (CPF_CODE:=11): 'CPF_CODE', (CPG_CODE:=12): 'CPG_CODE', (SPI_CODE:=13): 'SPI_CODE', (RLC_CODE:=14): 'RLC_CODE', (SQC_CODE:=15): 'SQC_CODE', (TA_CODE:=16): 'TA_CODE', (TD_CODE:=17): 'TD_CODE', (TCP_CODE:=18): 'TCP_CODE', (TCI_CODE:=19): 'TCI_CODE', (GC_ROUTER_CODE:=20): 'GC_ROUTER_CODE', (VML2_CODE:=21): 'VML2_CODE', (VML2_WALKER_CODE:=22): 'VML2_WALKER_CODE', (ATCL2_CODE:=23): 'ATCL2_CODE', (GC_CANE_CODE:=24): 'GC_CANE_CODE', (MP5_CODE_SMN_SLVERR:=40): 'MP5_CODE_SMN_SLVERR', (MP5_CODE_UNKNOWN:=42): 'MP5_CODE_UNKNOWN'}
@c.record
class SwI2cCmd_t(c.Struct):
SIZE = 2
ReadWriteData: Annotated[uint8_t, 0]
CmdConfig: Annotated[uint8_t, 1]
ReadWriteData: int
CmdConfig: int
SwI2cCmd_t.register_fields([('ReadWriteData', uint8_t, 0), ('CmdConfig', uint8_t, 1)])
@c.record
class SwI2cRequest_t(c.Struct):
SIZE = 52
I2CcontrollerPort: Annotated[uint8_t, 0]
I2CSpeed: Annotated[uint8_t, 1]
SlaveAddress: Annotated[uint8_t, 2]
NumCmds: Annotated[uint8_t, 3]
SwI2cCmds: Annotated[c.Array[SwI2cCmd_t, Literal[24]], 4]
I2CcontrollerPort: int
I2CSpeed: int
SlaveAddress: int
NumCmds: int
SwI2cCmds: c.Array[SwI2cCmd_t, Literal[24]]
SwI2cRequest_t.register_fields([('I2CcontrollerPort', uint8_t, 0), ('I2CSpeed', uint8_t, 1), ('SlaveAddress', uint8_t, 2), ('NumCmds', uint8_t, 3), ('SwI2cCmds', c.Array[SwI2cCmd_t, Literal[24]], 4)])
@c.record
class SwI2cRequestExternal_t(c.Struct):
SIZE = 116
SwI2cRequest: Annotated[SwI2cRequest_t, 0]
Spare: Annotated[c.Array[uint32_t, Literal[8]], 52]
MmHubPadding: Annotated[c.Array[uint32_t, Literal[8]], 84]
class PPCLK_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
PPCLK_VCLK = PPCLK_e.define('PPCLK_VCLK', 0)
PPCLK_DCLK = PPCLK_e.define('PPCLK_DCLK', 1)
PPCLK_SOCCLK = PPCLK_e.define('PPCLK_SOCCLK', 2)
PPCLK_UCLK = PPCLK_e.define('PPCLK_UCLK', 3)
PPCLK_FCLK = PPCLK_e.define('PPCLK_FCLK', 4)
PPCLK_LCLK = PPCLK_e.define('PPCLK_LCLK', 5)
PPCLK_COUNT = PPCLK_e.define('PPCLK_COUNT', 6)
class GpioIntPolarity_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
GPIO_INT_POLARITY_ACTIVE_LOW = GpioIntPolarity_e.define('GPIO_INT_POLARITY_ACTIVE_LOW', 0)
GPIO_INT_POLARITY_ACTIVE_HIGH = GpioIntPolarity_e.define('GPIO_INT_POLARITY_ACTIVE_HIGH', 1)
class UCLK_DPM_MODE_e(Annotated[int, ctypes.c_uint32], c.Enum): pass
UCLK_DPM_MODE_BANDWIDTH = UCLK_DPM_MODE_e.define('UCLK_DPM_MODE_BANDWIDTH', 0)
UCLK_DPM_MODE_LATENCY = UCLK_DPM_MODE_e.define('UCLK_DPM_MODE_LATENCY', 1)
SwI2cRequest: SwI2cRequest_t
Spare: c.Array[ctypes.c_uint32, Literal[8]]
MmHubPadding: c.Array[ctypes.c_uint32, Literal[8]]
SwI2cRequestExternal_t.register_fields([('SwI2cRequest', SwI2cRequest_t, 0), ('Spare', c.Array[uint32_t, Literal[8]], 52), ('MmHubPadding', c.Array[uint32_t, Literal[8]], 84)])
PPCLK_e: dict[int, str] = {(PPCLK_VCLK:=0): 'PPCLK_VCLK', (PPCLK_DCLK:=1): 'PPCLK_DCLK', (PPCLK_SOCCLK:=2): 'PPCLK_SOCCLK', (PPCLK_UCLK:=3): 'PPCLK_UCLK', (PPCLK_FCLK:=4): 'PPCLK_FCLK', (PPCLK_LCLK:=5): 'PPCLK_LCLK', (PPCLK_COUNT:=6): 'PPCLK_COUNT'}
GpioIntPolarity_e: dict[int, str] = {(GPIO_INT_POLARITY_ACTIVE_LOW:=0): 'GPIO_INT_POLARITY_ACTIVE_LOW', (GPIO_INT_POLARITY_ACTIVE_HIGH:=1): 'GPIO_INT_POLARITY_ACTIVE_HIGH'}
UCLK_DPM_MODE_e: dict[int, str] = {(UCLK_DPM_MODE_BANDWIDTH:=0): 'UCLK_DPM_MODE_BANDWIDTH', (UCLK_DPM_MODE_LATENCY:=1): 'UCLK_DPM_MODE_LATENCY'}
@c.record
class AvfsDebugTableAid_t(c.Struct):
SIZE = 360
avgPsmCount: Annotated[c.Array[uint16_t, Literal[30]], 0]
minPsmCount: Annotated[c.Array[uint16_t, Literal[30]], 60]
avgPsmVoltage: Annotated[c.Array[Annotated[float, ctypes.c_float], Literal[30]], 120]
minPsmVoltage: Annotated[c.Array[Annotated[float, ctypes.c_float], Literal[30]], 240]
avgPsmCount: c.Array[ctypes.c_uint16, Literal[30]]
minPsmCount: c.Array[ctypes.c_uint16, Literal[30]]
avgPsmVoltage: c.Array[ctypes.c_float, Literal[30]]
minPsmVoltage: c.Array[ctypes.c_float, Literal[30]]
AvfsDebugTableAid_t.register_fields([('avgPsmCount', c.Array[uint16_t, Literal[30]], 0), ('minPsmCount', c.Array[uint16_t, Literal[30]], 60), ('avgPsmVoltage', c.Array[ctypes.c_float, Literal[30]], 120), ('minPsmVoltage', c.Array[ctypes.c_float, Literal[30]], 240)])
@c.record
class AvfsDebugTableXcd_t(c.Struct):
SIZE = 360
avgPsmCount: Annotated[c.Array[uint16_t, Literal[30]], 0]
minPsmCount: Annotated[c.Array[uint16_t, Literal[30]], 60]
avgPsmVoltage: Annotated[c.Array[Annotated[float, ctypes.c_float], Literal[30]], 120]
minPsmVoltage: Annotated[c.Array[Annotated[float, ctypes.c_float], Literal[30]], 240]
avgPsmCount: c.Array[ctypes.c_uint16, Literal[30]]
minPsmCount: c.Array[ctypes.c_uint16, Literal[30]]
avgPsmVoltage: c.Array[ctypes.c_float, Literal[30]]
minPsmVoltage: c.Array[ctypes.c_float, Literal[30]]
AvfsDebugTableXcd_t.register_fields([('avgPsmCount', c.Array[uint16_t, Literal[30]], 0), ('minPsmCount', c.Array[uint16_t, Literal[30]], 60), ('avgPsmVoltage', c.Array[ctypes.c_float, Literal[30]], 120), ('minPsmVoltage', c.Array[ctypes.c_float, Literal[30]], 240)])
@c.record
class struct_smu_hw_power_state(c.Struct):
SIZE = 4
magic: Annotated[Annotated[int, ctypes.c_uint32], 0]
class struct_smu_power_state(c.Struct): SIZE = 0
class enum_smu_state_ui_label(Annotated[int, ctypes.c_uint32], c.Enum): pass
SMU_STATE_UI_LABEL_NONE = enum_smu_state_ui_label.define('SMU_STATE_UI_LABEL_NONE', 0)
SMU_STATE_UI_LABEL_BATTERY = enum_smu_state_ui_label.define('SMU_STATE_UI_LABEL_BATTERY', 1)
SMU_STATE_UI_TABEL_MIDDLE_LOW = enum_smu_state_ui_label.define('SMU_STATE_UI_TABEL_MIDDLE_LOW', 2)
SMU_STATE_UI_LABEL_BALLANCED = enum_smu_state_ui_label.define('SMU_STATE_UI_LABEL_BALLANCED', 3)
SMU_STATE_UI_LABEL_MIDDLE_HIGHT = enum_smu_state_ui_label.define('SMU_STATE_UI_LABEL_MIDDLE_HIGHT', 4)
SMU_STATE_UI_LABEL_PERFORMANCE = enum_smu_state_ui_label.define('SMU_STATE_UI_LABEL_PERFORMANCE', 5)
SMU_STATE_UI_LABEL_BACO = enum_smu_state_ui_label.define('SMU_STATE_UI_LABEL_BACO', 6)
class enum_smu_state_classification_flag(Annotated[int, ctypes.c_uint32], c.Enum): pass
SMU_STATE_CLASSIFICATION_FLAG_BOOT = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_BOOT', 1)
SMU_STATE_CLASSIFICATION_FLAG_THERMAL = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_THERMAL', 2)
SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE', 4)
SMU_STATE_CLASSIFICATION_FLAG_RESET = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_RESET', 8)
SMU_STATE_CLASSIFICATION_FLAG_FORCED = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_FORCED', 16)
SMU_STATE_CLASSIFICATION_FLAG_USER_3D_PERFORMANCE = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_USER_3D_PERFORMANCE', 32)
SMU_STATE_CLASSIFICATION_FLAG_USER_2D_PERFORMANCE = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_USER_2D_PERFORMANCE', 64)
SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE', 128)
SMU_STATE_CLASSIFICATION_FLAG_AC_OVERDIRVER_TEMPLATE = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_AC_OVERDIRVER_TEMPLATE', 256)
SMU_STATE_CLASSIFICATION_FLAG_UVD = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_UVD', 512)
SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE_LOW = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE_LOW', 1024)
SMU_STATE_CLASSIFICATION_FLAG_ACPI = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_ACPI', 2048)
SMU_STATE_CLASSIFICATION_FLAG_HD2 = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_HD2', 4096)
SMU_STATE_CLASSIFICATION_FLAG_UVD_HD = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_UVD_HD', 8192)
SMU_STATE_CLASSIFICATION_FLAG_UVD_SD = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_UVD_SD', 16384)
SMU_STATE_CLASSIFICATION_FLAG_USER_DC_PERFORMANCE = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_USER_DC_PERFORMANCE', 32768)
SMU_STATE_CLASSIFICATION_FLAG_DC_OVERDIRVER_TEMPLATE = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_DC_OVERDIRVER_TEMPLATE', 65536)
SMU_STATE_CLASSIFICATION_FLAG_BACO = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_BACO', 131072)
SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE2 = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE2', 262144)
SMU_STATE_CLASSIFICATION_FLAG_ULV = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_ULV', 524288)
SMU_STATE_CLASSIFICATION_FLAG_UVD_MVC = enum_smu_state_classification_flag.define('SMU_STATE_CLASSIFICATION_FLAG_UVD_MVC', 1048576)
magic: int
struct_smu_hw_power_state.register_fields([('magic', ctypes.c_uint32, 0)])
class struct_smu_power_state(c.Struct): pass
enum_smu_state_ui_label: dict[int, str] = {(SMU_STATE_UI_LABEL_NONE:=0): 'SMU_STATE_UI_LABEL_NONE', (SMU_STATE_UI_LABEL_BATTERY:=1): 'SMU_STATE_UI_LABEL_BATTERY', (SMU_STATE_UI_TABEL_MIDDLE_LOW:=2): 'SMU_STATE_UI_TABEL_MIDDLE_LOW', (SMU_STATE_UI_LABEL_BALLANCED:=3): 'SMU_STATE_UI_LABEL_BALLANCED', (SMU_STATE_UI_LABEL_MIDDLE_HIGHT:=4): 'SMU_STATE_UI_LABEL_MIDDLE_HIGHT', (SMU_STATE_UI_LABEL_PERFORMANCE:=5): 'SMU_STATE_UI_LABEL_PERFORMANCE', (SMU_STATE_UI_LABEL_BACO:=6): 'SMU_STATE_UI_LABEL_BACO'}
enum_smu_state_classification_flag: dict[int, str] = {(SMU_STATE_CLASSIFICATION_FLAG_BOOT:=1): 'SMU_STATE_CLASSIFICATION_FLAG_BOOT', (SMU_STATE_CLASSIFICATION_FLAG_THERMAL:=2): 'SMU_STATE_CLASSIFICATION_FLAG_THERMAL', (SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE:=4): 'SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE', (SMU_STATE_CLASSIFICATION_FLAG_RESET:=8): 'SMU_STATE_CLASSIFICATION_FLAG_RESET', (SMU_STATE_CLASSIFICATION_FLAG_FORCED:=16): 'SMU_STATE_CLASSIFICATION_FLAG_FORCED', (SMU_STATE_CLASSIFICATION_FLAG_USER_3D_PERFORMANCE:=32): 'SMU_STATE_CLASSIFICATION_FLAG_USER_3D_PERFORMANCE', (SMU_STATE_CLASSIFICATION_FLAG_USER_2D_PERFORMANCE:=64): 'SMU_STATE_CLASSIFICATION_FLAG_USER_2D_PERFORMANCE', (SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE:=128): 'SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE', (SMU_STATE_CLASSIFICATION_FLAG_AC_OVERDIRVER_TEMPLATE:=256): 'SMU_STATE_CLASSIFICATION_FLAG_AC_OVERDIRVER_TEMPLATE', (SMU_STATE_CLASSIFICATION_FLAG_UVD:=512): 'SMU_STATE_CLASSIFICATION_FLAG_UVD', (SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE_LOW:=1024): 'SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE_LOW', (SMU_STATE_CLASSIFICATION_FLAG_ACPI:=2048): 'SMU_STATE_CLASSIFICATION_FLAG_ACPI', (SMU_STATE_CLASSIFICATION_FLAG_HD2:=4096): 'SMU_STATE_CLASSIFICATION_FLAG_HD2', (SMU_STATE_CLASSIFICATION_FLAG_UVD_HD:=8192): 'SMU_STATE_CLASSIFICATION_FLAG_UVD_HD', (SMU_STATE_CLASSIFICATION_FLAG_UVD_SD:=16384): 'SMU_STATE_CLASSIFICATION_FLAG_UVD_SD', (SMU_STATE_CLASSIFICATION_FLAG_USER_DC_PERFORMANCE:=32768): 'SMU_STATE_CLASSIFICATION_FLAG_USER_DC_PERFORMANCE', (SMU_STATE_CLASSIFICATION_FLAG_DC_OVERDIRVER_TEMPLATE:=65536): 'SMU_STATE_CLASSIFICATION_FLAG_DC_OVERDIRVER_TEMPLATE', (SMU_STATE_CLASSIFICATION_FLAG_BACO:=131072): 'SMU_STATE_CLASSIFICATION_FLAG_BACO', (SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE2:=262144): 'SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE2', (SMU_STATE_CLASSIFICATION_FLAG_ULV:=524288): 'SMU_STATE_CLASSIFICATION_FLAG_ULV', (SMU_STATE_CLASSIFICATION_FLAG_UVD_MVC:=1048576): 'SMU_STATE_CLASSIFICATION_FLAG_UVD_MVC'}
@c.record
class struct_smu_state_classification_block(c.Struct):
SIZE = 16
ui_label: Annotated[enum_smu_state_ui_label, 0]
flags: Annotated[enum_smu_state_classification_flag, 4]
bios_index: Annotated[Annotated[int, ctypes.c_int32], 8]
temporary_state: Annotated[Annotated[bool, ctypes.c_bool], 12]
to_be_deleted: Annotated[Annotated[bool, ctypes.c_bool], 13]
ui_label: int
flags: int
bios_index: int
temporary_state: bool
to_be_deleted: bool
struct_smu_state_classification_block.register_fields([('ui_label', ctypes.c_uint32, 0), ('flags', ctypes.c_uint32, 4), ('bios_index', ctypes.c_int32, 8), ('temporary_state', ctypes.c_bool, 12), ('to_be_deleted', ctypes.c_bool, 13)])
@c.record
class struct_smu_state_pcie_block(c.Struct):
SIZE = 4
lanes: Annotated[Annotated[int, ctypes.c_uint32], 0]
class enum_smu_refreshrate_source(Annotated[int, ctypes.c_uint32], c.Enum): pass
SMU_REFRESHRATE_SOURCE_EDID = enum_smu_refreshrate_source.define('SMU_REFRESHRATE_SOURCE_EDID', 0)
SMU_REFRESHRATE_SOURCE_EXPLICIT = enum_smu_refreshrate_source.define('SMU_REFRESHRATE_SOURCE_EXPLICIT', 1)
lanes: int
struct_smu_state_pcie_block.register_fields([('lanes', ctypes.c_uint32, 0)])
enum_smu_refreshrate_source: dict[int, str] = {(SMU_REFRESHRATE_SOURCE_EDID:=0): 'SMU_REFRESHRATE_SOURCE_EDID', (SMU_REFRESHRATE_SOURCE_EXPLICIT:=1): 'SMU_REFRESHRATE_SOURCE_EXPLICIT'}
@c.record
class struct_smu_state_display_block(c.Struct):
SIZE = 20
disable_frame_modulation: Annotated[Annotated[bool, ctypes.c_bool], 0]
limit_refreshrate: Annotated[Annotated[bool, ctypes.c_bool], 1]
refreshrate_source: Annotated[enum_smu_refreshrate_source, 4]
explicit_refreshrate: Annotated[Annotated[int, ctypes.c_int32], 8]
edid_refreshrate_index: Annotated[Annotated[int, ctypes.c_int32], 12]
enable_vari_bright: Annotated[Annotated[bool, ctypes.c_bool], 16]
disable_frame_modulation: bool
limit_refreshrate: bool
refreshrate_source: int
explicit_refreshrate: int
edid_refreshrate_index: int
enable_vari_bright: bool
struct_smu_state_display_block.register_fields([('disable_frame_modulation', ctypes.c_bool, 0), ('limit_refreshrate', ctypes.c_bool, 1), ('refreshrate_source', ctypes.c_uint32, 4), ('explicit_refreshrate', ctypes.c_int32, 8), ('edid_refreshrate_index', ctypes.c_int32, 12), ('enable_vari_bright', ctypes.c_bool, 16)])
@c.record
class struct_smu_state_memory_block(c.Struct):
SIZE = 5
dll_off: Annotated[Annotated[bool, ctypes.c_bool], 0]
m3arb: Annotated[Annotated[int, ctypes.c_ubyte], 1]
unused: Annotated[c.Array[Annotated[int, ctypes.c_ubyte], Literal[3]], 2]
dll_off: bool
m3arb: int
unused: c.Array[ctypes.c_ubyte, Literal[3]]
struct_smu_state_memory_block.register_fields([('dll_off', ctypes.c_bool, 0), ('m3arb', ctypes.c_ubyte, 1), ('unused', c.Array[ctypes.c_ubyte, Literal[3]], 2)])
@c.record
class struct_smu_state_software_algorithm_block(c.Struct):
SIZE = 2
disable_load_balancing: Annotated[Annotated[bool, ctypes.c_bool], 0]
enable_sleep_for_timestamps: Annotated[Annotated[bool, ctypes.c_bool], 1]
disable_load_balancing: bool
enable_sleep_for_timestamps: bool
struct_smu_state_software_algorithm_block.register_fields([('disable_load_balancing', ctypes.c_bool, 0), ('enable_sleep_for_timestamps', ctypes.c_bool, 1)])
@c.record
class struct_smu_temperature_range(c.Struct):
SIZE = 44
min: Annotated[Annotated[int, ctypes.c_int32], 0]
max: Annotated[Annotated[int, ctypes.c_int32], 4]
edge_emergency_max: Annotated[Annotated[int, ctypes.c_int32], 8]
hotspot_min: Annotated[Annotated[int, ctypes.c_int32], 12]
hotspot_crit_max: Annotated[Annotated[int, ctypes.c_int32], 16]
hotspot_emergency_max: Annotated[Annotated[int, ctypes.c_int32], 20]
mem_min: Annotated[Annotated[int, ctypes.c_int32], 24]
mem_crit_max: Annotated[Annotated[int, ctypes.c_int32], 28]
mem_emergency_max: Annotated[Annotated[int, ctypes.c_int32], 32]
software_shutdown_temp: Annotated[Annotated[int, ctypes.c_int32], 36]
software_shutdown_temp_offset: Annotated[Annotated[int, ctypes.c_int32], 40]
min: int
max: int
edge_emergency_max: int
hotspot_min: int
hotspot_crit_max: int
hotspot_emergency_max: int
mem_min: int
mem_crit_max: int
mem_emergency_max: int
software_shutdown_temp: int
software_shutdown_temp_offset: int
struct_smu_temperature_range.register_fields([('min', ctypes.c_int32, 0), ('max', ctypes.c_int32, 4), ('edge_emergency_max', ctypes.c_int32, 8), ('hotspot_min', ctypes.c_int32, 12), ('hotspot_crit_max', ctypes.c_int32, 16), ('hotspot_emergency_max', ctypes.c_int32, 20), ('mem_min', ctypes.c_int32, 24), ('mem_crit_max', ctypes.c_int32, 28), ('mem_emergency_max', ctypes.c_int32, 32), ('software_shutdown_temp', ctypes.c_int32, 36), ('software_shutdown_temp_offset', ctypes.c_int32, 40)])
@c.record
class struct_smu_state_validation_block(c.Struct):
SIZE = 3
single_display_only: Annotated[Annotated[bool, ctypes.c_bool], 0]
disallow_on_dc: Annotated[Annotated[bool, ctypes.c_bool], 1]
supported_power_levels: Annotated[Annotated[int, ctypes.c_ubyte], 2]
single_display_only: bool
disallow_on_dc: bool
supported_power_levels: int
struct_smu_state_validation_block.register_fields([('single_display_only', ctypes.c_bool, 0), ('disallow_on_dc', ctypes.c_bool, 1), ('supported_power_levels', ctypes.c_ubyte, 2)])
@c.record
class struct_smu_uvd_clocks(c.Struct):
SIZE = 8
vclk: Annotated[Annotated[int, ctypes.c_uint32], 0]
dclk: Annotated[Annotated[int, ctypes.c_uint32], 4]
class enum_smu_power_src_type(Annotated[int, ctypes.c_uint32], c.Enum): pass
SMU_POWER_SOURCE_AC = enum_smu_power_src_type.define('SMU_POWER_SOURCE_AC', 0)
SMU_POWER_SOURCE_DC = enum_smu_power_src_type.define('SMU_POWER_SOURCE_DC', 1)
SMU_POWER_SOURCE_COUNT = enum_smu_power_src_type.define('SMU_POWER_SOURCE_COUNT', 2)
class enum_smu_ppt_limit_type(Annotated[int, ctypes.c_uint32], c.Enum): pass
SMU_DEFAULT_PPT_LIMIT = enum_smu_ppt_limit_type.define('SMU_DEFAULT_PPT_LIMIT', 0)
SMU_FAST_PPT_LIMIT = enum_smu_ppt_limit_type.define('SMU_FAST_PPT_LIMIT', 1)
class enum_smu_ppt_limit_level(Annotated[int, ctypes.c_int32], c.Enum): pass
SMU_PPT_LIMIT_MIN = enum_smu_ppt_limit_level.define('SMU_PPT_LIMIT_MIN', -1)
SMU_PPT_LIMIT_CURRENT = enum_smu_ppt_limit_level.define('SMU_PPT_LIMIT_CURRENT', 0)
SMU_PPT_LIMIT_DEFAULT = enum_smu_ppt_limit_level.define('SMU_PPT_LIMIT_DEFAULT', 1)
SMU_PPT_LIMIT_MAX = enum_smu_ppt_limit_level.define('SMU_PPT_LIMIT_MAX', 2)
class enum_smu_memory_pool_size(Annotated[int, ctypes.c_uint32], c.Enum): pass
SMU_MEMORY_POOL_SIZE_ZERO = enum_smu_memory_pool_size.define('SMU_MEMORY_POOL_SIZE_ZERO', 0)
SMU_MEMORY_POOL_SIZE_256_MB = enum_smu_memory_pool_size.define('SMU_MEMORY_POOL_SIZE_256_MB', 268435456)
SMU_MEMORY_POOL_SIZE_512_MB = enum_smu_memory_pool_size.define('SMU_MEMORY_POOL_SIZE_512_MB', 536870912)
SMU_MEMORY_POOL_SIZE_1_GB = enum_smu_memory_pool_size.define('SMU_MEMORY_POOL_SIZE_1_GB', 1073741824)
SMU_MEMORY_POOL_SIZE_2_GB = enum_smu_memory_pool_size.define('SMU_MEMORY_POOL_SIZE_2_GB', 2147483648)
class enum_smu_clk_type(Annotated[int, ctypes.c_uint32], c.Enum): pass
SMU_GFXCLK = enum_smu_clk_type.define('SMU_GFXCLK', 0)
SMU_VCLK = enum_smu_clk_type.define('SMU_VCLK', 1)
SMU_DCLK = enum_smu_clk_type.define('SMU_DCLK', 2)
SMU_VCLK1 = enum_smu_clk_type.define('SMU_VCLK1', 3)
SMU_DCLK1 = enum_smu_clk_type.define('SMU_DCLK1', 4)
SMU_ECLK = enum_smu_clk_type.define('SMU_ECLK', 5)
SMU_SOCCLK = enum_smu_clk_type.define('SMU_SOCCLK', 6)
SMU_UCLK = enum_smu_clk_type.define('SMU_UCLK', 7)
SMU_DCEFCLK = enum_smu_clk_type.define('SMU_DCEFCLK', 8)
SMU_DISPCLK = enum_smu_clk_type.define('SMU_DISPCLK', 9)
SMU_PIXCLK = enum_smu_clk_type.define('SMU_PIXCLK', 10)
SMU_PHYCLK = enum_smu_clk_type.define('SMU_PHYCLK', 11)
SMU_FCLK = enum_smu_clk_type.define('SMU_FCLK', 12)
SMU_SCLK = enum_smu_clk_type.define('SMU_SCLK', 13)
SMU_MCLK = enum_smu_clk_type.define('SMU_MCLK', 14)
SMU_PCIE = enum_smu_clk_type.define('SMU_PCIE', 15)
SMU_LCLK = enum_smu_clk_type.define('SMU_LCLK', 16)
SMU_OD_CCLK = enum_smu_clk_type.define('SMU_OD_CCLK', 17)
SMU_OD_SCLK = enum_smu_clk_type.define('SMU_OD_SCLK', 18)
SMU_OD_MCLK = enum_smu_clk_type.define('SMU_OD_MCLK', 19)
SMU_OD_VDDC_CURVE = enum_smu_clk_type.define('SMU_OD_VDDC_CURVE', 20)
SMU_OD_RANGE = enum_smu_clk_type.define('SMU_OD_RANGE', 21)
SMU_OD_VDDGFX_OFFSET = enum_smu_clk_type.define('SMU_OD_VDDGFX_OFFSET', 22)
SMU_OD_FAN_CURVE = enum_smu_clk_type.define('SMU_OD_FAN_CURVE', 23)
SMU_OD_ACOUSTIC_LIMIT = enum_smu_clk_type.define('SMU_OD_ACOUSTIC_LIMIT', 24)
SMU_OD_ACOUSTIC_TARGET = enum_smu_clk_type.define('SMU_OD_ACOUSTIC_TARGET', 25)
SMU_OD_FAN_TARGET_TEMPERATURE = enum_smu_clk_type.define('SMU_OD_FAN_TARGET_TEMPERATURE', 26)
SMU_OD_FAN_MINIMUM_PWM = enum_smu_clk_type.define('SMU_OD_FAN_MINIMUM_PWM', 27)
SMU_CLK_COUNT = enum_smu_clk_type.define('SMU_CLK_COUNT', 28)
vclk: int
dclk: int
struct_smu_uvd_clocks.register_fields([('vclk', ctypes.c_uint32, 0), ('dclk', ctypes.c_uint32, 4)])
enum_smu_power_src_type: dict[int, str] = {(SMU_POWER_SOURCE_AC:=0): 'SMU_POWER_SOURCE_AC', (SMU_POWER_SOURCE_DC:=1): 'SMU_POWER_SOURCE_DC', (SMU_POWER_SOURCE_COUNT:=2): 'SMU_POWER_SOURCE_COUNT'}
enum_smu_ppt_limit_type: dict[int, str] = {(SMU_DEFAULT_PPT_LIMIT:=0): 'SMU_DEFAULT_PPT_LIMIT', (SMU_FAST_PPT_LIMIT:=1): 'SMU_FAST_PPT_LIMIT'}
enum_smu_ppt_limit_level: dict[int, str] = {(SMU_PPT_LIMIT_MIN:=-1): 'SMU_PPT_LIMIT_MIN', (SMU_PPT_LIMIT_CURRENT:=0): 'SMU_PPT_LIMIT_CURRENT', (SMU_PPT_LIMIT_DEFAULT:=1): 'SMU_PPT_LIMIT_DEFAULT', (SMU_PPT_LIMIT_MAX:=2): 'SMU_PPT_LIMIT_MAX'}
enum_smu_memory_pool_size: dict[int, str] = {(SMU_MEMORY_POOL_SIZE_ZERO:=0): 'SMU_MEMORY_POOL_SIZE_ZERO', (SMU_MEMORY_POOL_SIZE_256_MB:=268435456): 'SMU_MEMORY_POOL_SIZE_256_MB', (SMU_MEMORY_POOL_SIZE_512_MB:=536870912): 'SMU_MEMORY_POOL_SIZE_512_MB', (SMU_MEMORY_POOL_SIZE_1_GB:=1073741824): 'SMU_MEMORY_POOL_SIZE_1_GB', (SMU_MEMORY_POOL_SIZE_2_GB:=2147483648): 'SMU_MEMORY_POOL_SIZE_2_GB'}
enum_smu_clk_type: dict[int, str] = {(SMU_GFXCLK:=0): 'SMU_GFXCLK', (SMU_VCLK:=1): 'SMU_VCLK', (SMU_DCLK:=2): 'SMU_DCLK', (SMU_VCLK1:=3): 'SMU_VCLK1', (SMU_DCLK1:=4): 'SMU_DCLK1', (SMU_ECLK:=5): 'SMU_ECLK', (SMU_SOCCLK:=6): 'SMU_SOCCLK', (SMU_UCLK:=7): 'SMU_UCLK', (SMU_DCEFCLK:=8): 'SMU_DCEFCLK', (SMU_DISPCLK:=9): 'SMU_DISPCLK', (SMU_PIXCLK:=10): 'SMU_PIXCLK', (SMU_PHYCLK:=11): 'SMU_PHYCLK', (SMU_FCLK:=12): 'SMU_FCLK', (SMU_SCLK:=13): 'SMU_SCLK', (SMU_MCLK:=14): 'SMU_MCLK', (SMU_PCIE:=15): 'SMU_PCIE', (SMU_LCLK:=16): 'SMU_LCLK', (SMU_OD_CCLK:=17): 'SMU_OD_CCLK', (SMU_OD_SCLK:=18): 'SMU_OD_SCLK', (SMU_OD_MCLK:=19): 'SMU_OD_MCLK', (SMU_OD_VDDC_CURVE:=20): 'SMU_OD_VDDC_CURVE', (SMU_OD_RANGE:=21): 'SMU_OD_RANGE', (SMU_OD_VDDGFX_OFFSET:=22): 'SMU_OD_VDDGFX_OFFSET', (SMU_OD_FAN_CURVE:=23): 'SMU_OD_FAN_CURVE', (SMU_OD_ACOUSTIC_LIMIT:=24): 'SMU_OD_ACOUSTIC_LIMIT', (SMU_OD_ACOUSTIC_TARGET:=25): 'SMU_OD_ACOUSTIC_TARGET', (SMU_OD_FAN_TARGET_TEMPERATURE:=26): 'SMU_OD_FAN_TARGET_TEMPERATURE', (SMU_OD_FAN_MINIMUM_PWM:=27): 'SMU_OD_FAN_MINIMUM_PWM', (SMU_CLK_COUNT:=28): 'SMU_CLK_COUNT'}
@c.record
class struct_smu_user_dpm_profile(c.Struct):
SIZE = 140
fan_mode: Annotated[Annotated[int, ctypes.c_uint32], 0]
power_limit: Annotated[Annotated[int, ctypes.c_uint32], 4]
fan_speed_pwm: Annotated[Annotated[int, ctypes.c_uint32], 8]
fan_speed_rpm: Annotated[Annotated[int, ctypes.c_uint32], 12]
flags: Annotated[Annotated[int, ctypes.c_uint32], 16]
user_od: Annotated[Annotated[int, ctypes.c_uint32], 20]
clk_mask: Annotated[c.Array[Annotated[int, ctypes.c_uint32], Literal[28]], 24]
clk_dependency: Annotated[Annotated[int, ctypes.c_uint32], 136]
fan_mode: int
power_limit: int
fan_speed_pwm: int
fan_speed_rpm: int
flags: int
user_od: int
clk_mask: c.Array[ctypes.c_uint32, Literal[28]]
clk_dependency: int
struct_smu_user_dpm_profile.register_fields([('fan_mode', ctypes.c_uint32, 0), ('power_limit', ctypes.c_uint32, 4), ('fan_speed_pwm', ctypes.c_uint32, 8), ('fan_speed_rpm', ctypes.c_uint32, 12), ('flags', ctypes.c_uint32, 16), ('user_od', ctypes.c_uint32, 20), ('clk_mask', c.Array[ctypes.c_uint32, Literal[28]], 24), ('clk_dependency', ctypes.c_uint32, 136)])
@c.record
class struct_smu_table(c.Struct):
SIZE = 48
size: Annotated[Annotated[int, ctypes.c_uint64], 0]
align: Annotated[Annotated[int, ctypes.c_uint32], 8]
domain: Annotated[Annotated[int, ctypes.c_ubyte], 12]
mc_address: Annotated[Annotated[int, ctypes.c_uint64], 16]
cpu_addr: Annotated[ctypes.c_void_p, 24]
bo: Annotated[c.POINTER[struct_amdgpu_bo], 32]
version: Annotated[Annotated[int, ctypes.c_uint32], 40]
class struct_amdgpu_bo(c.Struct): SIZE = 0
class enum_smu_perf_level_designation(Annotated[int, ctypes.c_uint32], c.Enum): pass
PERF_LEVEL_ACTIVITY = enum_smu_perf_level_designation.define('PERF_LEVEL_ACTIVITY', 0)
PERF_LEVEL_POWER_CONTAINMENT = enum_smu_perf_level_designation.define('PERF_LEVEL_POWER_CONTAINMENT', 1)
size: int
align: int
domain: int
mc_address: int
cpu_addr: ctypes.c_void_p
bo: c.POINTER[struct_amdgpu_bo]
version: int
class struct_amdgpu_bo(c.Struct): pass
struct_smu_table.register_fields([('size', ctypes.c_uint64, 0), ('align', ctypes.c_uint32, 8), ('domain', ctypes.c_ubyte, 12), ('mc_address', ctypes.c_uint64, 16), ('cpu_addr', ctypes.c_void_p, 24), ('bo', c.POINTER[struct_amdgpu_bo], 32), ('version', ctypes.c_uint32, 40)])
enum_smu_perf_level_designation: dict[int, str] = {(PERF_LEVEL_ACTIVITY:=0): 'PERF_LEVEL_ACTIVITY', (PERF_LEVEL_POWER_CONTAINMENT:=1): 'PERF_LEVEL_POWER_CONTAINMENT'}
@c.record
class struct_smu_performance_level(c.Struct):
SIZE = 24
core_clock: Annotated[Annotated[int, ctypes.c_uint32], 0]
memory_clock: Annotated[Annotated[int, ctypes.c_uint32], 4]
vddc: Annotated[Annotated[int, ctypes.c_uint32], 8]
vddci: Annotated[Annotated[int, ctypes.c_uint32], 12]
non_local_mem_freq: Annotated[Annotated[int, ctypes.c_uint32], 16]
non_local_mem_width: Annotated[Annotated[int, ctypes.c_uint32], 20]
core_clock: int
memory_clock: int
vddc: int
vddci: int
non_local_mem_freq: int
non_local_mem_width: int
struct_smu_performance_level.register_fields([('core_clock', ctypes.c_uint32, 0), ('memory_clock', ctypes.c_uint32, 4), ('vddc', ctypes.c_uint32, 8), ('vddci', ctypes.c_uint32, 12), ('non_local_mem_freq', ctypes.c_uint32, 16), ('non_local_mem_width', ctypes.c_uint32, 20)])
@c.record
class struct_smu_clock_info(c.Struct):
SIZE = 24
min_mem_clk: Annotated[Annotated[int, ctypes.c_uint32], 0]
max_mem_clk: Annotated[Annotated[int, ctypes.c_uint32], 4]
min_eng_clk: Annotated[Annotated[int, ctypes.c_uint32], 8]
max_eng_clk: Annotated[Annotated[int, ctypes.c_uint32], 12]
min_bus_bandwidth: Annotated[Annotated[int, ctypes.c_uint32], 16]
max_bus_bandwidth: Annotated[Annotated[int, ctypes.c_uint32], 20]
min_mem_clk: int
max_mem_clk: int
min_eng_clk: int
max_eng_clk: int
min_bus_bandwidth: int
max_bus_bandwidth: int
struct_smu_clock_info.register_fields([('min_mem_clk', ctypes.c_uint32, 0), ('max_mem_clk', ctypes.c_uint32, 4), ('min_eng_clk', ctypes.c_uint32, 8), ('max_eng_clk', ctypes.c_uint32, 12), ('min_bus_bandwidth', ctypes.c_uint32, 16), ('max_bus_bandwidth', ctypes.c_uint32, 20)])
@c.record
class struct_smu_bios_boot_up_values(c.Struct):
SIZE = 68
revision: Annotated[Annotated[int, ctypes.c_uint32], 0]
gfxclk: Annotated[Annotated[int, ctypes.c_uint32], 4]
uclk: Annotated[Annotated[int, ctypes.c_uint32], 8]
socclk: Annotated[Annotated[int, ctypes.c_uint32], 12]
dcefclk: Annotated[Annotated[int, ctypes.c_uint32], 16]
eclk: Annotated[Annotated[int, ctypes.c_uint32], 20]
vclk: Annotated[Annotated[int, ctypes.c_uint32], 24]
dclk: Annotated[Annotated[int, ctypes.c_uint32], 28]
vddc: Annotated[Annotated[int, ctypes.c_uint16], 32]
vddci: Annotated[Annotated[int, ctypes.c_uint16], 34]
mvddc: Annotated[Annotated[int, ctypes.c_uint16], 36]
vdd_gfx: Annotated[Annotated[int, ctypes.c_uint16], 38]
cooling_id: Annotated[Annotated[int, ctypes.c_ubyte], 40]
pp_table_id: Annotated[Annotated[int, ctypes.c_uint32], 44]
format_revision: Annotated[Annotated[int, ctypes.c_uint32], 48]
content_revision: Annotated[Annotated[int, ctypes.c_uint32], 52]
fclk: Annotated[Annotated[int, ctypes.c_uint32], 56]
lclk: Annotated[Annotated[int, ctypes.c_uint32], 60]
firmware_caps: Annotated[Annotated[int, ctypes.c_uint32], 64]
class enum_smu_table_id(Annotated[int, ctypes.c_uint32], c.Enum): pass
SMU_TABLE_PPTABLE = enum_smu_table_id.define('SMU_TABLE_PPTABLE', 0)
SMU_TABLE_WATERMARKS = enum_smu_table_id.define('SMU_TABLE_WATERMARKS', 1)
SMU_TABLE_CUSTOM_DPM = enum_smu_table_id.define('SMU_TABLE_CUSTOM_DPM', 2)
SMU_TABLE_DPMCLOCKS = enum_smu_table_id.define('SMU_TABLE_DPMCLOCKS', 3)
SMU_TABLE_AVFS = enum_smu_table_id.define('SMU_TABLE_AVFS', 4)
SMU_TABLE_AVFS_PSM_DEBUG = enum_smu_table_id.define('SMU_TABLE_AVFS_PSM_DEBUG', 5)
SMU_TABLE_AVFS_FUSE_OVERRIDE = enum_smu_table_id.define('SMU_TABLE_AVFS_FUSE_OVERRIDE', 6)
SMU_TABLE_PMSTATUSLOG = enum_smu_table_id.define('SMU_TABLE_PMSTATUSLOG', 7)
SMU_TABLE_SMU_METRICS = enum_smu_table_id.define('SMU_TABLE_SMU_METRICS', 8)
SMU_TABLE_DRIVER_SMU_CONFIG = enum_smu_table_id.define('SMU_TABLE_DRIVER_SMU_CONFIG', 9)
SMU_TABLE_ACTIVITY_MONITOR_COEFF = enum_smu_table_id.define('SMU_TABLE_ACTIVITY_MONITOR_COEFF', 10)
SMU_TABLE_OVERDRIVE = enum_smu_table_id.define('SMU_TABLE_OVERDRIVE', 11)
SMU_TABLE_I2C_COMMANDS = enum_smu_table_id.define('SMU_TABLE_I2C_COMMANDS', 12)
SMU_TABLE_PACE = enum_smu_table_id.define('SMU_TABLE_PACE', 13)
SMU_TABLE_ECCINFO = enum_smu_table_id.define('SMU_TABLE_ECCINFO', 14)
SMU_TABLE_COMBO_PPTABLE = enum_smu_table_id.define('SMU_TABLE_COMBO_PPTABLE', 15)
SMU_TABLE_WIFIBAND = enum_smu_table_id.define('SMU_TABLE_WIFIBAND', 16)
SMU_TABLE_COUNT = enum_smu_table_id.define('SMU_TABLE_COUNT', 17)
c.init_records()
revision: int
gfxclk: int
uclk: int
socclk: int
dcefclk: int
eclk: int
vclk: int
dclk: int
vddc: int
vddci: int
mvddc: int
vdd_gfx: int
cooling_id: int
pp_table_id: int
format_revision: int
content_revision: int
fclk: int
lclk: int
firmware_caps: int
struct_smu_bios_boot_up_values.register_fields([('revision', ctypes.c_uint32, 0), ('gfxclk', ctypes.c_uint32, 4), ('uclk', ctypes.c_uint32, 8), ('socclk', ctypes.c_uint32, 12), ('dcefclk', ctypes.c_uint32, 16), ('eclk', ctypes.c_uint32, 20), ('vclk', ctypes.c_uint32, 24), ('dclk', ctypes.c_uint32, 28), ('vddc', ctypes.c_uint16, 32), ('vddci', ctypes.c_uint16, 34), ('mvddc', ctypes.c_uint16, 36), ('vdd_gfx', ctypes.c_uint16, 38), ('cooling_id', ctypes.c_ubyte, 40), ('pp_table_id', ctypes.c_uint32, 44), ('format_revision', ctypes.c_uint32, 48), ('content_revision', ctypes.c_uint32, 52), ('fclk', ctypes.c_uint32, 56), ('lclk', ctypes.c_uint32, 60), ('firmware_caps', ctypes.c_uint32, 64)])
enum_smu_table_id: dict[int, str] = {(SMU_TABLE_PPTABLE:=0): 'SMU_TABLE_PPTABLE', (SMU_TABLE_WATERMARKS:=1): 'SMU_TABLE_WATERMARKS', (SMU_TABLE_CUSTOM_DPM:=2): 'SMU_TABLE_CUSTOM_DPM', (SMU_TABLE_DPMCLOCKS:=3): 'SMU_TABLE_DPMCLOCKS', (SMU_TABLE_AVFS:=4): 'SMU_TABLE_AVFS', (SMU_TABLE_AVFS_PSM_DEBUG:=5): 'SMU_TABLE_AVFS_PSM_DEBUG', (SMU_TABLE_AVFS_FUSE_OVERRIDE:=6): 'SMU_TABLE_AVFS_FUSE_OVERRIDE', (SMU_TABLE_PMSTATUSLOG:=7): 'SMU_TABLE_PMSTATUSLOG', (SMU_TABLE_SMU_METRICS:=8): 'SMU_TABLE_SMU_METRICS', (SMU_TABLE_DRIVER_SMU_CONFIG:=9): 'SMU_TABLE_DRIVER_SMU_CONFIG', (SMU_TABLE_ACTIVITY_MONITOR_COEFF:=10): 'SMU_TABLE_ACTIVITY_MONITOR_COEFF', (SMU_TABLE_OVERDRIVE:=11): 'SMU_TABLE_OVERDRIVE', (SMU_TABLE_I2C_COMMANDS:=12): 'SMU_TABLE_I2C_COMMANDS', (SMU_TABLE_PACE:=13): 'SMU_TABLE_PACE', (SMU_TABLE_ECCINFO:=14): 'SMU_TABLE_ECCINFO', (SMU_TABLE_COMBO_PPTABLE:=15): 'SMU_TABLE_COMBO_PPTABLE', (SMU_TABLE_WIFIBAND:=16): 'SMU_TABLE_WIFIBAND', (SMU_TABLE_COUNT:=17): 'SMU_TABLE_COUNT'}
PPSMC_Result_OK = 0x1 # type: ignore
PPSMC_Result_Failed = 0xFF # type: ignore
PPSMC_Result_UnknownCmd = 0xFE # type: ignore

Some files were not shown because too many files have changed in this diff Show More