mirror of
https://github.com/tinygrad/tinygrad.git
synced 2026-08-17 14:18:26 +00:00
Compare commits
36
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e336f3cf8c | ||
|
|
10c262ced8 | ||
|
|
96092d110c | ||
|
|
41421c3b48 | ||
|
|
be8005c5dc | ||
|
|
507c02cecb | ||
|
|
164495678c | ||
|
|
1f26584b2e | ||
|
|
7cbfa1896a | ||
|
|
1c36878008 | ||
|
|
1ae6528bb6 | ||
|
|
3721c60bef | ||
|
|
480ad264a4 | ||
|
|
adc96cd724 | ||
|
|
3394d18066 | ||
|
|
e9ecc990ea | ||
|
|
2450c8cba8 | ||
|
|
528faa18ec | ||
|
|
359b1582d6 | ||
|
|
2b8d303f75 | ||
|
|
5683126844 | ||
|
|
70883a6950 | ||
|
|
355e2729d3 | ||
|
|
905b8adc97 | ||
|
|
d83707ec29 | ||
|
|
ac41f15fc1 | ||
|
|
eac481b67f | ||
|
|
b370f5c5ac | ||
|
|
931d6cc62a | ||
|
|
7610bdc59e | ||
|
|
84d64b5835 | ||
|
|
16f50a40a5 | ||
|
|
ac027055ef | ||
|
|
4c1fb18a09 | ||
|
|
0cec42db71 | ||
|
|
6f5d756282 |
@@ -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 ****
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -644,7 +644,6 @@ jobs:
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
DEV: AMD
|
||||
PYTHON_REMU: 1
|
||||
MOCKGPU: 1
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
+2
-1
@@ -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"
|
||||
|
||||
+2
-1
@@ -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"
|
||||
|
||||
+2
-1
@@ -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
@@ -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
@@ -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))
|
||||
|
||||
Generated
-66
@@ -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",
|
||||
]
|
||||
@@ -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"
|
||||
@@ -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 +0,0 @@
|
||||
max_width = 150
|
||||
@@ -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)
|
||||
}};
|
||||
}
|
||||
@@ -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)); } }
|
||||
}
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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', '')
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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)."""
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
@@ -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__':
|
||||
|
||||
@@ -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()
|
||||
@@ -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))
|
||||
|
||||
@@ -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."""
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Vendored
+1
-1
@@ -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
@@ -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):
|
||||
|
||||
Vendored
+1
-1
@@ -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:
|
||||
|
||||
Vendored
+1
-1
@@ -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
|
||||
|
||||
Vendored
+2
-2
@@ -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)
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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`
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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"):
|
||||
|
||||
@@ -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,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()
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
@@ -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():
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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]]])
|
||||
|
||||
@@ -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,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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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))
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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,
|
||||
|
||||
+3780
-4281
File diff suppressed because one or more lines are too long
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
Reference in New Issue
Block a user