mirror of
https://github.com/tinygrad/tinygrad.git
synced 2026-08-14 17:38:28 +00:00
Compare commits
27
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1223922b1 | ||
|
|
05c4b18f91 | ||
|
|
f58b3afeb2 | ||
|
|
e0a805765e | ||
|
|
7c66e44454 | ||
|
|
e75e391ad4 | ||
|
|
8c69e26d22 | ||
|
|
74fb405cc9 | ||
|
|
bf5de6ba5f | ||
|
|
183b3ced03 | ||
|
|
2280dae504 | ||
|
|
9ba612f0b4 | ||
|
|
32794853db | ||
|
|
4a72a49082 | ||
|
|
9e6f8c823d | ||
|
|
4459a88a54 | ||
|
|
9cdda8913f | ||
|
|
e644d59f9f | ||
|
|
37a930591f | ||
|
|
723179dfd6 | ||
|
|
81bafb1af3 | ||
|
|
ed89217ef2 | ||
|
|
79f2cfcb96 | ||
|
|
add768aab0 | ||
|
|
2d6cf839d5 | ||
|
|
b4c3a6977e | ||
|
|
7f7aa0a7f8 |
@@ -298,7 +298,7 @@ runs:
|
||||
- name: Install mesa (linux)
|
||||
if: inputs.mesa == 'true' && runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: sudo curl -fL https://github.com/sirhcm/tinymesa/releases/download/v1/libtinymesa_cpu-mesa-25.2.7-linux-amd64.so -o /usr/lib/libtinymesa_cpu.so
|
||||
run: sudo curl -fL https://github.com/sirhcm/tinymesa/releases/download/tinymesa-32dc66c/libtinymesa_cpu-mesa-25.2.4-linux-amd64.so -o /usr/lib/libtinymesa_cpu.so
|
||||
- name: Install mesa (macOS)
|
||||
if: inputs.mesa == 'true' && runner.os == 'macOS'
|
||||
shell: bash
|
||||
|
||||
@@ -116,9 +116,11 @@ jobs:
|
||||
- name: Verify Qualcomm autogen
|
||||
run: |
|
||||
mv tinygrad/runtime/autogen/kgsl.py /tmp/kgsl.py.bak
|
||||
mv tinygrad/runtime/autogen/adreno.py /tmp/adreno.py.bak
|
||||
mv tinygrad/runtime/autogen/qcom_dsp.py /tmp/qcom_dsp.py.bak
|
||||
python3 -c "from tinygrad.runtime.autogen import kgsl, qcom_dsp"
|
||||
python3 -c "from tinygrad.runtime.autogen import kgsl, adreno, qcom_dsp"
|
||||
diff /tmp/kgsl.py.bak tinygrad/runtime/autogen/kgsl.py
|
||||
diff /tmp/adreno.py.bak tinygrad/runtime/autogen/adreno.py
|
||||
diff /tmp/qcom_dsp.py.bak tinygrad/runtime/autogen/qcom_dsp.py
|
||||
- name: Verify libusb autogen
|
||||
run: |
|
||||
|
||||
@@ -132,10 +132,6 @@ jobs:
|
||||
run: sudo -E PYTHONPATH=. AMD=1 AMD_IFACE=USB python3.11 test/external/external_test_usb_asm24.py TestDevCopySpeeds
|
||||
#- name: UsbGPU openpilot test
|
||||
# run: sudo -E PYTHONPATH=. AMD=1 AMD_IFACE=USB GRAPH_ONE_KERNEL=1 python3.11 examples/openpilot/compile3.py https://github.com/commaai/openpilot/raw/9118973ed03c1ae1d40cf69a29507ec2cc78efd7/selfdrive/modeld/models/supercombo.onnx
|
||||
- name: UsbGPU (USB4/TB) boot time
|
||||
run: PYTHONPATH=. DEBUG=3 NV=1 NV_IFACE=PCI NV_NAK=1 time python3.11 test/test_tiny.py TestTiny.test_plus
|
||||
- name: UsbGPU (USB4/TB) tiny tests
|
||||
run: PYTHONPATH=. NV=1 NV_IFACE=PCI NV_NAK=1 python3.11 test/test_tiny.py
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Speed (Mac)
|
||||
@@ -346,7 +342,7 @@ jobs:
|
||||
run: BENCHMARK_LOG=resnet_10steps_6gpu NV=1 CAPTURE_PROCESS_REPLAY=0 DEFAULT_FLOAT=HALF BENCHMARK=10 BS=1536 GPUS=6 MODEL=resnet python3 examples/mlperf/model_train.py | tee train_resnet.txt
|
||||
- name: Run 10 MLPerf Bert training steps (6 gpu)
|
||||
# TODO: remove BERT_LAYERS once scheduler is fast
|
||||
run: BENCHMARK_LOG=bert_10steps_6gpu NV=1 CAPTURE_PROCESS_REPLAY=0 DEFAULT_FLOAT=HALF BENCHMARK=10 BS=72 GPUS=6 BERT_LAYERS=2 MODEL=bert python3 examples/mlperf/model_train.py | tee train_bert.txt
|
||||
run: BENCHMARK_LOG=bert_10steps_6gpu NV=1 CAPTURE_PROCESS_REPLAY=0 DEFAULT_FLOAT=HALF BENCHMARK=10 BS=66 GPUS=6 BERT_LAYERS=2 MODEL=bert python3 examples/mlperf/model_train.py | tee train_bert.txt
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Speed (NVIDIA Training)
|
||||
@@ -598,7 +594,7 @@ jobs:
|
||||
run: BENCHMARK_LOG=resnet_10steps_6gpu AMD=1 CAPTURE_PROCESS_REPLAY=0 DEFAULT_FLOAT=HALF BENCHMARK=10 BS=1536 GPUS=6 MODEL=resnet python3 examples/mlperf/model_train.py | tee train_resnet.txt
|
||||
- name: Run 10 MLPerf Bert training steps (6 gpu)
|
||||
# TODO: remove BERT_LAYERS once scheduler is fast
|
||||
run: BENCHMARK_LOG=bert_10steps_6gpu AMD=1 CAPTURE_PROCESS_REPLAY=0 DEFAULT_FLOAT=HALF BENCHMARK=10 BS=72 GPUS=6 BERT_LAYERS=2 MODEL=bert python3 examples/mlperf/model_train.py | tee train_bert.txt
|
||||
run: BENCHMARK_LOG=bert_10steps_6gpu AMD=1 CAPTURE_PROCESS_REPLAY=0 DEFAULT_FLOAT=HALF BENCHMARK=10 BS=66 GPUS=6 BERT_LAYERS=2 MODEL=bert python3 examples/mlperf/model_train.py | tee train_bert.txt
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Speed (AMD MLPerf)
|
||||
@@ -633,8 +629,6 @@ jobs:
|
||||
run: BENCHMARK_LOG=openpilot_0_10_0_dmonitoring PYTHONPATH="." ASSERT_MIN_STEP_TIME=11 DEV=QCOM FLOAT16=1 IMAGE=2 NOLOCALS=1 taskset -c 4-7 python3 examples/openpilot/compile3.py https://github.com/commaai/openpilot/raw/v0.10.0/selfdrive/modeld/models/dmonitoring_model.onnx
|
||||
- name: DEBUG=2 openpilot compile3 0.10.1 driving_vision
|
||||
run: PYTHONPATH="." DEBUG=2 DEV=QCOM FLOAT16=1 IMAGE=2 NOLOCALS=1 taskset -c 4-7 python3 examples/openpilot/compile3.py https://github.com/commaai/openpilot/raw/720392c9a5b986981fdbed1bb8c47a6c5573a50e/selfdrive/modeld/models/driving_vision.onnx
|
||||
- name: DEBUG=2 IMAGE=1 openpilot compile3 0.10.1 driving_vision
|
||||
run: PYTHONPATH="." DEBUG=2 DEV=QCOM FLOAT16=1 IMAGE=1 NOLOCALS=1 taskset -c 4-7 python3 examples/openpilot/compile3.py https://github.com/commaai/openpilot/raw/720392c9a5b986981fdbed1bb8c47a6c5573a50e/selfdrive/modeld/models/driving_vision.onnx
|
||||
- name: openpilot compile3 0.10.1 driving_vision
|
||||
run: BENCHMARK_LOG=openpilot_0_10_1_vision PYTHONPATH="." ASSERT_MIN_STEP_TIME=17 DEV=QCOM FLOAT16=1 IMAGE=2 NOLOCALS=1 taskset -c 4-7 python3 examples/openpilot/compile3.py https://github.com/commaai/openpilot/raw/720392c9a5b986981fdbed1bb8c47a6c5573a50e/selfdrive/modeld/models/driving_vision.onnx
|
||||
- name: openpilot compile3 0.10.1 driving_policy
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: Unit Tests
|
||||
env:
|
||||
# increment this when downloads substantially change to avoid the internet
|
||||
CACHE_VERSION: '15'
|
||||
CACHE_VERSION: '14'
|
||||
CAPTURE_PROCESS_REPLAY: 1
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
@@ -289,8 +289,8 @@ jobs:
|
||||
python extra/optimization/extract_dataset.py
|
||||
gzip -c /tmp/sops > extra/datasets/sops.gz
|
||||
#DEBUG=1 MIN_ASTS=1 python extra/optimization/get_action_space.py
|
||||
- name: Repo line count < 20000 lines
|
||||
run: MAX_LINE_COUNT=20000 python sz.py
|
||||
- name: Repo line count < 19000 lines
|
||||
run: MAX_LINE_COUNT=19000 python sz.py
|
||||
|
||||
spec:
|
||||
strategy:
|
||||
@@ -465,7 +465,7 @@ jobs:
|
||||
- name: Test Bert training
|
||||
run: NULL=1 DEFAULT_FLOAT=HALF BENCHMARK=10 BS=24 GPUS=4 BERT_LAYERS=2 MODEL=bert python3 examples/mlperf/model_train.py
|
||||
- name: Test llama 3 training
|
||||
run: NULL=1 SAMPLES=300 BS=8 SEQLEN=512 GRADIENT_ACC_STEPS=1 FAKEDATA=1 DEFAULT_FLOAT=bfloat16 OPTIM_DTYPE=bfloat16 LLAMA3_SIZE=1B MODEL=llama3 python3 examples/mlperf/model_train.py
|
||||
run: NULL=1 SAMPLES=300 BS=8 SEQLEN=512 GRADIENT_ACC_STEPS=8 FAKEDATA=1 DEFAULT_FLOAT=bfloat16 OPTIM_DTYPE=bfloat16 LLAMA3_SIZE=1B MODEL=llama3 python3 examples/mlperf/model_train.py
|
||||
- name: Run process replay tests
|
||||
uses: ./.github/actions/process-replay
|
||||
|
||||
@@ -972,33 +972,3 @@ jobs:
|
||||
run: |
|
||||
python -c "from tinygrad import Device; assert Device.DEFAULT == {'LLVM':'CPU'}.get(x:='${{ matrix.backend }}'.upper(), x), Device.DEFAULT"
|
||||
python -m pytest -n=auto test/test_tiny.py test/test_ops.py --durations=20
|
||||
|
||||
# ****** Compile-only Tests ******
|
||||
|
||||
compiletests:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
backend: [ir3, nak]
|
||||
name: Compile-only (${{ matrix.backend }})
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Environment
|
||||
uses: ./.github/actions/setup-tinygrad
|
||||
with:
|
||||
key: compile-${{ matrix.backend }}
|
||||
deps: testing_minimal
|
||||
mesa: ${{ (matrix.backend == 'ir3' || matrix.backend == 'nak') && 'true' }}
|
||||
python-version: '3.14'
|
||||
- name: Set env
|
||||
shell: bash
|
||||
run: printf "NULL=1\n${{ matrix.backend == 'ir3' && 'NULL_IR3=1' || matrix.backend == 'nak' && 'NULL_NAK=1' }}" >> $GITHUB_ENV
|
||||
- name: Run test_ops
|
||||
shell: bash
|
||||
run: |
|
||||
python -c "from tinygrad import Device; assert Device.DEFAULT == 'NULL'"
|
||||
DEBUG=4 python3 test/test_ops.py TestOps.test_add
|
||||
python -m pytest -n=auto test/test_ops.py --durations=20
|
||||
|
||||
@@ -1,213 +0,0 @@
|
||||
# Claude Code Guide for tinygrad
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
tinygrad compiles tensor operations into optimized kernels. The pipeline:
|
||||
|
||||
1. **Tensor** (`tensor.py`) - User-facing API, creates UOp graph
|
||||
2. **UOp** (`uop/ops.py`) - Unified IR for all operations (both tensor and kernel level)
|
||||
3. **Schedule** (`engine/schedule.py`, `schedule/`) - Converts tensor UOps to kernel UOps
|
||||
4. **Codegen** (`codegen/`) - Converts kernel UOps to device code
|
||||
5. **Runtime** (`runtime/`) - Device-specific execution
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### UOp (Universal Operation)
|
||||
Everything is a UOp - tensors, operations, buffers, kernels. Key properties:
|
||||
- `op`: The operation type (Ops enum)
|
||||
- `dtype`: Data type
|
||||
- `src`: Tuple of source UOps
|
||||
- `arg`: Operation-specific argument
|
||||
- `tag`: Optional tag for graph transformations
|
||||
|
||||
UOps are **immutable and cached** - creating the same UOp twice returns the same object (ucache).
|
||||
|
||||
### PatternMatcher
|
||||
Used extensively for graph transformations:
|
||||
```python
|
||||
pm = PatternMatcher([
|
||||
(UPat(Ops.ADD, src=(UPat.cvar("x"), UPat.cvar("x"))), lambda x: x * 2),
|
||||
])
|
||||
result = graph_rewrite(uop, pm)
|
||||
```
|
||||
|
||||
### Schedule Cache
|
||||
Schedules are cached by graph structure. BIND nodes (variables with bound values) are unbound before cache key computation so different values hit the same cache.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
tinygrad/
|
||||
├── tensor.py # Tensor class, user API
|
||||
├── device.py # Buffer, device management
|
||||
├── dtype.py # Data types
|
||||
├── helpers.py # Utilities, environment vars
|
||||
├── uop/
|
||||
│ ├── ops.py # UOp class, Ops enum, PatternMatcher
|
||||
│ ├── spec.py # UOp type verification
|
||||
│ └── symbolic.py # Symbolic math simplification
|
||||
├── engine/
|
||||
│ ├── schedule.py # Schedule creation, caching
|
||||
│ ├── realize.py # Tensor realization
|
||||
│ ├── jit.py # JIT compilation
|
||||
│ └── memory.py # Memory planning
|
||||
├── schedule/
|
||||
│ ├── rangeify.py # Convert movements to ranges
|
||||
│ └── indexing.py # Index calculations
|
||||
├── codegen/
|
||||
│ ├── kernel.py # Kernel optimization
|
||||
│ └── uopgraph.py # UOp graph transformations
|
||||
├── renderer/ # Code generation (CUDA, Metal, etc.)
|
||||
└── runtime/ # Device backends
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# Run specific test
|
||||
python -m pytest test/unit/test_schedule_cache.py -xvs
|
||||
|
||||
# Run with timeout
|
||||
python -m pytest test/test_symbolic_ops.py -x --timeout=60
|
||||
|
||||
# Debug with print
|
||||
DEBUG=2 python -m pytest test/test_schedule.py::test_name -xvs
|
||||
|
||||
# Visualize UOp graphs
|
||||
VIZ=1 python -c "from tinygrad import Tensor; Tensor.ones(10).sum().realize()"
|
||||
```
|
||||
|
||||
## Common Environment Variables
|
||||
|
||||
- `DEBUG=1-4` - Increasing verbosity
|
||||
- `VIZ=1` - Enable graph visualization
|
||||
- `SPEC=1` - Enable UOp spec verification
|
||||
- `NOOPT=1` - Disable optimizations
|
||||
- `DEVICE=CPU/CUDA/AMD/METAL` - Set default device
|
||||
|
||||
## Debugging Tips
|
||||
|
||||
1. **Print UOp graphs**: `print(tensor.uop)` or `print(tensor.uop.sink())`
|
||||
2. **Check schedule**: `tensor.schedule()` returns list of ScheduleItems
|
||||
3. **Trace graph rewrites**: Use `VIZ=1` or add print in PatternMatcher callbacks
|
||||
4. **Find UOps by type**: `[u for u in uop.toposort() if u.op is Ops.SOMETHING]`
|
||||
|
||||
## Workflow Rules
|
||||
|
||||
- **NEVER commit without explicit user approval** - always show the diff and wait for approval
|
||||
- Run tests before proposing commits
|
||||
- Test with `SPEC=2` when modifying UOp-related code
|
||||
|
||||
## Style Notes
|
||||
|
||||
- 2-space indentation, 150 char line limit
|
||||
- PatternMatchers should be defined at module level (slow to construct)
|
||||
- Prefer `graph_rewrite` over manual graph traversal
|
||||
- UOp methods like `.replace()` preserve tags unless explicitly changed
|
||||
- Use `.rtag(value)` to add tags to UOps
|
||||
|
||||
## Lessons Learned
|
||||
|
||||
### UOp ucache Behavior
|
||||
UOps are cached by their contents - creating a UOp with identical (op, dtype, src, arg) returns the **same object**. This means:
|
||||
- `uop.replace(tag=None)` on a tagged UOp returns the original untagged UOp if it exists in cache
|
||||
- Two UOps with same structure are identical (`is` comparison works)
|
||||
|
||||
### Spec Validation
|
||||
When adding new UOp patterns, update `tinygrad/uop/spec.py`. Test with:
|
||||
```bash
|
||||
SPEC=2 python3 test/unit/test_something.py
|
||||
```
|
||||
Spec issues appear as `RuntimeError: SPEC ISSUE None: UOp(...)`.
|
||||
|
||||
### Schedule Cache Key Normalization
|
||||
The schedule cache strips values from BIND nodes so different bound values (e.g., KV cache positions) hit the same cache entry:
|
||||
- `pm_pre_sched_cache`: BIND(DEFINE_VAR, CONST) → BIND(DEFINE_VAR) for cache key
|
||||
- `pm_post_sched_cache`: restores original BIND from context
|
||||
- When accessing `bind.src[1]`, check `len(bind.src) > 1` first (might be stripped)
|
||||
- Extract var_vals from `input_buffers` dict after graph_rewrite (avoids extra toposort)
|
||||
|
||||
### Avoiding Extra Work
|
||||
- Use ctx dict from graph_rewrite to collect info during traversal instead of separate toposort
|
||||
- Only extract var_vals when schedule is non-empty (no kernels = no vars needed)
|
||||
- PatternMatchers are slow to construct - define at module level, not in functions
|
||||
|
||||
### Testing LLM Changes
|
||||
```bash
|
||||
# Quick smoke test
|
||||
echo "Hello" | DEBUG=1 python tinygrad/apps/llm.py --model "llama3.2:1b"
|
||||
|
||||
# Check cache hits (should see "cache hit" after warmup)
|
||||
echo "Hello world" | DEBUG=1 python tinygrad/apps/llm.py --model "llama3.2:1b" 2>&1 | grep cache
|
||||
|
||||
# Test with beam search
|
||||
echo "Hello" | BEAM=2 python tinygrad/apps/llm.py --model "llama3.2:1b"
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Graph Transformation
|
||||
```python
|
||||
def my_transform(ctx, x):
|
||||
# Return new UOp or None to skip
|
||||
return x.replace(arg=new_arg)
|
||||
|
||||
pm = PatternMatcher([
|
||||
(UPat(Ops.SOMETHING, name="x"), my_transform),
|
||||
])
|
||||
result = graph_rewrite(input_uop, pm, ctx={})
|
||||
```
|
||||
|
||||
### Finding Variables
|
||||
```python
|
||||
# Get all variables in a UOp graph
|
||||
variables = uop.variables()
|
||||
|
||||
# Get bound variable values
|
||||
var, val = bind_uop.unbind()
|
||||
```
|
||||
|
||||
### Shape Handling
|
||||
```python
|
||||
# Shapes can be symbolic (contain UOps)
|
||||
shape = tensor.shape # tuple[sint, ...] where sint = int | UOp
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
When optimizing tinygrad internals:
|
||||
|
||||
1. **Measure wall time, not just call counts** - Reducing `graph_rewrite` calls doesn't always improve wall time. The overhead of conditional checks can exceed the cost of the operation being skipped.
|
||||
|
||||
2. **Profile each optimization individually** - Run benchmarks with and without each change to measure actual impact. Use `test/external/external_benchmark_schedule.py` for schedule/rewrite timing.
|
||||
|
||||
3. **Early exits in hot paths are effective** - Simple checks like `if self.op is Ops.CONST: return self` in `simplify()` can eliminate many unnecessary `graph_rewrite` calls.
|
||||
|
||||
4. **`graph_rewrite` is expensive** - Each call has overhead even for small graphs. Avoid calling it when the result is trivially known (e.g., simplifying a CONST returns itself).
|
||||
|
||||
5. **Beware iterator overhead** - Checks like `all(x.op is Ops.CONST for x in self.src)` can be slower than just running the operation, especially for small sequences.
|
||||
|
||||
6. **Verify cache hit rates before adding/keeping caches** - Measure actual hit rates with real workloads. A cache with 0% hit rate is pure overhead (e.g., `pm_cache` was removed because the algorithm guarantees each UOp is only passed to `pm_rewrite` once).
|
||||
|
||||
7. **Use `TRACK_MATCH_STATS=2` to profile pattern matching** - This shows match rates and time per pattern. Look for patterns with 0% match rate that still cost significant time - these are pure overhead for that workload.
|
||||
|
||||
8. **Cached properties beat manual traversal** - `backward_slice` uses `@functools.cached_property`. A DFS with early-exit sounds faster but is actually slower because it doesn't benefit from caching. The cache hit benefit often outweighs algorithmic improvements.
|
||||
|
||||
9. **Avoid creating intermediate objects in hot paths** - For example, `any(x.op in ops for x in self.backward_slice)` is faster than `any(x.op in ops for x in {self:None, **self.backward_slice})` because it avoids dict creation.
|
||||
|
||||
## Pattern Matching Profiling
|
||||
|
||||
Use `TRACK_MATCH_STATS=2` to identify expensive patterns:
|
||||
|
||||
```bash
|
||||
TRACK_MATCH_STATS=2 PYTHONPATH="." python3 test/external/external_benchmark_schedule.py
|
||||
```
|
||||
|
||||
Output format: `matches / attempts -- match_time / total_time ms -- location`
|
||||
|
||||
Key patterns to watch (from ResNet50 benchmark):
|
||||
- `split_load_store`: ~146ms, 31% match rate - does real work
|
||||
- `simplify_valid`: ~75ms, 0% match rate in this workload - checks AND ops for INDEX in backward slice
|
||||
- `vmin==vmax folding`: ~55ms, 0.33% match rate - checks 52K ops but rarely matches
|
||||
|
||||
Patterns with 0% match rate are workload-specific overhead. They may be useful in other workloads, so don't remove them without understanding their purpose.
|
||||
@@ -223,13 +223,13 @@ def get_mlperf_bert_model():
|
||||
|
||||
def get_fake_data_bert(BS:int):
|
||||
return {
|
||||
"input_ids": Tensor.zeros((BS, 512), dtype=dtypes.int32, device="CPU").contiguous(),
|
||||
"input_mask": Tensor.zeros((BS, 512), dtype=dtypes.int32, device="CPU").contiguous(),
|
||||
"segment_ids": Tensor.zeros((BS, 512), dtype=dtypes.int32, device="CPU").contiguous(),
|
||||
"masked_lm_positions": Tensor.zeros((BS, 76), dtype=dtypes.int32, device="CPU").contiguous(),
|
||||
"masked_lm_ids": Tensor.zeros((BS, 76), dtype=dtypes.int32, device="CPU").contiguous(),
|
||||
"masked_lm_weights": Tensor.zeros((BS, 76), dtype=dtypes.float32, device="CPU").contiguous(),
|
||||
"next_sentence_labels": Tensor.zeros((BS, 1), dtype=dtypes.int32, device="CPU").contiguous(),
|
||||
"input_ids": Tensor.empty((BS, 512), dtype=dtypes.int32, device="CPU"),
|
||||
"input_mask": Tensor.empty((BS, 512), dtype=dtypes.int32, device="CPU"),
|
||||
"segment_ids": Tensor.empty((BS, 512), dtype=dtypes.int32, device="CPU"),
|
||||
"masked_lm_positions": Tensor.empty((BS, 76), dtype=dtypes.int32, device="CPU"),
|
||||
"masked_lm_ids": Tensor.empty((BS, 76), dtype=dtypes.int32, device="CPU"),
|
||||
"masked_lm_weights": Tensor.empty((BS, 76), dtype=dtypes.float32, device="CPU"),
|
||||
"next_sentence_labels": Tensor.empty((BS, 1), dtype=dtypes.int32, device="CPU"),
|
||||
}
|
||||
|
||||
def find_matches(match_quality_matrix:np.ndarray, high_threshold:float=0.5, low_threshold:float=0.4, allow_low_quality_matches:bool=False) -> np.ndarray:
|
||||
|
||||
@@ -59,7 +59,9 @@ class EmbeddingBert(nn.Embedding):
|
||||
arange_shp, weight_shp, big_shp = (1, 1, self.vocab_sz, 1), (1, 1, self.vocab_sz, self.embed_sz), idx.shape+(self.vocab_sz, self.embed_sz,)
|
||||
if not hasattr(self, 'arange'): self.arange = Tensor.arange(self.vocab_sz, requires_grad=False, device=self.weight.device).reshape(arange_shp)
|
||||
arange, idx, vals = self.arange.expand(big_shp), idx.reshape(idx.shape+(1, 1,)).expand(big_shp), self.weight.cast(dtypes.default_float).reshape(weight_shp).expand(big_shp)
|
||||
return (arange == idx).where(vals, 0).sum(2, dtype=vals.dtype)
|
||||
# TODO: contiguous() here because the embedding dropout creates different asts on each device, and search becomes very slow.
|
||||
# Should fix with fixing random ast on multi device, and fuse arange to make embedding fast.
|
||||
return (arange == idx).mul(vals).sum(2, dtype=vals.dtype).contiguous()
|
||||
|
||||
class LayerNormBert:
|
||||
def __init__(self, normalized_shape:Union[int, tuple[int, ...]], eps:float=1e-12, elementwise_affine:bool=True):
|
||||
|
||||
@@ -918,6 +918,40 @@ def train_rnnt():
|
||||
# TODO: RNN-T
|
||||
pass
|
||||
|
||||
@TinyJit
|
||||
def train_step_bert(model, optimizer, scheduler, loss_scaler:float, GPUS, grad_acc:int, **kwargs):
|
||||
optimizer.zero_grad()
|
||||
|
||||
for i in range(grad_acc):
|
||||
input_ids, segment_ids = kwargs[f"input_ids{i}"], kwargs[f"segment_ids{i}"]
|
||||
# NOTE: these two have different names
|
||||
attention_mask, masked_positions = kwargs[f"input_mask{i}"], kwargs[f"masked_lm_positions{i}"]
|
||||
masked_lm_ids, masked_lm_weights, next_sentence_labels = kwargs[f"masked_lm_ids{i}"], kwargs[f"masked_lm_weights{i}"], kwargs[f"next_sentence_labels{i}"]
|
||||
|
||||
for t in [input_ids, segment_ids, attention_mask, masked_positions, masked_lm_ids, masked_lm_weights, next_sentence_labels]:
|
||||
if len(GPUS) > 1: t.shard_(GPUS, axis=0)
|
||||
else: t.to_(GPUS[0])
|
||||
|
||||
lm_logits, seq_relationship_logits = model(input_ids, attention_mask, masked_positions, segment_ids)
|
||||
loss = model.loss(lm_logits, seq_relationship_logits, masked_lm_ids, masked_lm_weights, next_sentence_labels)
|
||||
(loss * loss_scaler).backward()
|
||||
# TODO: OOM without this realize with large grad_acc
|
||||
Tensor.realize(*[p.grad for p in optimizer.params])
|
||||
|
||||
global_norm = Tensor(0.0, dtype=dtypes.float32, device=optimizer[0].device)
|
||||
for p in optimizer.params:
|
||||
p.grad = p.grad / loss_scaler
|
||||
global_norm += p.grad.float().square().sum()
|
||||
global_norm = global_norm.sqrt().contiguous()
|
||||
for p in optimizer.params:
|
||||
p.grad = (global_norm > 1.0).where((p.grad/global_norm).cast(p.grad.dtype), p.grad)
|
||||
|
||||
optimizer.step()
|
||||
scheduler.step()
|
||||
# TODO: no to("CPU") here because it blocks and messes the python time
|
||||
Tensor.realize(loss, global_norm, optimizer.optimizers[0].lr)
|
||||
return loss, global_norm, optimizer.optimizers[0].lr
|
||||
|
||||
@TinyJit
|
||||
def eval_step_bert(model, input_ids:Tensor, segment_ids:Tensor, attention_mask:Tensor, masked_positions:Tensor, masked_lm_ids:Tensor,
|
||||
masked_lm_weights:Tensor, next_sentence_labels:Tensor, GPUS):
|
||||
@@ -980,8 +1014,7 @@ def train_bert():
|
||||
# ** hyperparameters **
|
||||
BS = config["BS"] = getenv("BS", 11 * len(GPUS) if dtypes.default_float in (dtypes.float16, dtypes.bfloat16) else 8 * len(GPUS))
|
||||
grad_acc = config["GRADIENT_ACC_STEPS"] = getenv("GRADIENT_ACC_STEPS", 1)
|
||||
# TODO: implement grad accumulation + mlperf logging
|
||||
assert grad_acc == 1
|
||||
# TODO: mlperf logging
|
||||
GBS = config["GLOBAL_BATCH_SIZE"] = BS * grad_acc
|
||||
EVAL_BS = config["EVAL_BS"] = getenv("EVAL_BS", 1 * len(GPUS))
|
||||
max_lr = config["OPT_BASE_LEARNING_RATE"] = getenv("OPT_BASE_LEARNING_RATE", 0.000175 * math.sqrt(GBS/96))
|
||||
@@ -1040,8 +1073,8 @@ def train_bert():
|
||||
|
||||
# ** Optimizer **
|
||||
parameters_no_wd = [v for k, v in get_state_dict(model).items() if "bias" in k or "LayerNorm" in k]
|
||||
parameters_wd = [x for x in parameters if x not in set(parameters_no_wd)]
|
||||
optimizer_wd = LAMB(parameters_wd, lr=max_lr, b1=opt_lamb_beta_1, b2=opt_lamb_beta_2, eps=epsilon, weight_decay=decay, adam=False)
|
||||
parameters = [x for x in parameters if x not in set(parameters_no_wd)]
|
||||
optimizer_wd = LAMB(parameters, lr=max_lr, b1=opt_lamb_beta_1, b2=opt_lamb_beta_2, eps=epsilon, weight_decay=decay, adam=False)
|
||||
optimizer_no_wd = LAMB(parameters_no_wd, lr=max_lr, b1=opt_lamb_beta_1, b2=opt_lamb_beta_2, eps=epsilon, weight_decay=0.0, adam=False)
|
||||
optimizer_group = OptimizerGroup(optimizer_wd, optimizer_no_wd)
|
||||
|
||||
@@ -1098,38 +1131,12 @@ def train_bert():
|
||||
# ** train loop **
|
||||
wc_start = time.perf_counter()
|
||||
|
||||
i, train_data = start_step, next(train_it)
|
||||
i, train_data = start_step, [next(train_it) for _ in range(grad_acc)]
|
||||
|
||||
if RUNMLPERF:
|
||||
if MLLOGGER:
|
||||
MLLOGGER.start(key=mllog_constants.EPOCH_START, value=i*GBS, metadata={"epoch_num": i*GBS})
|
||||
|
||||
@TinyJit
|
||||
def train_step_bert(input_ids:Tensor, segment_ids:Tensor, attention_mask:Tensor,
|
||||
masked_positions:Tensor, masked_lm_ids:Tensor, masked_lm_weights:Tensor, next_sentence_labels:Tensor):
|
||||
for t in [input_ids, segment_ids, attention_mask, masked_positions, masked_lm_ids, masked_lm_weights, next_sentence_labels]:
|
||||
if len(GPUS) > 1: t.shard_(GPUS, axis=0)
|
||||
else: t.to_(GPUS[0])
|
||||
optimizer_group.zero_grad()
|
||||
|
||||
lm_logits, seq_relationship_logits = model(input_ids, attention_mask, masked_positions, segment_ids)
|
||||
loss = model.loss(lm_logits, seq_relationship_logits, masked_lm_ids, masked_lm_weights, next_sentence_labels)
|
||||
(loss * loss_scaler).backward()
|
||||
|
||||
global_norm = Tensor(0.0, dtype=dtypes.float32, device=optimizer_group[0].device)
|
||||
for p in optimizer_group.params:
|
||||
p.grad = p.grad / loss_scaler
|
||||
global_norm += p.grad.float().square().sum()
|
||||
global_norm = global_norm.sqrt().contiguous()
|
||||
for p in optimizer_group.params:
|
||||
p.grad = (global_norm > 1.0).where((p.grad/global_norm).cast(p.grad.dtype), p.grad)
|
||||
|
||||
optimizer_group.step()
|
||||
scheduler_group.step()
|
||||
# TODO: no to("CPU") here because it blocks and messes the python time
|
||||
Tensor.realize(loss, global_norm, optimizer_group.optimizers[0].lr)
|
||||
return loss, global_norm, optimizer_group.optimizers[0].lr
|
||||
|
||||
while train_data is not None and i < train_steps and not achieved:
|
||||
if getenv("TRAIN", 1):
|
||||
Tensor.training = True
|
||||
@@ -1137,12 +1144,16 @@ def train_bert():
|
||||
st = time.perf_counter()
|
||||
GlobalCounters.reset()
|
||||
with WallTimeEvent(BenchEvent.STEP):
|
||||
loss, global_norm, lr = train_step_bert(
|
||||
train_data["input_ids"], train_data["segment_ids"], train_data["input_mask"], train_data["masked_lm_positions"], \
|
||||
train_data["masked_lm_ids"], train_data["masked_lm_weights"], train_data["next_sentence_labels"])
|
||||
data = {f"{k}{i}":v for i,d in enumerate(train_data) for k,v in d.items()}
|
||||
loss, global_norm, lr = train_step_bert(model, optimizer_group, scheduler_group, loss_scaler, GPUS, grad_acc, **data)
|
||||
|
||||
pt = time.perf_counter()
|
||||
next_data = next(train_it)
|
||||
|
||||
try:
|
||||
next_data = [next(train_it) for _ in range(grad_acc)]
|
||||
except StopIteration:
|
||||
next_data = None
|
||||
|
||||
dt = time.perf_counter()
|
||||
|
||||
device_str = parameters[0].device if isinstance(parameters[0].device, str) else f"{parameters[0].device[0]} * {len(parameters[0].device)}"
|
||||
@@ -1177,8 +1188,8 @@ def train_bert():
|
||||
if MLLOGGER and RUNMLPERF:
|
||||
MLLOGGER.start(key=mllog_constants.EVAL_START, value=None, metadata={"epoch_num": i*GBS, "step_num": i})
|
||||
if getenv("RESET_STEP"): train_step_bert.reset()
|
||||
elif getenv("FREE_INTERMEDIATE") and train_step_bert.captured is not None:
|
||||
# TODO: this hangs on tiny green after 90 minutes of training
|
||||
elif getenv("FREE_INTERMEDIATE", 0) and train_step_bert.captured is not None:
|
||||
# TODO: FREE_INTERMEDIATE nan'ed after jit step 2
|
||||
train_step_bert.captured.free_intermediates()
|
||||
eval_lm_losses = []
|
||||
eval_clsf_losses = []
|
||||
@@ -1213,7 +1224,7 @@ def train_bert():
|
||||
return
|
||||
|
||||
if getenv("RESET_STEP"): eval_step_bert.reset()
|
||||
elif getenv("FREE_INTERMEDIATE") and eval_step_bert.captured is not None: eval_step_bert.captured.free_intermediates()
|
||||
elif getenv("FREE_INTERMEDIATE", 0) and eval_step_bert.captured is not None: eval_step_bert.captured.free_intermediates()
|
||||
|
||||
del eval_data
|
||||
avg_lm_loss = sum(eval_lm_losses) / len(eval_lm_losses)
|
||||
@@ -1289,7 +1300,6 @@ def train_llama3():
|
||||
BASEDIR = config["BASEDIR"] = Path(getenv("BASEDIR", "/raid/datasets/c4/"))
|
||||
BS = config["BS"] = getenv("BS", 16)
|
||||
grad_acc = config["GRADIENT_ACC_STEPS"] = getenv("GRADIENT_ACC_STEPS", 1)
|
||||
assert grad_acc == 1, f"{grad_acc=} is not supported"
|
||||
GBS = config["GLOBAL_BATCH_SIZE"] = BS * grad_acc
|
||||
SEED = config["SEED"] = getenv("SEED", 5760)
|
||||
SEQLEN = config["SEQLEN"] = getenv("SEQLEN", 8192)
|
||||
@@ -1364,17 +1374,20 @@ def train_llama3():
|
||||
|
||||
@TinyJit
|
||||
@Tensor.train()
|
||||
def train_step(model, tokens:Tensor):
|
||||
def train_step(model, tokens:Tensor, grad_acc:int):
|
||||
optim.zero_grad()
|
||||
if (DP := getenv("DP", 1)) > 1:
|
||||
device = tuple(f"{Device.DEFAULT}:{i}" for i in range(DP))
|
||||
tokens = tokens.shard(device, 0)
|
||||
if (MP := getenv("MP", 1)) > 1:
|
||||
device = tuple(f"{Device.DEFAULT}:{i}" for i in range(MP))
|
||||
tokens = tokens.shard(device)
|
||||
logits:Tensor = model(tokens[:, :-1], start_pos=0, temperature=math.nan)
|
||||
loss = logits.sparse_categorical_crossentropy(tokens[:, 1:])
|
||||
loss.backward()
|
||||
# grad acc
|
||||
for batch in tokens.split(tokens.shape[0]//grad_acc):
|
||||
if (DP := getenv("DP", 1)) > 1:
|
||||
device = tuple(f"{Device.DEFAULT}:{i}" for i in range(DP))
|
||||
batch = batch.shard(device, 0)
|
||||
if (MP := getenv("MP", 1)) > 1:
|
||||
device = tuple(f"{Device.DEFAULT}:{i}" for i in range(MP))
|
||||
batch = batch.shard(device)
|
||||
logits:Tensor = model(batch[:, :-1], start_pos=0, temperature=math.nan)
|
||||
loss = logits.sparse_categorical_crossentropy(batch[:, 1:])
|
||||
loss.backward()
|
||||
Tensor.realize(*[p.grad for p in optim.params])
|
||||
# L2 norm grad clip
|
||||
# https://github.com/NVIDIA/NeMo/blob/3368c3fc0b4a186ab33a1d68a504315100c0b2a6/nemo/collections/nlp/modules/common/megatron/clip_grads.py#L57
|
||||
# https://docs.pytorch.org/docs/stable/generated/torch.nn.utils.clip_grad_norm_.html
|
||||
@@ -1413,14 +1426,14 @@ def train_llama3():
|
||||
|
||||
def get_train_iter():
|
||||
if getenv("FAKEDATA", 0):
|
||||
return fake_data(BS, SAMPLES)
|
||||
return fake_data(GBS, SAMPLES)
|
||||
else:
|
||||
if SMALL:
|
||||
from examples.mlperf.dataloader import batch_load_llama3_small
|
||||
return batch_load_llama3_small(BS, SAMPLES, SEQLEN, BASEDIR, seed=SEED, val=bool(TRAIN_ON_VAL))
|
||||
return batch_load_llama3_small(GBS, SAMPLES, SEQLEN, BASEDIR, seed=SEED, val=bool(TRAIN_ON_VAL))
|
||||
else:
|
||||
from examples.mlperf.dataloader import batch_load_llama3
|
||||
return batch_load_llama3(BS, SAMPLES, SEQLEN, BASEDIR, seed=SEED, val=bool(TRAIN_ON_VAL))
|
||||
return batch_load_llama3(GBS, SAMPLES, SEQLEN, BASEDIR, seed=SEED, val=bool(TRAIN_ON_VAL))
|
||||
|
||||
def get_eval_iter():
|
||||
if getenv("FAKEDATA", 0):
|
||||
@@ -1438,7 +1451,7 @@ def train_llama3():
|
||||
for tokens in tqdm(iter, total=SAMPLES//GBS):
|
||||
t = time.perf_counter()
|
||||
GlobalCounters.reset()
|
||||
loss, lr = train_step(model, tokens)
|
||||
loss, lr = train_step(model, tokens, grad_acc)
|
||||
loss = loss.float().item()
|
||||
|
||||
i += 1
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
export PYTHONPATH="." NV=1
|
||||
export MODEL="bert"
|
||||
export DEFAULT_FLOAT="HALF" SUM_DTYPE="HALF" GPUS=6 BS=72 EVAL_BS=72
|
||||
export DEFAULT_FLOAT="HALF" SUM_DTYPE="HALF" GPUS=6 BS=96 EVAL_BS=96
|
||||
|
||||
export IGNORE_OOB=1
|
||||
export REWRITE_STACK_LIMIT=500000
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
export PYTHONPATH="." NV=1
|
||||
export MODEL="bert"
|
||||
export DEFAULT_FLOAT="HALF" SUM_DTYPE="HALF" GPUS=6 BS=72 EVAL_BS=72
|
||||
export DEFAULT_FLOAT="HALF" SUM_DTYPE="HALF" GPUS=6 BS=96 EVAL_BS=96
|
||||
|
||||
export IGNORE_OOB=1
|
||||
export REWRITE_STACK_LIMIT=500000
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ set -o pipefail # Make pipeline fail if any command fails
|
||||
export PYTHONPATH="." NV=1
|
||||
export MODEL="bert"
|
||||
export SUBMISSION_PLATFORM="tinybox_green"
|
||||
export DEFAULT_FLOAT="HALF" SUM_DTYPE="HALF" GPUS=6 BS=72 EVAL_BS=72
|
||||
export DEFAULT_FLOAT="HALF" SUM_DTYPE="HALF" GPUS=6 BS=96 EVAL_BS=96
|
||||
|
||||
export IGNORE_OOB=1
|
||||
export REWRITE_STACK_LIMIT=500000
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from tinygrad.helpers import Context
|
||||
from tinygrad.runtime.support.system import System, PCIDevice, PCIDevImplBase
|
||||
from tinygrad.runtime.support.am.amdev import AMDev
|
||||
|
||||
if __name__ == "__main__":
|
||||
gpus = System.pci_scan_bus(0x1002, [(0xffff, [0x74a1])])
|
||||
pcidevs = [PCIDevice(f"reset:{gpu}", gpu, bars=[0, 2, 5]) for gpu in gpus]
|
||||
amdevs = []
|
||||
with Context(DEBUG=2):
|
||||
for pcidev in pcidevs:
|
||||
amdevs.append(AMDev(pcidev, reset_mode=True))
|
||||
for amdev in amdevs: amdev.smu.mode1_reset()
|
||||
+20
-30
@@ -1,59 +1,48 @@
|
||||
import re, ctypes, sys, importlib
|
||||
from tinygrad.helpers import getenv
|
||||
|
||||
from tinygrad.runtime.support.am.amdev import AMDev, AMRegister
|
||||
class AMDFake(AMDev):
|
||||
def __init__(self, pci_dev, dma_regions=None):
|
||||
self.pci_dev, self.devfmt, self.dma_regions = pci_dev, pci_dev.pcibus, dma_regions
|
||||
self.vram, self.doorbell64, self.mmio = self.pci_dev.map_bar(0), self.pci_dev.map_bar(2, fmt='Q'), self.pci_dev.map_bar(5, fmt='I')
|
||||
def __init__(self, devfmt, vram, doorbell, mmio, dma_regions=None):
|
||||
self.devfmt, self.vram, self.doorbell64, self.mmio, self.dma_regions = devfmt, vram, doorbell, mmio, dma_regions
|
||||
self._run_discovery()
|
||||
self._build_regs()
|
||||
|
||||
amdev = importlib.import_module("tinygrad.runtime.support.am.amdev")
|
||||
amdev.AMDev = AMDFake
|
||||
|
||||
from tinygrad.runtime.ops_amd import PCIIface
|
||||
|
||||
def parse_amdgpu_logs(log_content, register_names=None, *, only_xcc0: bool = False):
|
||||
register_map = register_names or {}
|
||||
def parse_amdgpu_logs(log_content, register_names=None):
|
||||
register_map = register_names
|
||||
|
||||
final = ""
|
||||
def replace_register(match):
|
||||
reg = match.group(1)
|
||||
return f"Reading register {register_map.get(int(reg, 16), reg)}"
|
||||
register = match.group(1)
|
||||
return f"Reading register {register_map.get(int(register, base=16), register)}"
|
||||
|
||||
processed_log = re.sub(r'Reading register (0x[0-9a-fA-F]+)', replace_register, log_content)
|
||||
pattern = r'Reading register (0x[0-9a-fA-F]+)'
|
||||
|
||||
processed_log = re.sub(pattern, replace_register, log_content)
|
||||
|
||||
def replace_register_2(match):
|
||||
reg = match.group(1)
|
||||
return f"Writing register {register_map.get(int(reg, 16), reg)}"
|
||||
|
||||
processed_log = re.sub(r'Writing register (0x[0-9a-fA-F]+)', replace_register_2, processed_log)
|
||||
|
||||
# remove timing prefix
|
||||
processed_log = re.sub(r'^\[\s*\d+(?:\.\d+)?\]\s*', '', processed_log, flags=re.MULTILINE)
|
||||
|
||||
# keep only xcc=0 lines (but keep lines with no xcc at all)
|
||||
if only_xcc0:
|
||||
kept = []
|
||||
for line in processed_log.splitlines(True):
|
||||
if "xcc=" not in line or re.search(r'\bxcc=0\b', line): kept.append(line)
|
||||
processed_log = "".join(kept)
|
||||
register = match.group(1)
|
||||
return f"Writing register {register_map.get(int(register, base=16), register)}"
|
||||
|
||||
pattern = r'Writing register (0x[0-9a-fA-F]+)'
|
||||
processed_log = re.sub(pattern, replace_register_2, processed_log)
|
||||
return processed_log
|
||||
|
||||
def main():
|
||||
only_xcc0 = bool(getenv("ONLY_XCC0", 0))
|
||||
|
||||
reg_names = {}
|
||||
dev = PCIIface(None, 0)
|
||||
for x, y in dev.dev_impl.__dict__.items():
|
||||
if isinstance(y, AMRegister):
|
||||
for xcc, addr in y.addr.items():
|
||||
reg_names[addr] = f"{x}, xcc={xcc}"
|
||||
for inst, addr in y.addr.items(): reg_names[addr] = f"{x}, xcc={inst}"
|
||||
|
||||
with open(sys.argv[1], 'r') as f:
|
||||
log_content = f.read()
|
||||
log_content = log_content_them = f.read()
|
||||
|
||||
processed_log = parse_amdgpu_logs(log_content, reg_names, only_xcc0=only_xcc0)
|
||||
processed_log = parse_amdgpu_logs(log_content, reg_names)
|
||||
|
||||
with open(sys.argv[2], 'w') as f:
|
||||
f.write(processed_log)
|
||||
@@ -62,4 +51,5 @@ if __name__ == '__main__':
|
||||
if len(sys.argv) != 3:
|
||||
print("Usage: <input_file_path> <output_file_path>")
|
||||
sys.exit(1)
|
||||
main()
|
||||
|
||||
main()
|
||||
+12
-8
@@ -158,13 +158,14 @@ def decode(profile:list[ProfileEvent]) -> _ROCParseCtx:
|
||||
t.join()
|
||||
return ROCParseCtx
|
||||
|
||||
def print_pmc(events:list[ProfilePMCEvent]) -> None:
|
||||
from tinygrad.viz.serve import unpack_pmc
|
||||
from tabulate import tabulate
|
||||
for e in events:
|
||||
print("**", e.kern)
|
||||
data = unpack_pmc(e)
|
||||
print(tabulate([r[:-1] for r in data["rows"]], headers=data["cols"], tablefmt="github"))
|
||||
def print_pmc(ev:ProfilePMCEvent) -> None:
|
||||
ptr = 0
|
||||
view = memoryview(ev.blob).cast('Q')
|
||||
for s in ev.sched:
|
||||
print(f"\t{s.name}")
|
||||
for xcc, inst, se_idx, sa_idx, wgp_idx in itertools.product(range(s.xcc), range(s.inst), range(s.se), range(s.sa), range(s.wgp)):
|
||||
print(f"\t\tXCC {xcc} Inst {inst:<2} SE {se_idx} SA {sa_idx} WGP {wgp_idx}: {view[ptr]:#x}")
|
||||
ptr += 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
@@ -175,4 +176,7 @@ if __name__ == "__main__":
|
||||
rctx = decode(profile)
|
||||
print('SQTT:', rctx.inst_execs.keys())
|
||||
|
||||
print_pmc([ev for ev in profile if isinstance(ev, ProfilePMCEvent)])
|
||||
for ev in profile:
|
||||
if not isinstance(ev, ProfilePMCEvent): continue
|
||||
print(f"PMC Event: dev={ev.device} kern={ev.kern}")
|
||||
print_pmc(ev)
|
||||
|
||||
+2
-40
@@ -6,11 +6,8 @@ import unittest
|
||||
import functools, contextlib
|
||||
import numpy as np
|
||||
from tinygrad import Tensor, Context, Device
|
||||
from tinygrad.dtype import dtypes, AddrSpace
|
||||
from tinygrad.uop.ops import UOp, Ops, KernelInfo, AxisType
|
||||
from tinygrad.uop.ops import UOp, KernelInfo, AxisType
|
||||
from tinygrad.runtime.ops_amd import ProfilePMCEvent
|
||||
from tinygrad.engine.realize import get_runner
|
||||
from tinygrad.viz.serve import unpack_pmc
|
||||
from extra.sqtt.roc import print_pmc
|
||||
|
||||
def copy_kernel(B, A, stride=1):
|
||||
@@ -22,16 +19,6 @@ def copy_kernel(B, A, stride=1):
|
||||
index = (i * stride) % A.size
|
||||
return B[index].store(A[index]).sink(arg=KernelInfo(name=f"copy_{A.size}_stride_{stride}", opts_to_apply=()))
|
||||
|
||||
def lds_kernel(offset:UOp, size:int, inst:str) -> UOp:
|
||||
tid = UOp.range(offset.size, 0, AxisType.LOCAL)
|
||||
dst = UOp.placeholder((size,), dtypes.float32, 1, AddrSpace.REG)
|
||||
#lds = UOp.placeholder((1024,), dtypes.float32, 2, AddrSpace.LOCAL)
|
||||
u = UOp(Ops.CUSTOM, arg='__builtin_amdgcn_s_waitcnt(0);')
|
||||
u = UOp(Ops.CUSTOM, arg='__builtin_amdgcn_s_barrier();', src=(u,))
|
||||
u = UOp(Ops.CUSTOM, arg='__builtin_amdgcn_sched_barrier(0);', src=(u,))
|
||||
u = UOp(Ops.CUSTOM, arg=f'asm volatile("{inst} '+'%0, %1" : "=v"({0}) : "v"({1}));', src=(dst, offset[tid], u))
|
||||
return UOp.sink(u, arg=KernelInfo(name="test_lds", opts_to_apply=()))
|
||||
|
||||
dev = Device[Device.DEFAULT]
|
||||
|
||||
@contextlib.contextmanager
|
||||
@@ -53,35 +40,10 @@ class TestPMC(unittest.TestCase):
|
||||
b = Tensor.custom_kernel(b, a, fxn=functools.partial(copy_kernel, stride=stride))[0]
|
||||
with save_pmc() as pmc:
|
||||
b.realize()
|
||||
print_pmc(pmc)
|
||||
print_pmc(pmc[0])
|
||||
np.testing.assert_equal(a.numpy(), b.numpy())
|
||||
|
||||
def test_copy_uncoalesced(self): return self.test_copy(stride=17)
|
||||
|
||||
# test with two threads issuing ds_reads at different offsets
|
||||
def test_ds_read(self, size=1, inst='ds_read_b32'):
|
||||
test_banks = 256
|
||||
offsets = [Tensor([0, b*4]) for b in range(1, test_banks)]
|
||||
with Context(DEBUG=0): Tensor.realize(*offsets)
|
||||
k = Tensor.custom_kernel(offsets[0], fxn=functools.partial(lds_kernel, size=size, inst=inst))[0]
|
||||
# sample all kernels
|
||||
with save_pmc() as pmc_events:
|
||||
runner = get_runner(Device.DEFAULT, k.schedule()[0].ast)
|
||||
# TODO: llvm eliminates lds definition from the ELF, is there another way to pin lds size?
|
||||
runner._prg.group_segment_size = 1024
|
||||
for offset in offsets: runner([offset.uop.buffer])
|
||||
# find read offsets that created bank conflicts from the pmc counters
|
||||
found:list[Tensor] = []
|
||||
for i,e in enumerate(pmc_events):
|
||||
pmc = unpack_pmc(e)["rows"]
|
||||
# SQ on gfx9, renamed to SQC after gfx10
|
||||
val = next(total for name,total,_all_instances in pmc if name in {"SQ_LDS_BANK_CONFLICT", "SQC_LDS_BANK_CONFLICT"})
|
||||
if val > 0: found.append(offsets[i])
|
||||
print("Found bank conflicts at offsets:", [s.numpy() for s in found])
|
||||
|
||||
def test_ds_read_b64(self): self.test_ds_read(2, 'ds_read_b64')
|
||||
|
||||
def test_ds_read_b128(self): self.test_ds_read(4, 'ds_read_b128')
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
import math
|
||||
|
||||
from tinygrad import Tensor, dtypes
|
||||
from tinygrad.uop.ops import UOp, Ops, KernelInfo
|
||||
|
||||
from extra.thunder.tiny.tk import WARP_THREADS
|
||||
from extra.thunder.tiny.tk.kernel import Kernel
|
||||
from extra.thunder.tiny.tk.tiles import GL, TileLayout
|
||||
|
||||
NUM_WORKERS = 1
|
||||
Q_BLOCK_SIZE = 16
|
||||
KV_BLOCK_SIZE = 16
|
||||
|
||||
def flash_attention(xq, xk, xv, attn_mask:Tensor|None=None, is_causal:bool=False):
|
||||
if len(xq.shape) == 3: xq, xk, xv = xq.unsqueeze(0), xk.unsqueeze(0), xv.unsqueeze(0)
|
||||
|
||||
odtype = xq.dtype
|
||||
xq, xk, xv = xq.transpose(1, 2).cast(dtypes.bfloat16), xk.transpose(1, 2).cast(dtypes.bfloat16), xv.transpose(1, 2).cast(dtypes.bfloat16)
|
||||
|
||||
_, N_, _, D_ = xq.shape
|
||||
block_size = max(Q_BLOCK_SIZE, KV_BLOCK_SIZE)
|
||||
assert D_ % block_size == 0, f"embedding dimension must be multiple of block size, got {D_=} {block_size=}"
|
||||
|
||||
# pad to multiple of block size
|
||||
xq = xq.pad(((0, 0), (0, (block_size - (xq.shape[1] % block_size)) % block_size), (0, 0), (0, 0)))
|
||||
xk = xk.pad(((0, 0), (0, (block_size - (xk.shape[1] % block_size)) % block_size), (0, 0), (0, 0)))
|
||||
xv = xv.pad(((0, 0), (0, (block_size - (xv.shape[1] % block_size)) % block_size), (0, 0), (0, 0)))
|
||||
|
||||
B, N, H, D = xq.shape
|
||||
H_KV = xk.shape[2]
|
||||
GROUP_SIZE = H // H_KV
|
||||
print(f"Flash Attention {B=} {N=} {H=} {D=} {H_KV=} {GROUP_SIZE=}")
|
||||
|
||||
def custom_forward(ou:UOp, l_vecu:UOp, qu:UOp, ku:UOp, vu:UOp, mu:UOp) -> UOp:
|
||||
with Kernel("fa_custom_forward", (H, N // (Q_BLOCK_SIZE*NUM_WORKERS), B), NUM_WORKERS * WARP_THREADS) as ker:
|
||||
warp = ker.warp
|
||||
|
||||
o, q, k, v, mask, l_vec = GL(ou, ker), GL(qu, ker), GL(ku, ker), GL(vu, ker), GL(mu, ker), GL(l_vecu, ker)
|
||||
|
||||
head = ker.blockIdx_x
|
||||
head_kv = head // GROUP_SIZE
|
||||
batch = ker.blockIdx_z
|
||||
q_seq = ker.blockIdx_y * NUM_WORKERS + ker.warpid
|
||||
|
||||
k_smem = ker.st((KV_BLOCK_SIZE, D), dtypes.bfloat16)
|
||||
v_smem = ker.st((KV_BLOCK_SIZE, D), dtypes.bfloat16)
|
||||
|
||||
q_reg_fl = ker.rt((Q_BLOCK_SIZE, D), dtypes.float32)
|
||||
q_reg = ker.rt((Q_BLOCK_SIZE, D), dtypes.bfloat16)
|
||||
q_reg_transposed = ker.rt((D, Q_BLOCK_SIZE), dtypes.bfloat16, TileLayout.COL)
|
||||
k_reg = ker.rt((KV_BLOCK_SIZE, D), dtypes.bfloat16)
|
||||
k_reg_transposed = ker.rt((D, KV_BLOCK_SIZE), dtypes.bfloat16, TileLayout.COL)
|
||||
v_reg = ker.rt((KV_BLOCK_SIZE, D), dtypes.bfloat16, TileLayout.COL)
|
||||
o_reg = ker.rt((D, Q_BLOCK_SIZE), dtypes.float32, TileLayout.COL)
|
||||
o_reg_transposed = ker.rt((Q_BLOCK_SIZE, D), dtypes.float32)
|
||||
att_block = ker.rt((KV_BLOCK_SIZE, Q_BLOCK_SIZE), dtypes.float32, TileLayout.COL)
|
||||
att_block_mma = ker.rt((KV_BLOCK_SIZE, Q_BLOCK_SIZE), dtypes.bfloat16, TileLayout.COL)
|
||||
mask_reg = ker.rt((Q_BLOCK_SIZE, KV_BLOCK_SIZE), dtypes.float32)
|
||||
mask_reg_transposed = ker.rt((KV_BLOCK_SIZE, Q_BLOCK_SIZE), dtypes.float32, TileLayout.COL)
|
||||
|
||||
max_vec_last = ker.rv(KV_BLOCK_SIZE, dtypes.float32)
|
||||
max_vec = ker.rv(KV_BLOCK_SIZE, dtypes.float32)
|
||||
norm_vec = ker.rv(KV_BLOCK_SIZE, dtypes.float32)
|
||||
scale_vec = ker.rv(KV_BLOCK_SIZE, dtypes.float32)
|
||||
|
||||
max_vec = warp.neg_inf(max_vec)
|
||||
norm_vec = warp.zero(norm_vec)
|
||||
o_reg = warp.zero(o_reg)
|
||||
scale_vec = warp.ones(scale_vec)
|
||||
|
||||
# load q tile
|
||||
q_reg_fl = warp.load(q_reg_fl, q, (), (batch, q_seq, head, 0), axis=1)
|
||||
q_reg_fl *= (1.0 / math.sqrt(D)) * (1.0 / math.log(2))
|
||||
q_reg = warp.copy(q_reg, q_reg_fl)
|
||||
q_reg_transposed = warp.transpose(q_reg_transposed, q_reg)
|
||||
|
||||
for kv_idx in ker.range(N // KV_BLOCK_SIZE):
|
||||
k_smem = warp.load(k_smem, k, (), (batch, kv_idx, head_kv, 0), axis=1)
|
||||
v_smem = warp.load(v_smem, v, (), (batch, kv_idx, head_kv, 0), axis=1)
|
||||
|
||||
k_reg = warp.load(k_reg, k_smem)
|
||||
v_reg = warp.load(v_reg, v_smem)
|
||||
|
||||
# mma qk^t
|
||||
att_block = warp.zero(att_block.after(kv_idx))
|
||||
k_reg_transposed = warp.transpose(k_reg_transposed, k_reg)
|
||||
att_block = warp.mma_AtB(att_block, k_reg_transposed, q_reg_transposed)
|
||||
|
||||
# apply attention mask
|
||||
mask_reg = warp.load(mask_reg, mask, (), (batch, 0, q_seq, kv_idx), axis=2)
|
||||
mask_reg_transposed = warp.transpose(mask_reg_transposed, mask_reg)
|
||||
att_block += mask_reg_transposed
|
||||
|
||||
# softmax
|
||||
max_vec_last = warp.copy(max_vec_last.after(kv_idx), max_vec)
|
||||
max_vec = warp.row_reduce(max_vec.after(max_vec_last), att_block, lambda a, b: a.maximum(b), init_value=-math.inf)
|
||||
|
||||
scale_vec = warp.map(scale_vec.after(max_vec_last, max_vec), lambda _, idx: max_vec_last[*idx] - max_vec[*idx])
|
||||
scale_vec = scale_vec.exp2()
|
||||
|
||||
o_reg *= scale_vec
|
||||
norm_vec *= scale_vec
|
||||
|
||||
att_block -= max_vec
|
||||
att_block = att_block.exp2()
|
||||
|
||||
norm_vec = warp.row_reduce(norm_vec.after(scale_vec), att_block, lambda a, b: a + b)
|
||||
|
||||
# mma av
|
||||
att_block_mma = warp.copy(att_block_mma.after(kv_idx, norm_vec), att_block)
|
||||
o_reg = warp.mma_AtB(o_reg, v_reg, att_block_mma)
|
||||
o_reg = ker.endrange()
|
||||
norm_vec = norm_vec.after(o_reg)
|
||||
max_vec = max_vec.after(o_reg)
|
||||
|
||||
o_reg /= norm_vec
|
||||
|
||||
o_reg_transposed = warp.transpose(o_reg_transposed, o_reg)
|
||||
o = warp.store(o, o_reg_transposed, (batch, q_seq, head, 0), (), axis=1)
|
||||
|
||||
norm_vec = norm_vec.after(o)
|
||||
max_vec = max_vec.after(o)
|
||||
|
||||
max_vec *= math.log(2)
|
||||
norm_vec = norm_vec.log2() * math.log(2)
|
||||
norm_vec += max_vec
|
||||
l_vec = warp.store(l_vec, norm_vec, (batch, head, 0, q_seq), (), axis=2)
|
||||
o = o.after(l_vec)
|
||||
|
||||
return ker.finish()
|
||||
|
||||
def custom_backward_q(out_qu:UOp, gradu:UOp, qu:UOp, ku:UOp, vu:UOp, masku:UOp, l_vecu:UOp, delta_vecu:UOp) -> UOp:
|
||||
return UOp.sink(arg=KernelInfo(name="fa_custom_backward_q"))
|
||||
|
||||
def custom_backward_kv(out_ku:UOp, out_vu:UOp, gradu:UOp, qu:UOp, ku:UOp, vu:UOp, masku:UOp, l_vecu:UOp, delta_vecu:UOp) -> UOp:
|
||||
return UOp.sink(arg=KernelInfo(name="fa_custom_backward_kv"))
|
||||
|
||||
if is_causal:
|
||||
if attn_mask is not None: raise RuntimeError("cannot set attn_mask when is_causal=True")
|
||||
attn_mask = Tensor.ones((B, 1, N, N), requires_grad=False, device=xq.device, dtype=dtypes.bool).tril()
|
||||
if attn_mask is not None:
|
||||
if attn_mask.dtype == dtypes.bool: attn_mask = attn_mask.where(0, -float("inf"))
|
||||
else:
|
||||
attn_mask = Tensor.zeros((B, 1, N, N), requires_grad=False, device=xq.device, dtype=dtypes.float32)
|
||||
|
||||
attn = Tensor.empty_like(xq)
|
||||
l_vec = Tensor.empty(B, H, 1, N, requires_grad=False, device=xq.device, dtype=dtypes.float32).detach()
|
||||
|
||||
def grad(grad:UOp, kernel:UOp) -> tuple[None, None, UOp, UOp, UOp, None]:
|
||||
grad_q = Tensor.empty_like(q := Tensor(kernel.src[2]))
|
||||
grad_k = Tensor.empty_like(k := Tensor(kernel.src[3]))
|
||||
grad_v = Tensor.empty_like(v := Tensor(kernel.src[4]))
|
||||
mask = Tensor(kernel.src[5])
|
||||
|
||||
delta_vec = (Tensor(grad) * attn).sum(-1).unsqueeze(-2).detach()
|
||||
|
||||
print(l_vec.numpy())
|
||||
|
||||
grad_q = Tensor.custom_kernel(grad_q, Tensor(grad), q, k, v, mask, l_vec, delta_vec, fxn=custom_backward_q)[0]
|
||||
grad_k, grad_v = Tensor.custom_kernel(grad_k, grad_v, Tensor(grad), q, k, v, mask, l_vec, delta_vec, fxn=custom_backward_kv)[:2]
|
||||
return (None, None, grad_q.uop, grad_k.uop, grad_v.uop, None)
|
||||
|
||||
attn, l_vec = Tensor.custom_kernel(attn, l_vec, xq, xk, xv, attn_mask, fxn=custom_forward, grad_fxn=grad)[:2]
|
||||
attn = attn[:, :N_, :, :D_]
|
||||
|
||||
return attn.transpose(1, 2).cast(odtype)
|
||||
@@ -7,7 +7,7 @@ from tinygrad.dtype import AddrSpace, PtrDType
|
||||
from tinygrad.helpers import getenv, prod
|
||||
|
||||
from extra.thunder.tiny.tk import WARP_THREADS
|
||||
from extra.thunder.tiny.tk.tiles import ALL_TILES, GL, RT_16X16, RT_16X32, ST, RT, RV, TileLayout, VecLayout
|
||||
from extra.thunder.tiny.tk.tiles import ALL_TILES, GL, RT_16X16, RT_16X32, ST, RT, RV, TileLayout
|
||||
|
||||
class Group:
|
||||
def __init__(self, warps:int, ker):
|
||||
@@ -66,10 +66,7 @@ class Group:
|
||||
for height in self.ker.range(src.shape[-3], track=False):
|
||||
for width in self.ker.range(src.shape[-2], track=False):
|
||||
for inner in self.ker.range(src.shape[-1], track=False):
|
||||
src_load = src[height, width, inner]
|
||||
if src.dtype.base != dst.dtype.base:
|
||||
src_load = src_load.cast(dst.dtype.base)
|
||||
dst_store = dst[width, height, inner].store(src_load).end(height, width, inner)
|
||||
dst_store = dst[width, height, inner].store(src[height, width, inner]).end(height, width, inner)
|
||||
|
||||
self.ker.push_store(dst_store, dst)
|
||||
return dst.after(dst_store).reshape(dst.shape)
|
||||
@@ -80,9 +77,9 @@ class Group:
|
||||
|
||||
a_base_shape = cast(RT, a).base_shape
|
||||
if a_base_shape.cols == 16:
|
||||
wmma_arg = ('WMMA_16_16_16___bf16_float', (16, 16, 16), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2)), ((4, 2), (3, 2)), ((4, 2), (3, 2))), ()) # type: ignore
|
||||
wmma_arg = ('WMMA_16_16_16___bf16_float', (16, 16, 16), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2)), ((4, 2), (3, 2)), ((4, 2), (3, 2))), ())
|
||||
elif a_base_shape.cols == 32:
|
||||
wmma_arg = ('WMMA_16_16_32___bf16_float', (16, 16, 32), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2))), ()) # type: ignore
|
||||
wmma_arg = ('WMMA_16_16_32___bf16_float', (16, 16, 32), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2))), ())
|
||||
else: raise NotImplementedError(f"mma_AB not implemented for {a_base_shape.cols=}")
|
||||
|
||||
for height in self.ker.range(c.shape[-3], track=False):
|
||||
@@ -110,9 +107,9 @@ class Group:
|
||||
|
||||
a_base_shape = cast(RT, a).base_shape
|
||||
if a_base_shape.cols == 16:
|
||||
wmma_arg = ('WMMA_16_16_16___bf16_float', (16, 16, 16), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2)), ((4, 2), (3, 2)), ((4, 2), (3, 2))), ()) # type: ignore
|
||||
wmma_arg = ('WMMA_16_16_16___bf16_float', (16, 16, 16), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2)), ((4, 2), (3, 2)), ((4, 2), (3, 2))), ())
|
||||
elif a_base_shape.cols == 32:
|
||||
wmma_arg = ('WMMA_16_16_32___bf16_float', (16, 16, 32), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2))), ()) # type: ignore
|
||||
wmma_arg = ('WMMA_16_16_32___bf16_float', (16, 16, 32), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2))), ())
|
||||
else: raise NotImplementedError(f"mma_ABt not implemented for {a_base_shape.cols=}")
|
||||
|
||||
for height in self.ker.range(c.shape[-3], track=False):
|
||||
@@ -140,9 +137,9 @@ class Group:
|
||||
|
||||
a_base_shape = cast(RT, a).base_shape
|
||||
if a_base_shape.cols == 16:
|
||||
wmma_arg = ('WMMA_16_16_16___bf16_float', (16, 16, 16), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2)), ((4, 2), (3, 2)), ((4, 2), (3, 2))), ()) # type: ignore
|
||||
wmma_arg = ('WMMA_16_16_16___bf16_float', (16, 16, 16), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2)), ((4, 2), (3, 2)), ((4, 2), (3, 2))), ())
|
||||
elif a_base_shape.cols == 32:
|
||||
wmma_arg = ('WMMA_16_16_32___bf16_float', (16, 16, 32), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2))), ()) # type: ignore
|
||||
wmma_arg = ('WMMA_16_16_32___bf16_float', (16, 16, 32), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2))), ())
|
||||
else: raise NotImplementedError(f"mma_AtB not implemented for {a_base_shape.cols=}")
|
||||
|
||||
for height in self.ker.range(c.shape[-3], track=False):
|
||||
@@ -170,9 +167,9 @@ class Group:
|
||||
|
||||
a_base_shape = cast(RT, a).base_shape
|
||||
if a_base_shape.cols == 16:
|
||||
wmma_arg = ('WMMA_16_16_16___bf16_float', (16, 16, 16), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2)), ((4, 2), (3, 2)), ((4, 2), (3, 2))), ()) # type: ignore
|
||||
wmma_arg = ('WMMA_16_16_16___bf16_float', (16, 16, 16), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2)), ((4, 2), (3, 2)), ((4, 2), (3, 2))), ())
|
||||
elif a_base_shape.cols == 32:
|
||||
wmma_arg = ('WMMA_16_16_32___bf16_float', (16, 16, 32), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2))), ()) # type: ignore
|
||||
wmma_arg = ('WMMA_16_16_32___bf16_float', (16, 16, 32), dtypes.bfloat16, dtypes.float, 'AMD', 64, (((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2), (9, 2)), ((4, 2), (3, 2))), ())
|
||||
else: raise NotImplementedError(f"mma_AtBt not implemented for {a_base_shape.cols=}")
|
||||
|
||||
for height in self.ker.range(c.shape[-3], track=False):
|
||||
@@ -203,9 +200,9 @@ class Group:
|
||||
Group.map_rid += len(a.shape)
|
||||
|
||||
if op.__code__.co_argcount == 1:
|
||||
to_store = op(a[*rngs_for_shape]) # type: ignore
|
||||
to_store = op(a[*rngs_for_shape])
|
||||
else:
|
||||
to_store = op(a[*rngs_for_shape], rngs_for_shape) # type: ignore
|
||||
to_store = op(a[*rngs_for_shape], rngs_for_shape)
|
||||
|
||||
a_store = a[*rngs_for_shape].store(to_store).end(*rngs_for_shape)
|
||||
|
||||
@@ -287,7 +284,7 @@ class Group:
|
||||
def load(self, dst:ALL_TILES, src:ALL_TILES, dst_idxs:tuple[UOp|int,...]=(), idxs:tuple[UOp|int,...]=(), axis:int=0):
|
||||
dst, src = cast(UOp, dst), cast(UOp, src)
|
||||
assert isinstance(dst.dtype, PtrDType) and isinstance(src.dtype, PtrDType)
|
||||
dst_dtype, src_dtype = dst.dtype, src.dtype
|
||||
dst_dtype, src_dtype = cast(PtrDType, dst.dtype), cast(PtrDType, src.dtype)
|
||||
if dst_dtype.addrspace == AddrSpace.REG and src_dtype.addrspace == AddrSpace.LOCAL:
|
||||
laneid = self.ker.laneid
|
||||
rt, st = cast(RT, dst), cast(ST, src)
|
||||
@@ -341,7 +338,7 @@ class Group:
|
||||
src_load = src_load.cast(dst.dtype.base)
|
||||
dst_store = dst[*dst_idxs, height, width, srow, scol].store(src_load)
|
||||
dst_store = dst_store.end(height, width, outer, inner).barrier()
|
||||
elif dst_dtype.addrspace == AddrSpace.REG and src_dtype.addrspace == AddrSpace.GLOBAL and isinstance(dst, RT):
|
||||
elif dst_dtype.addrspace == AddrSpace.REG and src_dtype.addrspace ==AddrSpace.GLOBAL:
|
||||
srcf = src.flatten()
|
||||
row_stride = prod(src.shape[axis+1:])
|
||||
|
||||
@@ -374,28 +371,8 @@ class Group:
|
||||
if src.dtype.base != dst.dtype.base:
|
||||
src_load = src_load.cast(dst.dtype.base)
|
||||
dst_store = dst[*dst_idxs, height, width, inner].store(src_load).end(height, width, inner)
|
||||
elif dst_dtype.addrspace == AddrSpace.REG and src_dtype.addrspace == AddrSpace.GLOBAL and isinstance(dst, RV):
|
||||
srcf = src.flatten()
|
||||
row_stride = prod(src.shape[axis+1:])
|
||||
|
||||
laneid = self.ker.laneid
|
||||
rv = cast(RV, dst)
|
||||
reductions = rv.base_shape.rows
|
||||
|
||||
assert rv.layout == VecLayout.ORTHO, "only ortho layout supported"
|
||||
|
||||
idxs = tuple(idx * rv.length if i == 3 else idx for i, idx in enumerate(idxs))
|
||||
src_i = ((idxs[0] * src.shape[-3] + idxs[1]) * src.shape[-2] + idxs[2]) * src.shape[-1] + idxs[3]
|
||||
|
||||
for outer in self.ker.range(dst.shape[-2]):
|
||||
src_i += outer * reductions + (laneid % reductions)
|
||||
|
||||
src_load = srcf[src_i]
|
||||
if src.dtype.base != dst.dtype.base:
|
||||
src_load = src_load.cast(dst.dtype.base)
|
||||
dst_store = dst[outer, 0].store(src_load).end(outer)
|
||||
else:
|
||||
raise NotImplementedError(f"load from {src_dtype.addrspace} to {dst_dtype.addrspace} not implemented for {type(dst)=}")
|
||||
raise NotImplementedError(f"load from {src_dtype.addrspace} to {dst_dtype.addrspace} not implemented")
|
||||
|
||||
self.ker.push_store(dst_store, dst)
|
||||
return dst.after(dst_store).reshape(dst.shape)
|
||||
@@ -403,30 +380,8 @@ class Group:
|
||||
def store(self, dst:ALL_TILES, src:ALL_TILES, idxs:tuple[UOp|int,...]=(), src_idxs:tuple[UOp|int,...]=(), axis:int=0):
|
||||
dst, src = cast(UOp, dst), cast(UOp, src)
|
||||
assert isinstance(dst.dtype, PtrDType) and isinstance(src.dtype, PtrDType)
|
||||
dst_dtype, src_dtype = dst.dtype, src.dtype
|
||||
if src_dtype.addrspace == AddrSpace.REG and dst_dtype.addrspace == AddrSpace.LOCAL:
|
||||
laneid = self.ker.laneid
|
||||
st, rt = cast(ST, dst), cast(RT, src)
|
||||
elements_per_thread = rt.base_shape.elements_per_thread
|
||||
|
||||
for height in self.ker.range(src.shape[-3], track=False):
|
||||
for width in self.ker.range(src.shape[-2], track=False):
|
||||
for inner in self.ker.range(elements_per_thread, track=False):
|
||||
if rt.layout != st.layout:
|
||||
row = rt.base_shape.stride * (laneid // rt.base_shape.cols) + inner
|
||||
col = laneid % rt.base_shape.cols
|
||||
else:
|
||||
row = laneid % rt.base_shape.rows
|
||||
col = rt.base_shape.stride * (laneid // rt.base_shape.rows) + inner
|
||||
|
||||
srow, scol = cast(ST, dst).swizzle(row, col)
|
||||
|
||||
src_load = src[*src_idxs, height, width, inner]
|
||||
if src.dtype.base != dst.dtype.base:
|
||||
src_load = src_load.cast(dst.dtype.base)
|
||||
dst_store = dst[*idxs[:-2], height, width, srow, scol].store(src_load)
|
||||
dst_store = dst_store.end(height, width, inner)
|
||||
elif src_dtype.addrspace == AddrSpace.REG and dst_dtype.addrspace == AddrSpace.GLOBAL and isinstance(src, RT):
|
||||
dst_dtype, src_dtype = cast(PtrDType, dst.dtype), cast(PtrDType, src.dtype)
|
||||
if src_dtype.addrspace == AddrSpace.REG and dst_dtype.addrspace == AddrSpace.GLOBAL:
|
||||
dstf = dst.flatten()
|
||||
row_stride = prod(dst.shape[axis+1:])
|
||||
|
||||
@@ -459,28 +414,8 @@ class Group:
|
||||
if src.dtype.base != dst.dtype.base:
|
||||
src_load = src_load.cast(dst.dtype.base)
|
||||
dst_store = dstf[dst_i].store(src_load).end(height, width, inner)
|
||||
elif src_dtype.addrspace == AddrSpace.REG and dst_dtype.addrspace == AddrSpace.GLOBAL and isinstance(src, RV):
|
||||
dstf = dst.flatten()
|
||||
row_stride = prod(dst.shape[axis+1:])
|
||||
|
||||
laneid = self.ker.laneid
|
||||
rv = cast(RV, src)
|
||||
reductions = rv.base_shape.rows
|
||||
|
||||
assert rv.layout == VecLayout.ORTHO, "only ortho layout supported"
|
||||
|
||||
idxs = tuple(idx * rv.length if i == 3 else idx for i, idx in enumerate(idxs))
|
||||
dst_i = ((idxs[0] * dst.shape[-3] + idxs[1]) * dst.shape[-2] + idxs[2]) * dst.shape[-1] + idxs[3]
|
||||
|
||||
for outer in self.ker.range(src.shape[-2]):
|
||||
dst_i += outer * reductions + (laneid % reductions)
|
||||
|
||||
src_load = src[outer, 0]
|
||||
if src.dtype.base != dst.dtype.base:
|
||||
src_load = src_load.cast(dst.dtype.base)
|
||||
dst_store = dstf[dst_i].store(src_load).end(outer)
|
||||
else:
|
||||
raise NotImplementedError(f"store from {src_dtype.addrspace} to {dst_dtype.addrspace} not implemented for {type(src)=}")
|
||||
raise NotImplementedError(f"store from {src_dtype.addrspace} to {dst_dtype.addrspace} not implemented")
|
||||
|
||||
self.ker.push_store(dst_store, dst)
|
||||
return dst.after(dst_store).reshape(dst.shape)
|
||||
|
||||
@@ -25,14 +25,14 @@ class Kernel(AbstractContextManager):
|
||||
self.blockIdx_z = UOp.special(grid_size[2], "gidx2")
|
||||
self.threadIdx_x = UOp.special(block_size, "lidx0")
|
||||
|
||||
self.range_stack: list[_tk_range] = []
|
||||
self.store_stack: list[tuple[UOp, UOp]] = []
|
||||
self.range_stack = []
|
||||
self.store_stack = []
|
||||
|
||||
self.global_slot = 0
|
||||
self.shared_slot = 0
|
||||
self.register_slot = 0
|
||||
self.range_id = 0
|
||||
self.allocs: dict[tuple[str, tuple], UOp] = {}
|
||||
self.allocs = {}
|
||||
|
||||
@property
|
||||
def warpid(self): return self.threadIdx_x // WARP_THREADS
|
||||
|
||||
@@ -36,7 +36,7 @@ def autowrap(source_cls, blacklist=None):
|
||||
def proxy(*args, **kwargs):
|
||||
return wrap(val(*unwrap(args), **unwrap(kwargs)), self)
|
||||
return proxy
|
||||
if name in UOp.__slots__: return val # type: ignore
|
||||
if name in UOp.__slots__: return val
|
||||
return wrap(val, self)
|
||||
cls.__getattr__ = __getattr__
|
||||
|
||||
@@ -250,12 +250,11 @@ class RT(TileMathMixin):
|
||||
|
||||
@autowrap(UOp)
|
||||
class RV(TileMathMixin):
|
||||
def __init__(self, uop:UOp, length:int, layout:VecLayout, base_shape:RTBaseShape, ker):
|
||||
self._uop, self.ker = uop, ker
|
||||
self.length, self.layout, self.base_shape = length, layout, base_shape
|
||||
def __init__(self, uop:UOp, layout:VecLayout, ker):
|
||||
self._uop, self.layout, self.ker = uop, layout, ker
|
||||
|
||||
def ruop(self, uop:UOp):
|
||||
return RV(uop, self.length, self.layout, self.base_shape, self.ker)
|
||||
return RV(uop, self.layout, self.ker)
|
||||
|
||||
@classmethod
|
||||
def create(cls, length, dtype:DType, layout:VecLayout, base_shape:RTBaseShape, ker):
|
||||
@@ -267,6 +266,6 @@ class RV(TileMathMixin):
|
||||
outer_dim = tiles
|
||||
|
||||
uop = ker.alloc((outer_dim, inner_dim), dtype, AddrSpace.REG)
|
||||
return RV(uop, length, layout, base_shape, ker)
|
||||
return RV(uop, layout, ker)
|
||||
|
||||
ALL_TILES = UOp | GL | ST | RT | RV
|
||||
|
||||
+4
-15
@@ -3,13 +3,6 @@ import sys, os, zlib, struct, hashlib
|
||||
from tinygrad.helpers import DEBUG, getenv, fetch
|
||||
from tinygrad.runtime.support.usb import USB3
|
||||
|
||||
SUPPORTED_CONTROLLERS = [
|
||||
(0x174C, 0x2464),
|
||||
(0x174C, 0x2463),
|
||||
(0xADD1, 0x0001),
|
||||
]
|
||||
if getenv("USBDEV", ""): SUPPORTED_CONTROLLERS.insert(0, (int(x, 16) for x in getenv("USBDEV", "").split(":")))
|
||||
|
||||
def patch(input_filepath, file_hash, patches):
|
||||
with open(input_filepath, 'rb') as infile: data = bytearray(infile.read())
|
||||
|
||||
@@ -47,14 +40,10 @@ if not os.path.exists(file_path):
|
||||
patches = [(0x2a0d + 1 + 4, b'\x0a', b'\x05')]
|
||||
patched_fw = patch(file_path, file_hash, patches)
|
||||
|
||||
dev = None
|
||||
for vendor, device in SUPPORTED_CONTROLLERS:
|
||||
try:
|
||||
dev = USB3(vendor, device, 0x81, 0x83, 0x02, 0x04)
|
||||
break
|
||||
except RuntimeError: pass
|
||||
if dev is None:
|
||||
raise RuntimeError('Could not open controller. You can set USBDEV environment variable to your device\'s vendor and device ID (e.g., USBDEV="174C:2464")')
|
||||
vendor, device = [int(x, base=16) for x in getenv("USBDEV", "174C:2464").split(":")]
|
||||
try: dev = USB3(vendor, device, 0x81, 0x83, 0x02, 0x04)
|
||||
except RuntimeError as e:
|
||||
raise RuntimeError(f'{e}. You can set USBDEV environment variable to your device\'s vendor and device ID (e.g., USBDEV="174C:2464")') from e
|
||||
|
||||
config1 = bytes([
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, 0x30, 0x30, 0x36, 0x30,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# extra/weekly_commits_table.py
|
||||
import os, subprocess, datetime as dt
|
||||
|
||||
NAMES = ["chenyu","George Hotz","nimlgen","qazal","wozeparrot","Christopher Milan"]
|
||||
NAMES = ["chenyu","George Hotz","nimlgen","qazal","wozeparrot"]
|
||||
REPO = os.environ.get("REPO_PATH",".")
|
||||
today = dt.date.today()
|
||||
days = [(today - dt.timedelta(i)).strftime("%Y-%m-%d") for i in range(6,-1,-1)]
|
||||
|
||||
+6
-3
@@ -69,14 +69,17 @@ testing_minimal = [
|
||||
"hypothesis",
|
||||
"z3-solver",
|
||||
]
|
||||
testing_unit = ["tinygrad[testing_minimal]", "tqdm", "safetensors", "tabulate", "openai"]
|
||||
testing_unit = ["tinygrad[testing_minimal]", "tqdm", "safetensors", "tabulate"]
|
||||
testing = [
|
||||
"tinygrad[testing_unit]",
|
||||
"tinygrad[testing_minimal]",
|
||||
"pillow",
|
||||
"onnx==1.19.0",
|
||||
"onnx==1.18.0",
|
||||
"onnx2torch",
|
||||
"onnxruntime",
|
||||
"opencv-python",
|
||||
"tabulate",
|
||||
"tqdm",
|
||||
"safetensors",
|
||||
"transformers",
|
||||
"sentencepiece",
|
||||
"tiktoken",
|
||||
|
||||
Vendored
-2
@@ -32,8 +32,6 @@ class FakeAM:
|
||||
self.ip_ver = {am.GC_HWIP: (11, 0, 0)}
|
||||
def paddr2cpu(self, paddr:int) -> int: return paddr + mv_address(self.vram)
|
||||
def paddr2mc(self, paddr:int) -> int: return paddr
|
||||
def paddr2xgmi(self, paddr:int) -> int: return paddr
|
||||
def xgmi2paddr(self, xgmi_paddr:int) -> int: return xgmi_paddr
|
||||
|
||||
# * PTE format:
|
||||
# * 63:59 reserved
|
||||
|
||||
-13
@@ -170,19 +170,6 @@ backend_test.exclude('test_scan_*')
|
||||
backend_test.exclude('test_split_to_sequence_*')
|
||||
backend_test.exclude('test_ai_onnx_ml_tree_ensemble_*') # https://github.com/onnx/onnx/blob/main/onnx/reference/ops/aionnxml/op_tree_ensemble.py#L121
|
||||
|
||||
# TODO: not yet implemented
|
||||
backend_test.exclude('test_tensorscatter_*')
|
||||
backend_test.exclude('test_l1normalization_*')
|
||||
backend_test.exclude('test_l2normalization_*')
|
||||
backend_test.exclude('test_lpnormalization_*')
|
||||
backend_test.exclude('test_einsum_scalar_cpu')
|
||||
backend_test.exclude('test_mod_mixed_sign_float16_cpu')
|
||||
backend_test.exclude('test_qlinearmatmul_2D_uint8_float16_cpu')
|
||||
backend_test.exclude('test_qlinearmatmul_3D_uint8_float16_cpu')
|
||||
backend_test.exclude('test_attention_3d_*')
|
||||
backend_test.exclude('test_attention_4d_*')
|
||||
|
||||
|
||||
# rest of the failing tests
|
||||
backend_test.exclude('test_resize_tf_crop_and_resize_cpu') # tf_crop_and_resize not implemented
|
||||
backend_test.exclude('test_resize_tf_crop_and_resize_axes_2_3_cpu') # tf_crop_and_resize not implemented
|
||||
|
||||
@@ -58,6 +58,18 @@ class TestOnnxModel(unittest.TestCase):
|
||||
print(cls, _LABELS[cls])
|
||||
assert "car" in _LABELS[cls] or _LABELS[cls] == "convertible"
|
||||
|
||||
def test_pad_list_value(self):
|
||||
from tinygrad.nn.onnx import onnx_ops
|
||||
from tinygrad import Tensor
|
||||
Pad = onnx_ops['Pad']
|
||||
x = Tensor([1, 2, 3])
|
||||
out = Pad(x, pads=[0, 1], value=[-float('inf')])
|
||||
assert out.shape == (4,)
|
||||
assert out.numpy()[-1] == -float('inf')
|
||||
out2 = Pad(x, pads=[1, 0], constant_value=[5.0])
|
||||
assert out2.shape == (4,)
|
||||
assert out2.numpy()[0] == 5.0
|
||||
|
||||
@unittest.skipUnless(Device.DEFAULT == "METAL", "only run on METAL")
|
||||
class TestHuggingFaceOnnxModels(unittest.TestCase):
|
||||
@classmethod
|
||||
|
||||
+1
-2
@@ -3,7 +3,7 @@ import unittest
|
||||
import numpy as np
|
||||
from tinygrad import dtypes, Tensor, TinyJit, GlobalCounters, Variable
|
||||
from tinygrad.device import is_dtype_supported
|
||||
from tinygrad.helpers import temp, CI, CPU_LVP
|
||||
from tinygrad.helpers import temp
|
||||
|
||||
N = 200 # has to be bigger than the cache to fail
|
||||
|
||||
@@ -180,7 +180,6 @@ class TestAssign(unittest.TestCase):
|
||||
new = a + times_a
|
||||
np.testing.assert_allclose(new.numpy(), 8)
|
||||
|
||||
@unittest.skipIf(CI and CPU_LVP, "flaky in CI")
|
||||
def test_double_assign(self):
|
||||
a = Tensor.ones(4).contiguous().realize()
|
||||
a += 1
|
||||
|
||||
+2
-3
@@ -17,6 +17,8 @@ pytestmark = pytest.mark.filterwarnings("ignore")
|
||||
settings.register_profile("my_profile", max_examples=200, deadline=None, derandomize=getenv("DERANDOMIZE_CI", False))
|
||||
settings.load_profile("my_profile")
|
||||
|
||||
if Device.DEFAULT == "CPU": core_dtypes.remove(dtypes.bfloat16) # NOTE: this is for teenygrad, don't remove
|
||||
|
||||
def get_available_cast_dtypes(dtype: DType) -> List[DType]:
|
||||
if not is_dtype_supported(dtype): return []
|
||||
# dont cast internal dtypes
|
||||
@@ -433,8 +435,6 @@ class TestOpsBFloat16(unittest.TestCase):
|
||||
data = [60000.0, 70000.0, 80000.0]
|
||||
np.testing.assert_allclose(Tensor(data).cast("bfloat16").numpy(), torch.tensor(data).type(torch.bfloat16).float().numpy())
|
||||
|
||||
# some CPUs there is no native bfloat16 sqrt
|
||||
@unittest.skipIf(Device.DEFAULT == "CPU", "no approximation")
|
||||
def test_no_approximation(self):
|
||||
data = [326.0, 339.0, 10603200512.0]
|
||||
expected = torch.tensor(data, dtype=torch.bfloat16).sqrt().float().numpy()
|
||||
@@ -442,4 +442,3 @@ class TestOpsBFloat16(unittest.TestCase):
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
|
||||
@@ -501,18 +501,6 @@ class TestJit(unittest.TestCase):
|
||||
b = f(Tensor([2.0]))
|
||||
assert abs((a - b).item()) > 0.5
|
||||
|
||||
def test_jit_init_with_empty_different_size(self):
|
||||
@TinyJit
|
||||
def f(x:Tensor) -> Tensor: return (x + 1).realize()
|
||||
|
||||
f(Tensor.empty(1))
|
||||
f(Tensor.empty(1))
|
||||
# TODO: this should fail since input has a different size
|
||||
f(Tensor(2.0)).item()
|
||||
# TODO: this should not fail, and should return 3
|
||||
with self.assertRaises(AssertionError):
|
||||
f(Tensor([2.0])).item()
|
||||
|
||||
@unittest.skip("Pending multioutput implementation #3607")
|
||||
class TestMultioutputJit(unittest.TestCase):
|
||||
def _test(self, f):
|
||||
|
||||
@@ -57,12 +57,6 @@ class TestMultiTensor(unittest.TestCase):
|
||||
assert lb.shape == (128,)
|
||||
(X + X).realize()
|
||||
|
||||
def test_shard_empty(self):
|
||||
GlobalCounters.reset()
|
||||
X = Tensor.empty(256).shard(devices_2, 0).realize()
|
||||
assert GlobalCounters.kernel_count == 0
|
||||
(X + X).realize()
|
||||
|
||||
def _test_shard_op(self, op, out, n=4):
|
||||
t = Tensor.ones(n).contiguous().realize().shard(devices_2, 0)
|
||||
r = op(t).realize()
|
||||
|
||||
+16
-26
@@ -2,7 +2,7 @@ import time, math, unittest, functools, platform, warnings
|
||||
import numpy as np
|
||||
from typing import List, Callable
|
||||
import torch
|
||||
from tinygrad.helpers import getenv, IMAGE, DEBUG, CI, Context, CPU_LLVM, CPU_LVP, AMD_LLVM, EMULATE
|
||||
from tinygrad.helpers import getenv, IMAGE, DEBUG, CI, Context, CPU_LLVM, CPU_LVP, AMD_LLVM
|
||||
from tinygrad import Tensor, Device, dtypes
|
||||
from tinygrad.tensor import _to_np_dtype
|
||||
from tinygrad.device import is_dtype_supported
|
||||
@@ -16,7 +16,6 @@ if CI:
|
||||
|
||||
FORWARD_ONLY = getenv("FORWARD_ONLY", 0)
|
||||
PRINT_TENSORS = getenv("PRINT_TENSORS", 0)
|
||||
COMPILE_ONLY = Device.DEFAULT == "NULL" and not EMULATE
|
||||
|
||||
def slow_test(test_func):
|
||||
return unittest.skipIf(getenv("SKIP_SLOW_TEST"), "Skipping slow test")(test_func)
|
||||
@@ -39,7 +38,6 @@ def helper_test_op(shps, torch_fxn, tinygrad_fxn=None, atol=1e-6, rtol=1e-3, gra
|
||||
tinygrad_fp = time.monotonic() - st
|
||||
|
||||
def compare(s, tinygrad_output, torch_output, atol, rtol):
|
||||
if COMPILE_ONLY: return
|
||||
if PRINT_TENSORS: print(s, tinygrad_output, torch_output)
|
||||
try:
|
||||
assert tinygrad_output.shape == torch_output.shape, f"shape mismatch: tinygrad={tinygrad_output.shape} | torch={torch_output.shape}"
|
||||
@@ -423,9 +421,8 @@ class TestOps(unittest.TestCase):
|
||||
def test_isinf(self):
|
||||
val = [float('-inf'), 0., float('inf'), float('nan'), 1.1]
|
||||
helper_test_op(None, torch.isinf, Tensor.isinf, vals=[val], forward_only=True)
|
||||
if not COMPILE_ONLY:
|
||||
np.testing.assert_equal(Tensor(val).isinf(detect_positive=True, detect_negative=False).numpy(), [False, False, True, False, False])
|
||||
np.testing.assert_equal(Tensor(val).isinf(detect_positive=False, detect_negative=True).numpy(), [True, False, False, False, False])
|
||||
np.testing.assert_equal(Tensor(val).isinf(detect_positive=True, detect_negative=False).numpy(), [False, False, True, False, False])
|
||||
np.testing.assert_equal(Tensor(val).isinf(detect_positive=False, detect_negative=True).numpy(), [True, False, False, False, False])
|
||||
|
||||
def test_isnan(self):
|
||||
helper_test_op(None, torch.isnan, Tensor.isnan, vals=[[float('-inf'), 0., float('inf'), float('nan'), 1.1]], forward_only=True)
|
||||
@@ -597,7 +594,7 @@ class TestOps(unittest.TestCase):
|
||||
helper_test_op(None, lambda x: x//2, forward_only=True, vals=[[3, 4, 5]])
|
||||
helper_test_op(None, functools.partial(torch.div, rounding_mode="trunc"), Tensor.idiv, forward_only=True,
|
||||
vals=[[-4, 7, 5, 4, -7, 8], [2, -3, 8, -2, 3, 5]])
|
||||
if is_dtype_supported(dtypes.uint64) and not COMPILE_ONLY:
|
||||
if is_dtype_supported(dtypes.uint64):
|
||||
x = Tensor(2**64 - 1, dtype=dtypes.uint64).idiv(1)
|
||||
np.testing.assert_equal(x.numpy(), 2**64 - 1)
|
||||
|
||||
@@ -682,7 +679,6 @@ class TestOps(unittest.TestCase):
|
||||
# float to power of int
|
||||
helper_test_op(None, lambda x: 0.7**x, vals=[[-2,-1,0,1,2,3]], forward_only=True)
|
||||
|
||||
@unittest.skipIf(COMPILE_ONLY, "test requires runtime")
|
||||
def test_pow_const_direct(self):
|
||||
# x ** c
|
||||
def get_tiny_gradient(x, c):
|
||||
@@ -1074,7 +1070,8 @@ class TestOps(unittest.TestCase):
|
||||
@slow_test
|
||||
def test_cummax(self):
|
||||
helper_test_op([()], lambda x: torch.cummax(x, dim=0).values, lambda x: Tensor.cummax(x, axis=0))
|
||||
self.helper_test_exception([()], lambda x: torch.cummax(x, dim=1).values, lambda x: Tensor.cummax(x, axis=1), expected=IndexError)
|
||||
# TODO: torch allows this?
|
||||
# self.helper_test_exception([()], lambda x: torch.cummax(x, dim=1).values, lambda x: Tensor.cummax(x, axis=1), expected=IndexError)
|
||||
helper_test_op([(20,)], lambda x: torch.cummax(x, dim=0).values, lambda x: Tensor.cummax(x, axis=0))
|
||||
self.helper_test_exception([(20,)], lambda x: torch.cummax(x, dim=1).values, lambda x: Tensor.cummax(x, axis=1), expected=IndexError)
|
||||
self.helper_test_exception([(20,)], lambda x: torch.cummax(x, dim=-2).values, lambda x: Tensor.cummax(x, axis=-2), expected=IndexError)
|
||||
@@ -1091,9 +1088,8 @@ class TestOps(unittest.TestCase):
|
||||
# check if it returns the first index for multiple occurences
|
||||
helper_test_op(None, lambda x: x.argmax().type(torch.int32), lambda x: x.argmax(), forward_only=True, vals=[[2, 2]])
|
||||
helper_test_op(None, lambda x: x.argmax().type(torch.int32), lambda x: x.argmax(), forward_only=True, vals=[[1, 2, 2]])
|
||||
if not COMPILE_ONLY:
|
||||
np.testing.assert_equal(Tensor([2,2]).argmax().numpy(), 0)
|
||||
np.testing.assert_equal(Tensor([1,2,2]).argmax().numpy(), 1)
|
||||
np.testing.assert_equal(Tensor([2,2]).argmax().numpy(), 0)
|
||||
np.testing.assert_equal(Tensor([1,2,2]).argmax().numpy(), 1)
|
||||
helper_test_op([(10,20)], lambda x: x.argmax().type(torch.int32), lambda x: x.argmax(), forward_only=True)
|
||||
helper_test_op([(10,20)], lambda x: x.argmax(0, False).type(torch.int32), lambda x: x.argmax(0, False), forward_only=True)
|
||||
helper_test_op([(10,20)], lambda x: x.argmax(1, False).type(torch.int32), lambda x: x.argmax(1, False), forward_only=True)
|
||||
@@ -1111,9 +1107,8 @@ class TestOps(unittest.TestCase):
|
||||
# check if it returns the first index for multiple occurences
|
||||
helper_test_op(None, lambda x: x.argmin().type(torch.int32), lambda x: x.argmin(), forward_only=True, vals=[[2, 2]])
|
||||
helper_test_op(None, lambda x: x.argmin().type(torch.int32), lambda x: x.argmin(), forward_only=True, vals=[[3, 2, 2]])
|
||||
if not COMPILE_ONLY:
|
||||
np.testing.assert_equal(Tensor([2,2]).argmin().numpy(), 0)
|
||||
np.testing.assert_equal(Tensor([3,2,2]).argmin().numpy(), 1)
|
||||
np.testing.assert_equal(Tensor([2,2]).argmin().numpy(), 0)
|
||||
np.testing.assert_equal(Tensor([3,2,2]).argmin().numpy(), 1)
|
||||
helper_test_op([(10,20)], lambda x: x.argmin().type(torch.int32), lambda x: x.argmin(), forward_only=True)
|
||||
helper_test_op([(10,20)], lambda x: x.argmin(0, False).type(torch.int32), lambda x: x.argmin(0, False), forward_only=True)
|
||||
helper_test_op([(10,20)], lambda x: x.argmin(1, False).type(torch.int32), lambda x: x.argmin(1, False), forward_only=True)
|
||||
@@ -1161,13 +1156,12 @@ class TestOps(unittest.TestCase):
|
||||
lambda x: x.topk(4, dim, largest, sorted_).indices.type(torch.int32),
|
||||
lambda x: x.topk(4, dim, largest, sorted_)[1], forward_only=True)
|
||||
# repeated values
|
||||
if not COMPILE_ONLY:
|
||||
value, indices = Tensor([1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0]).topk(3)
|
||||
np.testing.assert_equal(value.numpy(), [1, 1, 1])
|
||||
np.testing.assert_equal(indices.numpy(), [0, 1, 3])
|
||||
value, indices = Tensor([1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0]).topk(3, largest=False)
|
||||
np.testing.assert_equal(value.numpy(), [0, 0, 0])
|
||||
np.testing.assert_equal(indices.numpy(), [2, 4, 6])
|
||||
value, indices = Tensor([1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0]).topk(3)
|
||||
np.testing.assert_equal(value.numpy(), [1, 1, 1])
|
||||
np.testing.assert_equal(indices.numpy(), [0, 1, 3])
|
||||
value, indices = Tensor([1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0]).topk(3, largest=False)
|
||||
np.testing.assert_equal(value.numpy(), [0, 0, 0])
|
||||
np.testing.assert_equal(indices.numpy(), [2, 4, 6])
|
||||
self.helper_test_exception([(4)], lambda x: x.topk(5), expected=(RuntimeError, ValueError))
|
||||
|
||||
@slow_test
|
||||
@@ -1319,7 +1313,6 @@ class TestOps(unittest.TestCase):
|
||||
helper_test_op(None, lambda x,y: x.matmul(y), lambda x,y: x@y, vals=[np.eye(8).astype(np.float32), np.eye(8).astype(np.float32)])
|
||||
@unittest.skipIf(CI and Device.DEFAULT in ["NV", "CL", "CUDA"] or (Device.DEFAULT == "CPU" and CPU_LLVM) or IMAGE
|
||||
or (Device.DEFAULT == "WEBGPU" and platform.system() == "Windows"), "not supported on these in CI/IMAGE")
|
||||
@unittest.skipIf(Device.DEFAULT == "QCOM", "not precise enough")
|
||||
def test_gemm_fp16(self):
|
||||
helper_test_op([(64,64), (64,64)], lambda x,y: x.half().matmul(y.half()), atol=5e-3, rtol=5e-3, grad_atol=5e-3, grad_rtol=5e-3)
|
||||
def test_gemm(self):
|
||||
@@ -1730,7 +1723,6 @@ class TestOps(unittest.TestCase):
|
||||
helper_test_op([(7,5,10)], lambda x: x[1:5:2, 3, ::4])
|
||||
helper_test_op([(7,5,10)], lambda x: x[1:5:2, None, None, 3, None, ::4])
|
||||
|
||||
@unittest.skipIf(COMPILE_ONLY, "test requires runtime")
|
||||
def test_slice_negative_strides(self):
|
||||
# Torch doesn't support slicing with negative steps
|
||||
a = np.random.randn(10, 10, 10).astype(np.float32)
|
||||
@@ -2760,7 +2752,6 @@ class TestOps(unittest.TestCase):
|
||||
n = Tensor([1, float("nan")]).max().numpy()
|
||||
assert math.isnan(n.item()), f"{n.item()} is not nan"
|
||||
|
||||
@unittest.skipIf(COMPILE_ONLY, "test requires runtime")
|
||||
def test_inf_where(self):
|
||||
x = Tensor.full((3, 3), float("inf"))
|
||||
n = (x < 0).where(x, 1).numpy()
|
||||
@@ -3177,7 +3168,6 @@ class TestOps(unittest.TestCase):
|
||||
|
||||
@unittest.skipIf((getenv("MOCKGPU") or Device.DEFAULT == "PYTHON"), "very slow on MOCKGPU because reduce does not fold")
|
||||
@unittest.skipIf(Device.DEFAULT == "WEBGPU", "webgpu runtime issue")
|
||||
@unittest.skipIf(Device.DEFAULT == "QCOM", "QCOM fails with: Resource deadlock avoided")
|
||||
def test_masked_select(self):
|
||||
helper_test_op([(32, 10)], lambda x: x.masked_select(x>0.5), lambda x: x.masked_select(x>0.5), forward_only=True)
|
||||
helper_test_op([(32, 10)], lambda x: x.masked_select(torch.tensor(True)), lambda x: x.masked_select(Tensor(True)), forward_only=True)
|
||||
|
||||
+7
-7
@@ -70,15 +70,15 @@ class TestTinygrad(unittest.TestCase):
|
||||
out = out.log_softmax()
|
||||
out = out.mul(m).add(m).sum()
|
||||
out.backward()
|
||||
xgrad, wgrad = x.grad.numpy(), W.grad.numpy()
|
||||
xgrad,wgrad = x.grad, W.grad
|
||||
out.backward()
|
||||
xgrad2, wgrad2 = x.grad.numpy(), W.grad.numpy()
|
||||
xgrad2,wgrad2 = x.grad, W.grad
|
||||
out.backward() # no need to retain again since we will not re-run backward
|
||||
xgrad3, wgrad3 = x.grad.numpy(), W.grad.numpy()
|
||||
np.testing.assert_allclose(xgrad3, xgrad * 3., atol=1e-6)
|
||||
np.testing.assert_allclose(wgrad3, wgrad * 3., atol=1e-6)
|
||||
np.testing.assert_allclose(xgrad2, xgrad * 2., atol=1e-6)
|
||||
np.testing.assert_allclose(wgrad2, wgrad * 2., atol=1e-6)
|
||||
xgrad3,wgrad3 = x.grad, W.grad
|
||||
np.testing.assert_allclose(xgrad3.numpy(), xgrad.numpy() * 3., atol=1e-6)
|
||||
np.testing.assert_allclose(wgrad3.numpy(), wgrad.numpy() * 3., atol=1e-6)
|
||||
np.testing.assert_allclose(xgrad2.numpy(), xgrad.numpy() * 2., atol=1e-6)
|
||||
np.testing.assert_allclose(wgrad2.numpy(), wgrad.numpy() * 2., atol=1e-6)
|
||||
|
||||
def test_second_order_backward_pass(self):
|
||||
def test_pytorch():
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import unittest, math, time
|
||||
import unittest, math
|
||||
|
||||
from tinygrad import Tensor, Device, dtypes, Context
|
||||
from tinygrad.uop.ops import UOp, Ops
|
||||
from tinygrad.engine.realize import ExecItem, get_runner
|
||||
from tinygrad.engine.jit import TinyJit
|
||||
from tinygrad.helpers import CI
|
||||
import numpy as np
|
||||
|
||||
@@ -31,16 +30,14 @@ class TestTK(unittest.TestCase):
|
||||
|
||||
a_smem = ker.st((BLOCK_SIZE, BLOCK_SIZE), dtypes.bfloat16)
|
||||
b_smem = ker.st((BLOCK_SIZE, BLOCK_SIZE), dtypes.bfloat16)
|
||||
c_smem = ker.st((BLOCK_SIZE, BLOCK_SIZE), dtypes.float32)
|
||||
|
||||
a_reg = ker.rt((BLOCK_SIZE, BLOCK_SIZE), dtypes.bfloat16)
|
||||
b_reg = ker.rt((BLOCK_SIZE, BLOCK_SIZE), dtypes.bfloat16, TileLayout.COL)
|
||||
c_reg_col = ker.rt((BLOCK_SIZE, BLOCK_SIZE), dtypes.float32, TileLayout.COL)
|
||||
c_reg = ker.rt((BLOCK_SIZE, BLOCK_SIZE), dtypes.float32)
|
||||
c_reg = ker.rt((BLOCK_SIZE, BLOCK_SIZE), dtypes.float32, TileLayout.COL)
|
||||
|
||||
col, row = ker.blockIdx_x, ker.blockIdx_y
|
||||
|
||||
c_reg_col = warp.zero(c_reg_col)
|
||||
c_reg = warp.zero(c_reg)
|
||||
for tile in ker.range(N // BLOCK_SIZE):
|
||||
a_smem = warp.load(a_smem, a, (), (0, 0, row, tile), axis=2)
|
||||
b_smem = warp.load(b_smem, b, (), (0, 0, tile, col), axis=2)
|
||||
@@ -48,11 +45,8 @@ class TestTK(unittest.TestCase):
|
||||
a_reg = warp.load(a_reg, a_smem)
|
||||
b_reg = warp.load(b_reg, b_smem)
|
||||
|
||||
c_reg_col = warp.mma_AB(c_reg_col, a_reg, b_reg)
|
||||
c_reg_col = ker.endrange()
|
||||
|
||||
c_smem = warp.store(c_smem, c_reg_col)
|
||||
c_reg = warp.load(c_reg, c_smem)
|
||||
c_reg = warp.mma_AB(c_reg, a_reg, b_reg)
|
||||
c_reg = ker.endrange()
|
||||
|
||||
c = warp.store(c, c_reg, (0, 0, row, col), (), axis=2)
|
||||
|
||||
@@ -157,45 +151,6 @@ class TestTK(unittest.TestCase):
|
||||
|
||||
np.testing.assert_allclose(b.numpy(), ref.numpy())
|
||||
|
||||
def test_load_store_local_hop(self):
|
||||
N = 64
|
||||
BLOCK_SIZE = 32
|
||||
with Kernel("load_store_local_hop", (N // BLOCK_SIZE, N // BLOCK_SIZE, 1), WARP_THREADS) as ker:
|
||||
warp = ker.warp
|
||||
|
||||
b = ker.gl((1, 1, N, N), dtypes.float32)
|
||||
a = ker.gl((1, 1, N, N), dtypes.float32)
|
||||
|
||||
a_smem = ker.st((BLOCK_SIZE, BLOCK_SIZE), dtypes.float32)
|
||||
b_smem = ker.st((BLOCK_SIZE, BLOCK_SIZE), dtypes.float32)
|
||||
|
||||
a_reg = ker.rt((BLOCK_SIZE, BLOCK_SIZE), dtypes.float32)
|
||||
b_reg = ker.rt((BLOCK_SIZE, BLOCK_SIZE), dtypes.float32)
|
||||
|
||||
col, row = ker.blockIdx_x, ker.blockIdx_y
|
||||
|
||||
a_smem = warp.load(a_smem, a, (), (0, 0, row, col), axis=2)
|
||||
a_reg = warp.load(a_reg, a_smem)
|
||||
b_reg = warp.copy(b_reg, a_reg)
|
||||
b_smem = warp.store(b_smem, b_reg)
|
||||
b_reg = warp.load(b_reg, b_smem)
|
||||
b = warp.store(b, b_reg, (0, 0, row, col), (), axis=2)
|
||||
|
||||
sink = ker.finish()
|
||||
|
||||
with Context(DEBUG=0):
|
||||
a = Tensor.rand(1, 1, N, N, dtype="float32").contiguous()
|
||||
b = Tensor.empty(1, 1, N, N, dtype="float32")
|
||||
Tensor.realize(a, b)
|
||||
|
||||
ei = ExecItem(get_runner(Device.DEFAULT, sink), [t.uop.buffer for t in (b, a)])
|
||||
for _ in range(5): ei.run(wait=True)
|
||||
b = b.float()
|
||||
|
||||
ref = a.float()
|
||||
|
||||
np.testing.assert_allclose(b.numpy(), ref.numpy())
|
||||
|
||||
@unittest.skip("TODO")
|
||||
def test_load_store_group(self):
|
||||
N = 256
|
||||
@@ -674,12 +629,7 @@ class TestTK(unittest.TestCase):
|
||||
Tensor.realize(q, k, v, out)
|
||||
|
||||
ei = ExecItem(get_runner(Device.DEFAULT, sink), [t.uop.buffer for t in (out, q, k, v)])
|
||||
for _ in range(5):
|
||||
et = ei.run(wait=True)
|
||||
attn_flops = 2 * B * H * N * N * D + \
|
||||
4 * B * H * N * N + \
|
||||
2 * B * H * N * N * D
|
||||
print(f"{attn_flops/(et*1e9):2f} GFLOPS")
|
||||
for _ in range(5): ei.run(wait=True)
|
||||
out = out.float()
|
||||
|
||||
q_permuted = q.permute(0, 2, 1, 3)
|
||||
@@ -690,34 +640,5 @@ class TestTK(unittest.TestCase):
|
||||
|
||||
np.testing.assert_allclose(out.numpy(), ref.numpy(), atol=2e-2, rtol=2e-2)
|
||||
|
||||
def test_fast_fa(self):
|
||||
from extra.thunder.tiny.fa import flash_attention
|
||||
|
||||
B, N, H, H_KV, D = 2, 8192, 32, 8, 128
|
||||
|
||||
with Context(DEBUG=0):
|
||||
q = Tensor.randn(B, N, H, D, dtype=dtypes.bfloat16).contiguous()
|
||||
k = Tensor.randn(B, N, H_KV, D, dtype=dtypes.bfloat16).contiguous()
|
||||
v = Tensor.randn(B, N, H_KV, D, dtype=dtypes.bfloat16).contiguous()
|
||||
Tensor.realize(q, k, v)
|
||||
|
||||
q, k, v = q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2)
|
||||
|
||||
fa_jitted = TinyJit(flash_attention)
|
||||
|
||||
for _ in range(10):
|
||||
st = time.perf_counter()
|
||||
out = fa_jitted(q, k, v, is_causal=True)
|
||||
et = time.perf_counter() - st
|
||||
attn_flops = 2 * B * H * N * N * D + \
|
||||
4 * B * H * N * N + \
|
||||
2 * B * H * N * N * D
|
||||
print(f"{attn_flops/(et*1e9):2f} GFLOPS")
|
||||
out = out.float().transpose(1, 2)
|
||||
|
||||
ref = q.scaled_dot_product_attention(k, v, is_causal=True, enable_gqa=True).float().transpose(1, 2)
|
||||
|
||||
np.testing.assert_allclose(out.numpy(), ref.numpy(), atol=2e-2, rtol=2e-2)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
import unittest
|
||||
from tinygrad import Tensor, dtypes, TinyJit, UOp
|
||||
from tinygrad.apps.llm import apply_rope as apply_rope_new, precompute_freqs_cis
|
||||
from tinygrad.apps.llm import apply_rope
|
||||
#from tinygrad.engine.realize import run_schedule
|
||||
|
||||
def apply_rope(x:Tensor, start_pos:int):
|
||||
B, H, T, Hd = x.shape
|
||||
precompute_freqs_cis.cache_clear()
|
||||
freqs_cis = precompute_freqs_cis(Hd, start_pos+T)[start_pos:start_pos+T]
|
||||
return apply_rope_new(x, freqs_cis)
|
||||
|
||||
# TODO: test_scheduler, but just in uint
|
||||
class TestAttention(unittest.TestCase):
|
||||
def test_half_qkv_buffers(self):
|
||||
@@ -45,7 +39,7 @@ class TestAttention(unittest.TestCase):
|
||||
prune_size = len(rope_prune.captured.jit_cache)
|
||||
|
||||
self.assertGreater(noprune_size, prune_size)
|
||||
self.assertGreaterEqual(noprune_size, 2)
|
||||
self.assertGreaterEqual(noprune_size, 3)
|
||||
self.assertEqual(prune_size, 1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -110,53 +110,4 @@ class TestAutogen(unittest.TestCase):
|
||||
assert frts_cmd.readVbiosDesc.__class__ is FWSECLIC_READ_VBIOS_DESC
|
||||
assert frts_cmd.frtsRegionDesc.__class__ is FWSECLIC_FRTS_REGION_DESC
|
||||
|
||||
def test_packed_fields(self):
|
||||
uint8_t = ctypes.c_ubyte
|
||||
uint16_t = ctypes.c_ushort
|
||||
uint32_t = ctypes.c_uint32
|
||||
|
||||
class struct_die_info(Struct): pass
|
||||
struct_die_info._packed_ = True
|
||||
struct_die_info._fields_ = [
|
||||
('die_id', uint16_t),
|
||||
('die_offset', uint16_t),
|
||||
]
|
||||
die_info = struct_die_info
|
||||
class struct_ip_discovery_header(Struct): pass
|
||||
class struct_ip_discovery_header_0(ctypes.Union): pass
|
||||
class struct_ip_discovery_header_0_0(Struct): pass
|
||||
uint8_t = ctypes.c_ubyte
|
||||
struct_ip_discovery_header_0_0._fields_ = [
|
||||
('base_addr_64_bit', uint8_t,1),
|
||||
('reserved', uint8_t,7),
|
||||
('reserved2', uint8_t),
|
||||
]
|
||||
struct_ip_discovery_header_0._anonymous_ = ['_0']
|
||||
struct_ip_discovery_header_0._packed_ = True
|
||||
struct_ip_discovery_header_0._fields_ = [
|
||||
('padding', (uint16_t * 1)),
|
||||
('_0', struct_ip_discovery_header_0_0),
|
||||
]
|
||||
struct_ip_discovery_header._anonymous_ = ['_0']
|
||||
struct_ip_discovery_header._packed_ = True
|
||||
struct_ip_discovery_header._fields_ = [
|
||||
('signature', uint32_t),
|
||||
('version', uint16_t),
|
||||
('size', uint16_t),
|
||||
('id', uint32_t),
|
||||
('num_dies', uint16_t),
|
||||
('die_info', (die_info * 16)),
|
||||
('_0', struct_ip_discovery_header_0),
|
||||
]
|
||||
ip_discovery_header = struct_ip_discovery_header
|
||||
|
||||
hdr = b'IPDS\x04\x00|\x1d\x80\x1a\xffd\x01\x00\x00\x00\x8c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00' # noqa: E501
|
||||
ihdr = ip_discovery_header.from_buffer_copy(hdr)
|
||||
|
||||
assert ctypes.sizeof(ihdr) == 80
|
||||
assert ihdr.signature == 0x53445049
|
||||
assert ihdr.version == 0x0004
|
||||
assert ihdr.num_dies == 1
|
||||
assert ihdr.base_addr_64_bit == 1
|
||||
|
||||
if __name__ == "__main__": unittest.main()
|
||||
|
||||
@@ -110,18 +110,6 @@ class TestTensorGradient(unittest.TestCase):
|
||||
with self.assertRaises(RuntimeError): x.sum().gradient(x)
|
||||
with self.assertRaises(RuntimeError): x.float().sum().gradient(x)
|
||||
|
||||
def test_multiple_backward(self):
|
||||
x = Tensor([3.], requires_grad=True)
|
||||
(x*2)[0].backward()
|
||||
np.testing.assert_allclose(x.grad.numpy(), [2.0])
|
||||
old_grad = x.grad
|
||||
(x*3)[0].backward()
|
||||
np.testing.assert_allclose(x.grad.numpy(), [2.0+3.0])
|
||||
self.assertIs(x.grad, old_grad)
|
||||
(x*x)[0].backward()
|
||||
np.testing.assert_allclose(x.grad.numpy(), [2.0+3.0+2*3.0])
|
||||
self.assertIs(x.grad, old_grad)
|
||||
|
||||
class TestRealizeMeansRealize(unittest.TestCase):
|
||||
def test_randn_realizes(self):
|
||||
x = Tensor.randn(2, 3, 64, 64, requires_grad=True).realize()
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
import unittest, threading, time
|
||||
from unittest.mock import Mock
|
||||
|
||||
class TestLLMServer(unittest.TestCase):
|
||||
"""Integration tests using the real OpenAI client."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.mock_tok = Mock()
|
||||
cls.mock_tok.role = Mock(return_value=[100, 101])
|
||||
cls.mock_tok.encode = Mock(return_value=[200, 201, 202])
|
||||
cls.mock_tok.decode = Mock(return_value="Hello")
|
||||
|
||||
cls.mock_model = Mock()
|
||||
cls.mock_model.generate = Mock(side_effect=lambda ids, **kwargs: iter([300, 301, 999]))
|
||||
|
||||
cls.bos_id = 1
|
||||
cls.eos_id = 999
|
||||
|
||||
import tinygrad.apps.llm as llm_module
|
||||
llm_module.model = cls.mock_model
|
||||
llm_module.tok = cls.mock_tok
|
||||
llm_module.bos_id = cls.bos_id
|
||||
llm_module.eos_id = cls.eos_id
|
||||
|
||||
from tinygrad.apps.llm import Handler
|
||||
from tinygrad.helpers import TCPServerWithReuse
|
||||
|
||||
cls.port = 11435
|
||||
cls.server = TCPServerWithReuse(('127.0.0.1', cls.port), Handler)
|
||||
cls.server_thread = threading.Thread(target=cls.server.serve_forever, daemon=True)
|
||||
cls.server_thread.start()
|
||||
time.sleep(0.1)
|
||||
|
||||
from openai import OpenAI
|
||||
cls.client = OpenAI(base_url=f"http://127.0.0.1:{cls.port}/v1", api_key="test")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.server.shutdown()
|
||||
cls.server.server_close()
|
||||
|
||||
def test_chat_completion_stream(self):
|
||||
stream = self.client.chat.completions.create(
|
||||
model="test",
|
||||
messages=[{"role": "user", "content": "Hello"}],
|
||||
stream=True
|
||||
)
|
||||
|
||||
chunks = list(stream)
|
||||
self.assertGreater(len(chunks), 0)
|
||||
self.assertEqual(chunks[0].choices[0].delta.role, "assistant")
|
||||
self.assertEqual(chunks[-1].choices[0].finish_reason, "stop")
|
||||
|
||||
def test_openai_response_structure(self):
|
||||
stream = self.client.chat.completions.create(
|
||||
model="test-model",
|
||||
messages=[{"role": "user", "content": "Test"}],
|
||||
stream=True
|
||||
)
|
||||
|
||||
for chunk in stream:
|
||||
self.assertTrue(chunk.id.startswith("chatcmpl-"))
|
||||
self.assertEqual(chunk.object, "chat.completion.chunk")
|
||||
self.assertIsNotNone(chunk.choices)
|
||||
self.assertIsNotNone(chunk.created)
|
||||
self.assertIsInstance(chunk.created, int)
|
||||
self.assertEqual(chunk.model, "test-model")
|
||||
|
||||
def test_stream_with_usage(self):
|
||||
stream = self.client.chat.completions.create(
|
||||
model="test",
|
||||
messages=[{"role": "user", "content": "Hello"}],
|
||||
stream=True,
|
||||
stream_options={"include_usage": True}
|
||||
)
|
||||
|
||||
chunks = list(stream)
|
||||
last_chunk = chunks[-1]
|
||||
|
||||
self.assertIsNotNone(last_chunk.usage)
|
||||
self.assertIsNotNone(last_chunk.usage.prompt_tokens)
|
||||
self.assertIsNotNone(last_chunk.usage.completion_tokens)
|
||||
self.assertIsNotNone(last_chunk.usage.total_tokens)
|
||||
|
||||
def test_multi_turn_conversation(self):
|
||||
stream = self.client.chat.completions.create(
|
||||
model="test",
|
||||
messages=[
|
||||
{"role": "system", "content": "You are helpful."},
|
||||
{"role": "user", "content": "Hello"},
|
||||
{"role": "assistant", "content": "Hi!"},
|
||||
{"role": "user", "content": "How are you?"}
|
||||
],
|
||||
stream=True
|
||||
)
|
||||
|
||||
chunks = list(stream)
|
||||
self.assertGreater(len(chunks), 0)
|
||||
self.assertEqual(chunks[-1].choices[0].finish_reason, "stop")
|
||||
|
||||
def test_content_is_streamed(self):
|
||||
stream = self.client.chat.completions.create(
|
||||
model="test",
|
||||
messages=[{"role": "user", "content": "Hello"}],
|
||||
stream=True
|
||||
)
|
||||
|
||||
contents = []
|
||||
for chunk in stream:
|
||||
if chunk.choices and chunk.choices[0].delta.content:
|
||||
contents.append(chunk.choices[0].delta.content)
|
||||
|
||||
self.assertGreater(len(contents), 0)
|
||||
|
||||
def test_non_streaming(self):
|
||||
resp = self.client.chat.completions.create(
|
||||
model="test-model",
|
||||
messages=[{"role": "user", "content": "Hello"}],
|
||||
stream=False
|
||||
)
|
||||
|
||||
self.assertTrue(resp.id.startswith("chatcmpl-"))
|
||||
self.assertEqual(resp.object, "chat.completion")
|
||||
self.assertEqual(resp.model, "test-model")
|
||||
self.assertIsNotNone(resp.created)
|
||||
self.assertEqual(len(resp.choices), 1)
|
||||
self.assertEqual(resp.choices[0].message.role, "assistant")
|
||||
self.assertIsNotNone(resp.choices[0].message.content)
|
||||
self.assertEqual(resp.choices[0].finish_reason, "stop")
|
||||
self.assertIsNotNone(resp.usage)
|
||||
self.assertIsNotNone(resp.usage.prompt_tokens)
|
||||
self.assertIsNotNone(resp.usage.completion_tokens)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import io, unittest
|
||||
import numpy as np
|
||||
from tinygrad import Tensor, fetch
|
||||
from tinygrad.nn.state import png_load
|
||||
try:
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
raise unittest.SkipTest("PIL not installed")
|
||||
|
||||
class TestPNGLoad(unittest.TestCase):
|
||||
def test_real_png(self):
|
||||
# test against a real PNG file (uses only filters 0, 1)
|
||||
fp = fetch('https://upload.wikimedia.org/wikipedia/en/d/d4/Norwegian_Forest_Cat_in_Norway.png')
|
||||
with open(fp, 'rb') as f: png_bytes = f.read()
|
||||
expected = np.array(Image.open(io.BytesIO(png_bytes)))[:, :, :3]
|
||||
result = png_load(Tensor(np.frombuffer(png_bytes, dtype=np.uint8))).numpy()
|
||||
np.testing.assert_array_equal(result, expected)
|
||||
|
||||
def test_roundtrip_png(self):
|
||||
# horizontal stripes pattern uses only filters 0, 1
|
||||
img_array = np.zeros((32, 32, 3), dtype=np.uint8)
|
||||
img_array[::2] = 255 # white stripes on black
|
||||
buf = io.BytesIO()
|
||||
Image.fromarray(img_array).save(buf, format='PNG')
|
||||
png_bytes = buf.getvalue()
|
||||
result = png_load(Tensor(np.frombuffer(png_bytes, dtype=np.uint8))).numpy()
|
||||
np.testing.assert_array_equal(result, img_array)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,31 +1,8 @@
|
||||
import unittest
|
||||
from tinygrad import Tensor, Variable
|
||||
from tinygrad import Tensor
|
||||
from tinygrad.engine.schedule import schedule_cache
|
||||
|
||||
class TestScheduleCache(unittest.TestCase):
|
||||
def test_bound_variable_reuses_cache(self):
|
||||
schedule_cache.clear()
|
||||
v = Variable('v', 1, 100)
|
||||
x = Tensor.ones(10).contiguous().realize()
|
||||
|
||||
# first run with v=5
|
||||
t1 = (x + Tensor(v.bind(5))).sum()
|
||||
self.assertEqual(t1.item(), 60.0)
|
||||
cache_size_after_first = len(schedule_cache)
|
||||
|
||||
# second run with v=10 should reuse cache
|
||||
t2 = (x + Tensor(v.bind(10))).sum()
|
||||
self.assertEqual(t2.item(), 110.0)
|
||||
self.assertEqual(len(schedule_cache), cache_size_after_first)
|
||||
|
||||
def test_bound_variable_var_vals(self):
|
||||
v = Variable('pos', 1, 100)
|
||||
x = Tensor.ones(10).contiguous().realize()
|
||||
|
||||
t = x + Tensor(v.bind(42))
|
||||
_, var_vals = t.schedule_with_vars()
|
||||
self.assertEqual(var_vals, {'pos': 42})
|
||||
|
||||
def test_simple(self):
|
||||
a = Tensor.ones(10).contiguous()
|
||||
b = Tensor.ones(10).contiguous()
|
||||
|
||||
+21
-96
@@ -1,7 +1,6 @@
|
||||
from __future__ import annotations
|
||||
import sys, argparse, typing, re, unicodedata, json, uuid, time, functools
|
||||
from tinygrad import Tensor, nn, UOp, TinyJit, getenv
|
||||
from tinygrad.helpers import partition, TCPServerWithReuse, HTTPRequestHandler, DEBUG, Timing, GlobalCounters, stderr_log, colored
|
||||
import sys, argparse, typing, re, unicodedata
|
||||
from tinygrad import Tensor, nn, UOp, TinyJit, getenv, helpers
|
||||
|
||||
class SimpleTokenizer:
|
||||
def __init__(self, normal_tokens:dict[str, int], special_tokens:dict[str, int]):
|
||||
@@ -10,7 +9,6 @@ class SimpleTokenizer:
|
||||
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)}
|
||||
|
||||
# https://github.com/ggml-org/llama.cpp/blob/94933c8c2eeaa9a7983e3f6c08af76bd86724094/src/llama-vocab.cpp#L286
|
||||
# TODO: ucat_range is slow
|
||||
def ucat_range(pre: str): return "".join(re.escape(chr(cp)) for cp in range(sys.maxunicode + 1) if unicodedata.category(chr(cp)).startswith(pre))
|
||||
r_ws, r_p_N, r_p_L = r"\t\n\x0b\x0c\r\x85" + ucat_range("Z"), ucat_range("N"), ucat_range("L")
|
||||
self._split_to_word = re.compile("(?i:'s|'t|'re|'ve|'m|'ll|'d)|" + \
|
||||
@@ -26,7 +24,7 @@ class SimpleTokenizer:
|
||||
# https://github.com/ggml-org/llama.cpp/blob/94933c8c2eeaa9a7983e3f6c08af76bd86724094/src/llama-vocab.cpp#L1818-L1820
|
||||
if kv["tokenizer.ggml.pre"] not in ("llama3","llama-v3","llama-bpe"): raise ValueError(f"Invalid tokenizer preset '{kv['tokenizer.ggml.pre']}'")
|
||||
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)
|
||||
normal_tokens, special_tokens = helpers.partition(vocab, lambda e: kv["tokenizer.ggml.token_type"][e[1]] == 1)
|
||||
return SimpleTokenizer(dict(normal_tokens), dict(special_tokens))
|
||||
|
||||
def _encode_word(self, word:bytes) -> list[int]:
|
||||
@@ -52,18 +50,15 @@ class SimpleTokenizer:
|
||||
def decode(self, ids:list[int]) -> str: return b''.join(self._tok2bytes[tid] for tid in ids).decode()
|
||||
def role(self, role:str): return self.encode("<|start_header_id|>" + role + "<|end_header_id|>\n\n")
|
||||
|
||||
@functools.cache
|
||||
def precompute_freqs_cis(dim: int, end: int, theta: float = 10000.0) -> Tensor:
|
||||
freqs = 1.0 / (theta ** (Tensor.arange(0, dim, 2)[:(dim // 2)] / dim))
|
||||
freqs = Tensor.arange(end).unsqueeze(dim=1) * freqs.unsqueeze(dim=0)
|
||||
return Tensor.stack(freqs.cos(), freqs.sin(), dim=-1).contiguous()
|
||||
|
||||
def apply_rope(x:Tensor, freqs_cis:Tensor) -> Tensor:
|
||||
def apply_rope(x:Tensor, start_pos:int|UOp, base:float = 10000.0) -> Tensor:
|
||||
B, H, T, Hd = x.shape
|
||||
assert isinstance(Hd, int) and (Hd & 1) == 0, "RoPE requires an even head dimension"
|
||||
x_pairs = x.reshape(B, H, T, Hd//2, 2)
|
||||
cos = freqs_cis.reshape(1, 1, T, Hd//2, 2)[..., 0]
|
||||
sin = freqs_cis.reshape(1, 1, T, Hd//2, 2)[..., 1]
|
||||
half = Hd // 2
|
||||
t_start_pos = start_pos if isinstance(start_pos, int) else Tensor(start_pos)
|
||||
angles = (Tensor.arange(T, dtype="float32") + t_start_pos)[:, None] * (base ** (-(Tensor.arange(half, dtype="float32") / half)))[None, :]
|
||||
# contiguous here allows RoPE to be pruned in the JIT
|
||||
cos, sin = angles.cos().reshape(1, 1, T, half).cast(x.dtype).contiguous(), angles.sin().reshape(1, 1, T, half).cast(x.dtype).contiguous()
|
||||
x_pairs = x.reshape(B, H, T, half, 2)
|
||||
return Tensor.stack(x_pairs[..., 0] * cos - x_pairs[..., 1] * sin,
|
||||
x_pairs[..., 0] * sin + x_pairs[..., 1] * cos, dim=-1).reshape(B, H, T, Hd)
|
||||
|
||||
@@ -99,10 +94,8 @@ class TransformerBlock:
|
||||
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)
|
||||
|
||||
# TODO: make UOp have SupportsIndex
|
||||
freqs_cis = precompute_freqs_cis(self.head_dim, self.max_context)[start_pos:start_pos+T] # type: ignore
|
||||
q = apply_rope(q, freqs_cis)
|
||||
k = apply_rope(k, freqs_cis)
|
||||
q = apply_rope(q, start_pos)
|
||||
k = apply_rope(k, start_pos)
|
||||
|
||||
# TODO: remove these kv cache realizes
|
||||
if not hasattr(self, "cache_kv"):
|
||||
@@ -120,8 +113,7 @@ class TransformerBlock:
|
||||
|
||||
def _feed_forward(self, h: Tensor) -> Tensor:
|
||||
h_norm = self.ffn_norm(h)
|
||||
# TODO: remove the need for this contiguous
|
||||
gated = self.ffn_gate(h_norm).silu().contiguous() * self.ffn_up(h_norm)
|
||||
gated = self.ffn_gate(h_norm).silu() * self.ffn_up(h_norm)
|
||||
return h + self.ffn_down(gated)
|
||||
|
||||
def __call__(self, x: Tensor, start_pos: int|UOp):
|
||||
@@ -147,7 +139,7 @@ class Transformer:
|
||||
return (self.forward_jit if getenv("JIT", 1) and tokens.shape[1] == 1 and isinstance(start_pos, UOp) else self.forward)(tokens, start_pos)
|
||||
|
||||
@staticmethod
|
||||
def from_gguf(gguf:Tensor, max_context:int|None=None, realize=True) -> tuple[Transformer, dict]:
|
||||
def from_gguf(gguf:Tensor, max_context:int|None=None) -> tuple[Transformer, dict]:
|
||||
# TODO: remove the need for copy to default device
|
||||
kv, state_dict = nn.state.gguf_load(gguf.to(None))
|
||||
|
||||
@@ -164,8 +156,7 @@ class Transformer:
|
||||
norm_eps=kv[f'{arch}.attention.layer_norm_rms_epsilon'], vocab_size=len(kv['tokenizer.ggml.tokens']), max_context=max_context)
|
||||
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
|
||||
for s in (params:=nn.state.get_parameters(model)): s.replace(s.contiguous())
|
||||
if realize: Tensor.realize(*params)
|
||||
for s in nn.state.get_parameters(model): s.replace(s.contiguous())
|
||||
return model, kv
|
||||
|
||||
def generate(self, tokens:list[int], start_pos=0):
|
||||
@@ -181,92 +172,26 @@ class Transformer:
|
||||
yield next_id
|
||||
|
||||
models = {
|
||||
"llama3.2:1b": "https://huggingface.co/bartowski/Llama-3.2-1B-Instruct-GGUF/resolve/main/Llama-3.2-1B-Instruct-Q6_K.gguf",
|
||||
"llama3.2:3b": "https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF/resolve/main/Llama-3.2-3B-Instruct-Q6_K.gguf",
|
||||
"llama3.2:3b-f16": "https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF/resolve/main/Llama-3.2-3B-Instruct-f16.gguf",
|
||||
"llama3.1:8b": "https://huggingface.co/bartowski/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct-Q8_0.gguf",
|
||||
"1B": "https://huggingface.co/bartowski/Llama-3.2-1B-Instruct-GGUF/resolve/main/Llama-3.2-1B-Instruct-Q6_K.gguf",
|
||||
"3B": "https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF/resolve/main/Llama-3.2-3B-Instruct-Q6_K.gguf",
|
||||
"3B_f16": "https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF/resolve/main/Llama-3.2-3B-Instruct-f16.gguf",
|
||||
"8B": "https://huggingface.co/bartowski/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct-Q8_0.gguf",
|
||||
}
|
||||
|
||||
# *** simple OpenAI compatible server on 11434 to match ollama ***
|
||||
# OPENAI_BASE_URL=http://localhost:11434/v1 OPENAI_API_KEY=ollama uvx --from gpt-command-line gpt
|
||||
|
||||
class Handler(HTTPRequestHandler):
|
||||
def log_request(self, code='-', size='-'): pass
|
||||
def run_model(self, ids:list[int], model_name:str, include_usage=False):
|
||||
stderr_log(f"{self.path} {colored('--', 'BLACK')} in:{len(ids):5d} {colored('--', 'BLACK')} ")
|
||||
tmpl = {"id":f"chatcmpl-{uuid.uuid4().hex[:24]}", "object":"chat.completion.chunk", "created":int(time.time()), "model":model_name}
|
||||
yield {"choices": [{"index":0, "delta":{"role":"assistant","content":""}, "finish_reason":None}], **tmpl}
|
||||
out: list[int] = []
|
||||
st = time.perf_counter()
|
||||
for next_id in model.generate(ids):
|
||||
if len(out) == 0: stderr_log(f"prefill:{len(ids)/((pt:=time.perf_counter())-st):4.0f} tok/s {colored('--', 'BLACK')} ")
|
||||
if next_id == eos_id: break
|
||||
out.append(next_id)
|
||||
yield {"choices": [{"index":0, "delta":{"content":tok.decode([next_id])}, "finish_reason":None}], **tmpl}
|
||||
yield {"choices": [{"index":0, "delta":{},"finish_reason":"stop"}], **tmpl}
|
||||
if include_usage:
|
||||
yield {"choices": [], "usage": {"prompt_tokens": len(ids), "completion_tokens": len(out), "total_tokens": len(ids) + len(out)}, **tmpl}
|
||||
stderr_log(f"out:{len(out):5d} {colored('--', 'BLACK')} gen: {len(out)/(time.perf_counter()-pt):4.0f} tok/s\n")
|
||||
|
||||
def do_POST(self):
|
||||
raw_body = self.rfile.read(int(self.headers.get("Content-Length", "0")))
|
||||
body: dict[str, typing.Any] = json.loads(raw_body.decode("utf-8"))
|
||||
if DEBUG >= 1: print(json.dumps(body, indent=2))
|
||||
if self.path == "/v1/chat/completions":
|
||||
# extract tokens
|
||||
ids = [bos_id]
|
||||
for msg in body["messages"]:
|
||||
ids += tok.role(msg["role"])
|
||||
# content can be a str or a list
|
||||
content = msg["content"]
|
||||
if isinstance(content, str): ids += tok.encode(content)
|
||||
elif isinstance(content, list):
|
||||
for c in content:
|
||||
if c["type"] == "text": ids += tok.encode(c["text"])
|
||||
else: raise RuntimeError(f"unhandled type: {c['type']}")
|
||||
else: raise RuntimeError(f"unknown content type: {type(content)}")
|
||||
ids += tok.role("assistant")
|
||||
|
||||
# reply
|
||||
chunks = self.run_model(ids, body["model"], not body.get("stream") or body.get("stream_options",{}).get("include_usage", False))
|
||||
if body.get("stream"): self.stream_json(chunks)
|
||||
else:
|
||||
out = []
|
||||
for c in chunks: out.append(c["choices"][0]["delta"].get("content", "") if c["choices"] else "")
|
||||
self.send_data(json.dumps({**c, "object":"chat.completion",
|
||||
"choices":[{"index":0, "message":{"role":"assistant","content":"".join(out)}, "finish_reason":"stop"}]}).encode())
|
||||
else:
|
||||
raise RuntimeError(f"unhandled path {self.path}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--model", choices=list(models.keys()), default=list(models.keys())[0], help="Model choice")
|
||||
parser.add_argument("--size", choices=list(models.keys()), default=list(models.keys())[0], help="Model size")
|
||||
parser.add_argument("--max_context", type=int, default=4096, help="Max Context Length")
|
||||
parser.add_argument("--serve", action="store_true", help="Run OpenAI compatible API")
|
||||
parser.add_argument("--benchmark", action="store_true", help="Benchmark tok/s")
|
||||
args = parser.parse_args()
|
||||
|
||||
# load the model
|
||||
model, kv = Transformer.from_gguf(Tensor.from_url(models[args.model]), args.max_context)
|
||||
if DEBUG >= 1: print(f"using model {args.model}")
|
||||
|
||||
# do benchmark
|
||||
if args.benchmark:
|
||||
param_bytes = sum(x.nbytes() for x in nn.state.get_parameters(model))
|
||||
gen = model.generate([0], 0)
|
||||
for _ in range(20):
|
||||
GlobalCounters.reset()
|
||||
with Timing(on_exit=lambda x: f", {1e9/x:6.2f} tok/s, {GlobalCounters.global_mem/x:7.2f} GB/s, param {param_bytes/x:7.2f} GB/s"): next(gen)
|
||||
exit(0)
|
||||
model, kv = Transformer.from_gguf(Tensor.from_url(models[args.size]), args.max_context)
|
||||
|
||||
# extract some metadata
|
||||
tok = SimpleTokenizer.from_gguf_kv(kv)
|
||||
bos_id: int = kv['tokenizer.ggml.bos_token_id']
|
||||
eos_id: int = kv['tokenizer.ggml.eos_token_id']
|
||||
|
||||
# start server
|
||||
if args.serve: TCPServerWithReuse(('', 11434), Handler).serve_forever()
|
||||
|
||||
ids: list[int] = [bos_id]
|
||||
while 1:
|
||||
start_pos = len(ids) - 1
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# classification in 50 lines
|
||||
import sys
|
||||
from tinygrad import nn, Tensor
|
||||
|
||||
class Bottleneck:
|
||||
expansion = 4
|
||||
def __init__(self, in_c, mid_c, stride=1):
|
||||
out_c = mid_c * self.expansion
|
||||
self.conv1, self.bn1 = nn.Conv2d(in_c, mid_c, 1, bias=False), nn.BatchNorm2d(mid_c)
|
||||
self.conv2, self.bn2 = nn.Conv2d(mid_c, mid_c, 3, stride, 1, bias=False), nn.BatchNorm2d(mid_c)
|
||||
self.conv3, self.bn3 = nn.Conv2d(mid_c, out_c, 1, bias=False), nn.BatchNorm2d(out_c)
|
||||
self.downsample = (stride != 1 or in_c != out_c) and [nn.Conv2d(in_c, out_c, 1, stride, bias=False), nn.BatchNorm2d(out_c)] or []
|
||||
|
||||
def __call__(self, x:Tensor) -> Tensor:
|
||||
identity = x.sequential(self.downsample)
|
||||
x = self.bn1(self.conv1(x)).relu()
|
||||
x = self.bn2(self.conv2(x)).relu()
|
||||
x = self.bn3(self.conv3(x))
|
||||
return (x + identity).relu()
|
||||
|
||||
class ResNet50:
|
||||
def __init__(self, num_classes=1000):
|
||||
self.conv1, self.bn1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False), nn.BatchNorm2d(64)
|
||||
self.layer1 = self._make_layer(64, 64, 3, 1)
|
||||
self.layer2 = self._make_layer(256, 128, 4, 2)
|
||||
self.layer3 = self._make_layer(512, 256, 6, 2)
|
||||
self.layer4 = self._make_layer(1024,512, 3, 2)
|
||||
self.fc = nn.Linear(2048, num_classes)
|
||||
|
||||
def _make_layer(self, in_c, mid_c, blocks, stride):
|
||||
layers = [Bottleneck(in_c, mid_c, stride)]
|
||||
for _ in range(1, blocks): layers.append(Bottleneck(mid_c * Bottleneck.expansion, mid_c))
|
||||
return layers
|
||||
|
||||
def __call__(self, x:Tensor) -> Tensor:
|
||||
x = self.bn1(self.conv1(x)).relu()
|
||||
# TODO: max_pool2d return type is Tensor | tuple[Tensor, Tensor], this should be type specialised
|
||||
x = x.max_pool2d() # type: ignore
|
||||
x = x.sequential([*self.layer1, *self.layer2, *self.layer3, *self.layer4])
|
||||
x = x.mean((2, 3))
|
||||
return self.fc(x)
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_url = "https://upload.wikimedia.org/wikipedia/en/d/d4/Norwegian_Forest_Cat_in_Norway.png"
|
||||
img = nn.state.png_load(Tensor.from_url(sys.argv[1] if len(sys.argv) > 1 else test_url))
|
||||
model = ResNet50()
|
||||
state_dict = nn.state.safe_load(Tensor.from_url("https://huggingface.co/timm/resnet50.a1_in1k/resolve/main/model.safetensors"))
|
||||
nn.state.load_state_dict(model, state_dict)
|
||||
value = model(img.rearrange("h w c -> 1 c h w").float()/255).argmax().item()
|
||||
print(value, nn.datasets.imagenet_labels()[value])
|
||||
@@ -92,9 +92,9 @@ def _ensure_buffer_alloc(bufs:list[Buffer]) -> list[Buffer]: return [buf.ensure_
|
||||
# *** external API ***
|
||||
|
||||
# get dictionary of all possible actions
|
||||
def get_kernel_actions(s:Scheduler, include_0=True) -> dict[int, Scheduler]:
|
||||
def get_kernel_actions(s:Scheduler, include_0=True, candidates:list[Opt]|None=None) -> dict[int, Scheduler]:
|
||||
acted, max_up, max_lcl = {0:s} if include_0 else {}, getenv("BEAM_UPCAST_MAX", 256), getenv("BEAM_LOCAL_MAX", 1024)
|
||||
kernel_actions = actions.copy()
|
||||
kernel_actions = (actions if candidates is None else candidates).copy()
|
||||
|
||||
for i,a in enumerate(kernel_actions):
|
||||
if a.axis is not None and a.op is not OptOps.TC:
|
||||
|
||||
+1
-1
@@ -366,7 +366,7 @@ def is_dtype_supported(dtype:DType, device:str|None=None) -> bool:
|
||||
if device in ["CUDA", "NV"]: return not CI
|
||||
if device == "CPU" and CPU_LLVM: return OSX
|
||||
if device == "PYTHON": return sys.version_info >= (3, 12)
|
||||
if dtype == dtypes.float64: return device not in {"METAL", "QCOM"} and not (OSX and device == "CL") and not getenv("NULL_IR3")
|
||||
if dtype == dtypes.float64: return device != "METAL" and not (OSX and device == "CL")
|
||||
return True
|
||||
|
||||
if PROFILE:
|
||||
|
||||
+14
-20
@@ -20,11 +20,12 @@ class ScheduleItem:
|
||||
|
||||
# **** schedule linearizer
|
||||
|
||||
def create_schedule(sched_sink:UOp) -> list[ScheduleItem]:
|
||||
def create_schedule_with_vars(sched_sink:UOp) -> tuple[list[ScheduleItem], dict[str, int]]:
|
||||
with cpu_profile(TracingKey("toposort sched_sink")):
|
||||
# construct the KERNEL children graph based on assigns
|
||||
children: dict[UOp, list[UOp]] = {}
|
||||
in_degree: dict[UOp, int] = {}
|
||||
var_vals: dict[str, int] = {}
|
||||
for u in sched_sink.toposort():
|
||||
if u.op is Ops.RANGE:
|
||||
in_degree.setdefault(u, 0)
|
||||
@@ -43,8 +44,14 @@ def create_schedule(sched_sink:UOp) -> list[ScheduleItem]:
|
||||
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
|
||||
elif s.op in {Ops.BUFFER, Ops.BIND}:
|
||||
pass # a BUFFER is already realized, BINDs are handled in complete_create_schedule_with_vars
|
||||
elif s.op is Ops.BUFFER:
|
||||
pass # a BUFFER is already realized, nothing to do here
|
||||
elif s.op is Ops.BIND:
|
||||
# for RANGE this is in fixedvars
|
||||
if s.src[1].op is not Ops.RANGE:
|
||||
var, val = s.unbind()
|
||||
assert var.expr not in var_vals or var_vals[var.expr] == val, f"bind mismatch on {var}, {var_vals[var.expr]} != {val}"
|
||||
var_vals[var.expr] = val
|
||||
else:
|
||||
raise RuntimeError(f"input to kernel must be AFTER or BUFFER, not {s.op}")
|
||||
|
||||
@@ -66,7 +73,7 @@ def create_schedule(sched_sink:UOp) -> list[ScheduleItem]:
|
||||
assert isinstance(base, Buffer), "base can't be MultiBuffer"
|
||||
buffers[k.src[0]] = base.view(k.size, ast.dtype, ast.arg[1]*base.dtype.itemsize)
|
||||
ubufs = tuple(s.buf_uop.buffer for s in k.src if s.op is not Ops.BIND)
|
||||
bound_ranges = tuple(s for s in k.src if s.op is Ops.BIND and len(s.src) > 1 and s.src[1].op is Ops.RANGE)
|
||||
bound_ranges = tuple(s for s in k.src if s.op is Ops.BIND and s.src[1].op is Ops.RANGE)
|
||||
if 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.arg[0] == '_device_num']
|
||||
@@ -101,7 +108,7 @@ def create_schedule(sched_sink:UOp) -> list[ScheduleItem]:
|
||||
else:
|
||||
real_schedule.append(replace(si, fixedvars=si.fixedvars | {s.src[0].arg[0]:in_ranges[s.src[1]] for s in si.bound_ranges}, bound_ranges=()))
|
||||
sched_ptr += 1
|
||||
return real_schedule
|
||||
return real_schedule, var_vals
|
||||
|
||||
from tinygrad.engine.memory import memory_planner
|
||||
from tinygrad.schedule.rangeify import get_rangeify_map
|
||||
@@ -122,8 +129,6 @@ pm_pre_sched_cache = PatternMatcher([
|
||||
(UPat(Ops.BUFFER, src=(UPat(Ops.UNIQUE), UPat(Ops.DEVICE)), name="b"), replace_input_buffer),
|
||||
# remove unique consts
|
||||
(UPat(Ops.CONST, src=(UPat(Ops.DEVICE), UPat(Ops.UNIQUE)), name="b"), replace_input_buffer),
|
||||
# strip value from BIND for cache key normalization, so different values hit same cache
|
||||
(UPat(Ops.BIND, src=(UPat(Ops.DEFINE_VAR), UPat(Ops.CONST)), name="b"), lambda ctx,b: ctx.setdefault(b, b.replace(src=(b.src[0],)))),
|
||||
])
|
||||
|
||||
def replace_input_buffer_back(ctx:dict[UOp, UOp], b:UOp):
|
||||
@@ -136,8 +141,6 @@ def replace_input_buffer_back(ctx:dict[UOp, UOp], b:UOp):
|
||||
pm_post_sched_cache = PatternMatcher([
|
||||
(UPat(Ops.BUFFER, src=(UPat(Ops.LUNIQUE), UPat(Ops.DEVICE)), name="b"), replace_input_buffer_back),
|
||||
(UPat(Ops.CONST, src=(UPat(Ops.DEVICE), UPat(Ops.LUNIQUE)), name="b"), replace_input_buffer_back),
|
||||
# restore BIND value stripped in pm_pre_sched_cache
|
||||
(UPat(Ops.BIND, src=(UPat(Ops.DEFINE_VAR),), name="b"), lambda ctx,b: ctx.get(b)),
|
||||
])
|
||||
|
||||
schedule_cache: dict[bytes, tuple[UOp, UOp]] = {}
|
||||
@@ -146,7 +149,7 @@ def complete_create_schedule_with_vars(big_sink:UOp) -> tuple[dict[UOp, UOp], li
|
||||
# big_sink srcs are all the Tensors
|
||||
st = time.perf_counter()
|
||||
|
||||
# replace all UNIQUE buffers with LUNIQUE, strip BIND values for cache key
|
||||
# replace all UNIQUE buffers with LUNIQUE
|
||||
input_buffers: dict[UOp, UOp] = {}
|
||||
big_sink_cache = graph_rewrite(big_sink, pm_pre_sched_cache, ctx=input_buffers, name="rewrite for sched cache")
|
||||
sched_cache_key = big_sink_cache.key
|
||||
@@ -184,18 +187,9 @@ def complete_create_schedule_with_vars(big_sink:UOp) -> tuple[dict[UOp, UOp], li
|
||||
tensor_map = {tm_src[i]:tm_src[i+1] for i in range(0, len(tm_src), 2)}
|
||||
|
||||
# create the schedule
|
||||
schedule = create_schedule(big_sink)
|
||||
schedule, var_vals = create_schedule_with_vars(big_sink)
|
||||
with cpu_profile(TracingKey("memory planner")): schedule = memory_planner(schedule)
|
||||
|
||||
# extract var_vals from BINDs that were stripped (only if there are kernels)
|
||||
var_vals: dict[str, int] = {}
|
||||
if schedule:
|
||||
for u in input_buffers:
|
||||
if u.op is Ops.BIND:
|
||||
var, val = u.unbind()
|
||||
assert var.expr not in var_vals or var_vals[var.expr] == val, f"bind mismatch on {var}, {var_vals[var.expr]} != {val}"
|
||||
var_vals[var.expr] = val
|
||||
|
||||
# remove all AFTERs, after scheduling, the tensors are just buffers
|
||||
tensor_map |= {u:u.buf_uop for u in big_sink.toposort() if u.op is Ops.AFTER}
|
||||
|
||||
|
||||
+2
-36
@@ -1,9 +1,8 @@
|
||||
from __future__ import annotations
|
||||
import os, functools, platform, time, re, contextlib, operator, hashlib, pickle, sqlite3, tempfile, pathlib, string, ctypes, sys, gzip, getpass, gc
|
||||
import urllib.request, subprocess, shutil, math, types, copyreg, inspect, importlib, decimal, itertools, socketserver, json
|
||||
import urllib.request, subprocess, shutil, math, types, copyreg, inspect, importlib, decimal, itertools
|
||||
from dataclasses import dataclass, field
|
||||
from typing import ClassVar, Iterable, Any, TypeVar, Callable, Sequence, TypeGuard, Iterator, Generic, Generator, cast, overload
|
||||
from http.server import BaseHTTPRequestHandler
|
||||
|
||||
T = TypeVar("T")
|
||||
U = TypeVar("U")
|
||||
@@ -149,10 +148,6 @@ def getenv(key:str, default:Any=0): return type(default)(os.getenv(key, default)
|
||||
def temp(x:str, append_user:bool=False) -> str:
|
||||
return (pathlib.Path(tempfile.gettempdir()) / (f"{x}.{getpass.getuser()}" if append_user else x)).as_posix()
|
||||
|
||||
def stderr_log(msg):
|
||||
sys.stderr.write(msg)
|
||||
sys.stderr.flush()
|
||||
|
||||
class Context(contextlib.ContextDecorator):
|
||||
def __init__(self, **kwargs): self.kwargs = kwargs
|
||||
def __enter__(self):
|
||||
@@ -191,10 +186,8 @@ EMULATE = ContextVar("EMULATE", "")
|
||||
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_LLVM, CPU_LVP, AMD_LLVM = ContextVar("CPU_LLVM", 0), ContextVar("CPU_LVP", 0), ContextVar("AMD_LLVM", 0)
|
||||
NV_PTX, CUDA_PTX, NV_NAK, QCOM_IR3 = ContextVar("NV_PTX", 0), ContextVar("CUDA_PTX", 0), ContextVar("NV_NAK", 0), ContextVar("QCOM_IR3", 0)
|
||||
NULL_IR3, NULL_NAK = ContextVar("NULL_IR3", 0), ContextVar("NULL_NAK", 0)
|
||||
NV_PTX, CUDA_PTX, NV_NAK = ContextVar("NV_PTX", 0), ContextVar("CUDA_PTX", 0), ContextVar("NV_NAK", 0)
|
||||
AMD_CC, CPU_CC, NV_CC, CUDA_CC = ContextVar("AMD_CC", ""), ContextVar("CPU_CC", ""), ContextVar("NV_CC", ""), ContextVar("CUDA_CC", "")
|
||||
QCOM_CC = ContextVar("QCOM_CC", "")
|
||||
# VIZ implies PROFILE, but you can run PROFILE without VIZ
|
||||
VIZ = ContextVar("VIZ", 0)
|
||||
PROFILE = ContextVar("PROFILE", VIZ.value)
|
||||
@@ -409,33 +402,6 @@ def fetch(url:str, name:pathlib.Path|str|None=None, subdir:str|None=None, gunzip
|
||||
if length and (file_size:=os.stat(fp).st_size) < length: raise RuntimeError(f"fetch size incomplete, {file_size} < {length}")
|
||||
return fp
|
||||
|
||||
# NOTE: using HTTPServer forces a potentially slow socket.getfqdn
|
||||
class TCPServerWithReuse(socketserver.TCPServer):
|
||||
allow_reuse_address = True
|
||||
def __init__(self, server_address, RequestHandlerClass):
|
||||
print(f"*** started server on http://127.0.0.1:{server_address[1]}")
|
||||
super().__init__(server_address, RequestHandlerClass)
|
||||
|
||||
class HTTPRequestHandler(BaseHTTPRequestHandler):
|
||||
def send_data(self, data:bytes, content_type:str="application/json", status_code:int=200):
|
||||
self.send_response(status_code)
|
||||
self.send_header("Content-Type", content_type)
|
||||
self.send_header("Content-Length", str(len(data)))
|
||||
self.end_headers()
|
||||
return self.wfile.write(data)
|
||||
def stream_json(self, source:Generator):
|
||||
try:
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", "text/event-stream")
|
||||
self.send_header("Cache-Control", "no-cache")
|
||||
self.end_headers()
|
||||
for r in source:
|
||||
self.wfile.write(f"data: {json.dumps(r)}\n\n".encode("utf-8"))
|
||||
self.wfile.flush()
|
||||
self.wfile.write("data: [DONE]\n\n".encode("utf-8"))
|
||||
# pass if client closed connection
|
||||
except (BrokenPipeError, ConnectionResetError): return
|
||||
|
||||
# *** Exec helpers
|
||||
|
||||
def system(cmd:str, **kwargs) -> str:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import ast
|
||||
from tinygrad.tensor import Tensor
|
||||
from tinygrad.nn.state import tar_extract
|
||||
|
||||
@@ -13,8 +12,3 @@ def cifar(device=None):
|
||||
train = Tensor.cat(*[tt[f"cifar-10-batches-bin/data_batch_{i}.bin"].reshape(-1, 3073).to(device) for i in range(1,6)])
|
||||
test = tt["cifar-10-batches-bin/test_batch.bin"].reshape(-1, 3073).to(device)
|
||||
return train[:, 1:].reshape(-1,3,32,32), train[:, 0], test[:, 1:].reshape(-1,3,32,32), test[:, 0]
|
||||
|
||||
def imagenet_labels():
|
||||
return ast.literal_eval(Tensor.from_url(
|
||||
"https://gist.githubusercontent.com/yrevar/942d3a0ac09ec9e5eb3a/raw/238f720ff059c1f82f368259d1ca4ffa5dd8f9f5/imagenet1000_clsidx_to_labels.txt"
|
||||
).tobytes().decode())
|
||||
|
||||
+15
-14
@@ -498,15 +498,13 @@ def get_onnx_ops() -> dict[str, types.FunctionType|dict[OpSetId, types.FunctionT
|
||||
def _axes(axes, noop_with_empty_axes): return axes or ([] if noop_with_empty_axes else None)
|
||||
|
||||
# (padding_top, padding_left, ..., padding_bottom, padding_right, ...) -> (padding_left, padding_right, padding_top, padding_bottom, ...)
|
||||
def _onnx_pads_to_tiny_pads(pads):
|
||||
n = len(pads) // 2
|
||||
return tuple(x for i in range(n-1, -1, -1) for x in (pads[i], pads[i+n]))
|
||||
def _onnx_pads_to_tiny_pads(pads): return tuple(flatten(reversed(list(zip(pads, pads[len(pads)//2:])))))
|
||||
|
||||
AUTO_PAD_OPTIONS = Literal["NOTSET", "SAME_UPPER", "SAME_LOWER", "VALID"]
|
||||
# (padding_height, padding_width) -> (padding_top, padding_left, padding_bottom, padding_right)
|
||||
def _auto_pad(pads, auto_pad: AUTO_PAD_OPTIONS):
|
||||
first = [p//2 for p in pads] if auto_pad == "SAME_UPPER" else [p - p//2 for p in pads]
|
||||
return first + [p - f for p, f in zip(pads, first)]
|
||||
if auto_pad == "SAME_UPPER": return [pads[i]//2 for i in range(len(pads))] + [pads[i]-pads[i]//2 for i in range(len(pads))]
|
||||
return [pads[i]-pads[i]//2 for i in range(len(pads))] + [pads[i]//2 for i in range(len(pads))]
|
||||
|
||||
def _resolve_pool_pads(x:Tensor, p_, k_, d_, s_, auto_pad:AUTO_PAD_OPTIONS):
|
||||
if auto_pad == "VALID": return [0]*(len(k_)*2)
|
||||
@@ -628,7 +626,6 @@ def get_onnx_ops() -> dict[str, types.FunctionType|dict[OpSetId, types.FunctionT
|
||||
def ThresholdedRelu(X:Tensor, alpha:float=1.0): return (X > alpha).where(X, 0)
|
||||
def LogSoftmax(x: Tensor, axis:int=-1): return x.log_softmax(axis)
|
||||
def Binarizer(x:Tensor, threshold:float=0.0): return (x > threshold).float()
|
||||
def Swish(x:Tensor, alpha:float=1.0): return x * (x * alpha).sigmoid()
|
||||
|
||||
# ***** Unary Ops (broadcasted) *****
|
||||
def Add(x:Tensor,y:Tensor, broadcast=None, axis=None): return x + y
|
||||
@@ -649,7 +646,7 @@ def get_onnx_ops() -> dict[str, types.FunctionType|dict[OpSetId, types.FunctionT
|
||||
def Mod(x:Tensor,y:Tensor,fmod=0): return x - x.div(y, rounding_mode="trunc") * y if fmod else x % y
|
||||
|
||||
# ***** Casting Ops *****
|
||||
# TODO: saturate parameter is ignored in Cast and CastLike
|
||||
# TODO: saturate
|
||||
def Cast(x:Tensor, to:int, saturate:int=1): return x.cast(dtype_fallback(OnnxDataType(to).to_dtype(), "Cast op"))
|
||||
def CastLike(x:Tensor, target_type:Tensor, saturate:int=1): return x.cast(target_type.dtype)
|
||||
|
||||
@@ -701,8 +698,8 @@ def get_onnx_ops() -> dict[str, types.FunctionType|dict[OpSetId, types.FunctionT
|
||||
def Concat(*xs:Tensor, axis:int): return Tensor.cat(*xs, dim=axis)
|
||||
def Slice(data:Tensor, starts:list[int], ends:list[int], axes:list[int]|None=None, steps:list[int]|None=None):
|
||||
axes = axes or list(range(data.ndim))
|
||||
steps = steps or [1] * data.ndim
|
||||
slices = [slice(None)] * data.ndim
|
||||
steps = steps or [1]*data.ndim
|
||||
slices = [slice(0,x,1) for x in data.shape]
|
||||
for i, axis in enumerate(axes): slices[axis] = slice(starts[i], ends[i], steps[i])
|
||||
return data[tuple(slices)]
|
||||
|
||||
@@ -812,7 +809,7 @@ def get_onnx_ops() -> dict[str, types.FunctionType|dict[OpSetId, types.FunctionT
|
||||
|
||||
input_shape = cast(tuple[int, ...], X.shape[2:])
|
||||
if scales is not None: assert all(sc==1 for sc in scales[:-len(input_shape)]), "resizing batch_size dim or channel dim not supported"
|
||||
if sizes is not None: assert tuple(sizes[:-2]) == tuple(X.shape[X.ndim-len(sizes):-2]), "resizing batch_size dim or channel dim not supported"
|
||||
if sizes is not None: assert tuple(sizes[:-2]) == tuple(X.shape[X.ndim-len(sizes):-2]), "resizing batch_size dim or channel dim not supported"
|
||||
|
||||
scales, sizes = (None if scales is None else scales[-len(input_shape):]), (None if sizes is None else sizes[-len(input_shape):])
|
||||
if sizes is not None:
|
||||
@@ -936,8 +933,11 @@ def get_onnx_ops() -> dict[str, types.FunctionType|dict[OpSetId, types.FunctionT
|
||||
# https://github.com/microsoft/onnxruntime/blob/main/docs/ContribOperators.md#com.microsoft.EmbedLayerNormalization
|
||||
assert (segment_ids is None) is (segment_embedding is None)
|
||||
assert mask is None and not mask_index_type, "functionality not supported yet" # TODO
|
||||
input_shape, seq_length = input_ids.shape, input_ids.shape[1]
|
||||
input_shape = input_ids.shape
|
||||
seq_length = input_shape[1]
|
||||
compute_seg_emb = (segment_embedding is not None and segment_ids is not None)
|
||||
vocab_size, max_position_embeddings = word_embedding.shape[0], position_embedding.shape[0]
|
||||
type_vocab_size = (segment_embedding.shape[0] if compute_seg_emb else None)
|
||||
|
||||
def embedding(x:Tensor, vocab_size, weight:Tensor) -> Tensor:
|
||||
return x.unsqueeze(-1).expand(*x.shape, vocab_size)._one_hot_along_dim(vocab_size) @ weight
|
||||
@@ -946,9 +946,10 @@ def get_onnx_ops() -> dict[str, types.FunctionType|dict[OpSetId, types.FunctionT
|
||||
if position_ids is None: position_ids = Tensor.arange(seq_length, requires_grad=False).unsqueeze(0).expand(*input_shape)
|
||||
wrd_embedding_res = embedding(input_ids, vocab_size, word_embedding)
|
||||
pos_embedding_res = embedding(position_ids, max_position_embeddings, position_embedding)
|
||||
seg_embedding_res = embedding(segment_ids, type_vocab_size, segment_embedding) if compute_seg_emb else None
|
||||
|
||||
embedding_sum = wrd_embedding_res + pos_embedding_res
|
||||
if segment_embedding is not None: embedding_sum = embedding_sum + embedding(segment_ids, segment_embedding.shape[0], segment_embedding)
|
||||
if seg_embedding_res is not None: embedding_sum = embedding_sum + seg_embedding_res
|
||||
out = embedding_sum.layernorm(eps=epsilon) * gamma + beta
|
||||
return out, None, embedding_sum
|
||||
def MeanVarianceNormalization(x:Tensor, axis:list[int]|None=None):
|
||||
@@ -1002,7 +1003,7 @@ def get_onnx_ops() -> dict[str, types.FunctionType|dict[OpSetId, types.FunctionT
|
||||
return (base_grid @ theta.transpose(1, 2)).reshape(N, *spatial_dims, -1)
|
||||
|
||||
def attention_contrib(x:Tensor, weights:Tensor, bias:Tensor|None=None, mask_index:Tensor|None=None, past:Tensor|None=None,
|
||||
attention_bias:Tensor|None=None, past_sequence_length:Tensor|None=None, do_rotary:int=0, mask_filter_value:float=-10000.0,
|
||||
attention_bias:Tensor|None=None, past_sequence_length:Tensor|None=None, do_rotary:int=0, mask_filter_value:float=-10000.0,
|
||||
num_heads:int|None=None, past_present_share_buffer:int|None=None, qkv_hidden_sizes:list[int]|None=None,
|
||||
rotary_embedding_dim:int|None=None, scale:float|None=None, unidirectional:int=0):
|
||||
assert not do_rotary and not attention_bias, "TODO"
|
||||
@@ -1286,7 +1287,7 @@ def get_onnx_ops() -> dict[str, types.FunctionType|dict[OpSetId, types.FunctionT
|
||||
# Tensor ops
|
||||
**{op: getattr(Tensor, op.lower()) for op in ("Neg", "Reciprocal", "Pow", "Sqrt", "Sign", "Abs", "Exp", "Log", "Mish", "Sin", "Cos", "Tan",
|
||||
"Asin", "Acos", "Atan", "Relu", "Sigmoid", "MatMul", "Floor", "Ceil", "IsNaN", "Softplus", "HardSwish", "Where", "Mul", "Sinh", "Cosh",
|
||||
"Tanh", "Softsign", "Asinh", "Acosh", "Atanh", "Elu", "Celu", "Selu", "Round", "Erf")},
|
||||
"Tanh", "Softsign", "Asinh", "Acosh", "Atanh", "Elu", "Celu", "Selu", "Round", "Erf")},
|
||||
# Implemented ops
|
||||
**{name:obj for name,obj in locals().items() if isinstance(obj, types.FunctionType) and not name.startswith("_") and name[0].isupper()},
|
||||
# Version ops
|
||||
|
||||
@@ -383,24 +383,3 @@ def gguf_load(tensor: Tensor) -> tuple[dict, dict[str, Tensor]]:
|
||||
for name, dims, typ, off in t_infos: state_dict[name] = ggml_data_to_tensor(tensor[data_start + off:], prod(dims), typ).reshape(*reversed(dims))
|
||||
|
||||
return kv_data, state_dict
|
||||
|
||||
@accept_filename
|
||||
def png_load(t:Tensor) -> Tensor:
|
||||
f = io.BufferedReader(TensorIO(t))
|
||||
assert f.read(8) == b'\x89PNG\r\n\x1a\n', "not a PNG"
|
||||
idats = []
|
||||
while (slen:=f.read(4)):
|
||||
typ, dat = f.read(4), f.read(struct.unpack(">I", slen)[0])
|
||||
if DEBUG >= 3: print(len(dat), typ)
|
||||
if typ == b'IHDR':
|
||||
width, height, depth, color_type = struct.unpack(">IIBB", dat[:10])
|
||||
assert depth == 8 and color_type in [2, 6], f"only 8-bit RGB/RGBA PNG supported {depth=} {color_type=}"
|
||||
bpp = 3 if color_type == 2 else 4
|
||||
if typ == b'IDAT': idats.append(dat)
|
||||
f.seek(4, 1)
|
||||
data = Tensor(zlib.decompress(b''.join(idats))).reshape(height, width * bpp + 1)
|
||||
filters, pixels = data[:, 0], data[:, 1:].reshape(height, width, bpp)
|
||||
assert filters.max().item() <= 1, f"only PNG filters 0/1 supported, got {set(filters.tolist())}" # type: ignore[arg-type]
|
||||
# Sub filter (type 1): each pixel adds the pixel to its left, which is cumsum along width
|
||||
pixels = (filters == 1).reshape(height, 1, 1).where(pixels.cast(dtypes.int16).cumsum(axis=1).bitwise_and(0xff).cast(dtypes.uint8), pixels)
|
||||
return pixels[:, :, :3]
|
||||
|
||||
@@ -224,12 +224,8 @@ class ClangRenderer(CStyleLanguage):
|
||||
Ops.SQRT: lambda x,dtype: f"__builtin_sqrt({x})" if dtype == dtypes.float64 else f"__builtin_sqrtf({x})",
|
||||
Ops.TRUNC: lambda x,dtype: f"__builtin_trunc({x})" if dtype == dtypes.float64 else f"__builtin_truncf({x})",
|
||||
Ops.FDIV: lambda a,b,dtype: f"({a}/{b})"}
|
||||
|
||||
# LLVM legalizes double => half/bf16 cast on systems that don't support it natively (like x86 cpus without AVX512-FP16) into a compiler-rt libcall.
|
||||
# there is also no native bfl16 <-> fp16 conversion on those CPUs
|
||||
# LLVM legalizes double => half cast on systems that don't support it natively (like x86 cpus without AVX512-FP16) into a compiler-rt libcall.
|
||||
extra_matcher = PatternMatcher([(UPat.var("x", dtypes.float64).cast(dtypes.float16), lambda x: x.cast(dtypes.float32).cast(dtypes.float16)),
|
||||
(UPat.var("x", dtypes.float64).cast(dtypes.bfloat16), lambda x: x.cast(dtypes.float32).cast(dtypes.bfloat16)),
|
||||
(UPat.var("x", dtypes.bfloat16).cast(dtypes.float16), lambda x: x.cast(dtypes.float32).cast(dtypes.float16)),
|
||||
(UPat((Ops.SQRT, Ops.TRUNC), name="alu"), no_vectorized_alu)]) + CStyleLanguage.extra_matcher
|
||||
|
||||
if sys.platform == 'win32':
|
||||
|
||||
+23
-77
@@ -1,18 +1,21 @@
|
||||
from typing import Callable, cast, Any
|
||||
from tinygrad.dtype import AddrSpace, DType, PtrDType, ImageDType, dtypes
|
||||
from tinygrad.dtype import AddrSpace, DType, PtrDType, dtypes
|
||||
from tinygrad.helpers import DEBUG, OSX, unwrap, charptr
|
||||
from tinygrad.renderer import Renderer
|
||||
from tinygrad.renderer.cstyle import CUDARenderer
|
||||
from tinygrad.uop.ops import GroupOp, Ops, UOp, PatternMatcher, UPat, range_str
|
||||
from tinygrad.runtime.autogen import mesa
|
||||
import base64, ctypes, ctypes.util, struct, functools, inspect, contextlib, itertools
|
||||
import base64, contextlib, ctypes, ctypes.util, struct, functools, inspect
|
||||
|
||||
def g(s:str): return getattr(mesa, s)
|
||||
def nsrc(d:mesa.nir_def) -> mesa.nir_src: return mesa.nir_src(ssa=ctypes.pointer(d))
|
||||
|
||||
def glsl_type(t:DType): return mesa.glsl_array_type(glsl_type(t.base), t.size, 0).contents if isinstance(t, PtrDType) else {
|
||||
**{getattr(dtypes,k):g(f"glsl_type_builtin_{v}") for k,v in [('double','double'),('float','float'),('float16','float16_t'),('bool','uint8_t')]},
|
||||
**{d:g(f"glsl_type_builtin_{'u' * (d in dtypes.uints)}int{str(d.itemsize*8)+'_t' if d.itemsize != 4 else ''}") for d in dtypes.ints}}[t]
|
||||
# this is a ridiculous hack, but I can't find a better way to grab the glsl_type objects
|
||||
glsl_base = {**{d:g(f"GLSL_TYPE_{'U' if d in dtypes.uints else ''}INT{d.itemsize*8 if d.itemsize != 4 else ''}") for d in dtypes.ints},
|
||||
**{getattr(dtypes,d):g(f"GLSL_TYPE_{d.upper()}") for d in ['double', 'float', 'float16']}, dtypes.bool: mesa.GLSL_TYPE_UINT8}
|
||||
def glsl_type(t:DType) -> mesa.struct_glsl_type:
|
||||
if isinstance(t, PtrDType): return mesa.glsl_array_type(glsl_type(t.base), t.size, 0).contents
|
||||
return mesa.glsl_get_base_glsl_type(mesa.glsl_type(base_type=glsl_base[t])).contents
|
||||
|
||||
# alu ops, aop[<dtype>][<op>]
|
||||
u_aop = { Ops.ADD: "iadd", Ops.MUL: "imul", Ops.IDIV: "udiv", Ops.MOD: "umod", Ops.CMPLT: "ult", Ops.CMPNE: "ine", Ops.CMPEQ: "ieq", Ops.OR: "ior",
|
||||
@@ -49,7 +52,7 @@ def nir_instr(nc=1, bs=lambda: None, intrins=None, srcs=None, has_def=True, df=N
|
||||
if has_def: mesa.nir_def_init(instr.contents.instr, getattr(instr.contents, "def"), go(nc), go(bs))
|
||||
for k, v in go(intrins or {}).items():
|
||||
idx = mesa.nir_intrinsic_infos[instr.contents.intrinsic.value].index_map[g(f"NIR_INTRINSIC_{k}")]
|
||||
assert idx > 0, "invalid intrinsic. mesa version mismatch?"
|
||||
assert idx > 0
|
||||
instr.contents.const_index[idx - 1] = go(v)
|
||||
for i, src in enumerate(go(srcs or [])): ctypes.cast(instr.contents.src, ctypes.POINTER(mesa.nir_src))[i] = go(src)
|
||||
for k,v in {k:vcomp for k,v in contents.items() if (vcomp:=go(v)) is not None}.items(): setattr(instr.contents, k, go(v))
|
||||
@@ -67,16 +70,11 @@ def nchannel(b:mesa.nir_builder, src:mesa.nir_def, c:int):
|
||||
ctypes.cast(mov.contents.src, ctypes.POINTER(mesa.nir_alu_src))[0] = alu_src
|
||||
return mov
|
||||
|
||||
def nimm_set(imm:mesa.nir_def, x, dtype:DType):
|
||||
instr = ctypes.cast(imm.parent_instr, ctypes.POINTER(mesa.nir_load_const_instr))
|
||||
struct.pack_into(unwrap(dtype.fmt), (ctypes.c_ubyte * dtype.itemsize).from_address(ctypes.addressof(instr.contents.value)), 0, x)
|
||||
|
||||
@nir_instr(nc=1, bs=lambda dtype: 1 if dtype == dtypes.bool else dtype.itemsize * 8)
|
||||
def nimm(b:mesa.nir_builder, x, dtype:DType) -> mesa.nir_def:
|
||||
nimm_set(getattr((instr:=mesa.nir_load_const_instr_create(b.shader, 1, 1 if dtype==dtypes.bool else dtype.itemsize * 8)).contents, "def"), x, dtype)
|
||||
instr = mesa.nir_load_const_instr_create(b.shader, 1, 1 if dtype == dtypes.bool else dtype.itemsize * 8)
|
||||
struct.pack_into(unwrap(dtype.fmt), (ctypes.c_ubyte * dtype.itemsize).from_address(ctypes.addressof(instr.contents.value)), 0, x)
|
||||
return instr
|
||||
@nir_instr(nc=1, bs=lambda dtype: 1 if dtype == dtypes.bool else dtype.itemsize * 8)
|
||||
def nundef(b, dtype): return mesa.nir_undef_instr_create(b.shader, 1, 1 if dtype == dtypes.bool else dtype.itemsize * 8)
|
||||
|
||||
deref_var = nir_instr(nc=1, bs=32, modes=lambda var:var.data.mode, type=lambda var:var.type, var=lambda var:ctypes.pointer(var))( # pylint: disable=W0108
|
||||
lambda b, var: mesa.nir_deref_instr_create(b.shader, mesa.nir_deref_type_var))
|
||||
@@ -92,8 +90,6 @@ nload = nir_instr(nc=lambda dtype:dtype.count, bs=lambda dtype:dtype.itemsize*8/
|
||||
|
||||
ngid = nir_instr(nc=3, bs=32)(lambda b: mesa.nir_intrinsic_instr_create(b.shader, mesa.nir_intrinsic_load_workgroup_id))
|
||||
nlid = nir_instr(nc=3, bs=32)(lambda b: mesa.nir_intrinsic_instr_create(b.shader, mesa.nir_intrinsic_load_local_invocation_id))
|
||||
ngsz = nir_instr(nc=3, bs=32)(lambda b: mesa.nir_intrinsic_instr_create(b.shader, mesa.nir_intrinsic_load_workgroup_size))
|
||||
def nid(b): return nalu(b, "iadd", nalu(b, "imul", ngid(b), ngsz(b)), nlid(b))
|
||||
|
||||
nbarrier = nir_instr(has_def=False, intrins={"EXECUTION_SCOPE":mesa.SCOPE_WORKGROUP})(
|
||||
lambda b: mesa.nir_intrinsic_instr_create(b.shader, mesa.nir_intrinsic_barrier))
|
||||
@@ -130,16 +126,16 @@ class NIRRenderer(Renderer):
|
||||
(UPat(Ops.STORE, src=(UPat(), UPat(dtype=dtypes.bool)), name="x", allow_any_len=True),
|
||||
lambda x: x.replace(src=x.src[0:1] + (x.src[1].cast(dtypes.uint8),) + x.src[2:])),
|
||||
# load/store use pointer arithmetic, and the cast does nothing
|
||||
(UPat(Ops.INDEX, src=(UPat.var("buf"), UPat.var("off")), allow_any_len=True, name="x"), lambda x,buf,off: x.replace(
|
||||
src=(buf,off.cast(dtypes.long))+x.src[2:]) if buf.dtype.addrspace != AddrSpace.REG and off.op not in (Ops.CAST, Ops.VECTORIZE) else None),
|
||||
(UPat(Ops.INDEX, src=(UPat.var("buf"), UPat.var("off")), allow_any_len=True, name="x"),
|
||||
lambda x,buf,off: x.replace(src=(buf,off.cast(dtypes.long))+x.src[2:]) if buf.dtype.addrspace != AddrSpace.REG and off.op != Ops.CAST else None),
|
||||
(UPat(Ops.CAST, name="x"), lambda x: x.src[0] if isinstance(x.dtype, PtrDType) or x.src[0].dtype == dtypes.void else None),
|
||||
])
|
||||
|
||||
def_rewrite = PatternMatcher([
|
||||
(UPat(Ops.CONST, name="x"), lambda ctx,x: nimm(ctx.b, x.arg, x.dtype)),
|
||||
(UPat(Ops.DEFINE_GLOBAL, name="x"), lambda ctx,x: ctx.param(ctx.b, x, 8)),
|
||||
(UPat(Ops.DEFINE_VAR, name="x"), lambda ctx,x: ctx.param(ctx.b, x, 4)),
|
||||
(UPat(Ops.SPECIAL, name="x"), lambda ctx,x: nchannel(ctx.b, {'g':ngid, 'l':nlid, 'i': nid}[x.arg[0]](ctx.b), int(x.arg[-1]))),
|
||||
(UPat(Ops.DEFINE_GLOBAL, name="x"), lambda ctx,x: ctx.param(ctx.b, x.dtype, 8)),
|
||||
(UPat(Ops.DEFINE_VAR, name="x"), lambda ctx,x: ctx.param(ctx.b, x.dtype, 4)),
|
||||
(UPat(Ops.SPECIAL, name="x"), lambda ctx,x: nchannel(ctx.b, ngid(ctx.b) if x.arg[0] == 'g' else nlid(ctx.b), int(x.arg[-1]))),
|
||||
(UPat(Ops.STORE, src=(UPat(Ops.INDEX, src=(UPat.var("buf"),UPat.var("off")), allow_any_len=True), UPat.var("val")), allow_any_len=True, name="x"),
|
||||
lambda ctx,x,buf,off,val: nstore(ctx.b, buf.ptrdtype.addrspace, nidx(ctx.b, ctx.r[buf], ctx.r[off], buf.dtype), ctx.r[val], val.dtype)),
|
||||
(UPat(Ops.LOAD, src=(UPat(Ops.INDEX, src=(UPat.var("buf"), UPat.var("off"), UPat.var("gate"))), UPat.var("alt")), allow_any_len=True, name="x"),
|
||||
@@ -161,15 +157,13 @@ class NIRRenderer(Renderer):
|
||||
def __init__(self): mesa.glsl_type_singleton_init_or_ref()
|
||||
|
||||
def __del__(self):
|
||||
with contextlib.suppress(AttributeError): mesa.glsl_type_singleton_decref()
|
||||
with contextlib.suppress(AttributeError):mesa.glsl_type_singleton_decref()
|
||||
|
||||
@property
|
||||
def nir_options(self): raise NotImplementedError("needs nir_options")
|
||||
def param(self, b:mesa.nir_builder, x, sz:int) -> mesa.nir_def: raise NotImplementedError("needs param")
|
||||
def param(self, b:mesa.nir_builder, dtype:DType, sz:int) -> mesa.nir_def: raise NotImplementedError("needs param")
|
||||
def prerender(self, uops:list[UOp]):
|
||||
self.b = mesa.nir_builder_init_simple_shader(mesa.MESA_SHADER_COMPUTE, mesa.nir_shader_compiler_options.from_buffer_copy(self.nir_options), None)
|
||||
self.b.shader.contents.info.workgroup_size_variable = any([u.op == Ops.SPECIAL and u.arg[0] == 'i' for u in uops])
|
||||
def postrender(self, uops:list[UOp]): pass
|
||||
|
||||
def render(self, uops:list[UOp]):
|
||||
self.prerender(uops)
|
||||
@@ -202,7 +196,6 @@ class NIRRenderer(Renderer):
|
||||
else:
|
||||
if (d:=self.def_rewrite.rewrite(u, ctx=self)) is None: raise RuntimeError(f"failed to render {u.op} srcs {[x.dtype for x in u.src]}")
|
||||
self.r[u] = cast(mesa.nir_def, d)
|
||||
self.postrender(uops)
|
||||
|
||||
mesa.nir_validate_shader(self.b.shader, b"after render")
|
||||
if DEBUG >= 4: mesa.nir_print_shader(self.b.shader, ctypes.POINTER(mesa.struct__IO_FILE).in_dll(ctypes.CDLL(ctypes.util.find_library('c')),
|
||||
@@ -216,23 +209,22 @@ class NIRRenderer(Renderer):
|
||||
|
||||
return ret
|
||||
|
||||
class NIRRendererWithOpts(NIRRenderer):
|
||||
class NAKRenderer(NIRRenderer):
|
||||
device = "NV"
|
||||
def __init__(self, dev=None, nir_options=None):
|
||||
self.dev, self._nir_options = dev, nir_options
|
||||
super().__init__()
|
||||
|
||||
def __reduce__(self): return self.__class__, (None, self.nir_options)
|
||||
def __reduce__(self): return NAKRenderer, (None, self.nir_options,)
|
||||
|
||||
@property
|
||||
def nir_options(self):
|
||||
if self._nir_options is None: self._nir_options = self.dev.compiler.nir_options
|
||||
return self._nir_options
|
||||
|
||||
class NAKRenderer(NIRRendererWithOpts):
|
||||
device = "NV"
|
||||
param = nir_instr(nc=1, num_components=1, bs=lambda sz:sz*8, also=lambda self,sz: setattr(self, "param_idx", self.param_idx + sz),
|
||||
intrins={"ALIGN_MUL":lambda sz:sz}, srcs=lambda self,b: [nsrc(nimm(b, 0, dtypes.int)), nsrc(nimm(b, self.param_idx, dtypes.int))])(
|
||||
lambda self, b, x, sz: mesa.nir_intrinsic_instr_create(b.shader, mesa.nir_intrinsic_ldc_nv))
|
||||
lambda self, b, dtype, sz: mesa.nir_intrinsic_instr_create(b.shader, mesa.nir_intrinsic_ldc_nv))
|
||||
|
||||
class LVPRenderer(NIRRenderer):
|
||||
device = "CPU"
|
||||
@@ -243,55 +235,9 @@ class LVPRenderer(NIRRenderer):
|
||||
|
||||
param = nir_instr(nc=1, bs=lambda sz: sz * 8, num_components=1, intrins={"ALIGN_MUL":lambda sz: sz, "RANGE":lambda self: self.param_sz},
|
||||
srcs=lambda b, self: [nsrc(nimm(b, 0, dtypes.int)), nsrc(nimm(b, self.param_idx, dtypes.int))], also=lambda self, sz:
|
||||
setattr(self, "param_idx", self.param_idx+sz))(lambda self,b,x,sz: mesa.nir_intrinsic_instr_create(b.shader, mesa.nir_intrinsic_load_ubo))
|
||||
setattr(self, "param_idx", self.param_idx+sz))(lambda self, b, dtype, sz: mesa.nir_intrinsic_instr_create(b.shader, mesa.nir_intrinsic_load_ubo))
|
||||
|
||||
def prerender(self, uops:list[UOp]):
|
||||
super().prerender(uops)
|
||||
self.param_sz = sum([8 if u.op == Ops.DEFINE_GLOBAL else u.dtype.itemsize for u in uops if u.op in (Ops.DEFINE_GLOBAL, Ops.DEFINE_VAR)])
|
||||
|
||||
# FIXME: this should be a rewrite rule
|
||||
def tovec(b, coord): return nalu(b, "vec4", nchannel(b, coord, 0), nchannel(b, coord, 1), nundef(b, dtypes.int), nundef(b, dtypes.int))
|
||||
def nfloat(dtype): return mesa.nir_type_float16 if dtype == dtypes.half else mesa.nir_type_float32
|
||||
nstore_img = nir_instr(has_def=False, df=lambda img:img, num_components=lambda val:val.num_components,
|
||||
intrins=lambda dtype:{'IMAGE_DIM':mesa.GLSL_SAMPLER_DIM_2D, 'ACCESS':mesa.ACCESS_CAN_REORDER, 'SRC_TYPE':nfloat(dtype)},
|
||||
srcs=lambda b,img,coord,val:[nsrc(x) for x in [img, tovec(b, coord), nundef(b, dtypes.int), val, nimm(b, 0, dtypes.int)]])(
|
||||
lambda b,img,coord,val,dtype:mesa.nir_intrinsic_instr_create(b.shader,g("nir_intrinsic_image_store")))
|
||||
|
||||
_nload_img = nir_instr(intrins=lambda dtype:{'IMAGE_DIM':mesa.GLSL_SAMPLER_DIM_2D, 'ACCESS':mesa.ACCESS_CAN_REORDER, 'DEST_TYPE':nfloat(dtype)},
|
||||
nc=4, bs=32, num_components=4, srcs=lambda b,img,coord:[nsrc(x) for x in [img, tovec(b, coord), nundef(b, dtypes.int), nimm(b, 0, dtypes.int)]])(
|
||||
lambda b,img,coord,dtype: mesa.nir_intrinsic_instr_create(b.shader, g("nir_intrinsic_image_load")))
|
||||
|
||||
class IR3Renderer(NIRRendererWithOpts):
|
||||
device = "QCOM"
|
||||
|
||||
def nload_img(ctx,img,coord):
|
||||
ctx.texs.add(img)
|
||||
return _nload_img(ctx.b, ctx.r[img], ctx.r[coord], img.dtype)
|
||||
|
||||
def_rewrite = PatternMatcher([
|
||||
(UPat(Ops.STORE, src=(UPat.var('img').index(UPat.var('coord', dtypes.int.vec(2)), allow_any_len=True), UPat.var("val")),
|
||||
allow_any_len=True), lambda ctx,img,coord,val: nstore_img(ctx.b, ctx.r[img], ctx.r[coord], ctx.r[val], val.dtype)),
|
||||
(UPat(Ops.LOAD, src=(UPat.var('img').index(UPat.var('coord', dtypes.int.vec(2)), UPat.var("gate")), UPat.var("alt"))),
|
||||
lambda ctx,img,coord,alt,gate: if_phi(ctx.b, ctx.r[gate], lambda: ctx.nload_img(img, coord), lambda: ctx.r[alt])),
|
||||
(UPat(Ops.LOAD, src=(UPat.var('img').index(UPat.var('coord', dtypes.int.vec(2))),)), nload_img),
|
||||
]) + NIRRenderer.def_rewrite
|
||||
|
||||
_param = LVPRenderer.param
|
||||
def _param_img(self, x):
|
||||
self.img_idx += 1
|
||||
return nimm(self.b, self.img_idx - 1, dtypes.int)
|
||||
|
||||
def param(self, b, x, sz): return self._param_img(x) if isinstance(x.dtype, ImageDType) else self._param(b, x, sz)
|
||||
|
||||
def prerender(self, uops:list[UOp]):
|
||||
super().prerender(uops)
|
||||
self.texs:set[UOp] = set()
|
||||
self.uops, self.ibo_idx, self.img_idx = uops, 0, 0
|
||||
self.param_sz = sum([8 if u.op == Ops.DEFINE_GLOBAL else u.dtype.itemsize for u in uops if u.op in (Ops.DEFINE_GLOBAL, Ops.DEFINE_VAR)])
|
||||
|
||||
def postrender(self, uops:list[UOp]):
|
||||
bufs, texs, imgs = [u for u in uops if u.op == Ops.DEFINE_GLOBAL], itertools.count().__next__, itertools.count().__next__
|
||||
for b in filter(lambda b: isinstance(b.dtype, ImageDType), bufs): nimm_set(self.r[b], texs() if b in self.texs else imgs(), dtypes.int)
|
||||
|
||||
self.b.shader.contents.info.num_ubos = len([u for u in bufs if not isinstance(u.dtype, ImageDType)])
|
||||
self.b.shader.contents.info.num_images = texs() + imgs()
|
||||
|
||||
@@ -99,6 +99,7 @@ def __getattr__(nm):
|
||||
"sienna_cichlid_ip_offset"]],
|
||||
args=["-I/opt/rocm/include", "-x", "c++"])
|
||||
case "kgsl": return load("kgsl", [], [root/"extra/qcom_gpu_driver/msm_kgsl.h"], args=["-D__user="])
|
||||
case "adreno": return load("adreno", [], [root/"extra/qcom_gpu_driver/a6xx.xml.h"])
|
||||
case "qcom_dsp":
|
||||
return load("qcom_dsp", [], [root/f"extra/dsp/include/{s}.h" for s in ["ion", "msm_ion", "adsprpc_shared", "remote_default", "apps_std"]])
|
||||
case "sqtt": return load("sqtt", [], [root/"extra/sqtt/sqtt.h"])
|
||||
@@ -113,20 +114,18 @@ def __getattr__(nm):
|
||||
*[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",
|
||||
"_flow", "_const"]],
|
||||
*[f"{{}}/src/freedreno/{s}.h" for s in ["common/freedreno_dev_info", "ir3/ir3_compiler", "ir3/ir3_shader", "ir3/ir3_nir"]],
|
||||
"{}/src/compiler/glsl_types.h", "{}/src/util/blob.h", "{}/src/util/ralloc.h", "{}/gen/ir3-isa.h", "{}/gen/builtin_types.h",
|
||||
"{}/gen/a6xx.xml.h", "{}/gen/adreno_pm4.xml.h", "{}/gen/a6xx_enums.xml.h", "{}/gen/a6xx_descriptors.xml.h"], args=lambda:[
|
||||
"{}/src/compiler/glsl_types.h", "{}/src/util/blob.h", "{}/src/util/ralloc.h"], args=lambda:[
|
||||
"-DHAVE_ENDIAN_H", "-DHAVE_STRUCT_TIMESPEC", "-DHAVE_PTHREAD", "-DHAVE_FUNC_ATTRIBUTE_PACKED", "-I{}/src", "-I{}/include", "-I{}/gen",
|
||||
"-I{}/src/compiler/nir", "-I{}/src/gallium/auxiliary", "-I{}/src/gallium/include", "-I{}/src/freedreno/common",
|
||||
f"-I{system('llvm-config-20 --includedir')}"],
|
||||
preprocess=lambda path: subprocess.run("\n".join(["mkdir -p gen/util/format", "python3 src/compiler/builtin_types_h.py gen/builtin_types.h",
|
||||
"python3 src/compiler/isaspec/decode.py --xml src/freedreno/isa/ir3.xml --out-c /dev/null --out-h gen/ir3-isa.h",
|
||||
"python3 src/util/format/u_format_table.py src/util/format/u_format.yaml --enums > gen/util/format/u_format_gen.h",
|
||||
*["python3 src/freedreno/registers/gen_header.py --rnn src/freedreno/registers/ --xml " +
|
||||
f"src/freedreno/registers/adreno/{s}.xml c-defines > gen/{s}.xml.h" for s in ["a6xx", "adreno_pm4", "a6xx_enums", "a6xx_descriptors"]],
|
||||
*[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),
|
||||
tarball="https://gitlab.freedesktop.org/mesa/mesa/-/archive/mesa-25.2.7/mesa-25.2.7.tar.gz",
|
||||
"-I{}/src/compiler/nir", "-I{}/src/gallium/auxiliary", "-I{}/src/gallium/include", f"-I{system('llvm-config-20 --includedir')}"],
|
||||
preprocess=lambda path: subprocess.run("""mkdir -p gen/util/format
|
||||
python3 src/util/format/u_format_table.py src/util/format/u_format.yaml --enums > gen/util/format/u_format_gen.h
|
||||
python3 src/compiler/nir/nir_opcodes_h.py > gen/nir_opcodes.h
|
||||
python3 src/compiler/nir/nir_intrinsics_h.py --outdir gen
|
||||
python3 src/compiler/nir/nir_intrinsics_indices_h.py --outdir gen
|
||||
python3 src/compiler/nir/nir_builder_opcodes_h.py > gen/nir_builder_opcodes.h
|
||||
python3 src/compiler/nir/nir_intrinsics_h.py --outdir gen
|
||||
python3 src/compiler/builtin_types_h.py gen/builtin_types.h""", cwd=path, shell=True, check=True),
|
||||
tarball="https://gitlab.freedesktop.org/mesa/mesa/-/archive/mesa-25.2.4/mesa-25.2.4.tar.gz",
|
||||
prolog=["import gzip, base64", "from tinygrad.helpers import OSX"], epilog=lambda path: [system(f"{root}/extra/mesa/lvp_nir_options.sh {path}")])
|
||||
case "libclang":
|
||||
return load("libclang", ["os.getenv('LIBCLANG_PATH', find_library('clang-20'))"],
|
||||
@@ -136,4 +135,4 @@ def __getattr__(nm):
|
||||
return load("metal", ["find_library('Metal')"],[f"{macossdk}/System/Library/Frameworks/Metal.framework/Headers/MTL{s}.h" for s in
|
||||
["ComputeCommandEncoder", "ComputePipeline", "CommandQueue", "Device", "IndirectCommandBuffer", "Resource", "CommandEncoder"]],
|
||||
args=["-xobjective-c","-isysroot",macossdk], types={"dispatch_data_t":"objc.id_"})
|
||||
case _: raise AttributeError(f"no such autogen: {nm}")
|
||||
case _: raise AttributeError(f"no such autogen: {nm}")
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,21 +6,18 @@ inc = ["-include", "stdint.h"]
|
||||
|
||||
def __getattr__(nm):
|
||||
match nm:
|
||||
case "am": return load("am/am", [], [root/f"extra/amdpci/headers/{s}.h" for s in ["v11_structs", "v12_structs", "amdgpu_vm",
|
||||
"discovery", "amdgpu_ucode", "psp_gfx_if", "amdgpu_psp", "amdgpu_irq", "amdgpu_doorbell"]] + \
|
||||
[f"{AMD}/include/{s}.h" for s in ["v9_structs", "soc15_ih_clientid"]], args=inc, tarball=am_src)
|
||||
case "am": return load("am/am", [], [root/f"extra/amdpci/headers/{s}.h" for s in ["v11_structs", "v12_structs", "amdgpu_vm", "discovery",
|
||||
"amdgpu_ucode", "psp_gfx_if", "amdgpu_psp", "amdgpu_irq", "amdgpu_doorbell"]]+[f"{AMD}/include/soc15_ih_clientid.h"], args=inc, tarball=am_src)
|
||||
case "pm4_soc15": return load("am/pm4_soc15", [], [f"{AMD}/amdkfd/kfd_pm4_headers_ai.h", f"{AMD}/amdgpu/soc15d.h"], tarball=am_src)
|
||||
case "pm4_nv": return load("am/pm4_nv", [], [f"{AMD}/amdkfd/kfd_pm4_headers_ai.h", f"{AMD}/amdgpu/nvd.h"], tarball=am_src)
|
||||
case "sdma_4_0_0": return load("am/sdma_4_0_0", [], [root/"extra/hip_gpu_driver/sdma_registers.h", f"{AMD}/amdgpu/vega10_sdma_pkt_open.h"],
|
||||
args=["-I/opt/rocm/include", "-x", "c++"], tarball=am_src)
|
||||
args=["-I/opt/rocm/include", "-x", "c++"], tarball=am_src),
|
||||
case "sdma_5_0_0": return load("am/sdma_5_0_0", [], [root/"extra/hip_gpu_driver/sdma_registers.h", f"{AMD}/amdgpu/navi10_sdma_pkt_open.h"],
|
||||
args=["-I/opt/rocm/include", "-x", "c++"], tarball=am_src)
|
||||
case "sdma_6_0_0": return load("am/sdma_6_0_0", [], [root/"extra/hip_gpu_driver/sdma_registers.h", f"{AMD}/amdgpu/sdma_v6_0_0_pkt_open.h"],
|
||||
args=["-I/opt/rocm/include", "-x", "c++"], tarball=am_src)
|
||||
args=["-I/opt/rocm/include", "-x", "c++"], tarball=am_src),
|
||||
case "sdma_6_0_0": return load("am/sdma_6_0_0", [], [root/"extra/hip_gpu_driver/sdma_registers.h", f"{AMD}//amdgpu/sdma_v6_0_0_pkt_open.h"],
|
||||
args=["-I/opt/rocm/include", "-x", "c++"], tarball=am_src),
|
||||
case "smu_v13_0_0": return load("am/smu_v13_0_0",[],[f"{AMD}/pm/swsmu/inc/pmfw_if/{s}.h" for s in ["smu_v13_0_0_ppsmc","smu13_driver_if_v13_0_0"]]
|
||||
+[root/"extra/amdpci/headers/amdgpu_smu.h"], args=inc, tarball=am_src)
|
||||
case "smu_v13_0_6": return load("am/smu_v13_0_6",[],[f"{AMD}/pm/swsmu/inc/pmfw_if/{s}.h" for s in ["smu_v13_0_6_ppsmc","smu13_driver_if_v13_0_6"]]
|
||||
+[root/"extra/amdpci/headers/amdgpu_smu.h"], args=inc, tarball=am_src)
|
||||
+[root/"extra/amdpci/headers/amdgpu_smu.h"], tarball=am_src),
|
||||
case "smu_v14_0_2": return load("am/smu_v14_0_2", [], [f"{AMD}/pm/swsmu/inc/pmfw_if/{s}.h" for s in ["smu_v14_0_0_pmfw", "smu_v14_0_2_ppsmc",
|
||||
"smu14_driver_if_v14_0"]]+[root/"extra/amdpci/headers/amdgpu_smu.h"], args=inc, tarball=am_src)
|
||||
case _: raise AttributeError(f"no such autogen: {nm}")
|
||||
|
||||
@@ -3878,745 +3878,6 @@ AMDGPU_DOORBELL_LAYOUT1_LAST_NON_CP = enum_AMDGPU_DOORBELL_ASSIGNMENT_LAYOUT1.de
|
||||
AMDGPU_DOORBELL_LAYOUT1_MAX_ASSIGNMENT = enum_AMDGPU_DOORBELL_ASSIGNMENT_LAYOUT1.define('AMDGPU_DOORBELL_LAYOUT1_MAX_ASSIGNMENT', 488)
|
||||
AMDGPU_DOORBELL_LAYOUT1_INVALID = enum_AMDGPU_DOORBELL_ASSIGNMENT_LAYOUT1.define('AMDGPU_DOORBELL_LAYOUT1_INVALID', 65535)
|
||||
|
||||
class struct_v9_sdma_mqd(Struct): pass
|
||||
struct_v9_sdma_mqd._fields_ = [
|
||||
('sdmax_rlcx_rb_cntl', uint32_t),
|
||||
('sdmax_rlcx_rb_base', uint32_t),
|
||||
('sdmax_rlcx_rb_base_hi', uint32_t),
|
||||
('sdmax_rlcx_rb_rptr', uint32_t),
|
||||
('sdmax_rlcx_rb_rptr_hi', uint32_t),
|
||||
('sdmax_rlcx_rb_wptr', uint32_t),
|
||||
('sdmax_rlcx_rb_wptr_hi', uint32_t),
|
||||
('sdmax_rlcx_rb_wptr_poll_cntl', uint32_t),
|
||||
('sdmax_rlcx_rb_rptr_addr_hi', uint32_t),
|
||||
('sdmax_rlcx_rb_rptr_addr_lo', uint32_t),
|
||||
('sdmax_rlcx_ib_cntl', uint32_t),
|
||||
('sdmax_rlcx_ib_rptr', uint32_t),
|
||||
('sdmax_rlcx_ib_offset', uint32_t),
|
||||
('sdmax_rlcx_ib_base_lo', uint32_t),
|
||||
('sdmax_rlcx_ib_base_hi', uint32_t),
|
||||
('sdmax_rlcx_ib_size', uint32_t),
|
||||
('sdmax_rlcx_skip_cntl', uint32_t),
|
||||
('sdmax_rlcx_context_status', uint32_t),
|
||||
('sdmax_rlcx_doorbell', uint32_t),
|
||||
('sdmax_rlcx_status', uint32_t),
|
||||
('sdmax_rlcx_doorbell_log', uint32_t),
|
||||
('sdmax_rlcx_watermark', uint32_t),
|
||||
('sdmax_rlcx_doorbell_offset', uint32_t),
|
||||
('sdmax_rlcx_csa_addr_lo', uint32_t),
|
||||
('sdmax_rlcx_csa_addr_hi', uint32_t),
|
||||
('sdmax_rlcx_ib_sub_remain', uint32_t),
|
||||
('sdmax_rlcx_preempt', uint32_t),
|
||||
('sdmax_rlcx_dummy_reg', uint32_t),
|
||||
('sdmax_rlcx_rb_wptr_poll_addr_hi', uint32_t),
|
||||
('sdmax_rlcx_rb_wptr_poll_addr_lo', uint32_t),
|
||||
('sdmax_rlcx_rb_aql_cntl', uint32_t),
|
||||
('sdmax_rlcx_minor_ptr_update', uint32_t),
|
||||
('sdmax_rlcx_midcmd_data0', uint32_t),
|
||||
('sdmax_rlcx_midcmd_data1', uint32_t),
|
||||
('sdmax_rlcx_midcmd_data2', uint32_t),
|
||||
('sdmax_rlcx_midcmd_data3', uint32_t),
|
||||
('sdmax_rlcx_midcmd_data4', uint32_t),
|
||||
('sdmax_rlcx_midcmd_data5', uint32_t),
|
||||
('sdmax_rlcx_midcmd_data6', uint32_t),
|
||||
('sdmax_rlcx_midcmd_data7', uint32_t),
|
||||
('sdmax_rlcx_midcmd_data8', uint32_t),
|
||||
('sdmax_rlcx_midcmd_cntl', uint32_t),
|
||||
('reserved_42', uint32_t),
|
||||
('reserved_43', uint32_t),
|
||||
('reserved_44', uint32_t),
|
||||
('reserved_45', uint32_t),
|
||||
('reserved_46', uint32_t),
|
||||
('reserved_47', uint32_t),
|
||||
('reserved_48', uint32_t),
|
||||
('reserved_49', uint32_t),
|
||||
('reserved_50', uint32_t),
|
||||
('reserved_51', uint32_t),
|
||||
('reserved_52', uint32_t),
|
||||
('reserved_53', uint32_t),
|
||||
('reserved_54', uint32_t),
|
||||
('reserved_55', uint32_t),
|
||||
('reserved_56', uint32_t),
|
||||
('reserved_57', uint32_t),
|
||||
('reserved_58', uint32_t),
|
||||
('reserved_59', uint32_t),
|
||||
('reserved_60', uint32_t),
|
||||
('reserved_61', uint32_t),
|
||||
('reserved_62', uint32_t),
|
||||
('reserved_63', uint32_t),
|
||||
('reserved_64', uint32_t),
|
||||
('reserved_65', uint32_t),
|
||||
('reserved_66', uint32_t),
|
||||
('reserved_67', uint32_t),
|
||||
('reserved_68', uint32_t),
|
||||
('reserved_69', uint32_t),
|
||||
('reserved_70', uint32_t),
|
||||
('reserved_71', uint32_t),
|
||||
('reserved_72', uint32_t),
|
||||
('reserved_73', uint32_t),
|
||||
('reserved_74', uint32_t),
|
||||
('reserved_75', uint32_t),
|
||||
('reserved_76', uint32_t),
|
||||
('reserved_77', uint32_t),
|
||||
('reserved_78', uint32_t),
|
||||
('reserved_79', uint32_t),
|
||||
('reserved_80', uint32_t),
|
||||
('reserved_81', uint32_t),
|
||||
('reserved_82', uint32_t),
|
||||
('reserved_83', uint32_t),
|
||||
('reserved_84', uint32_t),
|
||||
('reserved_85', uint32_t),
|
||||
('reserved_86', uint32_t),
|
||||
('reserved_87', uint32_t),
|
||||
('reserved_88', uint32_t),
|
||||
('reserved_89', uint32_t),
|
||||
('reserved_90', uint32_t),
|
||||
('reserved_91', uint32_t),
|
||||
('reserved_92', uint32_t),
|
||||
('reserved_93', uint32_t),
|
||||
('reserved_94', uint32_t),
|
||||
('reserved_95', uint32_t),
|
||||
('reserved_96', uint32_t),
|
||||
('reserved_97', uint32_t),
|
||||
('reserved_98', uint32_t),
|
||||
('reserved_99', uint32_t),
|
||||
('reserved_100', uint32_t),
|
||||
('reserved_101', uint32_t),
|
||||
('reserved_102', uint32_t),
|
||||
('reserved_103', uint32_t),
|
||||
('reserved_104', uint32_t),
|
||||
('reserved_105', uint32_t),
|
||||
('reserved_106', uint32_t),
|
||||
('reserved_107', uint32_t),
|
||||
('reserved_108', uint32_t),
|
||||
('reserved_109', uint32_t),
|
||||
('reserved_110', uint32_t),
|
||||
('reserved_111', uint32_t),
|
||||
('reserved_112', uint32_t),
|
||||
('reserved_113', uint32_t),
|
||||
('reserved_114', uint32_t),
|
||||
('reserved_115', uint32_t),
|
||||
('reserved_116', uint32_t),
|
||||
('reserved_117', uint32_t),
|
||||
('reserved_118', uint32_t),
|
||||
('reserved_119', uint32_t),
|
||||
('reserved_120', uint32_t),
|
||||
('reserved_121', uint32_t),
|
||||
('reserved_122', uint32_t),
|
||||
('reserved_123', uint32_t),
|
||||
('reserved_124', uint32_t),
|
||||
('reserved_125', uint32_t),
|
||||
('sdma_engine_id', uint32_t),
|
||||
('sdma_queue_id', uint32_t),
|
||||
]
|
||||
class struct_v9_mqd(Struct): pass
|
||||
class struct_v9_mqd_0(ctypes.Union): pass
|
||||
class struct_v9_mqd_0_0(Struct): pass
|
||||
struct_v9_mqd_0_0._fields_ = [
|
||||
('compute_static_thread_mgmt_se4', uint32_t),
|
||||
('compute_static_thread_mgmt_se5', uint32_t),
|
||||
('compute_static_thread_mgmt_se6', uint32_t),
|
||||
('compute_static_thread_mgmt_se7', uint32_t),
|
||||
]
|
||||
class struct_v9_mqd_0_1(Struct): pass
|
||||
struct_v9_mqd_0_1._fields_ = [
|
||||
('compute_current_logic_xcc_id', uint32_t),
|
||||
('compute_restart_cg_tg_id', uint32_t),
|
||||
('compute_tg_chunk_size', uint32_t),
|
||||
('compute_restore_tg_chunk_size', uint32_t),
|
||||
]
|
||||
struct_v9_mqd_0._anonymous_ = ['_0', '_1']
|
||||
struct_v9_mqd_0._fields_ = [
|
||||
('_0', struct_v9_mqd_0_0),
|
||||
('_1', struct_v9_mqd_0_1),
|
||||
]
|
||||
class struct_v9_mqd_1(ctypes.Union): pass
|
||||
class struct_v9_mqd_1_0(Struct): pass
|
||||
struct_v9_mqd_1_0._fields_ = [
|
||||
('reserved_225', uint32_t),
|
||||
('reserved_226', uint32_t),
|
||||
]
|
||||
class struct_v9_mqd_1_1(Struct): pass
|
||||
struct_v9_mqd_1_1._fields_ = [
|
||||
('pm4_target_xcc_in_xcp', uint32_t),
|
||||
('cp_mqd_stride_size', uint32_t),
|
||||
]
|
||||
struct_v9_mqd_1._anonymous_ = ['_0', '_1']
|
||||
struct_v9_mqd_1._fields_ = [
|
||||
('_0', struct_v9_mqd_1_0),
|
||||
('_1', struct_v9_mqd_1_1),
|
||||
]
|
||||
struct_v9_mqd._anonymous_ = ['_0', '_1']
|
||||
struct_v9_mqd._fields_ = [
|
||||
('header', uint32_t),
|
||||
('compute_dispatch_initiator', uint32_t),
|
||||
('compute_dim_x', uint32_t),
|
||||
('compute_dim_y', uint32_t),
|
||||
('compute_dim_z', uint32_t),
|
||||
('compute_start_x', uint32_t),
|
||||
('compute_start_y', uint32_t),
|
||||
('compute_start_z', uint32_t),
|
||||
('compute_num_thread_x', uint32_t),
|
||||
('compute_num_thread_y', uint32_t),
|
||||
('compute_num_thread_z', uint32_t),
|
||||
('compute_pipelinestat_enable', uint32_t),
|
||||
('compute_perfcount_enable', uint32_t),
|
||||
('compute_pgm_lo', uint32_t),
|
||||
('compute_pgm_hi', uint32_t),
|
||||
('compute_tba_lo', uint32_t),
|
||||
('compute_tba_hi', uint32_t),
|
||||
('compute_tma_lo', uint32_t),
|
||||
('compute_tma_hi', uint32_t),
|
||||
('compute_pgm_rsrc1', uint32_t),
|
||||
('compute_pgm_rsrc2', uint32_t),
|
||||
('compute_vmid', uint32_t),
|
||||
('compute_resource_limits', uint32_t),
|
||||
('compute_static_thread_mgmt_se0', uint32_t),
|
||||
('compute_static_thread_mgmt_se1', uint32_t),
|
||||
('compute_tmpring_size', uint32_t),
|
||||
('compute_static_thread_mgmt_se2', uint32_t),
|
||||
('compute_static_thread_mgmt_se3', uint32_t),
|
||||
('compute_restart_x', uint32_t),
|
||||
('compute_restart_y', uint32_t),
|
||||
('compute_restart_z', uint32_t),
|
||||
('compute_thread_trace_enable', uint32_t),
|
||||
('compute_misc_reserved', uint32_t),
|
||||
('compute_dispatch_id', uint32_t),
|
||||
('compute_threadgroup_id', uint32_t),
|
||||
('compute_relaunch', uint32_t),
|
||||
('compute_wave_restore_addr_lo', uint32_t),
|
||||
('compute_wave_restore_addr_hi', uint32_t),
|
||||
('compute_wave_restore_control', uint32_t),
|
||||
('_0', struct_v9_mqd_0),
|
||||
('reserved_43', uint32_t),
|
||||
('reserved_44', uint32_t),
|
||||
('reserved_45', uint32_t),
|
||||
('reserved_46', uint32_t),
|
||||
('reserved_47', uint32_t),
|
||||
('reserved_48', uint32_t),
|
||||
('reserved_49', uint32_t),
|
||||
('reserved_50', uint32_t),
|
||||
('reserved_51', uint32_t),
|
||||
('reserved_52', uint32_t),
|
||||
('reserved_53', uint32_t),
|
||||
('reserved_54', uint32_t),
|
||||
('reserved_55', uint32_t),
|
||||
('reserved_56', uint32_t),
|
||||
('reserved_57', uint32_t),
|
||||
('reserved_58', uint32_t),
|
||||
('reserved_59', uint32_t),
|
||||
('reserved_60', uint32_t),
|
||||
('reserved_61', uint32_t),
|
||||
('reserved_62', uint32_t),
|
||||
('reserved_63', uint32_t),
|
||||
('reserved_64', uint32_t),
|
||||
('compute_user_data_0', uint32_t),
|
||||
('compute_user_data_1', uint32_t),
|
||||
('compute_user_data_2', uint32_t),
|
||||
('compute_user_data_3', uint32_t),
|
||||
('compute_user_data_4', uint32_t),
|
||||
('compute_user_data_5', uint32_t),
|
||||
('compute_user_data_6', uint32_t),
|
||||
('compute_user_data_7', uint32_t),
|
||||
('compute_user_data_8', uint32_t),
|
||||
('compute_user_data_9', uint32_t),
|
||||
('compute_user_data_10', uint32_t),
|
||||
('compute_user_data_11', uint32_t),
|
||||
('compute_user_data_12', uint32_t),
|
||||
('compute_user_data_13', uint32_t),
|
||||
('compute_user_data_14', uint32_t),
|
||||
('compute_user_data_15', uint32_t),
|
||||
('cp_compute_csinvoc_count_lo', uint32_t),
|
||||
('cp_compute_csinvoc_count_hi', uint32_t),
|
||||
('reserved_83', uint32_t),
|
||||
('reserved_84', uint32_t),
|
||||
('reserved_85', uint32_t),
|
||||
('cp_mqd_query_time_lo', uint32_t),
|
||||
('cp_mqd_query_time_hi', uint32_t),
|
||||
('cp_mqd_connect_start_time_lo', uint32_t),
|
||||
('cp_mqd_connect_start_time_hi', uint32_t),
|
||||
('cp_mqd_connect_end_time_lo', uint32_t),
|
||||
('cp_mqd_connect_end_time_hi', uint32_t),
|
||||
('cp_mqd_connect_end_wf_count', uint32_t),
|
||||
('cp_mqd_connect_end_pq_rptr', uint32_t),
|
||||
('cp_mqd_connect_end_pq_wptr', uint32_t),
|
||||
('cp_mqd_connect_end_ib_rptr', uint32_t),
|
||||
('cp_mqd_readindex_lo', uint32_t),
|
||||
('cp_mqd_readindex_hi', uint32_t),
|
||||
('cp_mqd_save_start_time_lo', uint32_t),
|
||||
('cp_mqd_save_start_time_hi', uint32_t),
|
||||
('cp_mqd_save_end_time_lo', uint32_t),
|
||||
('cp_mqd_save_end_time_hi', uint32_t),
|
||||
('cp_mqd_restore_start_time_lo', uint32_t),
|
||||
('cp_mqd_restore_start_time_hi', uint32_t),
|
||||
('cp_mqd_restore_end_time_lo', uint32_t),
|
||||
('cp_mqd_restore_end_time_hi', uint32_t),
|
||||
('disable_queue', uint32_t),
|
||||
('reserved_107', uint32_t),
|
||||
('gds_cs_ctxsw_cnt0', uint32_t),
|
||||
('gds_cs_ctxsw_cnt1', uint32_t),
|
||||
('gds_cs_ctxsw_cnt2', uint32_t),
|
||||
('gds_cs_ctxsw_cnt3', uint32_t),
|
||||
('reserved_112', uint32_t),
|
||||
('reserved_113', uint32_t),
|
||||
('cp_pq_exe_status_lo', uint32_t),
|
||||
('cp_pq_exe_status_hi', uint32_t),
|
||||
('cp_packet_id_lo', uint32_t),
|
||||
('cp_packet_id_hi', uint32_t),
|
||||
('cp_packet_exe_status_lo', uint32_t),
|
||||
('cp_packet_exe_status_hi', uint32_t),
|
||||
('gds_save_base_addr_lo', uint32_t),
|
||||
('gds_save_base_addr_hi', uint32_t),
|
||||
('gds_save_mask_lo', uint32_t),
|
||||
('gds_save_mask_hi', uint32_t),
|
||||
('ctx_save_base_addr_lo', uint32_t),
|
||||
('ctx_save_base_addr_hi', uint32_t),
|
||||
('dynamic_cu_mask_addr_lo', uint32_t),
|
||||
('dynamic_cu_mask_addr_hi', uint32_t),
|
||||
('cp_mqd_base_addr_lo', uint32_t),
|
||||
('cp_mqd_base_addr_hi', uint32_t),
|
||||
('cp_hqd_active', uint32_t),
|
||||
('cp_hqd_vmid', uint32_t),
|
||||
('cp_hqd_persistent_state', uint32_t),
|
||||
('cp_hqd_pipe_priority', uint32_t),
|
||||
('cp_hqd_queue_priority', uint32_t),
|
||||
('cp_hqd_quantum', uint32_t),
|
||||
('cp_hqd_pq_base_lo', uint32_t),
|
||||
('cp_hqd_pq_base_hi', uint32_t),
|
||||
('cp_hqd_pq_rptr', uint32_t),
|
||||
('cp_hqd_pq_rptr_report_addr_lo', uint32_t),
|
||||
('cp_hqd_pq_rptr_report_addr_hi', uint32_t),
|
||||
('cp_hqd_pq_wptr_poll_addr_lo', uint32_t),
|
||||
('cp_hqd_pq_wptr_poll_addr_hi', uint32_t),
|
||||
('cp_hqd_pq_doorbell_control', uint32_t),
|
||||
('reserved_144', uint32_t),
|
||||
('cp_hqd_pq_control', uint32_t),
|
||||
('cp_hqd_ib_base_addr_lo', uint32_t),
|
||||
('cp_hqd_ib_base_addr_hi', uint32_t),
|
||||
('cp_hqd_ib_rptr', uint32_t),
|
||||
('cp_hqd_ib_control', uint32_t),
|
||||
('cp_hqd_iq_timer', uint32_t),
|
||||
('cp_hqd_iq_rptr', uint32_t),
|
||||
('cp_hqd_dequeue_request', uint32_t),
|
||||
('cp_hqd_dma_offload', uint32_t),
|
||||
('cp_hqd_sema_cmd', uint32_t),
|
||||
('cp_hqd_msg_type', uint32_t),
|
||||
('cp_hqd_atomic0_preop_lo', uint32_t),
|
||||
('cp_hqd_atomic0_preop_hi', uint32_t),
|
||||
('cp_hqd_atomic1_preop_lo', uint32_t),
|
||||
('cp_hqd_atomic1_preop_hi', uint32_t),
|
||||
('cp_hqd_hq_status0', uint32_t),
|
||||
('cp_hqd_hq_control0', uint32_t),
|
||||
('cp_mqd_control', uint32_t),
|
||||
('cp_hqd_hq_status1', uint32_t),
|
||||
('cp_hqd_hq_control1', uint32_t),
|
||||
('cp_hqd_eop_base_addr_lo', uint32_t),
|
||||
('cp_hqd_eop_base_addr_hi', uint32_t),
|
||||
('cp_hqd_eop_control', uint32_t),
|
||||
('cp_hqd_eop_rptr', uint32_t),
|
||||
('cp_hqd_eop_wptr', uint32_t),
|
||||
('cp_hqd_eop_done_events', uint32_t),
|
||||
('cp_hqd_ctx_save_base_addr_lo', uint32_t),
|
||||
('cp_hqd_ctx_save_base_addr_hi', uint32_t),
|
||||
('cp_hqd_ctx_save_control', uint32_t),
|
||||
('cp_hqd_cntl_stack_offset', uint32_t),
|
||||
('cp_hqd_cntl_stack_size', uint32_t),
|
||||
('cp_hqd_wg_state_offset', uint32_t),
|
||||
('cp_hqd_ctx_save_size', uint32_t),
|
||||
('cp_hqd_gds_resource_state', uint32_t),
|
||||
('cp_hqd_error', uint32_t),
|
||||
('cp_hqd_eop_wptr_mem', uint32_t),
|
||||
('cp_hqd_aql_control', uint32_t),
|
||||
('cp_hqd_pq_wptr_lo', uint32_t),
|
||||
('cp_hqd_pq_wptr_hi', uint32_t),
|
||||
('reserved_184', uint32_t),
|
||||
('reserved_185', uint32_t),
|
||||
('reserved_186', uint32_t),
|
||||
('reserved_187', uint32_t),
|
||||
('reserved_188', uint32_t),
|
||||
('reserved_189', uint32_t),
|
||||
('reserved_190', uint32_t),
|
||||
('reserved_191', uint32_t),
|
||||
('iqtimer_pkt_header', uint32_t),
|
||||
('iqtimer_pkt_dw0', uint32_t),
|
||||
('iqtimer_pkt_dw1', uint32_t),
|
||||
('iqtimer_pkt_dw2', uint32_t),
|
||||
('iqtimer_pkt_dw3', uint32_t),
|
||||
('iqtimer_pkt_dw4', uint32_t),
|
||||
('iqtimer_pkt_dw5', uint32_t),
|
||||
('iqtimer_pkt_dw6', uint32_t),
|
||||
('iqtimer_pkt_dw7', uint32_t),
|
||||
('iqtimer_pkt_dw8', uint32_t),
|
||||
('iqtimer_pkt_dw9', uint32_t),
|
||||
('iqtimer_pkt_dw10', uint32_t),
|
||||
('iqtimer_pkt_dw11', uint32_t),
|
||||
('iqtimer_pkt_dw12', uint32_t),
|
||||
('iqtimer_pkt_dw13', uint32_t),
|
||||
('iqtimer_pkt_dw14', uint32_t),
|
||||
('iqtimer_pkt_dw15', uint32_t),
|
||||
('iqtimer_pkt_dw16', uint32_t),
|
||||
('iqtimer_pkt_dw17', uint32_t),
|
||||
('iqtimer_pkt_dw18', uint32_t),
|
||||
('iqtimer_pkt_dw19', uint32_t),
|
||||
('iqtimer_pkt_dw20', uint32_t),
|
||||
('iqtimer_pkt_dw21', uint32_t),
|
||||
('iqtimer_pkt_dw22', uint32_t),
|
||||
('iqtimer_pkt_dw23', uint32_t),
|
||||
('iqtimer_pkt_dw24', uint32_t),
|
||||
('iqtimer_pkt_dw25', uint32_t),
|
||||
('iqtimer_pkt_dw26', uint32_t),
|
||||
('iqtimer_pkt_dw27', uint32_t),
|
||||
('iqtimer_pkt_dw28', uint32_t),
|
||||
('iqtimer_pkt_dw29', uint32_t),
|
||||
('iqtimer_pkt_dw30', uint32_t),
|
||||
('iqtimer_pkt_dw31', uint32_t),
|
||||
('_1', struct_v9_mqd_1),
|
||||
('reserved_227', uint32_t),
|
||||
('set_resources_header', uint32_t),
|
||||
('set_resources_dw1', uint32_t),
|
||||
('set_resources_dw2', uint32_t),
|
||||
('set_resources_dw3', uint32_t),
|
||||
('set_resources_dw4', uint32_t),
|
||||
('set_resources_dw5', uint32_t),
|
||||
('set_resources_dw6', uint32_t),
|
||||
('set_resources_dw7', uint32_t),
|
||||
('reserved_236', uint32_t),
|
||||
('reserved_237', uint32_t),
|
||||
('reserved_238', uint32_t),
|
||||
('reserved_239', uint32_t),
|
||||
('queue_doorbell_id0', uint32_t),
|
||||
('queue_doorbell_id1', uint32_t),
|
||||
('queue_doorbell_id2', uint32_t),
|
||||
('queue_doorbell_id3', uint32_t),
|
||||
('queue_doorbell_id4', uint32_t),
|
||||
('queue_doorbell_id5', uint32_t),
|
||||
('queue_doorbell_id6', uint32_t),
|
||||
('queue_doorbell_id7', uint32_t),
|
||||
('queue_doorbell_id8', uint32_t),
|
||||
('queue_doorbell_id9', uint32_t),
|
||||
('queue_doorbell_id10', uint32_t),
|
||||
('queue_doorbell_id11', uint32_t),
|
||||
('queue_doorbell_id12', uint32_t),
|
||||
('queue_doorbell_id13', uint32_t),
|
||||
('queue_doorbell_id14', uint32_t),
|
||||
('queue_doorbell_id15', uint32_t),
|
||||
('reserved_256', uint32_t),
|
||||
('reserved_257', uint32_t),
|
||||
('reserved_258', uint32_t),
|
||||
('reserved_259', uint32_t),
|
||||
('reserved_260', uint32_t),
|
||||
('reserved_261', uint32_t),
|
||||
('reserved_262', uint32_t),
|
||||
('reserved_263', uint32_t),
|
||||
('reserved_264', uint32_t),
|
||||
('reserved_265', uint32_t),
|
||||
('reserved_266', uint32_t),
|
||||
('reserved_267', uint32_t),
|
||||
('reserved_268', uint32_t),
|
||||
('reserved_269', uint32_t),
|
||||
('reserved_270', uint32_t),
|
||||
('reserved_271', uint32_t),
|
||||
('reserved_272', uint32_t),
|
||||
('reserved_273', uint32_t),
|
||||
('reserved_274', uint32_t),
|
||||
('reserved_275', uint32_t),
|
||||
('reserved_276', uint32_t),
|
||||
('reserved_277', uint32_t),
|
||||
('reserved_278', uint32_t),
|
||||
('reserved_279', uint32_t),
|
||||
('reserved_280', uint32_t),
|
||||
('reserved_281', uint32_t),
|
||||
('reserved_282', uint32_t),
|
||||
('reserved_283', uint32_t),
|
||||
('reserved_284', uint32_t),
|
||||
('reserved_285', uint32_t),
|
||||
('reserved_286', uint32_t),
|
||||
('reserved_287', uint32_t),
|
||||
('reserved_288', uint32_t),
|
||||
('reserved_289', uint32_t),
|
||||
('reserved_290', uint32_t),
|
||||
('reserved_291', uint32_t),
|
||||
('reserved_292', uint32_t),
|
||||
('reserved_293', uint32_t),
|
||||
('reserved_294', uint32_t),
|
||||
('reserved_295', uint32_t),
|
||||
('reserved_296', uint32_t),
|
||||
('reserved_297', uint32_t),
|
||||
('reserved_298', uint32_t),
|
||||
('reserved_299', uint32_t),
|
||||
('reserved_300', uint32_t),
|
||||
('reserved_301', uint32_t),
|
||||
('reserved_302', uint32_t),
|
||||
('reserved_303', uint32_t),
|
||||
('reserved_304', uint32_t),
|
||||
('reserved_305', uint32_t),
|
||||
('reserved_306', uint32_t),
|
||||
('reserved_307', uint32_t),
|
||||
('reserved_308', uint32_t),
|
||||
('reserved_309', uint32_t),
|
||||
('reserved_310', uint32_t),
|
||||
('reserved_311', uint32_t),
|
||||
('reserved_312', uint32_t),
|
||||
('reserved_313', uint32_t),
|
||||
('reserved_314', uint32_t),
|
||||
('reserved_315', uint32_t),
|
||||
('reserved_316', uint32_t),
|
||||
('reserved_317', uint32_t),
|
||||
('reserved_318', uint32_t),
|
||||
('reserved_319', uint32_t),
|
||||
('reserved_320', uint32_t),
|
||||
('reserved_321', uint32_t),
|
||||
('reserved_322', uint32_t),
|
||||
('reserved_323', uint32_t),
|
||||
('reserved_324', uint32_t),
|
||||
('reserved_325', uint32_t),
|
||||
('reserved_326', uint32_t),
|
||||
('reserved_327', uint32_t),
|
||||
('reserved_328', uint32_t),
|
||||
('reserved_329', uint32_t),
|
||||
('reserved_330', uint32_t),
|
||||
('reserved_331', uint32_t),
|
||||
('reserved_332', uint32_t),
|
||||
('reserved_333', uint32_t),
|
||||
('reserved_334', uint32_t),
|
||||
('reserved_335', uint32_t),
|
||||
('reserved_336', uint32_t),
|
||||
('reserved_337', uint32_t),
|
||||
('reserved_338', uint32_t),
|
||||
('reserved_339', uint32_t),
|
||||
('reserved_340', uint32_t),
|
||||
('reserved_341', uint32_t),
|
||||
('reserved_342', uint32_t),
|
||||
('reserved_343', uint32_t),
|
||||
('reserved_344', uint32_t),
|
||||
('reserved_345', uint32_t),
|
||||
('reserved_346', uint32_t),
|
||||
('reserved_347', uint32_t),
|
||||
('reserved_348', uint32_t),
|
||||
('reserved_349', uint32_t),
|
||||
('reserved_350', uint32_t),
|
||||
('reserved_351', uint32_t),
|
||||
('reserved_352', uint32_t),
|
||||
('reserved_353', uint32_t),
|
||||
('reserved_354', uint32_t),
|
||||
('reserved_355', uint32_t),
|
||||
('reserved_356', uint32_t),
|
||||
('reserved_357', uint32_t),
|
||||
('reserved_358', uint32_t),
|
||||
('reserved_359', uint32_t),
|
||||
('reserved_360', uint32_t),
|
||||
('reserved_361', uint32_t),
|
||||
('reserved_362', uint32_t),
|
||||
('reserved_363', uint32_t),
|
||||
('reserved_364', uint32_t),
|
||||
('reserved_365', uint32_t),
|
||||
('reserved_366', uint32_t),
|
||||
('reserved_367', uint32_t),
|
||||
('reserved_368', uint32_t),
|
||||
('reserved_369', uint32_t),
|
||||
('reserved_370', uint32_t),
|
||||
('reserved_371', uint32_t),
|
||||
('reserved_372', uint32_t),
|
||||
('reserved_373', uint32_t),
|
||||
('reserved_374', uint32_t),
|
||||
('reserved_375', uint32_t),
|
||||
('reserved_376', uint32_t),
|
||||
('reserved_377', uint32_t),
|
||||
('reserved_378', uint32_t),
|
||||
('reserved_379', uint32_t),
|
||||
('reserved_380', uint32_t),
|
||||
('reserved_381', uint32_t),
|
||||
('reserved_382', uint32_t),
|
||||
('reserved_383', uint32_t),
|
||||
('reserved_384', uint32_t),
|
||||
('reserved_385', uint32_t),
|
||||
('reserved_386', uint32_t),
|
||||
('reserved_387', uint32_t),
|
||||
('reserved_388', uint32_t),
|
||||
('reserved_389', uint32_t),
|
||||
('reserved_390', uint32_t),
|
||||
('reserved_391', uint32_t),
|
||||
('reserved_392', uint32_t),
|
||||
('reserved_393', uint32_t),
|
||||
('reserved_394', uint32_t),
|
||||
('reserved_395', uint32_t),
|
||||
('reserved_396', uint32_t),
|
||||
('reserved_397', uint32_t),
|
||||
('reserved_398', uint32_t),
|
||||
('reserved_399', uint32_t),
|
||||
('reserved_400', uint32_t),
|
||||
('reserved_401', uint32_t),
|
||||
('reserved_402', uint32_t),
|
||||
('reserved_403', uint32_t),
|
||||
('reserved_404', uint32_t),
|
||||
('reserved_405', uint32_t),
|
||||
('reserved_406', uint32_t),
|
||||
('reserved_407', uint32_t),
|
||||
('reserved_408', uint32_t),
|
||||
('reserved_409', uint32_t),
|
||||
('reserved_410', uint32_t),
|
||||
('reserved_411', uint32_t),
|
||||
('reserved_412', uint32_t),
|
||||
('reserved_413', uint32_t),
|
||||
('reserved_414', uint32_t),
|
||||
('reserved_415', uint32_t),
|
||||
('reserved_416', uint32_t),
|
||||
('reserved_417', uint32_t),
|
||||
('reserved_418', uint32_t),
|
||||
('reserved_419', uint32_t),
|
||||
('reserved_420', uint32_t),
|
||||
('reserved_421', uint32_t),
|
||||
('reserved_422', uint32_t),
|
||||
('reserved_423', uint32_t),
|
||||
('reserved_424', uint32_t),
|
||||
('reserved_425', uint32_t),
|
||||
('reserved_426', uint32_t),
|
||||
('reserved_427', uint32_t),
|
||||
('reserved_428', uint32_t),
|
||||
('reserved_429', uint32_t),
|
||||
('reserved_430', uint32_t),
|
||||
('reserved_431', uint32_t),
|
||||
('reserved_432', uint32_t),
|
||||
('reserved_433', uint32_t),
|
||||
('reserved_434', uint32_t),
|
||||
('reserved_435', uint32_t),
|
||||
('reserved_436', uint32_t),
|
||||
('reserved_437', uint32_t),
|
||||
('reserved_438', uint32_t),
|
||||
('reserved_439', uint32_t),
|
||||
('reserved_440', uint32_t),
|
||||
('reserved_441', uint32_t),
|
||||
('reserved_442', uint32_t),
|
||||
('reserved_443', uint32_t),
|
||||
('reserved_444', uint32_t),
|
||||
('reserved_445', uint32_t),
|
||||
('reserved_446', uint32_t),
|
||||
('reserved_447', uint32_t),
|
||||
('reserved_448', uint32_t),
|
||||
('reserved_449', uint32_t),
|
||||
('reserved_450', uint32_t),
|
||||
('reserved_451', uint32_t),
|
||||
('reserved_452', uint32_t),
|
||||
('reserved_453', uint32_t),
|
||||
('reserved_454', uint32_t),
|
||||
('reserved_455', uint32_t),
|
||||
('reserved_456', uint32_t),
|
||||
('reserved_457', uint32_t),
|
||||
('reserved_458', uint32_t),
|
||||
('reserved_459', uint32_t),
|
||||
('reserved_460', uint32_t),
|
||||
('reserved_461', uint32_t),
|
||||
('reserved_462', uint32_t),
|
||||
('reserved_463', uint32_t),
|
||||
('reserved_464', uint32_t),
|
||||
('reserved_465', uint32_t),
|
||||
('reserved_466', uint32_t),
|
||||
('reserved_467', uint32_t),
|
||||
('reserved_468', uint32_t),
|
||||
('reserved_469', uint32_t),
|
||||
('reserved_470', uint32_t),
|
||||
('reserved_471', uint32_t),
|
||||
('reserved_472', uint32_t),
|
||||
('reserved_473', uint32_t),
|
||||
('reserved_474', uint32_t),
|
||||
('reserved_475', uint32_t),
|
||||
('reserved_476', uint32_t),
|
||||
('reserved_477', uint32_t),
|
||||
('reserved_478', uint32_t),
|
||||
('reserved_479', uint32_t),
|
||||
('reserved_480', uint32_t),
|
||||
('reserved_481', uint32_t),
|
||||
('reserved_482', uint32_t),
|
||||
('reserved_483', uint32_t),
|
||||
('reserved_484', uint32_t),
|
||||
('reserved_485', uint32_t),
|
||||
('reserved_486', uint32_t),
|
||||
('reserved_487', uint32_t),
|
||||
('reserved_488', uint32_t),
|
||||
('reserved_489', uint32_t),
|
||||
('reserved_490', uint32_t),
|
||||
('reserved_491', uint32_t),
|
||||
('reserved_492', uint32_t),
|
||||
('reserved_493', uint32_t),
|
||||
('reserved_494', uint32_t),
|
||||
('reserved_495', uint32_t),
|
||||
('reserved_496', uint32_t),
|
||||
('reserved_497', uint32_t),
|
||||
('reserved_498', uint32_t),
|
||||
('reserved_499', uint32_t),
|
||||
('reserved_500', uint32_t),
|
||||
('reserved_501', uint32_t),
|
||||
('reserved_502', uint32_t),
|
||||
('reserved_503', uint32_t),
|
||||
('reserved_504', uint32_t),
|
||||
('reserved_505', uint32_t),
|
||||
('reserved_506', uint32_t),
|
||||
('reserved_507', uint32_t),
|
||||
('reserved_508', uint32_t),
|
||||
('reserved_509', uint32_t),
|
||||
('reserved_510', uint32_t),
|
||||
('reserved_511', uint32_t),
|
||||
]
|
||||
class struct_v9_mqd_allocation(Struct): pass
|
||||
struct_v9_mqd_allocation._fields_ = [
|
||||
('mqd', struct_v9_mqd),
|
||||
('wptr_poll_mem', uint32_t),
|
||||
('rptr_report_mem', uint32_t),
|
||||
('dynamic_cu_mask', uint32_t),
|
||||
('dynamic_rb_mask', uint32_t),
|
||||
]
|
||||
class struct_v9_ce_ib_state(Struct): pass
|
||||
struct_v9_ce_ib_state._fields_ = [
|
||||
('ce_ib_completion_status', uint32_t),
|
||||
('ce_constegnine_count', uint32_t),
|
||||
('ce_ibOffset_ib1', uint32_t),
|
||||
('ce_ibOffset_ib2', uint32_t),
|
||||
('ce_chainib_addrlo_ib1', uint32_t),
|
||||
('ce_chainib_addrlo_ib2', uint32_t),
|
||||
('ce_chainib_addrhi_ib1', uint32_t),
|
||||
('ce_chainib_addrhi_ib2', uint32_t),
|
||||
('ce_chainib_size_ib1', uint32_t),
|
||||
('ce_chainib_size_ib2', uint32_t),
|
||||
]
|
||||
class struct_v9_de_ib_state(Struct): pass
|
||||
struct_v9_de_ib_state._fields_ = [
|
||||
('ib_completion_status', uint32_t),
|
||||
('de_constEngine_count', uint32_t),
|
||||
('ib_offset_ib1', uint32_t),
|
||||
('ib_offset_ib2', uint32_t),
|
||||
('chain_ib_addrlo_ib1', uint32_t),
|
||||
('chain_ib_addrlo_ib2', uint32_t),
|
||||
('chain_ib_addrhi_ib1', uint32_t),
|
||||
('chain_ib_addrhi_ib2', uint32_t),
|
||||
('chain_ib_size_ib1', uint32_t),
|
||||
('chain_ib_size_ib2', uint32_t),
|
||||
('preamble_begin_ib1', uint32_t),
|
||||
('preamble_begin_ib2', uint32_t),
|
||||
('preamble_end_ib1', uint32_t),
|
||||
('preamble_end_ib2', uint32_t),
|
||||
('chain_ib_pream_addrlo_ib1', uint32_t),
|
||||
('chain_ib_pream_addrlo_ib2', uint32_t),
|
||||
('chain_ib_pream_addrhi_ib1', uint32_t),
|
||||
('chain_ib_pream_addrhi_ib2', uint32_t),
|
||||
('draw_indirect_baseLo', uint32_t),
|
||||
('draw_indirect_baseHi', uint32_t),
|
||||
('disp_indirect_baseLo', uint32_t),
|
||||
('disp_indirect_baseHi', uint32_t),
|
||||
('gds_backup_addrlo', uint32_t),
|
||||
('gds_backup_addrhi', uint32_t),
|
||||
('index_base_addrlo', uint32_t),
|
||||
('index_base_addrhi', uint32_t),
|
||||
('sample_cntl', uint32_t),
|
||||
]
|
||||
class struct_v9_gfx_meta_data(Struct): pass
|
||||
struct_v9_gfx_meta_data._fields_ = [
|
||||
('ce_payload', struct_v9_ce_ib_state),
|
||||
('reserved1', (uint32_t * 54)),
|
||||
('de_payload', struct_v9_de_ib_state),
|
||||
('DeIbBaseAddrLo', uint32_t),
|
||||
('DeIbBaseAddrHi', uint32_t),
|
||||
('reserved2', (uint32_t * 931)),
|
||||
]
|
||||
enum_soc15_ih_clientid = CEnum(ctypes.c_uint32)
|
||||
SOC15_IH_CLIENTID_IH = enum_soc15_ih_clientid.define('SOC15_IH_CLIENTID_IH', 0)
|
||||
SOC15_IH_CLIENTID_ACP = enum_soc15_ih_clientid.define('SOC15_IH_CLIENTID_ACP', 1)
|
||||
|
||||
@@ -3,15 +3,34 @@ import ctypes
|
||||
from tinygrad.helpers import unwrap
|
||||
from tinygrad.runtime.support.c import Struct, CEnum, _IO, _IOW, _IOR, _IOWR
|
||||
class union_PM4_MES_TYPE_3_HEADER(ctypes.Union): pass
|
||||
class _anonstruct0(Struct): pass
|
||||
enum_mes_set_resources_queue_type_enum = CEnum(ctypes.c_uint32)
|
||||
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(Struct): pass
|
||||
class _anonunion1(ctypes.Union): pass
|
||||
class _anonunion2(ctypes.Union): pass
|
||||
class _anonstruct3(Struct): pass
|
||||
class _anonunion4(ctypes.Union): pass
|
||||
class _anonstruct5(Struct): pass
|
||||
class _anonunion6(ctypes.Union): pass
|
||||
class _anonstruct7(Struct): pass
|
||||
class struct_pm4_mes_runlist(Struct): pass
|
||||
class _anonunion8(ctypes.Union): pass
|
||||
class _anonunion9(ctypes.Union): pass
|
||||
class _anonstruct10(Struct): pass
|
||||
class _anonunion11(ctypes.Union): pass
|
||||
class _anonstruct12(Struct): pass
|
||||
class struct_pm4_mes_map_process(Struct): pass
|
||||
class _anonunion13(ctypes.Union): pass
|
||||
class _anonunion14(ctypes.Union): pass
|
||||
class _anonstruct15(Struct): pass
|
||||
class _anonunion16(ctypes.Union): pass
|
||||
class _anonstruct17(Struct): pass
|
||||
class struct_PM4_MES_MAP_PROCESS_VM(Struct): pass
|
||||
class _anonunion18(ctypes.Union): pass
|
||||
enum_mes_map_queues_queue_sel_enum = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
@@ -33,6 +52,11 @@ extended_engine_sel__mes_map_queues__sdma0_to_7_sel = enum_mes_map_queues_extend
|
||||
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(Struct): pass
|
||||
class _anonunion19(ctypes.Union): pass
|
||||
class _anonunion20(ctypes.Union): pass
|
||||
class _anonstruct21(Struct): pass
|
||||
class _anonunion22(ctypes.Union): pass
|
||||
class _anonstruct23(Struct): pass
|
||||
enum_mes_query_status_interrupt_sel_enum = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
@@ -50,6 +74,12 @@ engine_sel__mes_query_status__sdma0_queue = enum_mes_query_status_engine_sel_enu
|
||||
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(Struct): pass
|
||||
class _anonunion24(ctypes.Union): pass
|
||||
class _anonunion25(ctypes.Union): pass
|
||||
class _anonstruct26(Struct): pass
|
||||
class _anonunion27(ctypes.Union): pass
|
||||
class _anonstruct28(Struct): pass
|
||||
class _anonstruct29(Struct): pass
|
||||
enum_mes_unmap_queues_action_enum = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
@@ -72,6 +102,18 @@ extended_engine_sel__mes_unmap_queues__legacy_engine_sel = enum_mes_unmap_queues
|
||||
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(Struct): pass
|
||||
class _anonunion30(ctypes.Union): pass
|
||||
class _anonunion31(ctypes.Union): pass
|
||||
class _anonstruct32(Struct): pass
|
||||
class _anonunion33(ctypes.Union): pass
|
||||
class _anonstruct34(Struct): pass
|
||||
class _anonstruct35(Struct): pass
|
||||
class _anonunion36(ctypes.Union): pass
|
||||
class _anonstruct37(Struct): pass
|
||||
class _anonunion38(ctypes.Union): pass
|
||||
class _anonstruct39(Struct): pass
|
||||
class _anonunion40(ctypes.Union): pass
|
||||
class _anonstruct41(Struct): pass
|
||||
enum_mec_release_mem_event_index_enum = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
@@ -108,6 +150,18 @@ data_sel__mec_release_mem__send_cp_perfcounter_hi_lo = enum_mec_release_mem_data
|
||||
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(Struct): pass
|
||||
class _anonunion42(ctypes.Union): pass
|
||||
class _anonunion43(ctypes.Union): pass
|
||||
class _anonstruct44(Struct): pass
|
||||
class _anonunion45(ctypes.Union): pass
|
||||
class _anonstruct46(Struct): pass
|
||||
class _anonunion47(ctypes.Union): pass
|
||||
class _anonstruct48(Struct): pass
|
||||
class _anonstruct49(Struct): pass
|
||||
class _anonunion50(ctypes.Union): pass
|
||||
class _anonunion51(ctypes.Union): pass
|
||||
class _anonstruct52(Struct): pass
|
||||
class _anonunion53(ctypes.Union): pass
|
||||
enum_WRITE_DATA_dst_sel_enum = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
@@ -128,8 +182,37 @@ cache_policy___write_data__lru = enum_WRITE_DATA_cache_policy_enum.define('cache
|
||||
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(Struct): pass
|
||||
_anonenum0 = CEnum(ctypes.c_uint32)
|
||||
CACHE_FLUSH_AND_INV_TS_EVENT = _anonenum0.define('CACHE_FLUSH_AND_INV_TS_EVENT', 20)
|
||||
class _anonunion54(ctypes.Union): pass
|
||||
class _anonunion55(ctypes.Union): pass
|
||||
class _anonunion55_bitfields2(Struct): pass
|
||||
_anonunion55_bitfields2._fields_ = [
|
||||
('reserved1', ctypes.c_uint32,8),
|
||||
('dst_sel', ctypes.c_uint32,4),
|
||||
('reserved2', ctypes.c_uint32,4),
|
||||
('addr_incr', ctypes.c_uint32,1),
|
||||
('reserved3', ctypes.c_uint32,2),
|
||||
('resume_vf', ctypes.c_uint32,1),
|
||||
('wr_confirm', ctypes.c_uint32,1),
|
||||
('reserved4', ctypes.c_uint32,4),
|
||||
('cache_policy', ctypes.c_uint32,2),
|
||||
('reserved5', ctypes.c_uint32,5),
|
||||
]
|
||||
_anonunion55._fields_ = [
|
||||
('bitfields2', _anonunion55_bitfields2),
|
||||
('ordinal2', ctypes.c_uint32),
|
||||
]
|
||||
class _anonunion56(ctypes.Union): pass
|
||||
class _anonunion56_bitfields3(Struct): pass
|
||||
_anonunion56_bitfields3._fields_ = [
|
||||
('dst_mmreg_addr', ctypes.c_uint32,18),
|
||||
('reserved6', ctypes.c_uint32,14),
|
||||
]
|
||||
_anonunion56._fields_ = [
|
||||
('bitfields3', _anonunion56_bitfields3),
|
||||
('ordinal3', ctypes.c_uint32),
|
||||
]
|
||||
_anonenum57 = CEnum(ctypes.c_uint32)
|
||||
CACHE_FLUSH_AND_INV_TS_EVENT = _anonenum57.define('CACHE_FLUSH_AND_INV_TS_EVENT', 20)
|
||||
|
||||
PACKET_TYPE0 = 0
|
||||
PACKET_TYPE1 = 1
|
||||
|
||||
@@ -3,15 +3,34 @@ import ctypes
|
||||
from tinygrad.helpers import unwrap
|
||||
from tinygrad.runtime.support.c import Struct, CEnum, _IO, _IOW, _IOR, _IOWR
|
||||
class union_PM4_MES_TYPE_3_HEADER(ctypes.Union): pass
|
||||
class _anonstruct0(Struct): pass
|
||||
enum_mes_set_resources_queue_type_enum = CEnum(ctypes.c_uint32)
|
||||
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(Struct): pass
|
||||
class _anonunion1(ctypes.Union): pass
|
||||
class _anonunion2(ctypes.Union): pass
|
||||
class _anonstruct3(Struct): pass
|
||||
class _anonunion4(ctypes.Union): pass
|
||||
class _anonstruct5(Struct): pass
|
||||
class _anonunion6(ctypes.Union): pass
|
||||
class _anonstruct7(Struct): pass
|
||||
class struct_pm4_mes_runlist(Struct): pass
|
||||
class _anonunion8(ctypes.Union): pass
|
||||
class _anonunion9(ctypes.Union): pass
|
||||
class _anonstruct10(Struct): pass
|
||||
class _anonunion11(ctypes.Union): pass
|
||||
class _anonstruct12(Struct): pass
|
||||
class struct_pm4_mes_map_process(Struct): pass
|
||||
class _anonunion13(ctypes.Union): pass
|
||||
class _anonunion14(ctypes.Union): pass
|
||||
class _anonstruct15(Struct): pass
|
||||
class _anonunion16(ctypes.Union): pass
|
||||
class _anonstruct17(Struct): pass
|
||||
class struct_PM4_MES_MAP_PROCESS_VM(Struct): pass
|
||||
class _anonunion18(ctypes.Union): pass
|
||||
enum_mes_map_queues_queue_sel_enum = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
@@ -33,6 +52,11 @@ extended_engine_sel__mes_map_queues__sdma0_to_7_sel = enum_mes_map_queues_extend
|
||||
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(Struct): pass
|
||||
class _anonunion19(ctypes.Union): pass
|
||||
class _anonunion20(ctypes.Union): pass
|
||||
class _anonstruct21(Struct): pass
|
||||
class _anonunion22(ctypes.Union): pass
|
||||
class _anonstruct23(Struct): pass
|
||||
enum_mes_query_status_interrupt_sel_enum = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
@@ -50,6 +74,12 @@ engine_sel__mes_query_status__sdma0_queue = enum_mes_query_status_engine_sel_enu
|
||||
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(Struct): pass
|
||||
class _anonunion24(ctypes.Union): pass
|
||||
class _anonunion25(ctypes.Union): pass
|
||||
class _anonstruct26(Struct): pass
|
||||
class _anonunion27(ctypes.Union): pass
|
||||
class _anonstruct28(Struct): pass
|
||||
class _anonstruct29(Struct): pass
|
||||
enum_mes_unmap_queues_action_enum = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
@@ -72,6 +102,18 @@ extended_engine_sel__mes_unmap_queues__legacy_engine_sel = enum_mes_unmap_queues
|
||||
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(Struct): pass
|
||||
class _anonunion30(ctypes.Union): pass
|
||||
class _anonunion31(ctypes.Union): pass
|
||||
class _anonstruct32(Struct): pass
|
||||
class _anonunion33(ctypes.Union): pass
|
||||
class _anonstruct34(Struct): pass
|
||||
class _anonstruct35(Struct): pass
|
||||
class _anonunion36(ctypes.Union): pass
|
||||
class _anonstruct37(Struct): pass
|
||||
class _anonunion38(ctypes.Union): pass
|
||||
class _anonstruct39(Struct): pass
|
||||
class _anonunion40(ctypes.Union): pass
|
||||
class _anonstruct41(Struct): pass
|
||||
enum_mec_release_mem_event_index_enum = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
@@ -108,6 +150,18 @@ data_sel__mec_release_mem__send_cp_perfcounter_hi_lo = enum_mec_release_mem_data
|
||||
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(Struct): pass
|
||||
class _anonunion42(ctypes.Union): pass
|
||||
class _anonunion43(ctypes.Union): pass
|
||||
class _anonstruct44(Struct): pass
|
||||
class _anonunion45(ctypes.Union): pass
|
||||
class _anonstruct46(Struct): pass
|
||||
class _anonunion47(ctypes.Union): pass
|
||||
class _anonstruct48(Struct): pass
|
||||
class _anonstruct49(Struct): pass
|
||||
class _anonunion50(ctypes.Union): pass
|
||||
class _anonunion51(ctypes.Union): pass
|
||||
class _anonstruct52(Struct): pass
|
||||
class _anonunion53(ctypes.Union): pass
|
||||
enum_WRITE_DATA_dst_sel_enum = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
@@ -128,8 +182,37 @@ cache_policy___write_data__lru = enum_WRITE_DATA_cache_policy_enum.define('cache
|
||||
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(Struct): pass
|
||||
_anonenum0 = CEnum(ctypes.c_uint32)
|
||||
CACHE_FLUSH_AND_INV_TS_EVENT = _anonenum0.define('CACHE_FLUSH_AND_INV_TS_EVENT', 20)
|
||||
class _anonunion54(ctypes.Union): pass
|
||||
class _anonunion55(ctypes.Union): pass
|
||||
class _anonunion55_bitfields2(Struct): pass
|
||||
_anonunion55_bitfields2._fields_ = [
|
||||
('reserved1', ctypes.c_uint32,8),
|
||||
('dst_sel', ctypes.c_uint32,4),
|
||||
('reserved2', ctypes.c_uint32,4),
|
||||
('addr_incr', ctypes.c_uint32,1),
|
||||
('reserved3', ctypes.c_uint32,2),
|
||||
('resume_vf', ctypes.c_uint32,1),
|
||||
('wr_confirm', ctypes.c_uint32,1),
|
||||
('reserved4', ctypes.c_uint32,4),
|
||||
('cache_policy', ctypes.c_uint32,2),
|
||||
('reserved5', ctypes.c_uint32,5),
|
||||
]
|
||||
_anonunion55._fields_ = [
|
||||
('bitfields2', _anonunion55_bitfields2),
|
||||
('ordinal2', ctypes.c_uint32),
|
||||
]
|
||||
class _anonunion56(ctypes.Union): pass
|
||||
class _anonunion56_bitfields3(Struct): pass
|
||||
_anonunion56_bitfields3._fields_ = [
|
||||
('dst_mmreg_addr', ctypes.c_uint32,18),
|
||||
('reserved6', ctypes.c_uint32,14),
|
||||
]
|
||||
_anonunion56._fields_ = [
|
||||
('bitfields3', _anonunion56_bitfields3),
|
||||
('ordinal3', ctypes.c_uint32),
|
||||
]
|
||||
_anonenum57 = CEnum(ctypes.c_uint32)
|
||||
CACHE_FLUSH_AND_INV_TS_EVENT = _anonenum57.define('CACHE_FLUSH_AND_INV_TS_EVENT', 20)
|
||||
|
||||
GFX9_NUM_GFX_RINGS = 1
|
||||
GFX9_NUM_COMPUTE_RINGS = 8
|
||||
|
||||
@@ -77,18 +77,8 @@ I2C_CONTROLLER_PROTOCOL_INA3221 = I2cControllerProtocol_e.define('I2C_CONTROLLER
|
||||
I2C_CONTROLLER_PROTOCOL_TMP_MAX6604 = I2cControllerProtocol_e.define('I2C_CONTROLLER_PROTOCOL_TMP_MAX6604', 4)
|
||||
I2C_CONTROLLER_PROTOCOL_COUNT = I2cControllerProtocol_e.define('I2C_CONTROLLER_PROTOCOL_COUNT', 5)
|
||||
|
||||
class I2cControllerConfig_t(Struct): pass
|
||||
uint8_t = ctypes.c_ubyte
|
||||
I2cControllerConfig_t._fields_ = [
|
||||
('Enabled', uint8_t),
|
||||
('Speed', uint8_t),
|
||||
('SlaveAddress', uint8_t),
|
||||
('ControllerPort', uint8_t),
|
||||
('ControllerName', uint8_t),
|
||||
('ThermalThrotter', uint8_t),
|
||||
('I2cProtocol', uint8_t),
|
||||
('PaddingConfig', uint8_t),
|
||||
]
|
||||
class _anonstruct0(Struct): pass
|
||||
I2cControllerConfig_t = _anonstruct0
|
||||
I2cPort_e = CEnum(ctypes.c_uint32)
|
||||
I2C_PORT_SVD_SCL = I2cPort_e.define('I2C_PORT_SVD_SCL', 0)
|
||||
I2C_PORT_GPIO = I2cPort_e.define('I2C_PORT_GPIO', 1)
|
||||
@@ -107,40 +97,16 @@ 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 SwI2cCmd_t(Struct): pass
|
||||
SwI2cCmd_t._fields_ = [
|
||||
('ReadWriteData', uint8_t),
|
||||
('CmdConfig', uint8_t),
|
||||
]
|
||||
class SwI2cRequest_t(Struct): pass
|
||||
SwI2cRequest_t._fields_ = [
|
||||
('I2CcontrollerPort', uint8_t),
|
||||
('I2CSpeed', uint8_t),
|
||||
('SlaveAddress', uint8_t),
|
||||
('NumCmds', uint8_t),
|
||||
('SwI2cCmds', (SwI2cCmd_t * 24)),
|
||||
]
|
||||
class SwI2cRequestExternal_t(Struct): pass
|
||||
uint32_t = ctypes.c_uint32
|
||||
SwI2cRequestExternal_t._fields_ = [
|
||||
('SwI2cRequest', SwI2cRequest_t),
|
||||
('Spare', (uint32_t * 8)),
|
||||
('MmHubPadding', (uint32_t * 8)),
|
||||
]
|
||||
class EccInfo_t(Struct): pass
|
||||
uint64_t = ctypes.c_uint64
|
||||
uint16_t = ctypes.c_uint16
|
||||
EccInfo_t._fields_ = [
|
||||
('mca_umc_status', uint64_t),
|
||||
('mca_umc_addr', uint64_t),
|
||||
('ce_count_lo_chip', uint16_t),
|
||||
('ce_count_hi_chip', uint16_t),
|
||||
('eccPadding', uint32_t),
|
||||
]
|
||||
class EccInfoTable_t(Struct): pass
|
||||
EccInfoTable_t._fields_ = [
|
||||
('EccInfo', (EccInfo_t * 24)),
|
||||
]
|
||||
class _anonstruct1(Struct): pass
|
||||
SwI2cCmd_t = _anonstruct1
|
||||
class _anonstruct2(Struct): pass
|
||||
SwI2cRequest_t = _anonstruct2
|
||||
class _anonstruct3(Struct): pass
|
||||
SwI2cRequestExternal_t = _anonstruct3
|
||||
class _anonstruct4(Struct): pass
|
||||
EccInfo_t = _anonstruct4
|
||||
class _anonstruct5(Struct): pass
|
||||
EccInfoTable_t = _anonstruct5
|
||||
D3HOTSequence_e = CEnum(ctypes.c_uint32)
|
||||
BACO_SEQUENCE = D3HOTSequence_e.define('BACO_SEQUENCE', 0)
|
||||
MSR_SEQUENCE = D3HOTSequence_e.define('MSR_SEQUENCE', 1)
|
||||
@@ -156,23 +122,12 @@ PowerGatingSettings_e = CEnum(ctypes.c_uint32)
|
||||
PG_POWER_DOWN = PowerGatingSettings_e.define('PG_POWER_DOWN', 0)
|
||||
PG_POWER_UP = PowerGatingSettings_e.define('PG_POWER_UP', 1)
|
||||
|
||||
class QuadraticInt_t(Struct): pass
|
||||
QuadraticInt_t._fields_ = [
|
||||
('a', uint32_t),
|
||||
('b', uint32_t),
|
||||
('c', uint32_t),
|
||||
]
|
||||
class LinearInt_t(Struct): pass
|
||||
LinearInt_t._fields_ = [
|
||||
('m', uint32_t),
|
||||
('b', uint32_t),
|
||||
]
|
||||
class DroopInt_t(Struct): pass
|
||||
DroopInt_t._fields_ = [
|
||||
('a', uint32_t),
|
||||
('b', uint32_t),
|
||||
('c', uint32_t),
|
||||
]
|
||||
class _anonstruct6(Struct): pass
|
||||
QuadraticInt_t = _anonstruct6
|
||||
class _anonstruct7(Struct): pass
|
||||
LinearInt_t = _anonstruct7
|
||||
class _anonstruct8(Struct): pass
|
||||
DroopInt_t = _anonstruct8
|
||||
DCS_ARCH_e = CEnum(ctypes.c_uint32)
|
||||
DCS_ARCH_DISABLED = DCS_ARCH_e.define('DCS_ARCH_DISABLED', 0)
|
||||
DCS_ARCH_FADCS = DCS_ARCH_e.define('DCS_ARCH_FADCS', 1)
|
||||
@@ -231,19 +186,8 @@ PWR_CONFIG_TGP = PwrConfig_e.define('PWR_CONFIG_TGP', 1)
|
||||
PWR_CONFIG_TCP_ESTIMATED = PwrConfig_e.define('PWR_CONFIG_TCP_ESTIMATED', 2)
|
||||
PWR_CONFIG_TCP_MEASURED = PwrConfig_e.define('PWR_CONFIG_TCP_MEASURED', 3)
|
||||
|
||||
class DpmDescriptor_t(Struct): pass
|
||||
DpmDescriptor_t._fields_ = [
|
||||
('Padding', uint8_t),
|
||||
('SnapToDiscrete', uint8_t),
|
||||
('NumDiscreteLevels', uint8_t),
|
||||
('CalculateFopt', uint8_t),
|
||||
('ConversionToAvfsClk', LinearInt_t),
|
||||
('Padding3', (uint32_t * 3)),
|
||||
('Padding4', uint16_t),
|
||||
('FoptimalDc', uint16_t),
|
||||
('FoptimalAc', uint16_t),
|
||||
('Padding2', uint16_t),
|
||||
]
|
||||
class _anonstruct9(Struct): pass
|
||||
DpmDescriptor_t = _anonstruct9
|
||||
PPT_THROTTLER_e = CEnum(ctypes.c_uint32)
|
||||
PPT_THROTTLER_PPT0 = PPT_THROTTLER_e.define('PPT_THROTTLER_PPT0', 0)
|
||||
PPT_THROTTLER_PPT1 = PPT_THROTTLER_e.define('PPT_THROTTLER_PPT1', 1)
|
||||
@@ -388,70 +332,18 @@ PP_GRTAVFS_FW_SEP_FUSE_FREQUENCY_TO_COUNT_SCALER_3 = PP_GRTAVFS_FW_SEP_FUSE_e.de
|
||||
PP_GRTAVFS_FW_SEP_FUSE_FREQUENCY_TO_COUNT_SCALER_4 = PP_GRTAVFS_FW_SEP_FUSE_e.define('PP_GRTAVFS_FW_SEP_FUSE_FREQUENCY_TO_COUNT_SCALER_4', 18)
|
||||
PP_GRTAVFS_FW_SEP_FUSE_COUNT = PP_GRTAVFS_FW_SEP_FUSE_e.define('PP_GRTAVFS_FW_SEP_FUSE_COUNT', 19)
|
||||
|
||||
class SviTelemetryScale_t(Struct): pass
|
||||
int8_t = ctypes.c_byte
|
||||
SviTelemetryScale_t._fields_ = [
|
||||
('Offset', int8_t),
|
||||
('Padding', uint8_t),
|
||||
('MaxCurrent', uint16_t),
|
||||
]
|
||||
class _anonstruct10(Struct): pass
|
||||
SviTelemetryScale_t = _anonstruct10
|
||||
FanMode_e = CEnum(ctypes.c_uint32)
|
||||
FAN_MODE_AUTO = FanMode_e.define('FAN_MODE_AUTO', 0)
|
||||
FAN_MODE_MANUAL_LINEAR = FanMode_e.define('FAN_MODE_MANUAL_LINEAR', 1)
|
||||
|
||||
class OverDriveTable_t(Struct): pass
|
||||
int16_t = ctypes.c_int16
|
||||
OverDriveTable_t._fields_ = [
|
||||
('FeatureCtrlMask', uint32_t),
|
||||
('VoltageOffsetPerZoneBoundary', (int16_t * 6)),
|
||||
('Reserved', uint32_t),
|
||||
('GfxclkFmin', int16_t),
|
||||
('GfxclkFmax', int16_t),
|
||||
('UclkFmin', uint16_t),
|
||||
('UclkFmax', uint16_t),
|
||||
('Ppt', int16_t),
|
||||
('Tdc', int16_t),
|
||||
('FanLinearPwmPoints', (uint8_t * 6)),
|
||||
('FanLinearTempPoints', (uint8_t * 6)),
|
||||
('FanMinimumPwm', uint16_t),
|
||||
('AcousticTargetRpmThreshold', uint16_t),
|
||||
('AcousticLimitRpmThreshold', uint16_t),
|
||||
('FanTargetTemperature', uint16_t),
|
||||
('FanZeroRpmEnable', uint8_t),
|
||||
('FanZeroRpmStopTemp', uint8_t),
|
||||
('FanMode', uint8_t),
|
||||
('MaxOpTemp', uint8_t),
|
||||
('Spare', (uint32_t * 13)),
|
||||
('MmHubPadding', (uint32_t * 8)),
|
||||
]
|
||||
class OverDriveTableExternal_t(Struct): pass
|
||||
OverDriveTableExternal_t._fields_ = [
|
||||
('OverDriveTable', OverDriveTable_t),
|
||||
]
|
||||
class OverDriveLimits_t(Struct): pass
|
||||
OverDriveLimits_t._fields_ = [
|
||||
('FeatureCtrlMask', uint32_t),
|
||||
('VoltageOffsetPerZoneBoundary', int16_t),
|
||||
('Reserved1', uint16_t),
|
||||
('Reserved2', uint16_t),
|
||||
('GfxclkFmin', int16_t),
|
||||
('GfxclkFmax', int16_t),
|
||||
('UclkFmin', uint16_t),
|
||||
('UclkFmax', uint16_t),
|
||||
('Ppt', int16_t),
|
||||
('Tdc', int16_t),
|
||||
('FanLinearPwmPoints', uint8_t),
|
||||
('FanLinearTempPoints', uint8_t),
|
||||
('FanMinimumPwm', uint16_t),
|
||||
('AcousticTargetRpmThreshold', uint16_t),
|
||||
('AcousticLimitRpmThreshold', uint16_t),
|
||||
('FanTargetTemperature', uint16_t),
|
||||
('FanZeroRpmEnable', uint8_t),
|
||||
('FanZeroRpmStopTemp', uint8_t),
|
||||
('FanMode', uint8_t),
|
||||
('MaxOpTemp', uint8_t),
|
||||
('Spare', (uint32_t * 13)),
|
||||
]
|
||||
class _anonstruct11(Struct): pass
|
||||
OverDriveTable_t = _anonstruct11
|
||||
class _anonstruct12(Struct): pass
|
||||
OverDriveTableExternal_t = _anonstruct12
|
||||
class _anonstruct13(Struct): pass
|
||||
OverDriveLimits_t = _anonstruct13
|
||||
BOARD_GPIO_TYPE_e = CEnum(ctypes.c_uint32)
|
||||
BOARD_GPIO_SMUIO_0 = BOARD_GPIO_TYPE_e.define('BOARD_GPIO_SMUIO_0', 0)
|
||||
BOARD_GPIO_SMUIO_1 = BOARD_GPIO_TYPE_e.define('BOARD_GPIO_SMUIO_1', 1)
|
||||
@@ -498,522 +390,52 @@ BOARD_GPIO_DC_GENLK_VSYNC = BOARD_GPIO_TYPE_e.define('BOARD_GPIO_DC_GENLK_VSYNC'
|
||||
BOARD_GPIO_DC_SWAPLOCK_A = BOARD_GPIO_TYPE_e.define('BOARD_GPIO_DC_SWAPLOCK_A', 42)
|
||||
BOARD_GPIO_DC_SWAPLOCK_B = BOARD_GPIO_TYPE_e.define('BOARD_GPIO_DC_SWAPLOCK_B', 43)
|
||||
|
||||
class BootValues_t(Struct): pass
|
||||
BootValues_t._fields_ = [
|
||||
('InitGfxclk_bypass', uint16_t),
|
||||
('InitSocclk', uint16_t),
|
||||
('InitMp0clk', uint16_t),
|
||||
('InitMpioclk', uint16_t),
|
||||
('InitSmnclk', uint16_t),
|
||||
('InitUcpclk', uint16_t),
|
||||
('InitCsrclk', uint16_t),
|
||||
('InitDprefclk', uint16_t),
|
||||
('InitDcfclk', uint16_t),
|
||||
('InitDtbclk', uint16_t),
|
||||
('InitDclk', uint16_t),
|
||||
('InitVclk', uint16_t),
|
||||
('InitUsbdfsclk', uint16_t),
|
||||
('InitMp1clk', uint16_t),
|
||||
('InitLclk', uint16_t),
|
||||
('InitBaco400clk_bypass', uint16_t),
|
||||
('InitBaco1200clk_bypass', uint16_t),
|
||||
('InitBaco700clk_bypass', uint16_t),
|
||||
('InitFclk', uint16_t),
|
||||
('InitGfxclk_clkb', uint16_t),
|
||||
('InitUclkDPMState', uint8_t),
|
||||
('Padding', (uint8_t * 3)),
|
||||
('InitVcoFreqPll0', uint32_t),
|
||||
('InitVcoFreqPll1', uint32_t),
|
||||
('InitVcoFreqPll2', uint32_t),
|
||||
('InitVcoFreqPll3', uint32_t),
|
||||
('InitVcoFreqPll4', uint32_t),
|
||||
('InitVcoFreqPll5', uint32_t),
|
||||
('InitVcoFreqPll6', uint32_t),
|
||||
('InitGfx', uint16_t),
|
||||
('InitSoc', uint16_t),
|
||||
('InitU', uint16_t),
|
||||
('Padding2', uint16_t),
|
||||
('Spare', (uint32_t * 8)),
|
||||
]
|
||||
class MsgLimits_t(Struct): pass
|
||||
MsgLimits_t._fields_ = [
|
||||
('Power', ((uint16_t * 2) * 4)),
|
||||
('Tdc', (uint16_t * 3)),
|
||||
('Temperature', (uint16_t * 13)),
|
||||
('PwmLimitMin', uint8_t),
|
||||
('PwmLimitMax', uint8_t),
|
||||
('FanTargetTemperature', uint8_t),
|
||||
('Spare1', (uint8_t * 1)),
|
||||
('AcousticTargetRpmThresholdMin', uint16_t),
|
||||
('AcousticTargetRpmThresholdMax', uint16_t),
|
||||
('AcousticLimitRpmThresholdMin', uint16_t),
|
||||
('AcousticLimitRpmThresholdMax', uint16_t),
|
||||
('PccLimitMin', uint16_t),
|
||||
('PccLimitMax', uint16_t),
|
||||
('FanStopTempMin', uint16_t),
|
||||
('FanStopTempMax', uint16_t),
|
||||
('FanStartTempMin', uint16_t),
|
||||
('FanStartTempMax', uint16_t),
|
||||
('PowerMinPpt0', (uint16_t * 2)),
|
||||
('Spare', (uint32_t * 11)),
|
||||
]
|
||||
class DriverReportedClocks_t(Struct): pass
|
||||
DriverReportedClocks_t._fields_ = [
|
||||
('BaseClockAc', uint16_t),
|
||||
('GameClockAc', uint16_t),
|
||||
('BoostClockAc', uint16_t),
|
||||
('BaseClockDc', uint16_t),
|
||||
('GameClockDc', uint16_t),
|
||||
('BoostClockDc', uint16_t),
|
||||
('Reserved', (uint32_t * 4)),
|
||||
]
|
||||
class AvfsDcBtcParams_t(Struct): pass
|
||||
AvfsDcBtcParams_t._fields_ = [
|
||||
('DcBtcEnabled', uint8_t),
|
||||
('Padding', (uint8_t * 3)),
|
||||
('DcTol', uint16_t),
|
||||
('DcBtcGb', uint16_t),
|
||||
('DcBtcMin', uint16_t),
|
||||
('DcBtcMax', uint16_t),
|
||||
('DcBtcGbScalar', LinearInt_t),
|
||||
]
|
||||
class AvfsFuseOverride_t(Struct): pass
|
||||
AvfsFuseOverride_t._fields_ = [
|
||||
('AvfsTemp', (uint16_t * 2)),
|
||||
('VftFMin', uint16_t),
|
||||
('VInversion', uint16_t),
|
||||
('qVft', (QuadraticInt_t * 2)),
|
||||
('qAvfsGb', QuadraticInt_t),
|
||||
('qAvfsGb2', QuadraticInt_t),
|
||||
]
|
||||
class SkuTable_t(Struct): pass
|
||||
int32_t = ctypes.c_int32
|
||||
SkuTable_t._fields_ = [
|
||||
('Version', uint32_t),
|
||||
('FeaturesToRun', (uint32_t * 2)),
|
||||
('TotalPowerConfig', uint8_t),
|
||||
('CustomerVariant', uint8_t),
|
||||
('MemoryTemperatureTypeMask', uint8_t),
|
||||
('SmartShiftVersion', uint8_t),
|
||||
('SocketPowerLimitAc', (uint16_t * 4)),
|
||||
('SocketPowerLimitDc', (uint16_t * 4)),
|
||||
('SocketPowerLimitSmartShift2', uint16_t),
|
||||
('EnableLegacyPptLimit', uint8_t),
|
||||
('UseInputTelemetry', uint8_t),
|
||||
('SmartShiftMinReportedPptinDcs', uint8_t),
|
||||
('PaddingPpt', (uint8_t * 1)),
|
||||
('VrTdcLimit', (uint16_t * 3)),
|
||||
('PlatformTdcLimit', (uint16_t * 3)),
|
||||
('TemperatureLimit', (uint16_t * 13)),
|
||||
('HwCtfTempLimit', uint16_t),
|
||||
('PaddingInfra', uint16_t),
|
||||
('FitControllerFailureRateLimit', uint32_t),
|
||||
('FitControllerGfxDutyCycle', uint32_t),
|
||||
('FitControllerSocDutyCycle', uint32_t),
|
||||
('FitControllerSocOffset', uint32_t),
|
||||
('GfxApccPlusResidencyLimit', uint32_t),
|
||||
('ThrottlerControlMask', uint32_t),
|
||||
('FwDStateMask', uint32_t),
|
||||
('UlvVoltageOffset', (uint16_t * 2)),
|
||||
('UlvVoltageOffsetU', uint16_t),
|
||||
('DeepUlvVoltageOffsetSoc', uint16_t),
|
||||
('DefaultMaxVoltage', (uint16_t * 2)),
|
||||
('BoostMaxVoltage', (uint16_t * 2)),
|
||||
('VminTempHystersis', (int16_t * 2)),
|
||||
('VminTempThreshold', (int16_t * 2)),
|
||||
('Vmin_Hot_T0', (uint16_t * 2)),
|
||||
('Vmin_Cold_T0', (uint16_t * 2)),
|
||||
('Vmin_Hot_Eol', (uint16_t * 2)),
|
||||
('Vmin_Cold_Eol', (uint16_t * 2)),
|
||||
('Vmin_Aging_Offset', (uint16_t * 2)),
|
||||
('Spare_Vmin_Plat_Offset_Hot', (uint16_t * 2)),
|
||||
('Spare_Vmin_Plat_Offset_Cold', (uint16_t * 2)),
|
||||
('VcBtcFixedVminAgingOffset', (uint16_t * 2)),
|
||||
('VcBtcVmin2PsmDegrationGb', (uint16_t * 2)),
|
||||
('VcBtcPsmA', (uint32_t * 2)),
|
||||
('VcBtcPsmB', (uint32_t * 2)),
|
||||
('VcBtcVminA', (uint32_t * 2)),
|
||||
('VcBtcVminB', (uint32_t * 2)),
|
||||
('PerPartVminEnabled', (uint8_t * 2)),
|
||||
('VcBtcEnabled', (uint8_t * 2)),
|
||||
('SocketPowerLimitAcTau', (uint16_t * 4)),
|
||||
('SocketPowerLimitDcTau', (uint16_t * 4)),
|
||||
('Vmin_droop', QuadraticInt_t),
|
||||
('SpareVmin', (uint32_t * 9)),
|
||||
('DpmDescriptor', (DpmDescriptor_t * 13)),
|
||||
('FreqTableGfx', (uint16_t * 16)),
|
||||
('FreqTableVclk', (uint16_t * 8)),
|
||||
('FreqTableDclk', (uint16_t * 8)),
|
||||
('FreqTableSocclk', (uint16_t * 8)),
|
||||
('FreqTableUclk', (uint16_t * 4)),
|
||||
('FreqTableDispclk', (uint16_t * 8)),
|
||||
('FreqTableDppClk', (uint16_t * 8)),
|
||||
('FreqTableDprefclk', (uint16_t * 8)),
|
||||
('FreqTableDcfclk', (uint16_t * 8)),
|
||||
('FreqTableDtbclk', (uint16_t * 8)),
|
||||
('FreqTableFclk', (uint16_t * 8)),
|
||||
('DcModeMaxFreq', (uint32_t * 13)),
|
||||
('Mp0clkFreq', (uint16_t * 2)),
|
||||
('Mp0DpmVoltage', (uint16_t * 2)),
|
||||
('GfxclkSpare', (uint8_t * 2)),
|
||||
('GfxclkFreqCap', uint16_t),
|
||||
('GfxclkFgfxoffEntry', uint16_t),
|
||||
('GfxclkFgfxoffExitImu', uint16_t),
|
||||
('GfxclkFgfxoffExitRlc', uint16_t),
|
||||
('GfxclkThrottleClock', uint16_t),
|
||||
('EnableGfxPowerStagesGpio', uint8_t),
|
||||
('GfxIdlePadding', uint8_t),
|
||||
('SmsRepairWRCKClkDivEn', uint8_t),
|
||||
('SmsRepairWRCKClkDivVal', uint8_t),
|
||||
('GfxOffEntryEarlyMGCGEn', uint8_t),
|
||||
('GfxOffEntryForceCGCGEn', uint8_t),
|
||||
('GfxOffEntryForceCGCGDelayEn', uint8_t),
|
||||
('GfxOffEntryForceCGCGDelayVal', uint8_t),
|
||||
('GfxclkFreqGfxUlv', uint16_t),
|
||||
('GfxIdlePadding2', (uint8_t * 2)),
|
||||
('GfxOffEntryHysteresis', uint32_t),
|
||||
('GfxoffSpare', (uint32_t * 15)),
|
||||
('DfllBtcMasterScalerM', uint32_t),
|
||||
('DfllBtcMasterScalerB', int32_t),
|
||||
('DfllBtcSlaveScalerM', uint32_t),
|
||||
('DfllBtcSlaveScalerB', int32_t),
|
||||
('DfllPccAsWaitCtrl', uint32_t),
|
||||
('DfllPccAsStepCtrl', uint32_t),
|
||||
('DfllL2FrequencyBoostM', uint32_t),
|
||||
('DfllL2FrequencyBoostB', uint32_t),
|
||||
('GfxGpoSpare', (uint32_t * 8)),
|
||||
('DcsGfxOffVoltage', uint16_t),
|
||||
('PaddingDcs', uint16_t),
|
||||
('DcsMinGfxOffTime', uint16_t),
|
||||
('DcsMaxGfxOffTime', uint16_t),
|
||||
('DcsMinCreditAccum', uint32_t),
|
||||
('DcsExitHysteresis', uint16_t),
|
||||
('DcsTimeout', uint16_t),
|
||||
('FoptEnabled', uint8_t),
|
||||
('DcsSpare2', (uint8_t * 3)),
|
||||
('DcsFoptM', uint32_t),
|
||||
('DcsFoptB', uint32_t),
|
||||
('DcsSpare', (uint32_t * 11)),
|
||||
('ShadowFreqTableUclk', (uint16_t * 4)),
|
||||
('UseStrobeModeOptimizations', uint8_t),
|
||||
('PaddingMem', (uint8_t * 3)),
|
||||
('UclkDpmPstates', (uint8_t * 4)),
|
||||
('FreqTableUclkDiv', (uint8_t * 4)),
|
||||
('MemVmempVoltage', (uint16_t * 4)),
|
||||
('MemVddioVoltage', (uint16_t * 4)),
|
||||
('FclkDpmUPstates', (uint8_t * 8)),
|
||||
('FclkDpmVddU', (uint16_t * 8)),
|
||||
('FclkDpmUSpeed', (uint16_t * 8)),
|
||||
('FclkDpmDisallowPstateFreq', uint16_t),
|
||||
('PaddingFclk', uint16_t),
|
||||
('PcieGenSpeed', (uint8_t * 3)),
|
||||
('PcieLaneCount', (uint8_t * 3)),
|
||||
('LclkFreq', (uint16_t * 3)),
|
||||
('FanStopTemp', (uint16_t * 13)),
|
||||
('FanStartTemp', (uint16_t * 13)),
|
||||
('FanGain', (uint16_t * 13)),
|
||||
('FanGainPadding', uint16_t),
|
||||
('FanPwmMin', uint16_t),
|
||||
('AcousticTargetRpmThreshold', uint16_t),
|
||||
('AcousticLimitRpmThreshold', uint16_t),
|
||||
('FanMaximumRpm', uint16_t),
|
||||
('MGpuAcousticLimitRpmThreshold', uint16_t),
|
||||
('FanTargetGfxclk', uint16_t),
|
||||
('TempInputSelectMask', uint32_t),
|
||||
('FanZeroRpmEnable', uint8_t),
|
||||
('FanTachEdgePerRev', uint8_t),
|
||||
('FanTargetTemperature', (uint16_t * 13)),
|
||||
('FuzzyFan_ErrorSetDelta', int16_t),
|
||||
('FuzzyFan_ErrorRateSetDelta', int16_t),
|
||||
('FuzzyFan_PwmSetDelta', int16_t),
|
||||
('FuzzyFan_Reserved', uint16_t),
|
||||
('FwCtfLimit', (uint16_t * 13)),
|
||||
('IntakeTempEnableRPM', uint16_t),
|
||||
('IntakeTempOffsetTemp', int16_t),
|
||||
('IntakeTempReleaseTemp', uint16_t),
|
||||
('IntakeTempHighIntakeAcousticLimit', uint16_t),
|
||||
('IntakeTempAcouticLimitReleaseRate', uint16_t),
|
||||
('FanAbnormalTempLimitOffset', int16_t),
|
||||
('FanStalledTriggerRpm', uint16_t),
|
||||
('FanAbnormalTriggerRpmCoeff', uint16_t),
|
||||
('FanAbnormalDetectionEnable', uint16_t),
|
||||
('FanIntakeSensorSupport', uint8_t),
|
||||
('FanIntakePadding', (uint8_t * 3)),
|
||||
('FanSpare', (uint32_t * 13)),
|
||||
('OverrideGfxAvfsFuses', uint8_t),
|
||||
('GfxAvfsPadding', (uint8_t * 3)),
|
||||
('L2HwRtAvfsFuses', (uint32_t * 32)),
|
||||
('SeHwRtAvfsFuses', (uint32_t * 32)),
|
||||
('CommonRtAvfs', (uint32_t * 13)),
|
||||
('L2FwRtAvfsFuses', (uint32_t * 19)),
|
||||
('SeFwRtAvfsFuses', (uint32_t * 19)),
|
||||
('Droop_PWL_F', (uint32_t * 5)),
|
||||
('Droop_PWL_a', (uint32_t * 5)),
|
||||
('Droop_PWL_b', (uint32_t * 5)),
|
||||
('Droop_PWL_c', (uint32_t * 5)),
|
||||
('Static_PWL_Offset', (uint32_t * 5)),
|
||||
('dGbV_dT_vmin', uint32_t),
|
||||
('dGbV_dT_vmax', uint32_t),
|
||||
('V2F_vmin_range_low', uint32_t),
|
||||
('V2F_vmin_range_high', uint32_t),
|
||||
('V2F_vmax_range_low', uint32_t),
|
||||
('V2F_vmax_range_high', uint32_t),
|
||||
('DcBtcGfxParams', AvfsDcBtcParams_t),
|
||||
('GfxAvfsSpare', (uint32_t * 32)),
|
||||
('OverrideSocAvfsFuses', uint8_t),
|
||||
('MinSocAvfsRevision', uint8_t),
|
||||
('SocAvfsPadding', (uint8_t * 2)),
|
||||
('SocAvfsFuseOverride', (AvfsFuseOverride_t * 3)),
|
||||
('dBtcGbSoc', (DroopInt_t * 3)),
|
||||
('qAgingGb', (LinearInt_t * 3)),
|
||||
('qStaticVoltageOffset', (QuadraticInt_t * 3)),
|
||||
('DcBtcSocParams', (AvfsDcBtcParams_t * 3)),
|
||||
('SocAvfsSpare', (uint32_t * 32)),
|
||||
('BootValues', BootValues_t),
|
||||
('DriverReportedClocks', DriverReportedClocks_t),
|
||||
('MsgLimits', MsgLimits_t),
|
||||
('OverDriveLimitsMin', OverDriveLimits_t),
|
||||
('OverDriveLimitsBasicMax', OverDriveLimits_t),
|
||||
('reserved', (uint32_t * 22)),
|
||||
('DebugOverrides', uint32_t),
|
||||
('TotalBoardPowerSupport', uint8_t),
|
||||
('TotalBoardPowerPadding', (uint8_t * 3)),
|
||||
('TotalIdleBoardPowerM', int16_t),
|
||||
('TotalIdleBoardPowerB', int16_t),
|
||||
('TotalBoardPowerM', int16_t),
|
||||
('TotalBoardPowerB', int16_t),
|
||||
('qFeffCoeffGameClock', (QuadraticInt_t * 2)),
|
||||
('qFeffCoeffBaseClock', (QuadraticInt_t * 2)),
|
||||
('qFeffCoeffBoostClock', (QuadraticInt_t * 2)),
|
||||
('TemperatureLimit_Hynix', uint16_t),
|
||||
('TemperatureLimit_Micron', uint16_t),
|
||||
('TemperatureFwCtfLimit_Hynix', uint16_t),
|
||||
('TemperatureFwCtfLimit_Micron', uint16_t),
|
||||
('Spare', (uint32_t * 41)),
|
||||
('MmHubPadding', (uint32_t * 8)),
|
||||
]
|
||||
class BoardTable_t(Struct): pass
|
||||
BoardTable_t._fields_ = [
|
||||
('Version', uint32_t),
|
||||
('I2cControllers', (I2cControllerConfig_t * 8)),
|
||||
('VddGfxVrMapping', uint8_t),
|
||||
('VddSocVrMapping', uint8_t),
|
||||
('VddMem0VrMapping', uint8_t),
|
||||
('VddMem1VrMapping', uint8_t),
|
||||
('GfxUlvPhaseSheddingMask', uint8_t),
|
||||
('SocUlvPhaseSheddingMask', uint8_t),
|
||||
('VmempUlvPhaseSheddingMask', uint8_t),
|
||||
('VddioUlvPhaseSheddingMask', uint8_t),
|
||||
('SlaveAddrMapping', (uint8_t * 5)),
|
||||
('VrPsiSupport', (uint8_t * 5)),
|
||||
('PaddingPsi', (uint8_t * 5)),
|
||||
('EnablePsi6', (uint8_t * 5)),
|
||||
('SviTelemetryScale', (SviTelemetryScale_t * 5)),
|
||||
('VoltageTelemetryRatio', (uint32_t * 5)),
|
||||
('DownSlewRateVr', (uint8_t * 5)),
|
||||
('LedOffGpio', uint8_t),
|
||||
('FanOffGpio', uint8_t),
|
||||
('GfxVrPowerStageOffGpio', uint8_t),
|
||||
('AcDcGpio', uint8_t),
|
||||
('AcDcPolarity', uint8_t),
|
||||
('VR0HotGpio', uint8_t),
|
||||
('VR0HotPolarity', uint8_t),
|
||||
('GthrGpio', uint8_t),
|
||||
('GthrPolarity', uint8_t),
|
||||
('LedPin0', uint8_t),
|
||||
('LedPin1', uint8_t),
|
||||
('LedPin2', uint8_t),
|
||||
('LedEnableMask', uint8_t),
|
||||
('LedPcie', uint8_t),
|
||||
('LedError', uint8_t),
|
||||
('UclkTrainingModeSpreadPercent', uint8_t),
|
||||
('UclkSpreadPadding', uint8_t),
|
||||
('UclkSpreadFreq', uint16_t),
|
||||
('UclkSpreadPercent', (uint8_t * 16)),
|
||||
('GfxclkSpreadEnable', uint8_t),
|
||||
('FclkSpreadPercent', uint8_t),
|
||||
('FclkSpreadFreq', uint16_t),
|
||||
('DramWidth', uint8_t),
|
||||
('PaddingMem1', (uint8_t * 7)),
|
||||
('HsrEnabled', uint8_t),
|
||||
('VddqOffEnabled', uint8_t),
|
||||
('PaddingUmcFlags', (uint8_t * 2)),
|
||||
('PostVoltageSetBacoDelay', uint32_t),
|
||||
('BacoEntryDelay', uint32_t),
|
||||
('FuseWritePowerMuxPresent', uint8_t),
|
||||
('FuseWritePadding', (uint8_t * 3)),
|
||||
('BoardSpare', (uint32_t * 63)),
|
||||
('MmHubPadding', (uint32_t * 8)),
|
||||
]
|
||||
class PPTable_t(Struct): pass
|
||||
PPTable_t._packed_ = True
|
||||
PPTable_t._fields_ = [
|
||||
('SkuTable', SkuTable_t),
|
||||
('BoardTable', BoardTable_t),
|
||||
]
|
||||
class DriverSmuConfig_t(Struct): pass
|
||||
DriverSmuConfig_t._fields_ = [
|
||||
('GfxclkAverageLpfTau', uint16_t),
|
||||
('FclkAverageLpfTau', uint16_t),
|
||||
('UclkAverageLpfTau', uint16_t),
|
||||
('GfxActivityLpfTau', uint16_t),
|
||||
('UclkActivityLpfTau', uint16_t),
|
||||
('SocketPowerLpfTau', uint16_t),
|
||||
('VcnClkAverageLpfTau', uint16_t),
|
||||
('VcnUsageAverageLpfTau', uint16_t),
|
||||
]
|
||||
class DriverSmuConfigExternal_t(Struct): pass
|
||||
DriverSmuConfigExternal_t._fields_ = [
|
||||
('DriverSmuConfig', DriverSmuConfig_t),
|
||||
('Spare', (uint32_t * 8)),
|
||||
('MmHubPadding', (uint32_t * 8)),
|
||||
]
|
||||
class DriverInfoTable_t(Struct): pass
|
||||
DriverInfoTable_t._fields_ = [
|
||||
('FreqTableGfx', (uint16_t * 16)),
|
||||
('FreqTableVclk', (uint16_t * 8)),
|
||||
('FreqTableDclk', (uint16_t * 8)),
|
||||
('FreqTableSocclk', (uint16_t * 8)),
|
||||
('FreqTableUclk', (uint16_t * 4)),
|
||||
('FreqTableDispclk', (uint16_t * 8)),
|
||||
('FreqTableDppClk', (uint16_t * 8)),
|
||||
('FreqTableDprefclk', (uint16_t * 8)),
|
||||
('FreqTableDcfclk', (uint16_t * 8)),
|
||||
('FreqTableDtbclk', (uint16_t * 8)),
|
||||
('FreqTableFclk', (uint16_t * 8)),
|
||||
('DcModeMaxFreq', (uint16_t * 13)),
|
||||
('Padding', uint16_t),
|
||||
('Spare', (uint32_t * 32)),
|
||||
('MmHubPadding', (uint32_t * 8)),
|
||||
]
|
||||
class SmuMetrics_t(Struct): pass
|
||||
SmuMetrics_t._fields_ = [
|
||||
('CurrClock', (uint32_t * 13)),
|
||||
('AverageGfxclkFrequencyTarget', uint16_t),
|
||||
('AverageGfxclkFrequencyPreDs', uint16_t),
|
||||
('AverageGfxclkFrequencyPostDs', uint16_t),
|
||||
('AverageFclkFrequencyPreDs', uint16_t),
|
||||
('AverageFclkFrequencyPostDs', uint16_t),
|
||||
('AverageMemclkFrequencyPreDs', uint16_t),
|
||||
('AverageMemclkFrequencyPostDs', uint16_t),
|
||||
('AverageVclk0Frequency', uint16_t),
|
||||
('AverageDclk0Frequency', uint16_t),
|
||||
('AverageVclk1Frequency', uint16_t),
|
||||
('AverageDclk1Frequency', uint16_t),
|
||||
('PCIeBusy', uint16_t),
|
||||
('dGPU_W_MAX', uint16_t),
|
||||
('padding', uint16_t),
|
||||
('MetricsCounter', uint32_t),
|
||||
('AvgVoltage', (uint16_t * 5)),
|
||||
('AvgCurrent', (uint16_t * 5)),
|
||||
('AverageGfxActivity', uint16_t),
|
||||
('AverageUclkActivity', uint16_t),
|
||||
('Vcn0ActivityPercentage', uint16_t),
|
||||
('Vcn1ActivityPercentage', uint16_t),
|
||||
('EnergyAccumulator', uint32_t),
|
||||
('AverageSocketPower', uint16_t),
|
||||
('AverageTotalBoardPower', uint16_t),
|
||||
('AvgTemperature', (uint16_t * 13)),
|
||||
('AvgTemperatureFanIntake', uint16_t),
|
||||
('PcieRate', uint8_t),
|
||||
('PcieWidth', uint8_t),
|
||||
('AvgFanPwm', uint8_t),
|
||||
('Padding', (uint8_t * 1)),
|
||||
('AvgFanRpm', uint16_t),
|
||||
('ThrottlingPercentage', (uint8_t * 22)),
|
||||
('VmaxThrottlingPercentage', uint8_t),
|
||||
('Padding1', (uint8_t * 3)),
|
||||
('D3HotEntryCountPerMode', (uint32_t * 4)),
|
||||
('D3HotExitCountPerMode', (uint32_t * 4)),
|
||||
('ArmMsgReceivedCountPerMode', (uint32_t * 4)),
|
||||
('ApuSTAPMSmartShiftLimit', uint16_t),
|
||||
('ApuSTAPMLimit', uint16_t),
|
||||
('AvgApuSocketPower', uint16_t),
|
||||
('AverageUclkActivity_MAX', uint16_t),
|
||||
('PublicSerialNumberLower', uint32_t),
|
||||
('PublicSerialNumberUpper', uint32_t),
|
||||
]
|
||||
class SmuMetricsExternal_t(Struct): pass
|
||||
SmuMetricsExternal_t._fields_ = [
|
||||
('SmuMetrics', SmuMetrics_t),
|
||||
('Spare', (uint32_t * 29)),
|
||||
('MmHubPadding', (uint32_t * 8)),
|
||||
]
|
||||
class WatermarkRowGeneric_t(Struct): pass
|
||||
WatermarkRowGeneric_t._fields_ = [
|
||||
('WmSetting', uint8_t),
|
||||
('Flags', uint8_t),
|
||||
('Padding', (uint8_t * 2)),
|
||||
]
|
||||
class _anonstruct14(Struct): pass
|
||||
BootValues_t = _anonstruct14
|
||||
class _anonstruct15(Struct): pass
|
||||
MsgLimits_t = _anonstruct15
|
||||
class _anonstruct16(Struct): pass
|
||||
DriverReportedClocks_t = _anonstruct16
|
||||
class _anonstruct17(Struct): pass
|
||||
AvfsDcBtcParams_t = _anonstruct17
|
||||
class _anonstruct18(Struct): pass
|
||||
AvfsFuseOverride_t = _anonstruct18
|
||||
class _anonstruct19(Struct): pass
|
||||
SkuTable_t = _anonstruct19
|
||||
class _anonstruct20(Struct): pass
|
||||
BoardTable_t = _anonstruct20
|
||||
class _anonstruct21(Struct): pass
|
||||
PPTable_t = _anonstruct21
|
||||
class _anonstruct22(Struct): pass
|
||||
DriverSmuConfig_t = _anonstruct22
|
||||
class _anonstruct23(Struct): pass
|
||||
DriverSmuConfigExternal_t = _anonstruct23
|
||||
class _anonstruct24(Struct): pass
|
||||
DriverInfoTable_t = _anonstruct24
|
||||
class _anonstruct25(Struct): pass
|
||||
SmuMetrics_t = _anonstruct25
|
||||
class _anonstruct26(Struct): pass
|
||||
SmuMetricsExternal_t = _anonstruct26
|
||||
class _anonstruct27(Struct): pass
|
||||
WatermarkRowGeneric_t = _anonstruct27
|
||||
WATERMARKS_FLAGS_e = CEnum(ctypes.c_uint32)
|
||||
WATERMARKS_CLOCK_RANGE = WATERMARKS_FLAGS_e.define('WATERMARKS_CLOCK_RANGE', 0)
|
||||
WATERMARKS_DUMMY_PSTATE = WATERMARKS_FLAGS_e.define('WATERMARKS_DUMMY_PSTATE', 1)
|
||||
WATERMARKS_MALL = WATERMARKS_FLAGS_e.define('WATERMARKS_MALL', 2)
|
||||
WATERMARKS_COUNT = WATERMARKS_FLAGS_e.define('WATERMARKS_COUNT', 3)
|
||||
|
||||
class Watermarks_t(Struct): pass
|
||||
Watermarks_t._fields_ = [
|
||||
('WatermarkRow', (WatermarkRowGeneric_t * 4)),
|
||||
]
|
||||
class WatermarksExternal_t(Struct): pass
|
||||
WatermarksExternal_t._fields_ = [
|
||||
('Watermarks', Watermarks_t),
|
||||
('Spare', (uint32_t * 16)),
|
||||
('MmHubPadding', (uint32_t * 8)),
|
||||
]
|
||||
class AvfsDebugTable_t(Struct): pass
|
||||
AvfsDebugTable_t._fields_ = [
|
||||
('avgPsmCount', (uint16_t * 214)),
|
||||
('minPsmCount', (uint16_t * 214)),
|
||||
('avgPsmVoltage', (ctypes.c_float * 214)),
|
||||
('minPsmVoltage', (ctypes.c_float * 214)),
|
||||
]
|
||||
class AvfsDebugTableExternal_t(Struct): pass
|
||||
AvfsDebugTableExternal_t._fields_ = [
|
||||
('AvfsDebugTable', AvfsDebugTable_t),
|
||||
('MmHubPadding', (uint32_t * 8)),
|
||||
]
|
||||
class DpmActivityMonitorCoeffInt_t(Struct): pass
|
||||
DpmActivityMonitorCoeffInt_t._fields_ = [
|
||||
('Gfx_ActiveHystLimit', uint8_t),
|
||||
('Gfx_IdleHystLimit', uint8_t),
|
||||
('Gfx_FPS', uint8_t),
|
||||
('Gfx_MinActiveFreqType', uint8_t),
|
||||
('Gfx_BoosterFreqType', uint8_t),
|
||||
('PaddingGfx', uint8_t),
|
||||
('Gfx_MinActiveFreq', uint16_t),
|
||||
('Gfx_BoosterFreq', uint16_t),
|
||||
('Gfx_PD_Data_time_constant', uint16_t),
|
||||
('Gfx_PD_Data_limit_a', uint32_t),
|
||||
('Gfx_PD_Data_limit_b', uint32_t),
|
||||
('Gfx_PD_Data_limit_c', uint32_t),
|
||||
('Gfx_PD_Data_error_coeff', uint32_t),
|
||||
('Gfx_PD_Data_error_rate_coeff', uint32_t),
|
||||
('Fclk_ActiveHystLimit', uint8_t),
|
||||
('Fclk_IdleHystLimit', uint8_t),
|
||||
('Fclk_FPS', uint8_t),
|
||||
('Fclk_MinActiveFreqType', uint8_t),
|
||||
('Fclk_BoosterFreqType', uint8_t),
|
||||
('PaddingFclk', uint8_t),
|
||||
('Fclk_MinActiveFreq', uint16_t),
|
||||
('Fclk_BoosterFreq', uint16_t),
|
||||
('Fclk_PD_Data_time_constant', uint16_t),
|
||||
('Fclk_PD_Data_limit_a', uint32_t),
|
||||
('Fclk_PD_Data_limit_b', uint32_t),
|
||||
('Fclk_PD_Data_limit_c', uint32_t),
|
||||
('Fclk_PD_Data_error_coeff', uint32_t),
|
||||
('Fclk_PD_Data_error_rate_coeff', uint32_t),
|
||||
('Mem_UpThreshold_Limit', (uint32_t * 4)),
|
||||
('Mem_UpHystLimit', (uint8_t * 4)),
|
||||
('Mem_DownHystLimit', (uint8_t * 4)),
|
||||
('Mem_Fps', uint16_t),
|
||||
('padding', (uint8_t * 2)),
|
||||
]
|
||||
class DpmActivityMonitorCoeffIntExternal_t(Struct): pass
|
||||
DpmActivityMonitorCoeffIntExternal_t._fields_ = [
|
||||
('DpmActivityMonitorCoeffInt', DpmActivityMonitorCoeffInt_t),
|
||||
('MmHubPadding', (uint32_t * 8)),
|
||||
]
|
||||
class _anonstruct28(Struct): pass
|
||||
Watermarks_t = _anonstruct28
|
||||
class _anonstruct29(Struct): pass
|
||||
WatermarksExternal_t = _anonstruct29
|
||||
class _anonstruct30(Struct): pass
|
||||
AvfsDebugTable_t = _anonstruct30
|
||||
class _anonstruct31(Struct): pass
|
||||
AvfsDebugTableExternal_t = _anonstruct31
|
||||
class _anonstruct32(Struct): pass
|
||||
DpmActivityMonitorCoeffInt_t = _anonstruct32
|
||||
class _anonstruct33(Struct): pass
|
||||
DpmActivityMonitorCoeffIntExternal_t = _anonstruct33
|
||||
class struct_smu_hw_power_state(Struct): pass
|
||||
struct_smu_hw_power_state._fields_ = [
|
||||
('magic', ctypes.c_uint32),
|
||||
|
||||
@@ -1,531 +0,0 @@
|
||||
# mypy: ignore-errors
|
||||
import ctypes
|
||||
from tinygrad.helpers import unwrap
|
||||
from tinygrad.runtime.support.c import Struct, CEnum, _IO, _IOW, _IOR, _IOWR
|
||||
PPSMC_Result = ctypes.c_uint32
|
||||
PPSMC_MSG = ctypes.c_uint32
|
||||
I2cControllerPort_e = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
I2cSpeed_e = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
I2cCmdType_e = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
ERR_CODE_e = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
GC_ERROR_CODE_e = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
class SwI2cCmd_t(Struct): pass
|
||||
uint8_t = ctypes.c_ubyte
|
||||
SwI2cCmd_t._fields_ = [
|
||||
('ReadWriteData', uint8_t),
|
||||
('CmdConfig', uint8_t),
|
||||
]
|
||||
class SwI2cRequest_t(Struct): pass
|
||||
SwI2cRequest_t._fields_ = [
|
||||
('I2CcontrollerPort', uint8_t),
|
||||
('I2CSpeed', uint8_t),
|
||||
('SlaveAddress', uint8_t),
|
||||
('NumCmds', uint8_t),
|
||||
('SwI2cCmds', (SwI2cCmd_t * 24)),
|
||||
]
|
||||
class SwI2cRequestExternal_t(Struct): pass
|
||||
uint32_t = ctypes.c_uint32
|
||||
SwI2cRequestExternal_t._fields_ = [
|
||||
('SwI2cRequest', SwI2cRequest_t),
|
||||
('Spare', (uint32_t * 8)),
|
||||
('MmHubPadding', (uint32_t * 8)),
|
||||
]
|
||||
PPCLK_e = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
GpioIntPolarity_e = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
UCLK_DPM_MODE_e = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
class AvfsDebugTableAid_t(Struct): pass
|
||||
uint16_t = ctypes.c_uint16
|
||||
AvfsDebugTableAid_t._fields_ = [
|
||||
('avgPsmCount', (uint16_t * 30)),
|
||||
('minPsmCount', (uint16_t * 30)),
|
||||
('avgPsmVoltage', (ctypes.c_float * 30)),
|
||||
('minPsmVoltage', (ctypes.c_float * 30)),
|
||||
]
|
||||
class AvfsDebugTableXcd_t(Struct): pass
|
||||
AvfsDebugTableXcd_t._fields_ = [
|
||||
('avgPsmCount', (uint16_t * 30)),
|
||||
('minPsmCount', (uint16_t * 30)),
|
||||
('avgPsmVoltage', (ctypes.c_float * 30)),
|
||||
('minPsmVoltage', (ctypes.c_float * 30)),
|
||||
]
|
||||
class struct_smu_hw_power_state(Struct): pass
|
||||
struct_smu_hw_power_state._fields_ = [
|
||||
('magic', ctypes.c_uint32),
|
||||
]
|
||||
class struct_smu_power_state(Struct): pass
|
||||
enum_smu_state_ui_label = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
enum_smu_state_classification_flag = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
class struct_smu_state_classification_block(Struct): pass
|
||||
struct_smu_state_classification_block._fields_ = [
|
||||
('ui_label', enum_smu_state_ui_label),
|
||||
('flags', enum_smu_state_classification_flag),
|
||||
('bios_index', ctypes.c_int32),
|
||||
('temporary_state', ctypes.c_bool),
|
||||
('to_be_deleted', ctypes.c_bool),
|
||||
]
|
||||
class struct_smu_state_pcie_block(Struct): pass
|
||||
struct_smu_state_pcie_block._fields_ = [
|
||||
('lanes', ctypes.c_uint32),
|
||||
]
|
||||
enum_smu_refreshrate_source = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
class struct_smu_state_display_block(Struct): pass
|
||||
struct_smu_state_display_block._fields_ = [
|
||||
('disable_frame_modulation', ctypes.c_bool),
|
||||
('limit_refreshrate', ctypes.c_bool),
|
||||
('refreshrate_source', enum_smu_refreshrate_source),
|
||||
('explicit_refreshrate', ctypes.c_int32),
|
||||
('edid_refreshrate_index', ctypes.c_int32),
|
||||
('enable_vari_bright', ctypes.c_bool),
|
||||
]
|
||||
class struct_smu_state_memory_block(Struct): pass
|
||||
struct_smu_state_memory_block._fields_ = [
|
||||
('dll_off', ctypes.c_bool),
|
||||
('m3arb', ctypes.c_ubyte),
|
||||
('unused', (ctypes.c_ubyte * 3)),
|
||||
]
|
||||
class struct_smu_state_software_algorithm_block(Struct): pass
|
||||
struct_smu_state_software_algorithm_block._fields_ = [
|
||||
('disable_load_balancing', ctypes.c_bool),
|
||||
('enable_sleep_for_timestamps', ctypes.c_bool),
|
||||
]
|
||||
class struct_smu_temperature_range(Struct): pass
|
||||
struct_smu_temperature_range._fields_ = [
|
||||
('min', ctypes.c_int32),
|
||||
('max', ctypes.c_int32),
|
||||
('edge_emergency_max', ctypes.c_int32),
|
||||
('hotspot_min', ctypes.c_int32),
|
||||
('hotspot_crit_max', ctypes.c_int32),
|
||||
('hotspot_emergency_max', ctypes.c_int32),
|
||||
('mem_min', ctypes.c_int32),
|
||||
('mem_crit_max', ctypes.c_int32),
|
||||
('mem_emergency_max', ctypes.c_int32),
|
||||
('software_shutdown_temp', ctypes.c_int32),
|
||||
('software_shutdown_temp_offset', ctypes.c_int32),
|
||||
]
|
||||
class struct_smu_state_validation_block(Struct): pass
|
||||
struct_smu_state_validation_block._fields_ = [
|
||||
('single_display_only', ctypes.c_bool),
|
||||
('disallow_on_dc', ctypes.c_bool),
|
||||
('supported_power_levels', ctypes.c_ubyte),
|
||||
]
|
||||
class struct_smu_uvd_clocks(Struct): pass
|
||||
struct_smu_uvd_clocks._fields_ = [
|
||||
('vclk', ctypes.c_uint32),
|
||||
('dclk', ctypes.c_uint32),
|
||||
]
|
||||
enum_smu_power_src_type = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
enum_smu_ppt_limit_type = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
enum_smu_ppt_limit_level = CEnum(ctypes.c_int32)
|
||||
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)
|
||||
|
||||
enum_smu_memory_pool_size = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
enum_smu_clk_type = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
class struct_smu_user_dpm_profile(Struct): pass
|
||||
struct_smu_user_dpm_profile._fields_ = [
|
||||
('fan_mode', ctypes.c_uint32),
|
||||
('power_limit', ctypes.c_uint32),
|
||||
('fan_speed_pwm', ctypes.c_uint32),
|
||||
('fan_speed_rpm', ctypes.c_uint32),
|
||||
('flags', ctypes.c_uint32),
|
||||
('user_od', ctypes.c_uint32),
|
||||
('clk_mask', (ctypes.c_uint32 * 28)),
|
||||
('clk_dependency', ctypes.c_uint32),
|
||||
]
|
||||
class struct_smu_table(Struct): pass
|
||||
class struct_amdgpu_bo(Struct): pass
|
||||
struct_smu_table._fields_ = [
|
||||
('size', ctypes.c_uint64),
|
||||
('align', ctypes.c_uint32),
|
||||
('domain', ctypes.c_ubyte),
|
||||
('mc_address', ctypes.c_uint64),
|
||||
('cpu_addr', ctypes.c_void_p),
|
||||
('bo', ctypes.POINTER(struct_amdgpu_bo)),
|
||||
('version', ctypes.c_uint32),
|
||||
]
|
||||
enum_smu_perf_level_designation = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
class struct_smu_performance_level(Struct): pass
|
||||
struct_smu_performance_level._fields_ = [
|
||||
('core_clock', ctypes.c_uint32),
|
||||
('memory_clock', ctypes.c_uint32),
|
||||
('vddc', ctypes.c_uint32),
|
||||
('vddci', ctypes.c_uint32),
|
||||
('non_local_mem_freq', ctypes.c_uint32),
|
||||
('non_local_mem_width', ctypes.c_uint32),
|
||||
]
|
||||
class struct_smu_clock_info(Struct): pass
|
||||
struct_smu_clock_info._fields_ = [
|
||||
('min_mem_clk', ctypes.c_uint32),
|
||||
('max_mem_clk', ctypes.c_uint32),
|
||||
('min_eng_clk', ctypes.c_uint32),
|
||||
('max_eng_clk', ctypes.c_uint32),
|
||||
('min_bus_bandwidth', ctypes.c_uint32),
|
||||
('max_bus_bandwidth', ctypes.c_uint32),
|
||||
]
|
||||
class struct_smu_bios_boot_up_values(Struct): pass
|
||||
struct_smu_bios_boot_up_values._fields_ = [
|
||||
('revision', ctypes.c_uint32),
|
||||
('gfxclk', ctypes.c_uint32),
|
||||
('uclk', ctypes.c_uint32),
|
||||
('socclk', ctypes.c_uint32),
|
||||
('dcefclk', ctypes.c_uint32),
|
||||
('eclk', ctypes.c_uint32),
|
||||
('vclk', ctypes.c_uint32),
|
||||
('dclk', ctypes.c_uint32),
|
||||
('vddc', ctypes.c_uint16),
|
||||
('vddci', ctypes.c_uint16),
|
||||
('mvddc', ctypes.c_uint16),
|
||||
('vdd_gfx', ctypes.c_uint16),
|
||||
('cooling_id', ctypes.c_ubyte),
|
||||
('pp_table_id', ctypes.c_uint32),
|
||||
('format_revision', ctypes.c_uint32),
|
||||
('content_revision', ctypes.c_uint32),
|
||||
('fclk', ctypes.c_uint32),
|
||||
('lclk', ctypes.c_uint32),
|
||||
('firmware_caps', ctypes.c_uint32),
|
||||
]
|
||||
enum_smu_table_id = CEnum(ctypes.c_uint32)
|
||||
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)
|
||||
|
||||
PPSMC_Result_OK = 0x1
|
||||
PPSMC_Result_Failed = 0xFF
|
||||
PPSMC_Result_UnknownCmd = 0xFE
|
||||
PPSMC_Result_CmdRejectedPrereq = 0xFD
|
||||
PPSMC_Result_CmdRejectedBusy = 0xFC
|
||||
PPSMC_MSG_TestMessage = 0x1
|
||||
PPSMC_MSG_GetSmuVersion = 0x2
|
||||
PPSMC_MSG_GfxDriverReset = 0x3
|
||||
PPSMC_MSG_GetDriverIfVersion = 0x4
|
||||
PPSMC_MSG_EnableAllSmuFeatures = 0x5
|
||||
PPSMC_MSG_DisableAllSmuFeatures = 0x6
|
||||
PPSMC_MSG_RequestI2cTransaction = 0x7
|
||||
PPSMC_MSG_GetMetricsVersion = 0x8
|
||||
PPSMC_MSG_GetMetricsTable = 0x9
|
||||
PPSMC_MSG_GetEccInfoTable = 0xA
|
||||
PPSMC_MSG_GetEnabledSmuFeaturesLow = 0xB
|
||||
PPSMC_MSG_GetEnabledSmuFeaturesHigh = 0xC
|
||||
PPSMC_MSG_SetDriverDramAddrHigh = 0xD
|
||||
PPSMC_MSG_SetDriverDramAddrLow = 0xE
|
||||
PPSMC_MSG_SetToolsDramAddrHigh = 0xF
|
||||
PPSMC_MSG_SetToolsDramAddrLow = 0x10
|
||||
PPSMC_MSG_SetSystemVirtualDramAddrHigh = 0x11
|
||||
PPSMC_MSG_SetSystemVirtualDramAddrLow = 0x12
|
||||
PPSMC_MSG_SetSoftMinByFreq = 0x13
|
||||
PPSMC_MSG_SetSoftMaxByFreq = 0x14
|
||||
PPSMC_MSG_GetMinDpmFreq = 0x15
|
||||
PPSMC_MSG_GetMaxDpmFreq = 0x16
|
||||
PPSMC_MSG_GetDpmFreqByIndex = 0x17
|
||||
PPSMC_MSG_SetPptLimit = 0x18
|
||||
PPSMC_MSG_GetPptLimit = 0x19
|
||||
PPSMC_MSG_DramLogSetDramAddrHigh = 0x1A
|
||||
PPSMC_MSG_DramLogSetDramAddrLow = 0x1B
|
||||
PPSMC_MSG_DramLogSetDramSize = 0x1C
|
||||
PPSMC_MSG_GetDebugData = 0x1D
|
||||
PPSMC_MSG_HeavySBR = 0x1E
|
||||
PPSMC_MSG_SetNumBadHbmPagesRetired = 0x1F
|
||||
PPSMC_MSG_DFCstateControl = 0x20
|
||||
PPSMC_MSG_GetGmiPwrDnHyst = 0x21
|
||||
PPSMC_MSG_SetGmiPwrDnHyst = 0x22
|
||||
PPSMC_MSG_GmiPwrDnControl = 0x23
|
||||
PPSMC_MSG_EnterGfxoff = 0x24
|
||||
PPSMC_MSG_ExitGfxoff = 0x25
|
||||
PPSMC_MSG_EnableDeterminism = 0x26
|
||||
PPSMC_MSG_DisableDeterminism = 0x27
|
||||
PPSMC_MSG_DumpSTBtoDram = 0x28
|
||||
PPSMC_MSG_STBtoDramLogSetDramAddrHigh = 0x29
|
||||
PPSMC_MSG_STBtoDramLogSetDramAddrLow = 0x2A
|
||||
PPSMC_MSG_STBtoDramLogSetDramSize = 0x2B
|
||||
PPSMC_MSG_SetSystemVirtualSTBtoDramAddrHigh = 0x2C
|
||||
PPSMC_MSG_SetSystemVirtualSTBtoDramAddrLow = 0x2D
|
||||
PPSMC_MSG_GfxDriverResetRecovery = 0x2E
|
||||
PPSMC_MSG_TriggerVFFLR = 0x2F
|
||||
PPSMC_MSG_SetSoftMinGfxClk = 0x30
|
||||
PPSMC_MSG_SetSoftMaxGfxClk = 0x31
|
||||
PPSMC_MSG_GetMinGfxDpmFreq = 0x32
|
||||
PPSMC_MSG_GetMaxGfxDpmFreq = 0x33
|
||||
PPSMC_MSG_PrepareForDriverUnload = 0x34
|
||||
PPSMC_MSG_ReadThrottlerLimit = 0x35
|
||||
PPSMC_MSG_QueryValidMcaCount = 0x36
|
||||
PPSMC_MSG_McaBankDumpDW = 0x37
|
||||
PPSMC_MSG_GetCTFLimit = 0x38
|
||||
PPSMC_MSG_ClearMcaOnRead = 0x39
|
||||
PPSMC_MSG_QueryValidMcaCeCount = 0x3A
|
||||
PPSMC_MSG_McaBankCeDumpDW = 0x3B
|
||||
PPSMC_MSG_SelectPLPDMode = 0x40
|
||||
PPSMC_MSG_RmaDueToBadPageThreshold = 0x43
|
||||
PPSMC_MSG_SelectPstatePolicy = 0x44
|
||||
PPSMC_MSG_SetPhsDetWRbwThreshold = 0x45
|
||||
PPSMC_MSG_SetPhsDetWRbwFreqHigh = 0x46
|
||||
PPSMC_MSG_SetPhsDetWRbwFreqLow = 0x47
|
||||
PPSMC_MSG_SetPhsDetWRbwHystDown = 0x48
|
||||
PPSMC_MSG_SetPhsDetWRbwAlpha = 0x49
|
||||
PPSMC_MSG_SetPhsDetOnOff = 0x4A
|
||||
PPSMC_MSG_GetPhsDetResidency = 0x4B
|
||||
PPSMC_Message_Count = 0x4C
|
||||
PPSMC_RESET_TYPE_DRIVER_MODE_1_RESET = 0x1
|
||||
PPSMC_RESET_TYPE_DRIVER_MODE_2_RESET = 0x2
|
||||
PPSMC_RESET_TYPE_DRIVER_MODE_3_RESET = 0x3
|
||||
PPSMC_THROTTLING_LIMIT_TYPE_SOCKET = 0x1
|
||||
PPSMC_THROTTLING_LIMIT_TYPE_HBM = 0x2
|
||||
PPSMC_AID_THM_TYPE = 0x1
|
||||
PPSMC_CCD_THM_TYPE = 0x2
|
||||
PPSMC_XCD_THM_TYPE = 0x3
|
||||
PPSMC_HBM_THM_TYPE = 0x4
|
||||
PPSMC_PLPD_MODE_DEFAULT = 0x1
|
||||
PPSMC_PLPD_MODE_OPTIMIZED = 0x2
|
||||
SMU13_0_6_DRIVER_IF_VERSION = 0x08042024
|
||||
NUM_I2C_CONTROLLERS = 8
|
||||
I2C_CONTROLLER_ENABLED = 1
|
||||
I2C_CONTROLLER_DISABLED = 0
|
||||
MAX_SW_I2C_COMMANDS = 24
|
||||
CMDCONFIG_STOP_BIT = 0
|
||||
CMDCONFIG_RESTART_BIT = 1
|
||||
CMDCONFIG_READWRITE_BIT = 2
|
||||
CMDCONFIG_STOP_MASK = (1 << CMDCONFIG_STOP_BIT)
|
||||
CMDCONFIG_RESTART_MASK = (1 << CMDCONFIG_RESTART_BIT)
|
||||
CMDCONFIG_READWRITE_MASK = (1 << CMDCONFIG_READWRITE_BIT)
|
||||
IH_INTERRUPT_ID_TO_DRIVER = 0xFE
|
||||
IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING = 0x7
|
||||
THROTTLER_PROCHOT_BIT = 0
|
||||
THROTTLER_PPT_BIT = 1
|
||||
THROTTLER_THERMAL_SOCKET_BIT = 2
|
||||
THROTTLER_THERMAL_VR_BIT = 3
|
||||
THROTTLER_THERMAL_HBM_BIT = 4
|
||||
ClearMcaOnRead_UE_FLAG_MASK = 0x1
|
||||
ClearMcaOnRead_CE_POLL_MASK = 0x2
|
||||
int32_t = int
|
||||
SMU_THERMAL_MINIMUM_ALERT_TEMP = 0
|
||||
SMU_THERMAL_MAXIMUM_ALERT_TEMP = 255
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES = 1000
|
||||
SMU_FW_NAME_LEN = 0x24
|
||||
SMU_DPM_USER_PROFILE_RESTORE = (1 << 0)
|
||||
SMU_CUSTOM_FAN_SPEED_RPM = (1 << 1)
|
||||
SMU_CUSTOM_FAN_SPEED_PWM = (1 << 2)
|
||||
SMU_THROTTLER_PPT0_BIT = 0
|
||||
SMU_THROTTLER_PPT1_BIT = 1
|
||||
SMU_THROTTLER_PPT2_BIT = 2
|
||||
SMU_THROTTLER_PPT3_BIT = 3
|
||||
SMU_THROTTLER_SPL_BIT = 4
|
||||
SMU_THROTTLER_FPPT_BIT = 5
|
||||
SMU_THROTTLER_SPPT_BIT = 6
|
||||
SMU_THROTTLER_SPPT_APU_BIT = 7
|
||||
SMU_THROTTLER_TDC_GFX_BIT = 16
|
||||
SMU_THROTTLER_TDC_SOC_BIT = 17
|
||||
SMU_THROTTLER_TDC_MEM_BIT = 18
|
||||
SMU_THROTTLER_TDC_VDD_BIT = 19
|
||||
SMU_THROTTLER_TDC_CVIP_BIT = 20
|
||||
SMU_THROTTLER_EDC_CPU_BIT = 21
|
||||
SMU_THROTTLER_EDC_GFX_BIT = 22
|
||||
SMU_THROTTLER_APCC_BIT = 23
|
||||
SMU_THROTTLER_TEMP_GPU_BIT = 32
|
||||
SMU_THROTTLER_TEMP_CORE_BIT = 33
|
||||
SMU_THROTTLER_TEMP_MEM_BIT = 34
|
||||
SMU_THROTTLER_TEMP_EDGE_BIT = 35
|
||||
SMU_THROTTLER_TEMP_HOTSPOT_BIT = 36
|
||||
SMU_THROTTLER_TEMP_SOC_BIT = 37
|
||||
SMU_THROTTLER_TEMP_VR_GFX_BIT = 38
|
||||
SMU_THROTTLER_TEMP_VR_SOC_BIT = 39
|
||||
SMU_THROTTLER_TEMP_VR_MEM0_BIT = 40
|
||||
SMU_THROTTLER_TEMP_VR_MEM1_BIT = 41
|
||||
SMU_THROTTLER_TEMP_LIQUID0_BIT = 42
|
||||
SMU_THROTTLER_TEMP_LIQUID1_BIT = 43
|
||||
SMU_THROTTLER_VRHOT0_BIT = 44
|
||||
SMU_THROTTLER_VRHOT1_BIT = 45
|
||||
SMU_THROTTLER_PROCHOT_CPU_BIT = 46
|
||||
SMU_THROTTLER_PROCHOT_GFX_BIT = 47
|
||||
SMU_THROTTLER_PPM_BIT = 56
|
||||
SMU_THROTTLER_FIT_BIT = 57
|
||||
@@ -1809,7 +1809,8 @@ except AttributeError: pass
|
||||
try: (hipMemcpy2DToArrayAsync:=dll.hipMemcpy2DToArrayAsync).restype, hipMemcpy2DToArrayAsync.argtypes = hipError_t, [hipArray_t, size_t, size_t, ctypes.c_void_p, size_t, size_t, size_t, hipMemcpyKind, hipStream_t]
|
||||
except AttributeError: pass
|
||||
|
||||
hipArray_const_t = ctypes.POINTER(hipArray)
|
||||
class const_hipArray(Struct): pass
|
||||
hipArray_const_t = ctypes.POINTER(const_hipArray)
|
||||
try: (hipMemcpy2DArrayToArray:=dll.hipMemcpy2DArrayToArray).restype, hipMemcpy2DArrayToArray.argtypes = hipError_t, [hipArray_t, size_t, size_t, hipArray_const_t, size_t, size_t, size_t, size_t, hipMemcpyKind]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -2357,7 +2358,21 @@ except AttributeError: pass
|
||||
try: (hipFreeMipmappedArray:=dll.hipFreeMipmappedArray).restype, hipFreeMipmappedArray.argtypes = hipError_t, [hipMipmappedArray_t]
|
||||
except AttributeError: pass
|
||||
|
||||
hipMipmappedArray_const_t = ctypes.POINTER(hipMipmappedArray)
|
||||
class const_hipMipmappedArray(Struct): pass
|
||||
const_hipMipmappedArray._fields_ = [
|
||||
('data', ctypes.c_void_p),
|
||||
('desc', hipChannelFormatDesc),
|
||||
('type', ctypes.c_uint32),
|
||||
('width', ctypes.c_uint32),
|
||||
('height', ctypes.c_uint32),
|
||||
('depth', ctypes.c_uint32),
|
||||
('min_mipmap_level', ctypes.c_uint32),
|
||||
('max_mipmap_level', ctypes.c_uint32),
|
||||
('flags', ctypes.c_uint32),
|
||||
('format', hipArray_Format),
|
||||
('num_channels', ctypes.c_uint32),
|
||||
]
|
||||
hipMipmappedArray_const_t = ctypes.POINTER(const_hipMipmappedArray)
|
||||
try: (hipGetMipmappedArrayLevel:=dll.hipGetMipmappedArrayLevel).restype, hipGetMipmappedArrayLevel.argtypes = hipError_t, [ctypes.POINTER(hipArray_t), hipMipmappedArray_const_t, ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
@@ -1294,13 +1294,18 @@ struct_hsa_amd_aie_ert_start_kernel_data_s._fields_ = [
|
||||
]
|
||||
hsa_amd_aie_ert_start_kernel_data_t = struct_hsa_amd_aie_ert_start_kernel_data_s
|
||||
class struct_hsa_amd_aie_ert_packet_s(Struct): pass
|
||||
struct_hsa_amd_aie_ert_packet_s._fields_ = [
|
||||
('header', hsa_amd_vendor_packet_header_t),
|
||||
class struct_hsa_amd_aie_ert_packet_s_0(Struct): pass
|
||||
struct_hsa_amd_aie_ert_packet_s_0._fields_ = [
|
||||
('state', uint32_t,4),
|
||||
('custom', uint32_t,8),
|
||||
('count', uint32_t,11),
|
||||
('opcode', uint32_t,5),
|
||||
('type', uint32_t,4),
|
||||
]
|
||||
struct_hsa_amd_aie_ert_packet_s._anonymous_ = ['_0']
|
||||
struct_hsa_amd_aie_ert_packet_s._fields_ = [
|
||||
('header', hsa_amd_vendor_packet_header_t),
|
||||
('_0', struct_hsa_amd_aie_ert_packet_s_0),
|
||||
('reserved0', uint64_t),
|
||||
('reserved1', uint64_t),
|
||||
('reserved2', uint64_t),
|
||||
@@ -1778,7 +1783,13 @@ struct_hsa_amd_event_s._fields_ = [
|
||||
('_0', struct_hsa_amd_event_s_0),
|
||||
]
|
||||
hsa_amd_event_t = struct_hsa_amd_event_s
|
||||
hsa_amd_system_event_callback_t = ctypes.CFUNCTYPE(hsa_status_t, ctypes.POINTER(struct_hsa_amd_event_s), ctypes.c_void_p)
|
||||
class const_struct_hsa_amd_event_s(Struct): pass
|
||||
const_struct_hsa_amd_event_s._anonymous_ = ['_0']
|
||||
const_struct_hsa_amd_event_s._fields_ = [
|
||||
('event_type', hsa_amd_event_type_t),
|
||||
('_0', struct_hsa_amd_event_s_0),
|
||||
]
|
||||
hsa_amd_system_event_callback_t = ctypes.CFUNCTYPE(hsa_status_t, ctypes.POINTER(const_struct_hsa_amd_event_s), ctypes.c_void_p)
|
||||
try: (hsa_amd_register_system_event_handler:=dll.hsa_amd_register_system_event_handler).restype, hsa_amd_register_system_event_handler.argtypes = hsa_status_t, [hsa_amd_system_event_callback_t, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
@@ -181,14 +181,94 @@ struct_statx._fields_ = [
|
||||
('__spare3', (ctypes.c_uint64 * 12)),
|
||||
]
|
||||
class struct_epoll_event(Struct): pass
|
||||
_anonenum0 = CEnum(ctypes.c_uint32)
|
||||
IOSQE_FIXED_FILE_BIT = _anonenum0.define('IOSQE_FIXED_FILE_BIT', 0)
|
||||
IOSQE_IO_DRAIN_BIT = _anonenum0.define('IOSQE_IO_DRAIN_BIT', 1)
|
||||
IOSQE_IO_LINK_BIT = _anonenum0.define('IOSQE_IO_LINK_BIT', 2)
|
||||
IOSQE_IO_HARDLINK_BIT = _anonenum0.define('IOSQE_IO_HARDLINK_BIT', 3)
|
||||
IOSQE_ASYNC_BIT = _anonenum0.define('IOSQE_ASYNC_BIT', 4)
|
||||
IOSQE_BUFFER_SELECT_BIT = _anonenum0.define('IOSQE_BUFFER_SELECT_BIT', 5)
|
||||
IOSQE_CQE_SKIP_SUCCESS_BIT = _anonenum0.define('IOSQE_CQE_SKIP_SUCCESS_BIT', 6)
|
||||
class _anonunion0(ctypes.Union): pass
|
||||
class _anonunion0_0(Struct): pass
|
||||
_anonunion0_0._fields_ = [
|
||||
('cmd_op', ctypes.c_uint32),
|
||||
('__pad1', ctypes.c_uint32),
|
||||
]
|
||||
_anonunion0._anonymous_ = ['_0']
|
||||
_anonunion0._fields_ = [
|
||||
('off', ctypes.c_uint64),
|
||||
('addr2', ctypes.c_uint64),
|
||||
('_0', _anonunion0_0),
|
||||
]
|
||||
class _anonunion1(ctypes.Union): pass
|
||||
class _anonunion1_0(Struct): pass
|
||||
_anonunion1_0._fields_ = [
|
||||
('level', ctypes.c_uint32),
|
||||
('optname', ctypes.c_uint32),
|
||||
]
|
||||
_anonunion1._anonymous_ = ['_0']
|
||||
_anonunion1._fields_ = [
|
||||
('addr', ctypes.c_uint64),
|
||||
('splice_off_in', ctypes.c_uint64),
|
||||
('_0', _anonunion1_0),
|
||||
]
|
||||
class _anonunion2(ctypes.Union): pass
|
||||
_anonunion2._fields_ = [
|
||||
('rw_flags', ctypes.c_int32),
|
||||
('fsync_flags', ctypes.c_uint32),
|
||||
('poll_events', ctypes.c_uint16),
|
||||
('poll32_events', ctypes.c_uint32),
|
||||
('sync_range_flags', ctypes.c_uint32),
|
||||
('msg_flags', ctypes.c_uint32),
|
||||
('timeout_flags', ctypes.c_uint32),
|
||||
('accept_flags', ctypes.c_uint32),
|
||||
('cancel_flags', ctypes.c_uint32),
|
||||
('open_flags', ctypes.c_uint32),
|
||||
('statx_flags', ctypes.c_uint32),
|
||||
('fadvise_advice', ctypes.c_uint32),
|
||||
('splice_flags', ctypes.c_uint32),
|
||||
('rename_flags', ctypes.c_uint32),
|
||||
('unlink_flags', ctypes.c_uint32),
|
||||
('hardlink_flags', ctypes.c_uint32),
|
||||
('xattr_flags', ctypes.c_uint32),
|
||||
('msg_ring_flags', ctypes.c_uint32),
|
||||
('uring_cmd_flags', ctypes.c_uint32),
|
||||
('waitid_flags', ctypes.c_uint32),
|
||||
('futex_flags', ctypes.c_uint32),
|
||||
('install_fd_flags', ctypes.c_uint32),
|
||||
]
|
||||
class _anonunion3(ctypes.Union): pass
|
||||
_anonunion3._packed_ = True
|
||||
_anonunion3._fields_ = [
|
||||
('buf_index', ctypes.c_uint16),
|
||||
('buf_group', ctypes.c_uint16),
|
||||
]
|
||||
class _anonunion4(ctypes.Union): pass
|
||||
class _anonunion4_0(Struct): pass
|
||||
_anonunion4_0._fields_ = [
|
||||
('addr_len', ctypes.c_uint16),
|
||||
('__pad3', (ctypes.c_uint16 * 1)),
|
||||
]
|
||||
_anonunion4._anonymous_ = ['_0']
|
||||
_anonunion4._fields_ = [
|
||||
('splice_fd_in', ctypes.c_int32),
|
||||
('file_index', ctypes.c_uint32),
|
||||
('optlen', ctypes.c_uint32),
|
||||
('_0', _anonunion4_0),
|
||||
]
|
||||
class _anonunion5(ctypes.Union): pass
|
||||
class _anonunion5_0(Struct): pass
|
||||
_anonunion5_0._fields_ = [
|
||||
('addr3', ctypes.c_uint64),
|
||||
('__pad2', (ctypes.c_uint64 * 1)),
|
||||
]
|
||||
_anonunion5._anonymous_ = ['_0']
|
||||
_anonunion5._fields_ = [
|
||||
('_0', _anonunion5_0),
|
||||
('optval', ctypes.c_uint64),
|
||||
('cmd', (ctypes.c_ubyte * 0)),
|
||||
]
|
||||
_anonenum6 = CEnum(ctypes.c_uint32)
|
||||
IOSQE_FIXED_FILE_BIT = _anonenum6.define('IOSQE_FIXED_FILE_BIT', 0)
|
||||
IOSQE_IO_DRAIN_BIT = _anonenum6.define('IOSQE_IO_DRAIN_BIT', 1)
|
||||
IOSQE_IO_LINK_BIT = _anonenum6.define('IOSQE_IO_LINK_BIT', 2)
|
||||
IOSQE_IO_HARDLINK_BIT = _anonenum6.define('IOSQE_IO_HARDLINK_BIT', 3)
|
||||
IOSQE_ASYNC_BIT = _anonenum6.define('IOSQE_ASYNC_BIT', 4)
|
||||
IOSQE_BUFFER_SELECT_BIT = _anonenum6.define('IOSQE_BUFFER_SELECT_BIT', 5)
|
||||
IOSQE_CQE_SKIP_SUCCESS_BIT = _anonenum6.define('IOSQE_CQE_SKIP_SUCCESS_BIT', 6)
|
||||
|
||||
enum_io_uring_op = CEnum(ctypes.c_uint32)
|
||||
IORING_OP_NOP = enum_io_uring_op.define('IORING_OP_NOP', 0)
|
||||
@@ -248,12 +328,12 @@ IORING_OP_FUTEX_WAITV = enum_io_uring_op.define('IORING_OP_FUTEX_WAITV', 53)
|
||||
IORING_OP_FIXED_FD_INSTALL = enum_io_uring_op.define('IORING_OP_FIXED_FD_INSTALL', 54)
|
||||
IORING_OP_LAST = enum_io_uring_op.define('IORING_OP_LAST', 55)
|
||||
|
||||
_anonenum1 = CEnum(ctypes.c_uint32)
|
||||
IORING_MSG_DATA = _anonenum1.define('IORING_MSG_DATA', 0)
|
||||
IORING_MSG_SEND_FD = _anonenum1.define('IORING_MSG_SEND_FD', 1)
|
||||
_anonenum7 = CEnum(ctypes.c_uint32)
|
||||
IORING_MSG_DATA = _anonenum7.define('IORING_MSG_DATA', 0)
|
||||
IORING_MSG_SEND_FD = _anonenum7.define('IORING_MSG_SEND_FD', 1)
|
||||
|
||||
_anonenum2 = CEnum(ctypes.c_uint32)
|
||||
IORING_CQE_BUFFER_SHIFT = _anonenum2.define('IORING_CQE_BUFFER_SHIFT', 16)
|
||||
_anonenum8 = CEnum(ctypes.c_uint32)
|
||||
IORING_CQE_BUFFER_SHIFT = _anonenum8.define('IORING_CQE_BUFFER_SHIFT', 16)
|
||||
|
||||
class struct_io_sqring_offsets(Struct): pass
|
||||
struct_io_sqring_offsets._fields_ = [
|
||||
@@ -292,40 +372,40 @@ struct_io_uring_params._fields_ = [
|
||||
('sq_off', struct_io_sqring_offsets),
|
||||
('cq_off', struct_io_cqring_offsets),
|
||||
]
|
||||
_anonenum3 = CEnum(ctypes.c_uint32)
|
||||
IORING_REGISTER_BUFFERS = _anonenum3.define('IORING_REGISTER_BUFFERS', 0)
|
||||
IORING_UNREGISTER_BUFFERS = _anonenum3.define('IORING_UNREGISTER_BUFFERS', 1)
|
||||
IORING_REGISTER_FILES = _anonenum3.define('IORING_REGISTER_FILES', 2)
|
||||
IORING_UNREGISTER_FILES = _anonenum3.define('IORING_UNREGISTER_FILES', 3)
|
||||
IORING_REGISTER_EVENTFD = _anonenum3.define('IORING_REGISTER_EVENTFD', 4)
|
||||
IORING_UNREGISTER_EVENTFD = _anonenum3.define('IORING_UNREGISTER_EVENTFD', 5)
|
||||
IORING_REGISTER_FILES_UPDATE = _anonenum3.define('IORING_REGISTER_FILES_UPDATE', 6)
|
||||
IORING_REGISTER_EVENTFD_ASYNC = _anonenum3.define('IORING_REGISTER_EVENTFD_ASYNC', 7)
|
||||
IORING_REGISTER_PROBE = _anonenum3.define('IORING_REGISTER_PROBE', 8)
|
||||
IORING_REGISTER_PERSONALITY = _anonenum3.define('IORING_REGISTER_PERSONALITY', 9)
|
||||
IORING_UNREGISTER_PERSONALITY = _anonenum3.define('IORING_UNREGISTER_PERSONALITY', 10)
|
||||
IORING_REGISTER_RESTRICTIONS = _anonenum3.define('IORING_REGISTER_RESTRICTIONS', 11)
|
||||
IORING_REGISTER_ENABLE_RINGS = _anonenum3.define('IORING_REGISTER_ENABLE_RINGS', 12)
|
||||
IORING_REGISTER_FILES2 = _anonenum3.define('IORING_REGISTER_FILES2', 13)
|
||||
IORING_REGISTER_FILES_UPDATE2 = _anonenum3.define('IORING_REGISTER_FILES_UPDATE2', 14)
|
||||
IORING_REGISTER_BUFFERS2 = _anonenum3.define('IORING_REGISTER_BUFFERS2', 15)
|
||||
IORING_REGISTER_BUFFERS_UPDATE = _anonenum3.define('IORING_REGISTER_BUFFERS_UPDATE', 16)
|
||||
IORING_REGISTER_IOWQ_AFF = _anonenum3.define('IORING_REGISTER_IOWQ_AFF', 17)
|
||||
IORING_UNREGISTER_IOWQ_AFF = _anonenum3.define('IORING_UNREGISTER_IOWQ_AFF', 18)
|
||||
IORING_REGISTER_IOWQ_MAX_WORKERS = _anonenum3.define('IORING_REGISTER_IOWQ_MAX_WORKERS', 19)
|
||||
IORING_REGISTER_RING_FDS = _anonenum3.define('IORING_REGISTER_RING_FDS', 20)
|
||||
IORING_UNREGISTER_RING_FDS = _anonenum3.define('IORING_UNREGISTER_RING_FDS', 21)
|
||||
IORING_REGISTER_PBUF_RING = _anonenum3.define('IORING_REGISTER_PBUF_RING', 22)
|
||||
IORING_UNREGISTER_PBUF_RING = _anonenum3.define('IORING_UNREGISTER_PBUF_RING', 23)
|
||||
IORING_REGISTER_SYNC_CANCEL = _anonenum3.define('IORING_REGISTER_SYNC_CANCEL', 24)
|
||||
IORING_REGISTER_FILE_ALLOC_RANGE = _anonenum3.define('IORING_REGISTER_FILE_ALLOC_RANGE', 25)
|
||||
IORING_REGISTER_PBUF_STATUS = _anonenum3.define('IORING_REGISTER_PBUF_STATUS', 26)
|
||||
IORING_REGISTER_LAST = _anonenum3.define('IORING_REGISTER_LAST', 27)
|
||||
IORING_REGISTER_USE_REGISTERED_RING = _anonenum3.define('IORING_REGISTER_USE_REGISTERED_RING', 2147483648)
|
||||
_anonenum9 = CEnum(ctypes.c_uint32)
|
||||
IORING_REGISTER_BUFFERS = _anonenum9.define('IORING_REGISTER_BUFFERS', 0)
|
||||
IORING_UNREGISTER_BUFFERS = _anonenum9.define('IORING_UNREGISTER_BUFFERS', 1)
|
||||
IORING_REGISTER_FILES = _anonenum9.define('IORING_REGISTER_FILES', 2)
|
||||
IORING_UNREGISTER_FILES = _anonenum9.define('IORING_UNREGISTER_FILES', 3)
|
||||
IORING_REGISTER_EVENTFD = _anonenum9.define('IORING_REGISTER_EVENTFD', 4)
|
||||
IORING_UNREGISTER_EVENTFD = _anonenum9.define('IORING_UNREGISTER_EVENTFD', 5)
|
||||
IORING_REGISTER_FILES_UPDATE = _anonenum9.define('IORING_REGISTER_FILES_UPDATE', 6)
|
||||
IORING_REGISTER_EVENTFD_ASYNC = _anonenum9.define('IORING_REGISTER_EVENTFD_ASYNC', 7)
|
||||
IORING_REGISTER_PROBE = _anonenum9.define('IORING_REGISTER_PROBE', 8)
|
||||
IORING_REGISTER_PERSONALITY = _anonenum9.define('IORING_REGISTER_PERSONALITY', 9)
|
||||
IORING_UNREGISTER_PERSONALITY = _anonenum9.define('IORING_UNREGISTER_PERSONALITY', 10)
|
||||
IORING_REGISTER_RESTRICTIONS = _anonenum9.define('IORING_REGISTER_RESTRICTIONS', 11)
|
||||
IORING_REGISTER_ENABLE_RINGS = _anonenum9.define('IORING_REGISTER_ENABLE_RINGS', 12)
|
||||
IORING_REGISTER_FILES2 = _anonenum9.define('IORING_REGISTER_FILES2', 13)
|
||||
IORING_REGISTER_FILES_UPDATE2 = _anonenum9.define('IORING_REGISTER_FILES_UPDATE2', 14)
|
||||
IORING_REGISTER_BUFFERS2 = _anonenum9.define('IORING_REGISTER_BUFFERS2', 15)
|
||||
IORING_REGISTER_BUFFERS_UPDATE = _anonenum9.define('IORING_REGISTER_BUFFERS_UPDATE', 16)
|
||||
IORING_REGISTER_IOWQ_AFF = _anonenum9.define('IORING_REGISTER_IOWQ_AFF', 17)
|
||||
IORING_UNREGISTER_IOWQ_AFF = _anonenum9.define('IORING_UNREGISTER_IOWQ_AFF', 18)
|
||||
IORING_REGISTER_IOWQ_MAX_WORKERS = _anonenum9.define('IORING_REGISTER_IOWQ_MAX_WORKERS', 19)
|
||||
IORING_REGISTER_RING_FDS = _anonenum9.define('IORING_REGISTER_RING_FDS', 20)
|
||||
IORING_UNREGISTER_RING_FDS = _anonenum9.define('IORING_UNREGISTER_RING_FDS', 21)
|
||||
IORING_REGISTER_PBUF_RING = _anonenum9.define('IORING_REGISTER_PBUF_RING', 22)
|
||||
IORING_UNREGISTER_PBUF_RING = _anonenum9.define('IORING_UNREGISTER_PBUF_RING', 23)
|
||||
IORING_REGISTER_SYNC_CANCEL = _anonenum9.define('IORING_REGISTER_SYNC_CANCEL', 24)
|
||||
IORING_REGISTER_FILE_ALLOC_RANGE = _anonenum9.define('IORING_REGISTER_FILE_ALLOC_RANGE', 25)
|
||||
IORING_REGISTER_PBUF_STATUS = _anonenum9.define('IORING_REGISTER_PBUF_STATUS', 26)
|
||||
IORING_REGISTER_LAST = _anonenum9.define('IORING_REGISTER_LAST', 27)
|
||||
IORING_REGISTER_USE_REGISTERED_RING = _anonenum9.define('IORING_REGISTER_USE_REGISTERED_RING', 2147483648)
|
||||
|
||||
_anonenum4 = CEnum(ctypes.c_uint32)
|
||||
IO_WQ_BOUND = _anonenum4.define('IO_WQ_BOUND', 0)
|
||||
IO_WQ_UNBOUND = _anonenum4.define('IO_WQ_UNBOUND', 1)
|
||||
_anonenum10 = CEnum(ctypes.c_uint32)
|
||||
IO_WQ_BOUND = _anonenum10.define('IO_WQ_BOUND', 0)
|
||||
IO_WQ_UNBOUND = _anonenum10.define('IO_WQ_UNBOUND', 1)
|
||||
|
||||
class struct_io_uring_files_update(Struct): pass
|
||||
struct_io_uring_files_update._fields_ = [
|
||||
@@ -416,8 +496,8 @@ struct_io_uring_buf_ring._anonymous_ = ['_0']
|
||||
struct_io_uring_buf_ring._fields_ = [
|
||||
('_0', struct_io_uring_buf_ring_0),
|
||||
]
|
||||
_anonenum5 = CEnum(ctypes.c_uint32)
|
||||
IOU_PBUF_RING_MMAP = _anonenum5.define('IOU_PBUF_RING_MMAP', 1)
|
||||
_anonenum11 = CEnum(ctypes.c_uint32)
|
||||
IOU_PBUF_RING_MMAP = _anonenum11.define('IOU_PBUF_RING_MMAP', 1)
|
||||
|
||||
class struct_io_uring_buf_reg(Struct): pass
|
||||
struct_io_uring_buf_reg._fields_ = [
|
||||
@@ -433,12 +513,12 @@ struct_io_uring_buf_status._fields_ = [
|
||||
('head', ctypes.c_uint32),
|
||||
('resv', (ctypes.c_uint32 * 8)),
|
||||
]
|
||||
_anonenum6 = CEnum(ctypes.c_uint32)
|
||||
IORING_RESTRICTION_REGISTER_OP = _anonenum6.define('IORING_RESTRICTION_REGISTER_OP', 0)
|
||||
IORING_RESTRICTION_SQE_OP = _anonenum6.define('IORING_RESTRICTION_SQE_OP', 1)
|
||||
IORING_RESTRICTION_SQE_FLAGS_ALLOWED = _anonenum6.define('IORING_RESTRICTION_SQE_FLAGS_ALLOWED', 2)
|
||||
IORING_RESTRICTION_SQE_FLAGS_REQUIRED = _anonenum6.define('IORING_RESTRICTION_SQE_FLAGS_REQUIRED', 3)
|
||||
IORING_RESTRICTION_LAST = _anonenum6.define('IORING_RESTRICTION_LAST', 4)
|
||||
_anonenum12 = CEnum(ctypes.c_uint32)
|
||||
IORING_RESTRICTION_REGISTER_OP = _anonenum12.define('IORING_RESTRICTION_REGISTER_OP', 0)
|
||||
IORING_RESTRICTION_SQE_OP = _anonenum12.define('IORING_RESTRICTION_SQE_OP', 1)
|
||||
IORING_RESTRICTION_SQE_FLAGS_ALLOWED = _anonenum12.define('IORING_RESTRICTION_SQE_FLAGS_ALLOWED', 2)
|
||||
IORING_RESTRICTION_SQE_FLAGS_REQUIRED = _anonenum12.define('IORING_RESTRICTION_SQE_FLAGS_REQUIRED', 3)
|
||||
IORING_RESTRICTION_LAST = _anonenum12.define('IORING_RESTRICTION_LAST', 4)
|
||||
|
||||
class struct_io_uring_getevents_arg(Struct): pass
|
||||
struct_io_uring_getevents_arg._fields_ = [
|
||||
@@ -476,11 +556,11 @@ struct_io_uring_recvmsg_out._fields_ = [
|
||||
('payloadlen', ctypes.c_uint32),
|
||||
('flags', ctypes.c_uint32),
|
||||
]
|
||||
_anonenum7 = CEnum(ctypes.c_uint32)
|
||||
SOCKET_URING_OP_SIOCINQ = _anonenum7.define('SOCKET_URING_OP_SIOCINQ', 0)
|
||||
SOCKET_URING_OP_SIOCOUTQ = _anonenum7.define('SOCKET_URING_OP_SIOCOUTQ', 1)
|
||||
SOCKET_URING_OP_GETSOCKOPT = _anonenum7.define('SOCKET_URING_OP_GETSOCKOPT', 2)
|
||||
SOCKET_URING_OP_SETSOCKOPT = _anonenum7.define('SOCKET_URING_OP_SETSOCKOPT', 3)
|
||||
_anonenum13 = CEnum(ctypes.c_uint32)
|
||||
SOCKET_URING_OP_SIOCINQ = _anonenum13.define('SOCKET_URING_OP_SIOCINQ', 0)
|
||||
SOCKET_URING_OP_SIOCOUTQ = _anonenum13.define('SOCKET_URING_OP_SIOCOUTQ', 1)
|
||||
SOCKET_URING_OP_GETSOCKOPT = _anonenum13.define('SOCKET_URING_OP_GETSOCKOPT', 2)
|
||||
SOCKET_URING_OP_SETSOCKOPT = _anonenum13.define('SOCKET_URING_OP_SETSOCKOPT', 3)
|
||||
|
||||
_XOPEN_SOURCE = 500
|
||||
uring_unlikely = lambda cond: __builtin_expect( not not (cond), 0)
|
||||
|
||||
@@ -9,6 +9,13 @@ def dll():
|
||||
return None
|
||||
dll = dll()
|
||||
|
||||
class _anonunion0(ctypes.Union): pass
|
||||
uint8_t = ctypes.c_ubyte
|
||||
uint16_t = ctypes.c_uint16
|
||||
_anonunion0._fields_ = [
|
||||
('b8', (uint8_t * 2)),
|
||||
('b16', uint16_t),
|
||||
]
|
||||
enum_libusb_class_code = CEnum(ctypes.c_uint32)
|
||||
LIBUSB_CLASS_PER_INTERFACE = enum_libusb_class_code.define('LIBUSB_CLASS_PER_INTERFACE', 0)
|
||||
LIBUSB_CLASS_AUDIO = enum_libusb_class_code.define('LIBUSB_CLASS_AUDIO', 1)
|
||||
@@ -115,8 +122,6 @@ LIBUSB_BT_CONTAINER_ID = enum_libusb_bos_type.define('LIBUSB_BT_CONTAINER_ID', 4
|
||||
LIBUSB_BT_PLATFORM_DESCRIPTOR = enum_libusb_bos_type.define('LIBUSB_BT_PLATFORM_DESCRIPTOR', 5)
|
||||
|
||||
class struct_libusb_device_descriptor(Struct): pass
|
||||
uint8_t = ctypes.c_ubyte
|
||||
uint16_t = ctypes.c_uint16
|
||||
struct_libusb_device_descriptor._fields_ = [
|
||||
('bLength', uint8_t),
|
||||
('bDescriptorType', uint8_t),
|
||||
|
||||
+82
-7761
File diff suppressed because it is too large
Load Diff
@@ -1323,6 +1323,17 @@ nvdec_crc_s._fields_ = [
|
||||
('reserved1', ctypes.c_uint32,16),
|
||||
('reserved2', (ctypes.c_ubyte * 56)),
|
||||
]
|
||||
class _anonunion12(ctypes.Union): pass
|
||||
NvUPtr = ctypes.c_uint64
|
||||
_anonunion12._fields_ = [
|
||||
('v', NvUPtr),
|
||||
('p', ctypes.c_void_p),
|
||||
]
|
||||
class _anonunion13(ctypes.Union): pass
|
||||
_anonunion13._fields_ = [
|
||||
('v', NvUPtr),
|
||||
('p', ctypes.c_void_p),
|
||||
]
|
||||
class struct_NV0000_ALLOC_PARAMETERS(Struct): pass
|
||||
NvHandle = ctypes.c_uint32
|
||||
NvU32 = ctypes.c_uint32
|
||||
@@ -6649,7 +6660,6 @@ struct_NV2080_CTRL_FLCN_USTREAMER_EVENT_FILTER._fields_ = [
|
||||
]
|
||||
NV2080_CTRL_FLCN_USTREAMER_EVENT_FILTER = struct_NV2080_CTRL_FLCN_USTREAMER_EVENT_FILTER
|
||||
class struct_NV2080_CTRL_FLCN_USTREAMER_QUEUE_INFO_PARAMS(Struct): pass
|
||||
NvUPtr = ctypes.c_uint64
|
||||
struct_NV2080_CTRL_FLCN_USTREAMER_QUEUE_INFO_PARAMS._fields_ = [
|
||||
('engine', NvU32),
|
||||
('pageSize', NvU32),
|
||||
|
||||
@@ -1323,6 +1323,17 @@ nvdec_crc_s._fields_ = [
|
||||
('reserved1', ctypes.c_uint32,16),
|
||||
('reserved2', (ctypes.c_ubyte * 56)),
|
||||
]
|
||||
class _anonunion12(ctypes.Union): pass
|
||||
NvUPtr = ctypes.c_uint64
|
||||
_anonunion12._fields_ = [
|
||||
('v', NvUPtr),
|
||||
('p', ctypes.c_void_p),
|
||||
]
|
||||
class _anonunion13(ctypes.Union): pass
|
||||
_anonunion13._fields_ = [
|
||||
('v', NvUPtr),
|
||||
('p', ctypes.c_void_p),
|
||||
]
|
||||
class struct_NV0000_ALLOC_PARAMETERS(Struct): pass
|
||||
NvHandle = ctypes.c_uint32
|
||||
NvU32 = ctypes.c_uint32
|
||||
@@ -7208,7 +7219,6 @@ struct_NV2080_CTRL_FLCN_USTREAMER_EVENT_FILTER._fields_ = [
|
||||
]
|
||||
NV2080_CTRL_FLCN_USTREAMER_EVENT_FILTER = struct_NV2080_CTRL_FLCN_USTREAMER_EVENT_FILTER
|
||||
class struct_NV2080_CTRL_FLCN_USTREAMER_QUEUE_INFO_PARAMS(Struct): pass
|
||||
NvUPtr = ctypes.c_uint64
|
||||
struct_NV2080_CTRL_FLCN_USTREAMER_QUEUE_INFO_PARAMS._fields_ = [
|
||||
('engine', NvU32),
|
||||
('pageSize', NvU32),
|
||||
|
||||
@@ -293,7 +293,7 @@ WGPUCompilationInfoRequestStatus_DeviceLost = enum_WGPUCompilationInfoRequestSta
|
||||
WGPUCompilationInfoRequestStatus_Unknown = enum_WGPUCompilationInfoRequestStatus.define('WGPUCompilationInfoRequestStatus_Unknown', 5)
|
||||
WGPUCompilationInfoRequestStatus_Force32 = enum_WGPUCompilationInfoRequestStatus.define('WGPUCompilationInfoRequestStatus_Force32', 2147483647)
|
||||
|
||||
class struct_WGPUCompilationInfo(Struct): pass
|
||||
class const_struct_WGPUCompilationInfo(Struct): pass
|
||||
size_t = ctypes.c_uint64
|
||||
class struct_WGPUCompilationMessage(Struct): pass
|
||||
WGPUCompilationMessage = struct_WGPUCompilationMessage
|
||||
@@ -322,12 +322,12 @@ struct_WGPUCompilationMessage._fields_ = [
|
||||
('utf16Offset', uint64_t),
|
||||
('utf16Length', uint64_t),
|
||||
]
|
||||
struct_WGPUCompilationInfo._fields_ = [
|
||||
const_struct_WGPUCompilationInfo._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('messageCount', size_t),
|
||||
('messages', ctypes.POINTER(WGPUCompilationMessage)),
|
||||
]
|
||||
WGPUCompilationInfoCallback = ctypes.CFUNCTYPE(None, enum_WGPUCompilationInfoRequestStatus, ctypes.POINTER(struct_WGPUCompilationInfo), ctypes.c_void_p)
|
||||
WGPUCompilationInfoCallback = ctypes.CFUNCTYPE(None, enum_WGPUCompilationInfoRequestStatus, ctypes.POINTER(const_struct_WGPUCompilationInfo), ctypes.c_void_p)
|
||||
struct_WGPUCompilationInfoCallbackInfo._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('mode', WGPUCallbackMode),
|
||||
@@ -1874,6 +1874,12 @@ struct_WGPUColorTargetState._fields_ = [
|
||||
('blend', ctypes.POINTER(WGPUBlendState)),
|
||||
('writeMask', WGPUColorWriteMask),
|
||||
]
|
||||
class struct_WGPUCompilationInfo(Struct): pass
|
||||
struct_WGPUCompilationInfo._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('messageCount', size_t),
|
||||
('messages', ctypes.POINTER(WGPUCompilationMessage)),
|
||||
]
|
||||
class struct_WGPUComputeState(Struct): pass
|
||||
WGPUConstantEntry = struct_WGPUConstantEntry
|
||||
struct_WGPUComputeState._fields_ = [
|
||||
@@ -2056,7 +2062,7 @@ WGPUDeviceLostCallback = ctypes.CFUNCTYPE(None, enum_WGPUDeviceLostReason, struc
|
||||
WGPULoggingCallback = ctypes.CFUNCTYPE(None, enum_WGPULoggingType, struct_WGPUStringView, ctypes.c_void_p)
|
||||
WGPUProc = ctypes.CFUNCTYPE(None, )
|
||||
WGPUBufferMapCallback2 = ctypes.CFUNCTYPE(None, enum_WGPUMapAsyncStatus, struct_WGPUStringView, ctypes.c_void_p, ctypes.c_void_p)
|
||||
WGPUCompilationInfoCallback2 = ctypes.CFUNCTYPE(None, enum_WGPUCompilationInfoRequestStatus, ctypes.POINTER(struct_WGPUCompilationInfo), ctypes.c_void_p, ctypes.c_void_p)
|
||||
WGPUCompilationInfoCallback2 = ctypes.CFUNCTYPE(None, enum_WGPUCompilationInfoRequestStatus, ctypes.POINTER(const_struct_WGPUCompilationInfo), ctypes.c_void_p, ctypes.c_void_p)
|
||||
WGPUCreateComputePipelineAsyncCallback2 = ctypes.CFUNCTYPE(None, enum_WGPUCreatePipelineAsyncStatus, ctypes.POINTER(struct_WGPUComputePipelineImpl), struct_WGPUStringView, ctypes.c_void_p, ctypes.c_void_p)
|
||||
WGPUCreateRenderPipelineAsyncCallback2 = ctypes.CFUNCTYPE(None, enum_WGPUCreatePipelineAsyncStatus, ctypes.POINTER(struct_WGPURenderPipelineImpl), struct_WGPUStringView, ctypes.c_void_p, ctypes.c_void_p)
|
||||
WGPUPopErrorScopeCallback2 = ctypes.CFUNCTYPE(None, enum_WGPUPopErrorScopeStatus, enum_WGPUErrorType, struct_WGPUStringView, ctypes.c_void_p, ctypes.c_void_p)
|
||||
@@ -2266,7 +2272,12 @@ WGPUSurfaceDescriptorFromXcbWindow = struct_WGPUSurfaceSourceXCBWindow
|
||||
WGPUSurfaceDescriptorFromXlibWindow = struct_WGPUSurfaceSourceXlibWindow
|
||||
WGPUProcAdapterInfoFreeMembers = ctypes.CFUNCTYPE(None, struct_WGPUAdapterInfo)
|
||||
WGPUProcAdapterPropertiesMemoryHeapsFreeMembers = ctypes.CFUNCTYPE(None, struct_WGPUAdapterPropertiesMemoryHeaps)
|
||||
WGPUProcCreateInstance = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(struct_WGPUInstanceDescriptor))
|
||||
class const_struct_WGPUInstanceDescriptor(Struct): pass
|
||||
const_struct_WGPUInstanceDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('features', WGPUInstanceFeatures),
|
||||
]
|
||||
WGPUProcCreateInstance = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(const_struct_WGPUInstanceDescriptor))
|
||||
WGPUProcDrmFormatCapabilitiesFreeMembers = ctypes.CFUNCTYPE(None, struct_WGPUDrmFormatCapabilities)
|
||||
WGPUProcGetInstanceFeatures = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUInstanceFeatures))
|
||||
WGPUProcGetProcAddress = ctypes.CFUNCTYPE(ctypes.CFUNCTYPE(None, ), struct_WGPUStringView)
|
||||
@@ -2274,16 +2285,27 @@ WGPUProcSharedBufferMemoryEndAccessStateFreeMembers = ctypes.CFUNCTYPE(None, str
|
||||
WGPUProcSharedTextureMemoryEndAccessStateFreeMembers = ctypes.CFUNCTYPE(None, struct_WGPUSharedTextureMemoryEndAccessState)
|
||||
WGPUProcSupportedFeaturesFreeMembers = ctypes.CFUNCTYPE(None, struct_WGPUSupportedFeatures)
|
||||
WGPUProcSurfaceCapabilitiesFreeMembers = ctypes.CFUNCTYPE(None, struct_WGPUSurfaceCapabilities)
|
||||
WGPUProcAdapterCreateDevice = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(struct_WGPUDeviceDescriptor))
|
||||
class const_struct_WGPUDeviceDescriptor(Struct): pass
|
||||
const_struct_WGPUDeviceDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('requiredFeatureCount', size_t),
|
||||
('requiredFeatures', ctypes.POINTER(WGPUFeatureName)),
|
||||
('requiredLimits', ctypes.POINTER(WGPURequiredLimits)),
|
||||
('defaultQueue', WGPUQueueDescriptor),
|
||||
('deviceLostCallbackInfo2', WGPUDeviceLostCallbackInfo2),
|
||||
('uncapturedErrorCallbackInfo2', WGPUUncapturedErrorCallbackInfo2),
|
||||
]
|
||||
WGPUProcAdapterCreateDevice = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(const_struct_WGPUDeviceDescriptor))
|
||||
WGPUProcAdapterGetFeatures = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(struct_WGPUSupportedFeatures))
|
||||
WGPUProcAdapterGetFormatCapabilities = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUAdapterImpl), enum_WGPUTextureFormat, ctypes.POINTER(struct_WGPUFormatCapabilities))
|
||||
WGPUProcAdapterGetInfo = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(struct_WGPUAdapterInfo))
|
||||
WGPUProcAdapterGetInstance = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(struct_WGPUAdapterImpl))
|
||||
WGPUProcAdapterGetLimits = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(struct_WGPUSupportedLimits))
|
||||
WGPUProcAdapterHasFeature = ctypes.CFUNCTYPE(ctypes.c_uint32, ctypes.POINTER(struct_WGPUAdapterImpl), enum_WGPUFeatureName)
|
||||
WGPUProcAdapterRequestDevice = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(struct_WGPUDeviceDescriptor), ctypes.CFUNCTYPE(None, enum_WGPURequestDeviceStatus, ctypes.POINTER(struct_WGPUDeviceImpl), struct_WGPUStringView, ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcAdapterRequestDevice2 = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(struct_WGPUDeviceDescriptor), struct_WGPURequestDeviceCallbackInfo2)
|
||||
WGPUProcAdapterRequestDeviceF = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(struct_WGPUDeviceDescriptor), struct_WGPURequestDeviceCallbackInfo)
|
||||
WGPUProcAdapterRequestDevice = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(const_struct_WGPUDeviceDescriptor), ctypes.CFUNCTYPE(None, enum_WGPURequestDeviceStatus, ctypes.POINTER(struct_WGPUDeviceImpl), struct_WGPUStringView, ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcAdapterRequestDevice2 = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(const_struct_WGPUDeviceDescriptor), struct_WGPURequestDeviceCallbackInfo2)
|
||||
WGPUProcAdapterRequestDeviceF = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(const_struct_WGPUDeviceDescriptor), struct_WGPURequestDeviceCallbackInfo)
|
||||
WGPUProcAdapterAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUAdapterImpl))
|
||||
WGPUProcAdapterRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUAdapterImpl))
|
||||
WGPUProcBindGroupSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUBindGroupImpl), struct_WGPUStringView)
|
||||
@@ -2308,14 +2330,53 @@ WGPUProcBufferRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUBufferI
|
||||
WGPUProcCommandBufferSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandBufferImpl), struct_WGPUStringView)
|
||||
WGPUProcCommandBufferAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandBufferImpl))
|
||||
WGPUProcCommandBufferRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandBufferImpl))
|
||||
WGPUProcCommandEncoderBeginComputePass = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUComputePassEncoderImpl), ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(struct_WGPUComputePassDescriptor))
|
||||
WGPUProcCommandEncoderBeginRenderPass = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPURenderPassEncoderImpl), ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(struct_WGPURenderPassDescriptor))
|
||||
class const_struct_WGPUComputePassDescriptor(Struct): pass
|
||||
const_struct_WGPUComputePassDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('timestampWrites', ctypes.POINTER(WGPUComputePassTimestampWrites)),
|
||||
]
|
||||
WGPUProcCommandEncoderBeginComputePass = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUComputePassEncoderImpl), ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(const_struct_WGPUComputePassDescriptor))
|
||||
class const_struct_WGPURenderPassDescriptor(Struct): pass
|
||||
const_struct_WGPURenderPassDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('colorAttachmentCount', size_t),
|
||||
('colorAttachments', ctypes.POINTER(WGPURenderPassColorAttachment)),
|
||||
('depthStencilAttachment', ctypes.POINTER(WGPURenderPassDepthStencilAttachment)),
|
||||
('occlusionQuerySet', WGPUQuerySet),
|
||||
('timestampWrites', ctypes.POINTER(WGPURenderPassTimestampWrites)),
|
||||
]
|
||||
WGPUProcCommandEncoderBeginRenderPass = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPURenderPassEncoderImpl), ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(const_struct_WGPURenderPassDescriptor))
|
||||
WGPUProcCommandEncoderClearBuffer = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(struct_WGPUBufferImpl), ctypes.c_uint64, ctypes.c_uint64)
|
||||
WGPUProcCommandEncoderCopyBufferToBuffer = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(struct_WGPUBufferImpl), ctypes.c_uint64, ctypes.POINTER(struct_WGPUBufferImpl), ctypes.c_uint64, ctypes.c_uint64)
|
||||
WGPUProcCommandEncoderCopyBufferToTexture = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(struct_WGPUImageCopyBuffer), ctypes.POINTER(struct_WGPUImageCopyTexture), ctypes.POINTER(struct_WGPUExtent3D))
|
||||
WGPUProcCommandEncoderCopyTextureToBuffer = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(struct_WGPUImageCopyTexture), ctypes.POINTER(struct_WGPUImageCopyBuffer), ctypes.POINTER(struct_WGPUExtent3D))
|
||||
WGPUProcCommandEncoderCopyTextureToTexture = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(struct_WGPUImageCopyTexture), ctypes.POINTER(struct_WGPUImageCopyTexture), ctypes.POINTER(struct_WGPUExtent3D))
|
||||
WGPUProcCommandEncoderFinish = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUCommandBufferImpl), ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(struct_WGPUCommandBufferDescriptor))
|
||||
class const_struct_WGPUImageCopyBuffer(Struct): pass
|
||||
const_struct_WGPUImageCopyBuffer._fields_ = [
|
||||
('layout', WGPUTextureDataLayout),
|
||||
('buffer', WGPUBuffer),
|
||||
]
|
||||
class const_struct_WGPUImageCopyTexture(Struct): pass
|
||||
const_struct_WGPUImageCopyTexture._fields_ = [
|
||||
('texture', WGPUTexture),
|
||||
('mipLevel', uint32_t),
|
||||
('origin', WGPUOrigin3D),
|
||||
('aspect', WGPUTextureAspect),
|
||||
]
|
||||
class const_struct_WGPUExtent3D(Struct): pass
|
||||
const_struct_WGPUExtent3D._fields_ = [
|
||||
('width', uint32_t),
|
||||
('height', uint32_t),
|
||||
('depthOrArrayLayers', uint32_t),
|
||||
]
|
||||
WGPUProcCommandEncoderCopyBufferToTexture = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(const_struct_WGPUImageCopyBuffer), ctypes.POINTER(const_struct_WGPUImageCopyTexture), ctypes.POINTER(const_struct_WGPUExtent3D))
|
||||
WGPUProcCommandEncoderCopyTextureToBuffer = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(const_struct_WGPUImageCopyTexture), ctypes.POINTER(const_struct_WGPUImageCopyBuffer), ctypes.POINTER(const_struct_WGPUExtent3D))
|
||||
WGPUProcCommandEncoderCopyTextureToTexture = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(const_struct_WGPUImageCopyTexture), ctypes.POINTER(const_struct_WGPUImageCopyTexture), ctypes.POINTER(const_struct_WGPUExtent3D))
|
||||
class const_struct_WGPUCommandBufferDescriptor(Struct): pass
|
||||
const_struct_WGPUCommandBufferDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
]
|
||||
WGPUProcCommandEncoderFinish = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUCommandBufferImpl), ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(const_struct_WGPUCommandBufferDescriptor))
|
||||
WGPUProcCommandEncoderInjectValidationError = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandEncoderImpl), struct_WGPUStringView)
|
||||
WGPUProcCommandEncoderInsertDebugMarker = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandEncoderImpl), struct_WGPUStringView)
|
||||
WGPUProcCommandEncoderPopDebugGroup = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUCommandEncoderImpl))
|
||||
@@ -2342,29 +2403,151 @@ WGPUProcComputePipelineGetBindGroupLayout = ctypes.CFUNCTYPE(ctypes.POINTER(stru
|
||||
WGPUProcComputePipelineSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUComputePipelineImpl), struct_WGPUStringView)
|
||||
WGPUProcComputePipelineAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUComputePipelineImpl))
|
||||
WGPUProcComputePipelineRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUComputePipelineImpl))
|
||||
WGPUProcDeviceCreateBindGroup = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUBindGroupImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUBindGroupDescriptor))
|
||||
WGPUProcDeviceCreateBindGroupLayout = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUBindGroupLayoutImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUBindGroupLayoutDescriptor))
|
||||
WGPUProcDeviceCreateBuffer = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUBufferImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUBufferDescriptor))
|
||||
WGPUProcDeviceCreateCommandEncoder = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUCommandEncoderDescriptor))
|
||||
WGPUProcDeviceCreateComputePipeline = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUComputePipelineImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUComputePipelineDescriptor))
|
||||
WGPUProcDeviceCreateComputePipelineAsync = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUComputePipelineDescriptor), ctypes.CFUNCTYPE(None, enum_WGPUCreatePipelineAsyncStatus, ctypes.POINTER(struct_WGPUComputePipelineImpl), struct_WGPUStringView, ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcDeviceCreateComputePipelineAsync2 = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUComputePipelineDescriptor), struct_WGPUCreateComputePipelineAsyncCallbackInfo2)
|
||||
WGPUProcDeviceCreateComputePipelineAsyncF = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUComputePipelineDescriptor), struct_WGPUCreateComputePipelineAsyncCallbackInfo)
|
||||
WGPUProcDeviceCreateErrorBuffer = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUBufferImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUBufferDescriptor))
|
||||
class const_struct_WGPUBindGroupDescriptor(Struct): pass
|
||||
const_struct_WGPUBindGroupDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('layout', WGPUBindGroupLayout),
|
||||
('entryCount', size_t),
|
||||
('entries', ctypes.POINTER(WGPUBindGroupEntry)),
|
||||
]
|
||||
WGPUProcDeviceCreateBindGroup = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUBindGroupImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUBindGroupDescriptor))
|
||||
class const_struct_WGPUBindGroupLayoutDescriptor(Struct): pass
|
||||
const_struct_WGPUBindGroupLayoutDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('entryCount', size_t),
|
||||
('entries', ctypes.POINTER(WGPUBindGroupLayoutEntry)),
|
||||
]
|
||||
WGPUProcDeviceCreateBindGroupLayout = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUBindGroupLayoutImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUBindGroupLayoutDescriptor))
|
||||
class const_struct_WGPUBufferDescriptor(Struct): pass
|
||||
const_struct_WGPUBufferDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('usage', WGPUBufferUsage),
|
||||
('size', uint64_t),
|
||||
('mappedAtCreation', WGPUBool),
|
||||
]
|
||||
WGPUProcDeviceCreateBuffer = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUBufferImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUBufferDescriptor))
|
||||
class const_struct_WGPUCommandEncoderDescriptor(Struct): pass
|
||||
const_struct_WGPUCommandEncoderDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
]
|
||||
WGPUProcDeviceCreateCommandEncoder = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUCommandEncoderImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUCommandEncoderDescriptor))
|
||||
class const_struct_WGPUComputePipelineDescriptor(Struct): pass
|
||||
const_struct_WGPUComputePipelineDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('layout', WGPUPipelineLayout),
|
||||
('compute', WGPUComputeState),
|
||||
]
|
||||
WGPUProcDeviceCreateComputePipeline = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUComputePipelineImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUComputePipelineDescriptor))
|
||||
WGPUProcDeviceCreateComputePipelineAsync = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUComputePipelineDescriptor), ctypes.CFUNCTYPE(None, enum_WGPUCreatePipelineAsyncStatus, ctypes.POINTER(struct_WGPUComputePipelineImpl), struct_WGPUStringView, ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcDeviceCreateComputePipelineAsync2 = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUComputePipelineDescriptor), struct_WGPUCreateComputePipelineAsyncCallbackInfo2)
|
||||
WGPUProcDeviceCreateComputePipelineAsyncF = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUComputePipelineDescriptor), struct_WGPUCreateComputePipelineAsyncCallbackInfo)
|
||||
WGPUProcDeviceCreateErrorBuffer = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUBufferImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUBufferDescriptor))
|
||||
WGPUProcDeviceCreateErrorExternalTexture = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUExternalTextureImpl), ctypes.POINTER(struct_WGPUDeviceImpl))
|
||||
WGPUProcDeviceCreateErrorShaderModule = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUShaderModuleImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUShaderModuleDescriptor), struct_WGPUStringView)
|
||||
WGPUProcDeviceCreateErrorTexture = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUTextureDescriptor))
|
||||
WGPUProcDeviceCreateExternalTexture = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUExternalTextureImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUExternalTextureDescriptor))
|
||||
WGPUProcDeviceCreatePipelineLayout = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUPipelineLayoutImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUPipelineLayoutDescriptor))
|
||||
WGPUProcDeviceCreateQuerySet = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUQuerySetImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUQuerySetDescriptor))
|
||||
WGPUProcDeviceCreateRenderBundleEncoder = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPURenderBundleEncoderImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPURenderBundleEncoderDescriptor))
|
||||
WGPUProcDeviceCreateRenderPipeline = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPURenderPipelineImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPURenderPipelineDescriptor))
|
||||
WGPUProcDeviceCreateRenderPipelineAsync = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPURenderPipelineDescriptor), ctypes.CFUNCTYPE(None, enum_WGPUCreatePipelineAsyncStatus, ctypes.POINTER(struct_WGPURenderPipelineImpl), struct_WGPUStringView, ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcDeviceCreateRenderPipelineAsync2 = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPURenderPipelineDescriptor), struct_WGPUCreateRenderPipelineAsyncCallbackInfo2)
|
||||
WGPUProcDeviceCreateRenderPipelineAsyncF = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPURenderPipelineDescriptor), struct_WGPUCreateRenderPipelineAsyncCallbackInfo)
|
||||
WGPUProcDeviceCreateSampler = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUSamplerImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUSamplerDescriptor))
|
||||
WGPUProcDeviceCreateShaderModule = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUShaderModuleImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUShaderModuleDescriptor))
|
||||
WGPUProcDeviceCreateTexture = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUTextureDescriptor))
|
||||
class const_struct_WGPUShaderModuleDescriptor(Struct): pass
|
||||
const_struct_WGPUShaderModuleDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
]
|
||||
WGPUProcDeviceCreateErrorShaderModule = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUShaderModuleImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUShaderModuleDescriptor), struct_WGPUStringView)
|
||||
class const_struct_WGPUTextureDescriptor(Struct): pass
|
||||
const_struct_WGPUTextureDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('usage', WGPUTextureUsage),
|
||||
('dimension', WGPUTextureDimension),
|
||||
('size', WGPUExtent3D),
|
||||
('format', WGPUTextureFormat),
|
||||
('mipLevelCount', uint32_t),
|
||||
('sampleCount', uint32_t),
|
||||
('viewFormatCount', size_t),
|
||||
('viewFormats', ctypes.POINTER(WGPUTextureFormat)),
|
||||
]
|
||||
WGPUProcDeviceCreateErrorTexture = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUTextureDescriptor))
|
||||
class const_struct_WGPUExternalTextureDescriptor(Struct): pass
|
||||
const_struct_WGPUExternalTextureDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('plane0', WGPUTextureView),
|
||||
('plane1', WGPUTextureView),
|
||||
('cropOrigin', WGPUOrigin2D),
|
||||
('cropSize', WGPUExtent2D),
|
||||
('apparentSize', WGPUExtent2D),
|
||||
('doYuvToRgbConversionOnly', WGPUBool),
|
||||
('yuvToRgbConversionMatrix', ctypes.POINTER(ctypes.c_float)),
|
||||
('srcTransferFunctionParameters', ctypes.POINTER(ctypes.c_float)),
|
||||
('dstTransferFunctionParameters', ctypes.POINTER(ctypes.c_float)),
|
||||
('gamutConversionMatrix', ctypes.POINTER(ctypes.c_float)),
|
||||
('mirrored', WGPUBool),
|
||||
('rotation', WGPUExternalTextureRotation),
|
||||
]
|
||||
WGPUProcDeviceCreateExternalTexture = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUExternalTextureImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUExternalTextureDescriptor))
|
||||
class const_struct_WGPUPipelineLayoutDescriptor(Struct): pass
|
||||
const_struct_WGPUPipelineLayoutDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('bindGroupLayoutCount', size_t),
|
||||
('bindGroupLayouts', ctypes.POINTER(WGPUBindGroupLayout)),
|
||||
('immediateDataRangeByteSize', uint32_t),
|
||||
]
|
||||
WGPUProcDeviceCreatePipelineLayout = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUPipelineLayoutImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUPipelineLayoutDescriptor))
|
||||
class const_struct_WGPUQuerySetDescriptor(Struct): pass
|
||||
const_struct_WGPUQuerySetDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('type', WGPUQueryType),
|
||||
('count', uint32_t),
|
||||
]
|
||||
WGPUProcDeviceCreateQuerySet = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUQuerySetImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUQuerySetDescriptor))
|
||||
class const_struct_WGPURenderBundleEncoderDescriptor(Struct): pass
|
||||
const_struct_WGPURenderBundleEncoderDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('colorFormatCount', size_t),
|
||||
('colorFormats', ctypes.POINTER(WGPUTextureFormat)),
|
||||
('depthStencilFormat', WGPUTextureFormat),
|
||||
('sampleCount', uint32_t),
|
||||
('depthReadOnly', WGPUBool),
|
||||
('stencilReadOnly', WGPUBool),
|
||||
]
|
||||
WGPUProcDeviceCreateRenderBundleEncoder = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPURenderBundleEncoderImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPURenderBundleEncoderDescriptor))
|
||||
class const_struct_WGPURenderPipelineDescriptor(Struct): pass
|
||||
const_struct_WGPURenderPipelineDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('layout', WGPUPipelineLayout),
|
||||
('vertex', WGPUVertexState),
|
||||
('primitive', WGPUPrimitiveState),
|
||||
('depthStencil', ctypes.POINTER(WGPUDepthStencilState)),
|
||||
('multisample', WGPUMultisampleState),
|
||||
('fragment', ctypes.POINTER(WGPUFragmentState)),
|
||||
]
|
||||
WGPUProcDeviceCreateRenderPipeline = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPURenderPipelineImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPURenderPipelineDescriptor))
|
||||
WGPUProcDeviceCreateRenderPipelineAsync = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPURenderPipelineDescriptor), ctypes.CFUNCTYPE(None, enum_WGPUCreatePipelineAsyncStatus, ctypes.POINTER(struct_WGPURenderPipelineImpl), struct_WGPUStringView, ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcDeviceCreateRenderPipelineAsync2 = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPURenderPipelineDescriptor), struct_WGPUCreateRenderPipelineAsyncCallbackInfo2)
|
||||
WGPUProcDeviceCreateRenderPipelineAsyncF = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPURenderPipelineDescriptor), struct_WGPUCreateRenderPipelineAsyncCallbackInfo)
|
||||
class const_struct_WGPUSamplerDescriptor(Struct): pass
|
||||
const_struct_WGPUSamplerDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('addressModeU', WGPUAddressMode),
|
||||
('addressModeV', WGPUAddressMode),
|
||||
('addressModeW', WGPUAddressMode),
|
||||
('magFilter', WGPUFilterMode),
|
||||
('minFilter', WGPUFilterMode),
|
||||
('mipmapFilter', WGPUMipmapFilterMode),
|
||||
('lodMinClamp', ctypes.c_float),
|
||||
('lodMaxClamp', ctypes.c_float),
|
||||
('compare', WGPUCompareFunction),
|
||||
('maxAnisotropy', uint16_t),
|
||||
]
|
||||
WGPUProcDeviceCreateSampler = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUSamplerImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUSamplerDescriptor))
|
||||
WGPUProcDeviceCreateShaderModule = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUShaderModuleImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUShaderModuleDescriptor))
|
||||
WGPUProcDeviceCreateTexture = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUTextureDescriptor))
|
||||
WGPUProcDeviceDestroy = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl))
|
||||
WGPUProcDeviceForceLoss = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl), enum_WGPUDeviceLostReason, struct_WGPUStringView)
|
||||
WGPUProcDeviceGetAHardwareBufferProperties = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.c_void_p, ctypes.POINTER(struct_WGPUAHardwareBufferProperties))
|
||||
@@ -2375,9 +2558,24 @@ WGPUProcDeviceGetLimits = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struc
|
||||
WGPUProcDeviceGetLostFuture = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUDeviceImpl))
|
||||
WGPUProcDeviceGetQueue = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUQueueImpl), ctypes.POINTER(struct_WGPUDeviceImpl))
|
||||
WGPUProcDeviceHasFeature = ctypes.CFUNCTYPE(ctypes.c_uint32, ctypes.POINTER(struct_WGPUDeviceImpl), enum_WGPUFeatureName)
|
||||
WGPUProcDeviceImportSharedBufferMemory = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUSharedBufferMemoryImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUSharedBufferMemoryDescriptor))
|
||||
WGPUProcDeviceImportSharedFence = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUSharedFenceImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUSharedFenceDescriptor))
|
||||
WGPUProcDeviceImportSharedTextureMemory = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUSharedTextureMemoryDescriptor))
|
||||
class const_struct_WGPUSharedBufferMemoryDescriptor(Struct): pass
|
||||
const_struct_WGPUSharedBufferMemoryDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
]
|
||||
WGPUProcDeviceImportSharedBufferMemory = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUSharedBufferMemoryImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUSharedBufferMemoryDescriptor))
|
||||
class const_struct_WGPUSharedFenceDescriptor(Struct): pass
|
||||
const_struct_WGPUSharedFenceDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
]
|
||||
WGPUProcDeviceImportSharedFence = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUSharedFenceImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUSharedFenceDescriptor))
|
||||
class const_struct_WGPUSharedTextureMemoryDescriptor(Struct): pass
|
||||
const_struct_WGPUSharedTextureMemoryDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
]
|
||||
WGPUProcDeviceImportSharedTextureMemory = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl), ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUSharedTextureMemoryDescriptor))
|
||||
WGPUProcDeviceInjectError = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl), enum_WGPUErrorType, struct_WGPUStringView)
|
||||
WGPUProcDevicePopErrorScope = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.CFUNCTYPE(None, enum_WGPUErrorType, struct_WGPUStringView, ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcDevicePopErrorScope2 = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUDeviceImpl), struct_WGPUPopErrorScopeCallbackInfo2)
|
||||
@@ -2386,7 +2584,7 @@ WGPUProcDevicePushErrorScope = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPU
|
||||
WGPUProcDeviceSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl), struct_WGPUStringView)
|
||||
WGPUProcDeviceSetLoggingCallback = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.CFUNCTYPE(None, enum_WGPULoggingType, struct_WGPUStringView, ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcDeviceTick = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl))
|
||||
WGPUProcDeviceValidateTextureDescriptor = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(struct_WGPUTextureDescriptor))
|
||||
WGPUProcDeviceValidateTextureDescriptor = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl), ctypes.POINTER(const_struct_WGPUTextureDescriptor))
|
||||
WGPUProcDeviceAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl))
|
||||
WGPUProcDeviceRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUDeviceImpl))
|
||||
WGPUProcExternalTextureDestroy = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUExternalTextureImpl))
|
||||
@@ -2395,13 +2593,28 @@ WGPUProcExternalTextureRefresh = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WG
|
||||
WGPUProcExternalTextureSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUExternalTextureImpl), struct_WGPUStringView)
|
||||
WGPUProcExternalTextureAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUExternalTextureImpl))
|
||||
WGPUProcExternalTextureRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUExternalTextureImpl))
|
||||
WGPUProcInstanceCreateSurface = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUSurfaceImpl), ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(struct_WGPUSurfaceDescriptor))
|
||||
class const_struct_WGPUSurfaceDescriptor(Struct): pass
|
||||
const_struct_WGPUSurfaceDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
]
|
||||
WGPUProcInstanceCreateSurface = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUSurfaceImpl), ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(const_struct_WGPUSurfaceDescriptor))
|
||||
WGPUProcInstanceEnumerateWGSLLanguageFeatures = ctypes.CFUNCTYPE(ctypes.c_uint64, ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(enum_WGPUWGSLFeatureName))
|
||||
WGPUProcInstanceHasWGSLLanguageFeature = ctypes.CFUNCTYPE(ctypes.c_uint32, ctypes.POINTER(struct_WGPUInstanceImpl), enum_WGPUWGSLFeatureName)
|
||||
WGPUProcInstanceProcessEvents = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUInstanceImpl))
|
||||
WGPUProcInstanceRequestAdapter = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(struct_WGPURequestAdapterOptions), ctypes.CFUNCTYPE(None, enum_WGPURequestAdapterStatus, ctypes.POINTER(struct_WGPUAdapterImpl), struct_WGPUStringView, ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcInstanceRequestAdapter2 = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(struct_WGPURequestAdapterOptions), struct_WGPURequestAdapterCallbackInfo2)
|
||||
WGPUProcInstanceRequestAdapterF = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(struct_WGPURequestAdapterOptions), struct_WGPURequestAdapterCallbackInfo)
|
||||
class const_struct_WGPURequestAdapterOptions(Struct): pass
|
||||
const_struct_WGPURequestAdapterOptions._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('compatibleSurface', WGPUSurface),
|
||||
('featureLevel', WGPUFeatureLevel),
|
||||
('powerPreference', WGPUPowerPreference),
|
||||
('backendType', WGPUBackendType),
|
||||
('forceFallbackAdapter', WGPUBool),
|
||||
('compatibilityMode', WGPUBool),
|
||||
]
|
||||
WGPUProcInstanceRequestAdapter = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(const_struct_WGPURequestAdapterOptions), ctypes.CFUNCTYPE(None, enum_WGPURequestAdapterStatus, ctypes.POINTER(struct_WGPUAdapterImpl), struct_WGPUStringView, ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcInstanceRequestAdapter2 = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(const_struct_WGPURequestAdapterOptions), struct_WGPURequestAdapterCallbackInfo2)
|
||||
WGPUProcInstanceRequestAdapterF = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.POINTER(const_struct_WGPURequestAdapterOptions), struct_WGPURequestAdapterCallbackInfo)
|
||||
WGPUProcInstanceWaitAny = ctypes.CFUNCTYPE(enum_WGPUWaitStatus, ctypes.POINTER(struct_WGPUInstanceImpl), ctypes.c_uint64, ctypes.POINTER(struct_WGPUFutureWaitInfo), ctypes.c_uint64)
|
||||
WGPUProcInstanceAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUInstanceImpl))
|
||||
WGPUProcInstanceRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUInstanceImpl))
|
||||
@@ -2414,15 +2627,41 @@ WGPUProcQuerySetGetType = ctypes.CFUNCTYPE(enum_WGPUQueryType, ctypes.POINTER(st
|
||||
WGPUProcQuerySetSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQuerySetImpl), struct_WGPUStringView)
|
||||
WGPUProcQuerySetAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQuerySetImpl))
|
||||
WGPUProcQuerySetRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQuerySetImpl))
|
||||
WGPUProcQueueCopyExternalTextureForBrowser = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl), ctypes.POINTER(struct_WGPUImageCopyExternalTexture), ctypes.POINTER(struct_WGPUImageCopyTexture), ctypes.POINTER(struct_WGPUExtent3D), ctypes.POINTER(struct_WGPUCopyTextureForBrowserOptions))
|
||||
WGPUProcQueueCopyTextureForBrowser = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl), ctypes.POINTER(struct_WGPUImageCopyTexture), ctypes.POINTER(struct_WGPUImageCopyTexture), ctypes.POINTER(struct_WGPUExtent3D), ctypes.POINTER(struct_WGPUCopyTextureForBrowserOptions))
|
||||
class const_struct_WGPUImageCopyExternalTexture(Struct): pass
|
||||
const_struct_WGPUImageCopyExternalTexture._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('externalTexture', WGPUExternalTexture),
|
||||
('origin', WGPUOrigin3D),
|
||||
('naturalSize', WGPUExtent2D),
|
||||
]
|
||||
class const_struct_WGPUCopyTextureForBrowserOptions(Struct): pass
|
||||
const_struct_WGPUCopyTextureForBrowserOptions._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('flipY', WGPUBool),
|
||||
('needsColorSpaceConversion', WGPUBool),
|
||||
('srcAlphaMode', WGPUAlphaMode),
|
||||
('srcTransferFunctionParameters', ctypes.POINTER(ctypes.c_float)),
|
||||
('conversionMatrix', ctypes.POINTER(ctypes.c_float)),
|
||||
('dstTransferFunctionParameters', ctypes.POINTER(ctypes.c_float)),
|
||||
('dstAlphaMode', WGPUAlphaMode),
|
||||
('internalUsage', WGPUBool),
|
||||
]
|
||||
WGPUProcQueueCopyExternalTextureForBrowser = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl), ctypes.POINTER(const_struct_WGPUImageCopyExternalTexture), ctypes.POINTER(const_struct_WGPUImageCopyTexture), ctypes.POINTER(const_struct_WGPUExtent3D), ctypes.POINTER(const_struct_WGPUCopyTextureForBrowserOptions))
|
||||
WGPUProcQueueCopyTextureForBrowser = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl), ctypes.POINTER(const_struct_WGPUImageCopyTexture), ctypes.POINTER(const_struct_WGPUImageCopyTexture), ctypes.POINTER(const_struct_WGPUExtent3D), ctypes.POINTER(const_struct_WGPUCopyTextureForBrowserOptions))
|
||||
WGPUProcQueueOnSubmittedWorkDone = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl), ctypes.CFUNCTYPE(None, enum_WGPUQueueWorkDoneStatus, ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcQueueOnSubmittedWorkDone2 = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUQueueImpl), struct_WGPUQueueWorkDoneCallbackInfo2)
|
||||
WGPUProcQueueOnSubmittedWorkDoneF = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUQueueImpl), struct_WGPUQueueWorkDoneCallbackInfo)
|
||||
WGPUProcQueueSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl), struct_WGPUStringView)
|
||||
WGPUProcQueueSubmit = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl), ctypes.c_uint64, ctypes.POINTER(ctypes.POINTER(struct_WGPUCommandBufferImpl)))
|
||||
WGPUProcQueueWriteBuffer = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl), ctypes.POINTER(struct_WGPUBufferImpl), ctypes.c_uint64, ctypes.c_void_p, ctypes.c_uint64)
|
||||
WGPUProcQueueWriteTexture = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl), ctypes.POINTER(struct_WGPUImageCopyTexture), ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(struct_WGPUTextureDataLayout), ctypes.POINTER(struct_WGPUExtent3D))
|
||||
class const_struct_WGPUTextureDataLayout(Struct): pass
|
||||
const_struct_WGPUTextureDataLayout._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('offset', uint64_t),
|
||||
('bytesPerRow', uint32_t),
|
||||
('rowsPerImage', uint32_t),
|
||||
]
|
||||
WGPUProcQueueWriteTexture = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl), ctypes.POINTER(const_struct_WGPUImageCopyTexture), ctypes.c_void_p, ctypes.c_uint64, ctypes.POINTER(const_struct_WGPUTextureDataLayout), ctypes.POINTER(const_struct_WGPUExtent3D))
|
||||
WGPUProcQueueAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl))
|
||||
WGPUProcQueueRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUQueueImpl))
|
||||
WGPUProcRenderBundleSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderBundleImpl), struct_WGPUStringView)
|
||||
@@ -2432,7 +2671,12 @@ WGPUProcRenderBundleEncoderDraw = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_W
|
||||
WGPUProcRenderBundleEncoderDrawIndexed = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderBundleEncoderImpl), ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_int32, ctypes.c_uint32)
|
||||
WGPUProcRenderBundleEncoderDrawIndexedIndirect = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderBundleEncoderImpl), ctypes.POINTER(struct_WGPUBufferImpl), ctypes.c_uint64)
|
||||
WGPUProcRenderBundleEncoderDrawIndirect = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderBundleEncoderImpl), ctypes.POINTER(struct_WGPUBufferImpl), ctypes.c_uint64)
|
||||
WGPUProcRenderBundleEncoderFinish = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPURenderBundleImpl), ctypes.POINTER(struct_WGPURenderBundleEncoderImpl), ctypes.POINTER(struct_WGPURenderBundleDescriptor))
|
||||
class const_struct_WGPURenderBundleDescriptor(Struct): pass
|
||||
const_struct_WGPURenderBundleDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
]
|
||||
WGPUProcRenderBundleEncoderFinish = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPURenderBundleImpl), ctypes.POINTER(struct_WGPURenderBundleEncoderImpl), ctypes.POINTER(const_struct_WGPURenderBundleDescriptor))
|
||||
WGPUProcRenderBundleEncoderInsertDebugMarker = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderBundleEncoderImpl), struct_WGPUStringView)
|
||||
WGPUProcRenderBundleEncoderPopDebugGroup = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderBundleEncoderImpl))
|
||||
WGPUProcRenderBundleEncoderPushDebugGroup = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderBundleEncoderImpl), struct_WGPUStringView)
|
||||
@@ -2458,7 +2702,14 @@ WGPUProcRenderPassEncoderPixelLocalStorageBarrier = ctypes.CFUNCTYPE(None, ctype
|
||||
WGPUProcRenderPassEncoderPopDebugGroup = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderPassEncoderImpl))
|
||||
WGPUProcRenderPassEncoderPushDebugGroup = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderPassEncoderImpl), struct_WGPUStringView)
|
||||
WGPUProcRenderPassEncoderSetBindGroup = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderPassEncoderImpl), ctypes.c_uint32, ctypes.POINTER(struct_WGPUBindGroupImpl), ctypes.c_uint64, ctypes.POINTER(ctypes.c_uint32))
|
||||
WGPUProcRenderPassEncoderSetBlendConstant = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderPassEncoderImpl), ctypes.POINTER(struct_WGPUColor))
|
||||
class const_struct_WGPUColor(Struct): pass
|
||||
const_struct_WGPUColor._fields_ = [
|
||||
('r', ctypes.c_double),
|
||||
('g', ctypes.c_double),
|
||||
('b', ctypes.c_double),
|
||||
('a', ctypes.c_double),
|
||||
]
|
||||
WGPUProcRenderPassEncoderSetBlendConstant = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderPassEncoderImpl), ctypes.POINTER(const_struct_WGPUColor))
|
||||
WGPUProcRenderPassEncoderSetIndexBuffer = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderPassEncoderImpl), ctypes.POINTER(struct_WGPUBufferImpl), enum_WGPUIndexFormat, ctypes.c_uint64, ctypes.c_uint64)
|
||||
WGPUProcRenderPassEncoderSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderPassEncoderImpl), struct_WGPUStringView)
|
||||
WGPUProcRenderPassEncoderSetPipeline = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPURenderPassEncoderImpl), ctypes.POINTER(struct_WGPURenderPipelineImpl))
|
||||
@@ -2476,14 +2727,22 @@ WGPUProcRenderPipelineRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGP
|
||||
WGPUProcSamplerSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSamplerImpl), struct_WGPUStringView)
|
||||
WGPUProcSamplerAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSamplerImpl))
|
||||
WGPUProcSamplerRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSamplerImpl))
|
||||
WGPUProcShaderModuleGetCompilationInfo = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUShaderModuleImpl), ctypes.CFUNCTYPE(None, enum_WGPUCompilationInfoRequestStatus, ctypes.POINTER(struct_WGPUCompilationInfo), ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcShaderModuleGetCompilationInfo = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUShaderModuleImpl), ctypes.CFUNCTYPE(None, enum_WGPUCompilationInfoRequestStatus, ctypes.POINTER(const_struct_WGPUCompilationInfo), ctypes.c_void_p), ctypes.c_void_p)
|
||||
WGPUProcShaderModuleGetCompilationInfo2 = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUShaderModuleImpl), struct_WGPUCompilationInfoCallbackInfo2)
|
||||
WGPUProcShaderModuleGetCompilationInfoF = ctypes.CFUNCTYPE(struct_WGPUFuture, ctypes.POINTER(struct_WGPUShaderModuleImpl), struct_WGPUCompilationInfoCallbackInfo)
|
||||
WGPUProcShaderModuleSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUShaderModuleImpl), struct_WGPUStringView)
|
||||
WGPUProcShaderModuleAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUShaderModuleImpl))
|
||||
WGPUProcShaderModuleRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUShaderModuleImpl))
|
||||
WGPUProcSharedBufferMemoryBeginAccess = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUSharedBufferMemoryImpl), ctypes.POINTER(struct_WGPUBufferImpl), ctypes.POINTER(struct_WGPUSharedBufferMemoryBeginAccessDescriptor))
|
||||
WGPUProcSharedBufferMemoryCreateBuffer = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUBufferImpl), ctypes.POINTER(struct_WGPUSharedBufferMemoryImpl), ctypes.POINTER(struct_WGPUBufferDescriptor))
|
||||
class const_struct_WGPUSharedBufferMemoryBeginAccessDescriptor(Struct): pass
|
||||
const_struct_WGPUSharedBufferMemoryBeginAccessDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('initialized', WGPUBool),
|
||||
('fenceCount', size_t),
|
||||
('fences', ctypes.POINTER(WGPUSharedFence)),
|
||||
('signaledValues', ctypes.POINTER(uint64_t)),
|
||||
]
|
||||
WGPUProcSharedBufferMemoryBeginAccess = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUSharedBufferMemoryImpl), ctypes.POINTER(struct_WGPUBufferImpl), ctypes.POINTER(const_struct_WGPUSharedBufferMemoryBeginAccessDescriptor))
|
||||
WGPUProcSharedBufferMemoryCreateBuffer = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUBufferImpl), ctypes.POINTER(struct_WGPUSharedBufferMemoryImpl), ctypes.POINTER(const_struct_WGPUBufferDescriptor))
|
||||
WGPUProcSharedBufferMemoryEndAccess = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUSharedBufferMemoryImpl), ctypes.POINTER(struct_WGPUBufferImpl), ctypes.POINTER(struct_WGPUSharedBufferMemoryEndAccessState))
|
||||
WGPUProcSharedBufferMemoryGetProperties = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUSharedBufferMemoryImpl), ctypes.POINTER(struct_WGPUSharedBufferMemoryProperties))
|
||||
WGPUProcSharedBufferMemoryIsDeviceLost = ctypes.CFUNCTYPE(ctypes.c_uint32, ctypes.POINTER(struct_WGPUSharedBufferMemoryImpl))
|
||||
@@ -2493,15 +2752,37 @@ WGPUProcSharedBufferMemoryRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct
|
||||
WGPUProcSharedFenceExportInfo = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSharedFenceImpl), ctypes.POINTER(struct_WGPUSharedFenceExportInfo))
|
||||
WGPUProcSharedFenceAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSharedFenceImpl))
|
||||
WGPUProcSharedFenceRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSharedFenceImpl))
|
||||
WGPUProcSharedTextureMemoryBeginAccess = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl), ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(struct_WGPUSharedTextureMemoryBeginAccessDescriptor))
|
||||
WGPUProcSharedTextureMemoryCreateTexture = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl), ctypes.POINTER(struct_WGPUTextureDescriptor))
|
||||
class const_struct_WGPUSharedTextureMemoryBeginAccessDescriptor(Struct): pass
|
||||
const_struct_WGPUSharedTextureMemoryBeginAccessDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('concurrentRead', WGPUBool),
|
||||
('initialized', WGPUBool),
|
||||
('fenceCount', size_t),
|
||||
('fences', ctypes.POINTER(WGPUSharedFence)),
|
||||
('signaledValues', ctypes.POINTER(uint64_t)),
|
||||
]
|
||||
WGPUProcSharedTextureMemoryBeginAccess = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl), ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(const_struct_WGPUSharedTextureMemoryBeginAccessDescriptor))
|
||||
WGPUProcSharedTextureMemoryCreateTexture = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl), ctypes.POINTER(const_struct_WGPUTextureDescriptor))
|
||||
WGPUProcSharedTextureMemoryEndAccess = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl), ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(struct_WGPUSharedTextureMemoryEndAccessState))
|
||||
WGPUProcSharedTextureMemoryGetProperties = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl), ctypes.POINTER(struct_WGPUSharedTextureMemoryProperties))
|
||||
WGPUProcSharedTextureMemoryIsDeviceLost = ctypes.CFUNCTYPE(ctypes.c_uint32, ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl))
|
||||
WGPUProcSharedTextureMemorySetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl), struct_WGPUStringView)
|
||||
WGPUProcSharedTextureMemoryAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl))
|
||||
WGPUProcSharedTextureMemoryRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSharedTextureMemoryImpl))
|
||||
WGPUProcSurfaceConfigure = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSurfaceImpl), ctypes.POINTER(struct_WGPUSurfaceConfiguration))
|
||||
class const_struct_WGPUSurfaceConfiguration(Struct): pass
|
||||
const_struct_WGPUSurfaceConfiguration._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('device', WGPUDevice),
|
||||
('format', WGPUTextureFormat),
|
||||
('usage', WGPUTextureUsage),
|
||||
('viewFormatCount', size_t),
|
||||
('viewFormats', ctypes.POINTER(WGPUTextureFormat)),
|
||||
('alphaMode', WGPUCompositeAlphaMode),
|
||||
('width', uint32_t),
|
||||
('height', uint32_t),
|
||||
('presentMode', WGPUPresentMode),
|
||||
]
|
||||
WGPUProcSurfaceConfigure = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSurfaceImpl), ctypes.POINTER(const_struct_WGPUSurfaceConfiguration))
|
||||
WGPUProcSurfaceGetCapabilities = ctypes.CFUNCTYPE(enum_WGPUStatus, ctypes.POINTER(struct_WGPUSurfaceImpl), ctypes.POINTER(struct_WGPUAdapterImpl), ctypes.POINTER(struct_WGPUSurfaceCapabilities))
|
||||
WGPUProcSurfaceGetCurrentTexture = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSurfaceImpl), ctypes.POINTER(struct_WGPUSurfaceTexture))
|
||||
WGPUProcSurfacePresent = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSurfaceImpl))
|
||||
@@ -2509,8 +2790,21 @@ WGPUProcSurfaceSetLabel = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSurfa
|
||||
WGPUProcSurfaceUnconfigure = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSurfaceImpl))
|
||||
WGPUProcSurfaceAddRef = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSurfaceImpl))
|
||||
WGPUProcSurfaceRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUSurfaceImpl))
|
||||
WGPUProcTextureCreateErrorView = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUTextureViewImpl), ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(struct_WGPUTextureViewDescriptor))
|
||||
WGPUProcTextureCreateView = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUTextureViewImpl), ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(struct_WGPUTextureViewDescriptor))
|
||||
class const_struct_WGPUTextureViewDescriptor(Struct): pass
|
||||
const_struct_WGPUTextureViewDescriptor._fields_ = [
|
||||
('nextInChain', ctypes.POINTER(WGPUChainedStruct)),
|
||||
('label', WGPUStringView),
|
||||
('format', WGPUTextureFormat),
|
||||
('dimension', WGPUTextureViewDimension),
|
||||
('baseMipLevel', uint32_t),
|
||||
('mipLevelCount', uint32_t),
|
||||
('baseArrayLayer', uint32_t),
|
||||
('arrayLayerCount', uint32_t),
|
||||
('aspect', WGPUTextureAspect),
|
||||
('usage', WGPUTextureUsage),
|
||||
]
|
||||
WGPUProcTextureCreateErrorView = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUTextureViewImpl), ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(const_struct_WGPUTextureViewDescriptor))
|
||||
WGPUProcTextureCreateView = ctypes.CFUNCTYPE(ctypes.POINTER(struct_WGPUTextureViewImpl), ctypes.POINTER(struct_WGPUTextureImpl), ctypes.POINTER(const_struct_WGPUTextureViewDescriptor))
|
||||
WGPUProcTextureDestroy = ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_WGPUTextureImpl))
|
||||
WGPUProcTextureGetDepthOrArrayLayers = ctypes.CFUNCTYPE(ctypes.c_uint32, ctypes.POINTER(struct_WGPUTextureImpl))
|
||||
WGPUProcTextureGetDimension = ctypes.CFUNCTYPE(enum_WGPUTextureDimension, ctypes.POINTER(struct_WGPUTextureImpl))
|
||||
|
||||
@@ -239,7 +239,7 @@ class HCQGraph(MultiGraphRunner):
|
||||
cpu_support = all(isinstance(d.timeline_signal.base_buf.view, MMIOInterface) for d in all_devs)
|
||||
|
||||
# Check if all devices are within the same peer group. If CPU is supported, don't count it as a separate peer group.
|
||||
if len(set(d.peer_group for d in all_devs if not (cpu_support and d._is_cpu()))) > 1: return False
|
||||
if len(set(d.peer_group for d in all_devs if cpu_support and not d._is_cpu())) > 1: return False
|
||||
|
||||
# MOCKGPU is not supported, since it can't execute commands in parallel
|
||||
copy = (isinstance(ei.prg, BufferCopy) and cast(HCQCompiled, devs[0]).hw_copy_queue_t is not None) and not getenv("MOCKGPU")
|
||||
|
||||
+33
-42
@@ -7,8 +7,8 @@ from tinygrad.runtime.support.hcq import HCQCompiled, HCQAllocator, HCQBuffer, H
|
||||
from tinygrad.runtime.support.hcq import MMIOInterface, BumpAllocator, hcq_filter_visible_devices
|
||||
from tinygrad.uop.ops import sint
|
||||
from tinygrad.device import Compiled, DMAFdRef, BufferSpec, CompilerSet, CompilerPair
|
||||
from tinygrad.helpers import getenv, round_up, data64_le, DEBUG, PROFILE, ProfileEvent, lo32, hi32, colored, prod, ContextVar
|
||||
from tinygrad.helpers import VIZ, AMD_CC, AMD_LLVM, ceildiv
|
||||
from tinygrad.helpers import getenv, round_up, data64_le, DEBUG, PROFILE, ProfileEvent, suppress_finalizing, lo32, hi32, colored, prod, ContextVar
|
||||
from tinygrad.helpers import VIZ, AMD_CC, AMD_LLVM
|
||||
from tinygrad.renderer.cstyle import AMDRenderer
|
||||
from tinygrad.renderer.llvmir import AMDLLVMRenderer
|
||||
from tinygrad.runtime.autogen import kfd, hsa, pci, sqtt
|
||||
@@ -624,7 +624,10 @@ class AMDAllocator(HCQAllocator['AMDDevice']):
|
||||
def _alloc(self, size:int, options:BufferSpec) -> HCQBuffer:
|
||||
return self.dev.iface.alloc(size, host=options.host, uncached=options.uncached, cpu_access=options.cpu_access)
|
||||
|
||||
def _do_free(self, opaque, options:BufferSpec): self.dev.iface.free(opaque)
|
||||
@suppress_finalizing
|
||||
def _free(self, opaque, options:BufferSpec):
|
||||
self.dev.synchronize()
|
||||
self.dev.iface.free(opaque)
|
||||
|
||||
def _map(self, buf:HCQBuffer): return self.dev.iface.map(buf._base if buf._base is not None else buf)
|
||||
|
||||
@@ -715,7 +718,8 @@ class KFDIface:
|
||||
buf = addr = cpu_addr or FileIOInterface.anon_mmap(0, size, mmap.PROT_READ | mmap.PROT_WRITE, mmap.MAP_SHARED | mmap.MAP_ANONYMOUS, 0)
|
||||
else: buf, addr = 0, FileIOInterface.anon_mmap(0, size, 0, mmap.MAP_PRIVATE | mmap.MAP_ANONYMOUS | MAP_NORESERVE, 0)
|
||||
|
||||
try: mem = kfd.AMDKFD_IOC_ALLOC_MEMORY_OF_GPU(self.kfd, va_addr=addr, size=size, gpu_id=self.gpu_id, flags=flags, mmap_offset=buf)
|
||||
try: mem = kfd.AMDKFD_IOC_ALLOC_MEMORY_OF_GPU(self.kfd, va_addr=addr, size=size, base=addr, length=size, gpu_id=self.gpu_id,
|
||||
flags=flags, mmap_offset=buf)
|
||||
except OSError as e:
|
||||
if e.errno == errno.EINVAL and (flags & kfd.KFD_IOC_ALLOC_MEM_FLAGS_VRAM) and cpu_access:
|
||||
raise MemoryError("Cannot allocate host-visible VRAM. Ensure the resizable BAR option is enabled on your system.") from e
|
||||
@@ -753,7 +757,7 @@ class KFDIface:
|
||||
|
||||
def create_queue(self, queue_type, ring, gart, rptr, wptr, eop_buffer=None, cwsr_buffer=None, ctl_stack_size=0, ctx_save_restore_size=0, xcc_id=0):
|
||||
queue = kfd.AMDKFD_IOC_CREATE_QUEUE(KFDIface.kfd, ring_base_address=ring.va_addr, ring_size=ring.size, gpu_id=self.gpu_id,
|
||||
queue_type=queue_type, queue_percentage=kfd.KFD_MAX_QUEUE_PERCENTAGE|(xcc_id<<8), queue_priority=getenv("AMD_KFD_QUEUE_PRIORITY", 7),
|
||||
queue_type=queue_type, queue_percentage=kfd.KFD_MAX_QUEUE_PERCENTAGE|(xcc_id<<8), queue_priority=kfd.KFD_MAX_QUEUE_PRIORITY,
|
||||
eop_buffer_address=eop_buffer.va_addr if eop_buffer else 0, eop_buffer_size=eop_buffer.size if eop_buffer else 0, ctl_stack_size=ctl_stack_size,
|
||||
ctx_save_restore_address=cwsr_buffer.va_addr if cwsr_buffer else 0, ctx_save_restore_size=ctx_save_restore_size,
|
||||
write_pointer_address=gart.va_addr+wptr, read_pointer_address=gart.va_addr+rptr+8*xcc_id)
|
||||
@@ -796,7 +800,7 @@ class PCIIface(PCIIfaceBase):
|
||||
gpus:ClassVar[list[str]] = []
|
||||
|
||||
def __init__(self, dev, dev_id):
|
||||
super().__init__(dev, dev_id, vendor=0x1002, devices=[(0xffff, [0x74a1, 0x744c, 0x7480, 0x7550, 0x7590])], bars=[0, 2, 5], vram_bar=0,
|
||||
super().__init__(dev, dev_id, vendor=0x1002, devices=[(0xffff, [0x744c, 0x7480, 0x7550, 0x7590])], bars=[0, 2, 5], vram_bar=0,
|
||||
va_start=AMMemoryManager.va_allocator.base, va_size=AMMemoryManager.va_allocator.size)
|
||||
self._setup_adev(self.pci_dev)
|
||||
self.pci_dev.write_config(pci.PCI_COMMAND, self.pci_dev.read_config(pci.PCI_COMMAND, 2) | pci.PCI_COMMAND_MASTER, 2)
|
||||
@@ -808,18 +812,11 @@ class PCIIface(PCIIfaceBase):
|
||||
self.ip_versions = self.dev_impl.ip_ver
|
||||
|
||||
gfxver = int(f"{self.dev_impl.ip_ver[am.GC_HWIP][0]:02d}{self.dev_impl.ip_ver[am.GC_HWIP][1]:02d}{self.dev_impl.ip_ver[am.GC_HWIP][2]:02d}")
|
||||
if self.dev_impl.gc_info.header.version_major == 2:
|
||||
cu_per_sa = self.dev_impl.gc_info.gc_num_cu_per_sh
|
||||
max_sh_per_se = self.dev_impl.gc_info.gc_num_sh_per_se
|
||||
else:
|
||||
cu_per_sa = 2 * (self.dev_impl.gc_info.gc_num_wgp0_per_sa + self.dev_impl.gc_info.gc_num_wgp1_per_sa)
|
||||
max_sh_per_se = self.dev_impl.gc_info.gc_num_sa_per_se
|
||||
|
||||
array_count = max_sh_per_se * self.dev_impl.gc_info.gc_num_se * self.dev_impl.gfx.xccs
|
||||
self.props = {'cu_per_simd_array': cu_per_sa, 'simd_count': 2 * cu_per_sa * array_count, 'simd_per_cu': 2, 'array_count': array_count,
|
||||
array_count = self.dev_impl.gc_info.gc_num_sa_per_se * self.dev_impl.gc_info.gc_num_se
|
||||
self.props = {'cu_per_simd_array': (cu_per_sa:=2 * (self.dev_impl.gc_info.gc_num_wgp0_per_sa + self.dev_impl.gc_info.gc_num_wgp1_per_sa)),
|
||||
'simd_count': 2 * cu_per_sa * array_count, 'simd_per_cu': 2, 'array_count': array_count, 'gfx_target_version': gfxver,
|
||||
'max_slots_scratch_cu': self.dev_impl.gc_info.gc_max_scratch_slots_per_cu, 'max_waves_per_simd': self.dev_impl.gc_info.gc_max_waves_per_simd,
|
||||
'simd_arrays_per_engine': max_sh_per_se, 'lds_size_in_kb': self.dev_impl.gc_info.gc_lds_size, 'num_xcc': self.dev_impl.gfx.xccs,
|
||||
'gfx_target_version': {90403: 90402}.get(gfxver, gfxver)}
|
||||
'simd_arrays_per_engine': self.dev_impl.gc_info.gc_num_sa_per_se, 'lds_size_in_kb': self.dev_impl.gc_info.gc_lds_size}
|
||||
|
||||
def create_queue(self, queue_type, ring, gart, rptr, wptr, eop_buffer=None, cwsr_buffer=None, ctl_stack_size=0, ctx_save_restore_size=0, xcc_id=0):
|
||||
assert cwsr_buffer is None, "no cwsr buffer for am"
|
||||
@@ -888,11 +885,11 @@ class AMDDevice(HCQCompiled):
|
||||
if self.target < (9,4,2) or self.target >= (13,0,0): raise RuntimeError(f"Unsupported arch: {self.arch}")
|
||||
if DEBUG >= 1: print(f"AMDDevice: opening {self.device_id} with target {self.target} arch {self.arch}")
|
||||
|
||||
self.xccs = self.iface.props.get('num_xcc', 1)
|
||||
self.se_cnt = self.iface.props['array_count'] // self.iface.props['simd_arrays_per_engine']
|
||||
self.max_cu_id = self.iface.props['simd_count'] // self.iface.props['simd_per_cu'] // self.xccs - 1
|
||||
self.max_cu_id = self.iface.props['simd_count'] // self.iface.props['simd_per_cu'] // self.iface.props.get('num_xcc', 1) - 1
|
||||
self.max_wave_id = (self.iface.props['max_waves_per_simd'] * self.iface.props['simd_per_cu'] - 1) if self.target >= (10,1,0) else \
|
||||
(min((self.max_cu_id+1)*40, self.se_cnt * 512) - 1)
|
||||
self.xccs = self.iface.props.get('num_xcc', 1)
|
||||
# this is what llvm refers to as "architected flat scratch"
|
||||
self.has_scratch_base_registers = self.target >= (11,0,0) or self.target in {(9,4,2), (9,5,0)}
|
||||
|
||||
@@ -951,8 +948,7 @@ class AMDDevice(HCQCompiled):
|
||||
self.pmc_counters = import_pmc(self.target)
|
||||
|
||||
# validate counters
|
||||
pmc_default = "TCC_HIT,TCC_MISS,SQ_LDS_IDX_ACTIVE,SQ_LDS_BANK_CONFLICT" if self.target[0] == 9 \
|
||||
else "GL2C_HIT,GL2C_MISS,SQC_LDS_IDX_ACTIVE,SQC_LDS_BANK_CONFLICT"
|
||||
pmc_default = "TCC_HIT,TCC_MISS,SQ_LDS_BANK_CONFLICT" if self.target[0] == 9 else "GL2C_HIT,GL2C_MISS,SQC_LDS_IDX_ACTIVE,SQC_LDS_BANK_CONFLICT"
|
||||
for k in (PMC_COUNTERS:=getenv("PMC_COUNTERS", pmc_default).split(",")):
|
||||
if k not in self.pmc_counters: raise RuntimeError(f"PMC counter {k} is not supported. Available: {','.join(self.pmc_counters.keys())}")
|
||||
|
||||
@@ -982,7 +978,7 @@ class AMDDevice(HCQCompiled):
|
||||
gart.cpu_view().view(fmt='B')[:ctypes.sizeof(aql_desc)] = bytes(aql_desc)
|
||||
self.aql_desc = hsa.amd_queue_t.from_address(gart.cpu_view().addr)
|
||||
|
||||
cwsr_buffer_size = round_up((ctx_save_restore_size + debug_memory_size) * self.xccs, mmap.PAGESIZE)
|
||||
cwsr_buffer_size = round_up((ctx_save_restore_size + debug_memory_size) * self.iface.props.get('num_xcc', 1), mmap.PAGESIZE)
|
||||
cwsr_buffer = self.iface.alloc(cwsr_buffer_size) if ctx_save_restore_size else None
|
||||
eop_buffer = self.iface.alloc(eop_buffer_size) if eop_buffer_size else None
|
||||
|
||||
@@ -990,36 +986,31 @@ class AMDDevice(HCQCompiled):
|
||||
wptr=getattr(hsa.amd_queue_t, 'write_dispatch_id').offset, eop_buffer=eop_buffer, cwsr_buffer=cwsr_buffer,
|
||||
ctx_save_restore_size=ctx_save_restore_size, ctl_stack_size=ctl_stack_size))
|
||||
|
||||
def _ensure_has_local_memory(self, private_segment_size):
|
||||
if self.max_private_segment_size >= private_segment_size: return
|
||||
def _ensure_has_local_memory(self, required):
|
||||
if self.max_private_segment_size >= required: return
|
||||
|
||||
lanes_per_wave = 64 # wave64
|
||||
mem_alignment_size = 256 if self.target >= (11,0,0) else 1024
|
||||
size_per_thread = round_up(private_segment_size, mem_alignment_size // lanes_per_wave)
|
||||
size_per_xcc = size_per_thread * lanes_per_wave * self.iface.props['max_slots_scratch_cu'] * (self.max_cu_id + 1)
|
||||
self.scratch, ok = self._realloc(getattr(self, 'scratch', None), size_per_xcc * self.xccs)
|
||||
# <gfx103 requires alignment of 1024, >=gfx11 requires 256
|
||||
wave_scratch_len = round_up(((self.max_wave_id + 1) * required), 256 if self.target >= (11,0,0) else 1024)
|
||||
|
||||
scratch_size = (self.max_cu_id+1)*self.iface.props['max_slots_scratch_cu']*wave_scratch_len # per xcc
|
||||
self.scratch, ok = self._realloc(getattr(self, 'scratch', None), scratch_size*self.xccs)
|
||||
if ok:
|
||||
# NOTE: xcc logic is correct only for GFX9.
|
||||
max_scratch_waves = (self.max_cu_id + 1) * self.iface.props['max_slots_scratch_cu'] * self.xccs
|
||||
wave_scratch = ceildiv(lanes_per_wave * size_per_thread, mem_alignment_size)
|
||||
num_waves = (size_per_xcc // (wave_scratch * mem_alignment_size)) // (self.se_cnt if self.target >= (11,0,0) else 1)
|
||||
|
||||
tmpring_t = getattr(hsa, f'union_COMPUTE_TMPRING_SIZE{"_GFX"+str(self.target[0]) if self.target[0] >= 11 else ""}_bitfields')
|
||||
self.tmpring_size = int.from_bytes(tmpring_t(WAVES=min(num_waves, max_scratch_waves), WAVESIZE=wave_scratch), 'little')
|
||||
self.max_private_segment_size = private_segment_size
|
||||
waves = wave_scratch_len // (256 if self.target >= (11,0,0) else 1024)
|
||||
# >=gfx11 wavesize is per SE
|
||||
wavesize = scratch_size // ((wave_scratch_len * self.se_cnt) if self.target >= (11,0,0) else wave_scratch_len)
|
||||
self.tmpring_size = waves << 12 | wavesize
|
||||
self.max_private_segment_size = required
|
||||
|
||||
if hasattr(self, 'aql_desc'):
|
||||
gfx9_rsrc = {'NUM_FORMAT':hsa.BUF_NUM_FORMAT_UINT, 'DATA_FORMAT':hsa.BUF_DATA_FORMAT_32, 'ELEMENT_SIZE':1, 'INDEX_STRIDE':3}
|
||||
rsrc = {'DST_SEL_X':hsa.SQ_SEL_X, 'DST_SEL_Y':hsa.SQ_SEL_Y, 'DST_SEL_Z':hsa.SQ_SEL_Z, 'DST_SEL_W':hsa.SQ_SEL_W, 'ADD_TID_ENABLE':1,
|
||||
'TYPE':hsa.SQ_RSRC_BUF, **(gfx9_rsrc if self.target[0] < 10 else {'FORMAT':hsa.BUF_FORMAT_32_UINT, 'OOB_SELECT':2})}
|
||||
rsrc1_t = getattr(hsa, f'union_SQ_BUF_RSRC_WORD1{"_GFX11" if self.target[0] >= 11 else ""}_bitfields')
|
||||
rsrc3_t = getattr(hsa, f'union_SQ_BUF_RSRC_WORD3{"_GFX"+str(self.target[0]) if self.target[0] >= 10 else ""}_bitfields')
|
||||
rsrc_t = getattr(hsa, f'union_SQ_BUF_RSRC_WORD3{"_GFX"+str(self.target[0]) if self.target[0] >= 10 else ""}_bitfields')
|
||||
|
||||
self.aql_desc.scratch_backing_memory_location = self.scratch.va_addr
|
||||
self.aql_desc.scratch_wave64_lane_byte_size = self.max_private_segment_size * (self.aql_desc.max_wave_id + 1) // 64
|
||||
self.aql_desc.scratch_resource_descriptor[:] = [lo32(self.scratch.va_addr),
|
||||
int.from_bytes(rsrc1_t(BASE_ADDRESS_HI=hi32(self.scratch.va_addr), SWIZZLE_ENABLE=1), 'little'),
|
||||
lo32(size_per_xcc), int.from_bytes(bytes(rsrc3_t(**rsrc)), 'little')]
|
||||
self.aql_desc.scratch_resource_descriptor[:] = [lo32(self.scratch.va_addr), hi32(self.scratch.va_addr) | (1 << 30), lo32(scratch_size),
|
||||
int.from_bytes(bytes(rsrc_t(**rsrc)), 'little')]
|
||||
self.aql_desc.compute_tmpring_size = self.tmpring_size
|
||||
|
||||
def invalidate_caches(self):
|
||||
|
||||
@@ -115,7 +115,7 @@ class CPUAllocator(HCQAllocatorBase):
|
||||
def _alloc(self, size:int, options:BufferSpec) -> HCQBuffer:
|
||||
if options.external_ptr: addr, buf = options.external_ptr, None
|
||||
elif WIN: addr = mv_address(buf:=mmap.mmap(-1, size, access=mmap.ACCESS_WRITE))
|
||||
else: addr = mv_address(buf:=mmap.mmap(-1, size, mmap.MAP_ANON | mmap.MAP_SHARED, mmap.PROT_READ | mmap.PROT_WRITE))
|
||||
else: addr = mv_address(buf:=mmap.mmap(-1, size, mmap.MAP_ANON | mmap.MAP_PRIVATE, mmap.PROT_READ | mmap.PROT_WRITE))
|
||||
return HCQBuffer(va:=addr, sz:=size, meta=buf, view=MMIOInterface(va, sz, fmt='B'), owner=self.dev)
|
||||
def _as_buffer(self, src) -> memoryview:
|
||||
self.dev.synchronize()
|
||||
|
||||
@@ -4,9 +4,7 @@ from tinygrad.engine.jit import MultiGraphRunner
|
||||
from tinygrad.renderer.cstyle import Renderer, CStyleLanguage
|
||||
from tinygrad.renderer.llvmir import AMDLLVMRenderer
|
||||
from tinygrad.uop.ops import Ops
|
||||
from tinygrad.helpers import cpu_profile, EMULATE, NULL_IR3, NULL_NAK
|
||||
from tinygrad.renderer.nir import IR3Renderer, NAKRenderer
|
||||
from tinygrad.runtime.support.compiler_mesa import IR3Compiler, NAKCompiler
|
||||
from tinygrad.helpers import cpu_profile, EMULATE
|
||||
|
||||
class NullRenderer(CStyleLanguage):
|
||||
device = "NULL"
|
||||
@@ -39,7 +37,4 @@ class NullDevice(Compiled):
|
||||
case "AMD_RDNA4": renderer = functools.partial(AMDLLVMRenderer, "gfx1201")
|
||||
case "": renderer = NullRenderer
|
||||
case _: raise RuntimeError(f"can't EMULATE device: {EMULATE.value}")
|
||||
compilers = CompilerSet([CompilerPair(renderer, Compiler),
|
||||
CompilerPair(functools.partial(IR3Renderer, self), functools.partial(IR3Compiler, 0x6030001), NULL_IR3), # adreno 630
|
||||
CompilerPair(functools.partial(NAKRenderer, self), functools.partial(NAKCompiler, "sm_120", 48), NULL_NAK)]) # 5090
|
||||
super().__init__(device, NullAllocator(self), compilers, functools.partial(NullProgram, device), NullGraph)
|
||||
super().__init__(device, NullAllocator(self), CompilerSet([CompilerPair(renderer, Compiler)]), functools.partial(NullProgram, device), NullGraph)
|
||||
|
||||
@@ -7,7 +7,7 @@ from tinygrad.runtime.support.hcq import HCQCompiled, HCQAllocator, HCQBuffer, H
|
||||
from tinygrad.runtime.support.hcq import MMIOInterface, FileIOInterface, MOCKGPU, hcq_filter_visible_devices
|
||||
from tinygrad.uop.ops import sint
|
||||
from tinygrad.device import BufferSpec, CompilerPair, CompilerSet
|
||||
from tinygrad.helpers import getenv, mv_address, round_up, data64, data64_le, prod, OSX, to_mv, hi32, lo32, NV_CC, NV_PTX, NV_NAK
|
||||
from tinygrad.helpers import getenv, mv_address, round_up, data64, data64_le, prod, OSX, to_mv, hi32, lo32, suppress_finalizing, NV_CC, NV_PTX, NV_NAK
|
||||
from tinygrad.renderer.ptx import PTXRenderer
|
||||
from tinygrad.renderer.cstyle import NVRenderer
|
||||
from tinygrad.runtime.support.compiler_cuda import CUDACompiler, PTXCompiler, NVPTXCompiler, NVCompiler
|
||||
@@ -300,7 +300,10 @@ class NVAllocator(HCQAllocator['NVDevice']):
|
||||
def _alloc(self, size:int, options:BufferSpec) -> HCQBuffer:
|
||||
return self.dev.iface.alloc(size, cpu_access=options.cpu_access, host=options.host)
|
||||
|
||||
def _do_free(self, opaque:HCQBuffer, options:BufferSpec): self.dev.iface.free(opaque)
|
||||
@suppress_finalizing
|
||||
def _free(self, opaque:HCQBuffer, options:BufferSpec):
|
||||
self.dev.synchronize()
|
||||
self.dev.iface.free(opaque)
|
||||
|
||||
def _map(self, buf:HCQBuffer): return self.dev.iface.map(buf._base if buf._base is not None else buf)
|
||||
|
||||
@@ -472,7 +475,7 @@ class NVKIface:
|
||||
if made.status != 0: raise RuntimeError(f"_gpu_free returned {get_error_str(made.status)}")
|
||||
|
||||
self.uvm(nv_gpu.UVM_FREE, nv_gpu.UVM_FREE_PARAMS(base=cast(int, mem.va_addr), length=mem.size))
|
||||
if mem.view is not None: FileIOInterface.munmap(cast(int, mem.va_addr), mem.size)
|
||||
if mem.meta.has_cpu_mapping: FileIOInterface.munmap(cast(int, mem.va_addr), mem.size)
|
||||
|
||||
def _gpu_uvm_map(self, va_base, size, mem_handle, create_range=True, has_cpu_mapping=False) -> HCQBuffer:
|
||||
if create_range:
|
||||
@@ -487,7 +490,8 @@ class NVKIface:
|
||||
attrs = (nv_gpu.UvmGpuMappingAttributes*256)(nv_gpu.UvmGpuMappingAttributes(gpuUuid=self.gpu_uuid, gpuMappingType=1))
|
||||
|
||||
self.uvm(nv_gpu.UVM_MAP_EXTERNAL_ALLOCATION, uvm_map:=nv_gpu.UVM_MAP_EXTERNAL_ALLOCATION_PARAMS(base=va_base, length=size,
|
||||
rmCtrlFd=self.fd_ctl.fd, hClient=self.root, hMemory=mem_handle, gpuAttributesCount=1, perGpuAttributes=attrs, mapped_gpu_ids=[self.gpu_uuid]))
|
||||
rmCtrlFd=self.fd_ctl.fd, hClient=self.root, hMemory=mem_handle, gpuAttributesCount=1, perGpuAttributes=attrs, mapped_gpu_ids=[self.gpu_uuid],
|
||||
has_cpu_mapping=has_cpu_mapping))
|
||||
return HCQBuffer(va_base, size, meta=uvm_map, view=MMIOInterface(va_base, size, fmt='B') if has_cpu_mapping else None, owner=self.dev)
|
||||
|
||||
def map(self, mem:HCQBuffer):
|
||||
|
||||
+79
-126
@@ -6,13 +6,10 @@ from typing import Any, cast
|
||||
from tinygrad.device import BufferSpec, CompilerSet, CompilerPair
|
||||
from tinygrad.runtime.support.hcq import HCQBuffer, HWQueue, HCQProgram, HCQCompiled, HCQAllocatorBase, HCQSignal, HCQArgsState, BumpAllocator
|
||||
from tinygrad.runtime.support.hcq import FileIOInterface, MMIOInterface
|
||||
from tinygrad.runtime.autogen import kgsl, mesa
|
||||
from tinygrad.runtime.autogen import kgsl, adreno
|
||||
from tinygrad.runtime.ops_cl import CLCompiler, CLDevice
|
||||
from tinygrad.renderer.cstyle import QCOMRenderer
|
||||
from tinygrad.renderer.nir import IR3Renderer
|
||||
from tinygrad.runtime.support.compiler_mesa import IR3Compiler
|
||||
from tinygrad.helpers import getenv, mv_address, to_mv, round_up, data64_le, prod, fromimport, cpu_profile, lo32, PROFILE, suppress_finalizing
|
||||
from tinygrad.helpers import flatten, QCOM_IR3, QCOM_CC
|
||||
from tinygrad.runtime.support.system import System
|
||||
if getenv("IOCTL"): import extra.qcom_gpu_driver.opencl_ioctl # noqa: F401 # pylint: disable=unused-import
|
||||
|
||||
@@ -23,9 +20,9 @@ BUFTYPE_BUF, BUFTYPE_TEX, BUFTYPE_IBO = 0, 1, 2
|
||||
def _qreg_exec(__reg, __val=0, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
reg_name = f"{__reg[4:]}_{k.removeprefix('_').upper()}"
|
||||
__val |= (getattr(mesa, reg_name) if v else 0) if type(v) is bool else (v << getattr(mesa, f'{reg_name}__SHIFT'))
|
||||
__val |= (getattr(adreno, reg_name) if v else 0) if type(v) is bool else (v << getattr(adreno, f'{reg_name}__SHIFT'))
|
||||
return __val
|
||||
qreg: Any = type("QREG", (object,), {name[4:].lower(): functools.partial(_qreg_exec, name) for name in mesa.__dict__.keys() if name[:4] == 'REG_'})
|
||||
qreg: Any = type("QREG", (object,), {name[4:].lower(): functools.partial(_qreg_exec, name) for name in adreno.__dict__.keys() if name[:4] == 'REG_'})
|
||||
|
||||
def next_power2(x): return 1 if x == 0 else 1 << (x - 1).bit_length()
|
||||
|
||||
@@ -33,15 +30,13 @@ def parity(val: int):
|
||||
for i in range(4,1,-1): val ^= val >> (1 << i)
|
||||
return (~0x6996 >> (val & 0xf)) & 1
|
||||
|
||||
def pkt7_hdr(opcode: int, cnt: int): return mesa.CP_TYPE7_PKT | cnt & 0x3FFF | parity(cnt) << 15 | (opcode & 0x7F) << 16 | parity(opcode) << 23
|
||||
def pkt7_hdr(opcode: int, cnt: int): return adreno.CP_TYPE7_PKT | cnt & 0x3FFF | parity(cnt) << 15 | (opcode & 0x7F) << 16 | parity(opcode) << 23
|
||||
|
||||
def pkt4_hdr(reg: int, cnt: int): return mesa.CP_TYPE4_PKT | cnt & 0x7F | parity(cnt) << 7 | (reg & 0x3FFFF) << 8 | parity(reg) << 27
|
||||
def pkt4_hdr(reg: int, cnt: int): return adreno.CP_TYPE4_PKT | cnt & 0x7F | parity(cnt) << 7 | (reg & 0x3FFFF) << 8 | parity(reg) << 27
|
||||
|
||||
def _read_lib(lib, off) -> int: return struct.unpack("I", lib[off:off+4])[0]
|
||||
class QCOMCompiler(CLCompiler):
|
||||
def __init__(self, device:str=""): super().__init__(CLDevice(device), 'compile_qcom')
|
||||
def disassemble(self, lib:bytes):
|
||||
fromimport('tinygrad.runtime.support.compiler_mesa', 'disas_adreno')(lib[(ofs:=_read_lib(lib, 0xc0)):ofs+_read_lib(lib, 0x100)])
|
||||
def disassemble(self, lib:bytes): fromimport('extra.disassemblers.adreno', 'disasm')(lib)
|
||||
|
||||
class QCOMSignal(HCQSignal):
|
||||
def __init__(self, *args, **kwargs): super().__init__(*args, **{**kwargs, 'timestamp_divider': 19.2})
|
||||
@@ -66,19 +61,19 @@ class QCOMComputeQueue(HWQueue):
|
||||
|
||||
def _cache_flush(self, write_back=True, invalidate=False, sync=True, memsync=False):
|
||||
# TODO: 7xx support.
|
||||
if write_back: self.cmd(mesa.CP_EVENT_WRITE, mesa.CACHE_FLUSH_TS, *data64_le(self.dev.dummy_addr), 0) # dirty cache write-back.
|
||||
if invalidate: self.cmd(mesa.CP_EVENT_WRITE, mesa.CACHE_INVALIDATE) # invalidate cache lines (following reads from RAM).
|
||||
if memsync: self.cmd(mesa.CP_WAIT_MEM_WRITES)
|
||||
if sync: self.cmd(mesa.CP_WAIT_FOR_IDLE)
|
||||
if write_back: self.cmd(adreno.CP_EVENT_WRITE, adreno.CACHE_FLUSH_TS, *data64_le(self.dev.dummy_addr), 0) # dirty cache write-back.
|
||||
if invalidate: self.cmd(adreno.CP_EVENT_WRITE, adreno.CACHE_INVALIDATE) # invalidate cache lines (following reads from RAM).
|
||||
if memsync: self.cmd(adreno.CP_WAIT_MEM_WRITES)
|
||||
if sync: self.cmd(adreno.CP_WAIT_FOR_IDLE)
|
||||
|
||||
def memory_barrier(self):
|
||||
self._cache_flush(write_back=True, invalidate=True, sync=True, memsync=True)
|
||||
return self
|
||||
|
||||
def signal(self, signal:QCOMSignal, value=0):
|
||||
self.cmd(mesa.CP_WAIT_FOR_IDLE)
|
||||
self.cmd(adreno.CP_WAIT_FOR_IDLE)
|
||||
if self.dev.gpu_id[:2] < (7, 3):
|
||||
self.cmd(mesa.CP_EVENT_WRITE, qreg.cp_event_write_0(event=mesa.CACHE_FLUSH_TS), *data64_le(signal.value_addr), lo32(value))
|
||||
self.cmd(adreno.CP_EVENT_WRITE, qreg.cp_event_write_0(event=adreno.CACHE_FLUSH_TS), *data64_le(signal.value_addr), lo32(value))
|
||||
self._cache_flush(write_back=True, invalidate=False, sync=False, memsync=False)
|
||||
else:
|
||||
# TODO: support devices starting with 8 Gen 1. Also, 700th series have convenient CP_GLOBAL_TIMESTAMP and CP_LOCAL_TIMESTAMP
|
||||
@@ -86,12 +81,12 @@ class QCOMComputeQueue(HWQueue):
|
||||
return self
|
||||
|
||||
def timestamp(self, signal:QCOMSignal):
|
||||
self.cmd(mesa.CP_WAIT_FOR_IDLE)
|
||||
self.cmd(mesa.CP_REG_TO_MEM, qreg.cp_reg_to_mem_0(reg=mesa.REG_A6XX_CP_ALWAYS_ON_COUNTER, cnt=2, _64b=True),*data64_le(signal.timestamp_addr))
|
||||
self.cmd(adreno.CP_WAIT_FOR_IDLE)
|
||||
self.cmd(adreno.CP_REG_TO_MEM, qreg.cp_reg_to_mem_0(reg=adreno.REG_A6XX_CP_ALWAYS_ON_COUNTER, cnt=2, _64b=True),*data64_le(signal.timestamp_addr))
|
||||
return self
|
||||
|
||||
def wait(self, signal:QCOMSignal, value=0):
|
||||
self.cmd(mesa.CP_WAIT_REG_MEM, qreg.cp_wait_reg_mem_0(function=mesa.WRITE_GE, poll=mesa.POLL_MEMORY),*data64_le(signal.value_addr),
|
||||
self.cmd(adreno.CP_WAIT_REG_MEM, qreg.cp_wait_reg_mem_0(function=adreno.WRITE_GE, poll=adreno.POLL_MEMORY),*data64_le(signal.value_addr),
|
||||
qreg.cp_wait_reg_mem_3(ref=value&0xFFFFFFFF), qreg.cp_wait_reg_mem_4(mask=0xFFFFFFFF), qreg.cp_wait_reg_mem_5(delay_loop_cycles=32))
|
||||
return self
|
||||
|
||||
@@ -120,72 +115,62 @@ class QCOMComputeQueue(HWQueue):
|
||||
def cast_int(x, ceil=False): return (math.ceil(x) if ceil else int(x)) if isinstance(x, float) else x
|
||||
global_size_mp = [cast_int(g*l) for g,l in zip(global_size, local_size)]
|
||||
|
||||
self.cmd(mesa.CP_SET_MARKER, qreg.a6xx_cp_set_marker_0(mode=mesa.RM6_COMPUTE))
|
||||
self.reg(mesa.REG_A6XX_SP_UPDATE_CNTL, qreg.a6xx_sp_update_cntl(cs_state=True, cs_uav=True))
|
||||
self.reg(mesa.REG_A6XX_SP_UPDATE_CNTL, 0x0)
|
||||
self.reg(mesa.REG_A6XX_SP_CS_TSIZE, qreg.a6xx_sp_cs_tsize(0x80)) # is this right? mesa uses 1
|
||||
self.reg(mesa.REG_A6XX_SP_CS_USIZE, qreg.a6xx_sp_cs_usize(0x40)) # mesa also uses 1
|
||||
self.reg(mesa.REG_A6XX_SP_MODE_CNTL, qreg.a6xx_sp_mode_cntl(isammode=mesa.ISAMMODE_GL if prg.NIR else mesa.ISAMMODE_CL))
|
||||
self.reg(mesa.REG_A6XX_SP_PERFCTR_SHADER_MASK, qreg.a6xx_sp_perfctr_shader_mask(cs=True))
|
||||
self.reg(mesa.REG_A6XX_TPL1_MODE_CNTL, qreg.a6xx_tpl1_mode_cntl(isammode=mesa.ISAMMODE_GL if prg.NIR else mesa.ISAMMODE_CL))
|
||||
self.reg(mesa.REG_A6XX_TPL1_DBG_ECO_CNTL, 0)
|
||||
self.cmd(mesa.CP_WAIT_FOR_IDLE)
|
||||
self.cmd(adreno.CP_SET_MARKER, qreg.a6xx_cp_set_marker_0(mode=adreno.RM6_COMPUTE))
|
||||
self.reg(adreno.REG_A6XX_HLSQ_INVALIDATE_CMD, qreg.a6xx_hlsq_invalidate_cmd(cs_state=True, cs_ibo=True))
|
||||
self.reg(adreno.REG_A6XX_HLSQ_INVALIDATE_CMD, 0x0)
|
||||
self.reg(adreno.REG_A6XX_SP_CS_TEX_COUNT, qreg.a6xx_sp_cs_tex_count(0x80))
|
||||
self.reg(adreno.REG_A6XX_SP_CS_IBO_COUNT, qreg.a6xx_sp_cs_ibo_count(0x40))
|
||||
self.reg(adreno.REG_A6XX_SP_MODE_CONTROL, qreg.a6xx_sp_mode_control(isammode=adreno.ISAMMODE_CL))
|
||||
self.reg(adreno.REG_A6XX_SP_PERFCTR_ENABLE, qreg.a6xx_sp_perfctr_enable(cs=True))
|
||||
self.reg(adreno.REG_A6XX_SP_TP_MODE_CNTL, qreg.a6xx_sp_tp_mode_cntl(isammode=adreno.ISAMMODE_CL, unk3=2))
|
||||
self.reg(adreno.REG_A6XX_TPL1_DBG_ECO_CNTL, 0)
|
||||
self.cmd(adreno.CP_WAIT_FOR_IDLE)
|
||||
|
||||
self.reg(mesa.REG_A6XX_SP_CS_NDRANGE_0,
|
||||
qreg.a6xx_sp_cs_ndrange_0(kerneldim=3, localsizex=local_size[0] - 1, localsizey=local_size[1] - 1, localsizez=local_size[2] - 1),
|
||||
global_size_mp[0], 0, global_size_mp[1], 0, global_size_mp[2], 0, 0xccc0cf, 0xfc | qreg.a6xx_sp_cs_wge_cntl(threadsize=mesa.THREAD64),
|
||||
self.reg(adreno.REG_A6XX_HLSQ_CS_NDRANGE_0,
|
||||
qreg.a6xx_hlsq_cs_ndrange_0(kerneldim=3, localsizex=local_size[0] - 1, localsizey=local_size[1] - 1, localsizez=local_size[2] - 1),
|
||||
global_size_mp[0], 0, global_size_mp[1], 0, global_size_mp[2], 0, 0xccc0cf, 0xfc | qreg.a6xx_hlsq_cs_cntl_1(threadsize=adreno.THREAD64),
|
||||
cast_int(global_size[0], ceil=True), cast_int(global_size[1], ceil=True), cast_int(global_size[2], ceil=True))
|
||||
|
||||
self.reg(mesa.REG_A6XX_SP_CS_CNTL_0,
|
||||
qreg.a6xx_sp_cs_cntl_0(threadsize=mesa.THREAD64, halfregfootprint=prg.hregs, fullregfootprint=prg.fregs, branchstack=prg.brnchstck),
|
||||
qreg.a6xx_sp_cs_cntl_1(constantrammode=mesa.CONSTLEN_256, shared_size=prg.shared_size), # should this be CONSTLEN_512?
|
||||
0, prg.prg_offset, *data64_le(prg.lib_gpu.va_addr),
|
||||
self.reg(adreno.REG_A6XX_SP_CS_CTRL_REG0,
|
||||
qreg.a6xx_sp_cs_ctrl_reg0(threadsize=adreno.THREAD64, halfregfootprint=prg.hregs, fullregfootprint=prg.fregs, branchstack=prg.brnchstck),
|
||||
qreg.a6xx_sp_cs_unknown_a9b1(unk6=True, shared_size=prg.shared_size), 0, prg.prg_offset, *data64_le(prg.lib_gpu.va_addr),
|
||||
qreg.a6xx_sp_cs_pvt_mem_param(memsizeperitem=prg.pvtmem_size_per_item), *data64_le(prg.dev._stack.va_addr),
|
||||
qreg.a6xx_sp_cs_pvt_mem_size(totalpvtmemsize=prg.pvtmem_size_total))
|
||||
|
||||
if prg.NIR and prg.wgsz != 0xfc: to_mv(args_state.buf.va_addr + prg.wgsz * 4, 12)[:] = struct.pack("III", *local_size)
|
||||
self.cmd(mesa.CP_LOAD_STATE6_FRAG, qreg.cp_load_state6_0(state_type=mesa.ST_CONSTANTS, state_src=mesa.SS6_INDIRECT,
|
||||
state_block=mesa.SB6_CS_SHADER, num_unit=1024 // 4),
|
||||
self.cmd(adreno.CP_LOAD_STATE6_FRAG, qreg.cp_load_state6_0(state_type=adreno.ST_CONSTANTS, state_src=adreno.SS6_INDIRECT,
|
||||
state_block=adreno.SB6_CS_SHADER, num_unit=1024 // 4),
|
||||
*data64_le(args_state.buf.va_addr))
|
||||
self.cmd(mesa.CP_LOAD_STATE6_FRAG, qreg.cp_load_state6_0(state_type=mesa.ST_SHADER, state_src=mesa.SS6_INDIRECT,
|
||||
state_block=mesa.SB6_CS_SHADER, num_unit=round_up(prg.image_size, 128) // 128),
|
||||
self.cmd(adreno.CP_LOAD_STATE6_FRAG, qreg.cp_load_state6_0(state_type=adreno.ST_SHADER, state_src=adreno.SS6_INDIRECT,
|
||||
state_block=adreno.SB6_CS_SHADER, num_unit=round_up(prg.image_size, 128) // 128),
|
||||
*data64_le(prg.lib_gpu.va_addr))
|
||||
|
||||
self.reg(mesa.REG_A6XX_SP_REG_PROG_ID_0, 0xfcfcfcfc, 0xfcfcfcfc, 0xfcfcfcfc, 0xfc, qreg.a6xx_sp_cs_const_config(constlen=1024 // 4, enabled=True))
|
||||
self.reg(adreno.REG_A6XX_HLSQ_CONTROL_2_REG, 0xfcfcfcfc, 0xfcfcfcfc, 0xfcfcfcfc, 0xfc, qreg.a6xx_hlsq_cs_cntl(constlen=1024 // 4, enabled=True))
|
||||
|
||||
self.reg(mesa.REG_A6XX_SP_CS_PVT_MEM_STACK_OFFSET, qreg.a6xx_sp_cs_pvt_mem_stack_offset(prg.hw_stack_offset))
|
||||
self.reg(mesa.REG_A6XX_SP_CS_INSTR_SIZE, qreg.a6xx_sp_cs_instr_size(prg.image_size // 4))
|
||||
self.reg(adreno.REG_A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET, qreg.a6xx_sp_cs_pvt_mem_hw_stack_offset(prg.hw_stack_offset))
|
||||
self.reg(adreno.REG_A6XX_SP_CS_INSTRLEN, qreg.a6xx_sp_cs_instrlen(prg.image_size // 4))
|
||||
|
||||
if prg.samp_cnt > 0:
|
||||
self.cmd(mesa.CP_LOAD_STATE6_FRAG, qreg.cp_load_state6_0(state_type=mesa.ST_SHADER, state_src=mesa.SS6_INDIRECT,
|
||||
state_block=mesa.SB6_CS_TEX, num_unit=args_state.prg.samp_cnt),
|
||||
if args_state.prg.samp_cnt > 0:
|
||||
self.cmd(adreno.CP_LOAD_STATE6_FRAG, qreg.cp_load_state6_0(state_type=adreno.ST_SHADER, state_src=adreno.SS6_INDIRECT,
|
||||
state_block=adreno.SB6_CS_TEX, num_unit=args_state.prg.samp_cnt),
|
||||
*data64_le(args_state.buf.va_addr + args_state.prg.samp_off))
|
||||
self.reg(mesa.REG_A6XX_SP_CS_SAMPLER_BASE, *data64_le(args_state.buf.va_addr + args_state.prg.samp_off))
|
||||
self.reg(mesa.REG_A6XX_TPL1_CS_BORDER_COLOR_BASE, *data64_le(prg.dev.border_color_buf.va_addr))
|
||||
self.reg(adreno.REG_A6XX_SP_CS_TEX_SAMP, *data64_le(args_state.buf.va_addr + args_state.prg.samp_off))
|
||||
self.reg(adreno.REG_A6XX_SP_PS_TP_BORDER_COLOR_BASE_ADDR, *data64_le(prg.dev.border_color_buf.va_addr))
|
||||
|
||||
if prg.tex_cnt > 0:
|
||||
self.cmd(mesa.CP_LOAD_STATE6_FRAG, qreg.cp_load_state6_0(state_type=mesa.ST_CONSTANTS, state_src=mesa.SS6_INDIRECT,
|
||||
state_block=mesa.SB6_CS_TEX, num_unit=min(16, args_state.prg.tex_cnt)),
|
||||
if args_state.prg.tex_cnt > 0:
|
||||
self.cmd(adreno.CP_LOAD_STATE6_FRAG, qreg.cp_load_state6_0(state_type=adreno.ST_CONSTANTS, state_src=adreno.SS6_INDIRECT,
|
||||
state_block=adreno.SB6_CS_TEX, num_unit=min(16, args_state.prg.tex_cnt)),
|
||||
*data64_le(args_state.buf.va_addr + args_state.prg.tex_off))
|
||||
self.reg(mesa.REG_A6XX_SP_CS_TEXMEMOBJ_BASE, *data64_le(args_state.buf.va_addr + args_state.prg.tex_off))
|
||||
self.reg(adreno.REG_A6XX_SP_CS_TEX_CONST, *data64_le(args_state.buf.va_addr + args_state.prg.tex_off))
|
||||
|
||||
if prg.ibo_cnt > 0:
|
||||
self.cmd(mesa.CP_LOAD_STATE6_FRAG, qreg.cp_load_state6_0(state_type=mesa.ST6_UAV, state_src=mesa.SS6_INDIRECT,
|
||||
state_block=mesa.SB6_CS_SHADER, num_unit=args_state.prg.ibo_cnt),
|
||||
if args_state.prg.ibo_cnt > 0:
|
||||
self.cmd(adreno.CP_LOAD_STATE6_FRAG, qreg.cp_load_state6_0(state_type=adreno.ST6_IBO, state_src=adreno.SS6_INDIRECT,
|
||||
state_block=adreno.SB6_CS_SHADER, num_unit=args_state.prg.ibo_cnt),
|
||||
*data64_le(args_state.buf.va_addr + args_state.prg.ibo_off))
|
||||
self.reg(mesa.REG_A6XX_SP_CS_UAV_BASE, *data64_le(args_state.buf.va_addr + args_state.prg.ibo_off))
|
||||
|
||||
self.reg(mesa.REG_A6XX_SP_CS_CONFIG,
|
||||
qreg.a6xx_sp_cs_config(enabled=True, nsamp=args_state.prg.samp_cnt, ntex=args_state.prg.tex_cnt, nuav=args_state.prg.ibo_cnt))
|
||||
|
||||
if prg.NIR:
|
||||
self.reg(mesa.REG_A6XX_SP_CS_CONST_CONFIG_0,
|
||||
qreg.a6xx_sp_cs_const_config_0(wgidconstid=prg.wgid, wgsizeconstid=prg.wgsz, wgoffsetconstid=0xfc, localidregid=prg.lid),
|
||||
qreg.a6xx_sp_cs_wge_cntl(linearlocalidregid=0xfc, threadsize=mesa.THREAD64))
|
||||
self.cmd(mesa.CP_EXEC_CS, 0,
|
||||
qreg.cp_exec_cs_1(ngroups_x=global_size[0]), qreg.cp_exec_cs_2(ngroups_y=global_size[1]), qreg.cp_exec_cs_3(_ngroups_z=global_size[2]))
|
||||
else: self.cmd(mesa.CP_RUN_OPENCL, 0)
|
||||
self.reg(adreno.REG_A6XX_SP_CS_IBO, *data64_le(args_state.buf.va_addr + args_state.prg.ibo_off))
|
||||
|
||||
self.reg(adreno.REG_A6XX_SP_CS_CONFIG,
|
||||
qreg.a6xx_sp_cs_config(enabled=True, nsamp=args_state.prg.samp_cnt, ntex=args_state.prg.tex_cnt, nibo=args_state.prg.ibo_cnt))
|
||||
self.cmd(adreno.CP_RUN_OPENCL, 0)
|
||||
self._cache_flush(write_back=True, invalidate=False, sync=False, memsync=False)
|
||||
return self
|
||||
|
||||
@@ -209,45 +194,11 @@ class QCOMArgsState(HCQArgsState):
|
||||
|
||||
for i, v in enumerate(vals): self.bind_sints_to_buf(v, buf=self.buf, fmt='I', offset=self.args_info[i].offset)
|
||||
|
||||
class IR3ArgsState(HCQArgsState):
|
||||
def __init__(self, buf:HCQBuffer, prg:QCOMProgram, bufs:tuple[HCQBuffer, ...], vals:tuple[int, ...]=()):
|
||||
super().__init__(buf, prg, bufs, vals=vals)
|
||||
ctypes.memset(cast(int, self.buf.va_addr), 0, prg.kernargs_alloc_size)
|
||||
to_mv(self.buf.va_addr + prg.imm_off, len(prg.imm_vals))[:] = prg.imm_vals
|
||||
|
||||
ubos, uavs = [b for b in bufs if b.texture_info is None], [b for b in bufs if b.texture_info is not None]
|
||||
ibos, texs = (uavs, []) if prg.tex_cnt == 0 else (uavs[:-prg.tex_cnt], uavs[-prg.tex_cnt:]) # textures are at the end
|
||||
|
||||
if prg.samp_cnt > 0: to_mv(self.buf.va_addr + prg.samp_off, len(prg.samplers) * 4).cast('I')[:] = array.array('I', prg.samplers)
|
||||
self.bind_sints_to_buf(*[b.va_addr for b in ubos], buf=self.buf, fmt='Q', offset=prg.buf_off)
|
||||
self.bind_sints_to_buf(*vals, buf=self.buf, fmt='I', offset=prg.buf_off + len(ubos) * 8)
|
||||
self.bind_sints_to_buf(*flatten([b.texture_info.desc + ([0] * 8) for b in texs]), buf=self.buf, fmt='I', offset=prg.tex_off)
|
||||
self.bind_sints_to_buf(*flatten([b.texture_info.ibo + ([0] * 8) for b in ibos]), buf=self.buf, fmt='I', offset=prg.ibo_off)
|
||||
|
||||
class QCOMProgram(HCQProgram):
|
||||
def __init__(self, dev: QCOMDevice, name: str, lib: bytes):
|
||||
self.dev: QCOMDevice = dev
|
||||
self.name, self.lib, self.NIR = name, lib, isinstance(dev.compiler, IR3Compiler)
|
||||
|
||||
if self.NIR:
|
||||
from tinygrad.runtime.autogen import mesa
|
||||
v, cs, self.imm_vals, self.image = IR3Compiler.unpack_lib(lib)
|
||||
self.prg_offset, self.brnchstck, self.image_size, self.pvtmem, self.shmem = 0, v.branchstack, v.info.size, v.pvtmem_size, v.shared_size
|
||||
self.wgsz = alloc.offset_vec4 * 4 + 8 if (alloc:=cs.allocs.consts[mesa.IR3_CONST_ALLOC_DRIVER_PARAMS]).size_vec4 else 0xfc
|
||||
|
||||
self.wgid, self.lid = v.cs.work_group_id, v.cs.local_invocation_id # register ids
|
||||
self.buf_off, self.imm_off = cs.ubo_state.range[0].offset, cs.allocs.max_const_offset_vec4 * 16
|
||||
|
||||
# see https://elixir.bootlin.com/mesa/mesa-25.3.0/source/src/freedreno/ir3/ir3_shader.h#L525
|
||||
# and https://elixir.bootlin.com/mesa/mesa-25.3.0/source/src/freedreno/ir3/ir3_compiler_nir.c#L5389
|
||||
self.samp_cnt, self.tex_cnt, self.ibo_cnt = (nt:=v.image_mapping.num_tex), nt, v.num_uavs - nt
|
||||
# IR3 outputs a sampler for every texture (https://elixir.bootlin.com/mesa/mesa-25.3.0/source/src/freedreno/ir3/ir3_compiler_nir.c#L1714)
|
||||
self.samplers = [qreg.a6xx_tex_samp_0(wrap_s=(clamp_mode:=mesa.A6XX_TEX_CLAMP_TO_BORDER), wrap_t=clamp_mode, wrap_r=clamp_mode),
|
||||
qreg.a6xx_tex_samp_1(unnorm_coords=True, cubemapseamlessfiltoff=True), 0, 0] * self.samp_cnt
|
||||
|
||||
self.tex_off, self.ibo_off, self.samp_off = 2048, 2048 + 0x40 * self.tex_cnt, 2048 + 0x40 * (self.tex_cnt + self.ibo_cnt)
|
||||
self.fregs, self.hregs = v.info.max_reg + 1, v.info.max_half_reg + 1
|
||||
else: self._parse_lib()
|
||||
self.name, self.lib = name, lib
|
||||
self._parse_lib()
|
||||
|
||||
self.lib_gpu: HCQBuffer = self.dev.allocator.alloc(self.image_size, buf_spec:=BufferSpec(cpu_access=True, nolru=True))
|
||||
to_mv(cast(int, self.lib_gpu.va_addr), self.image_size)[:] = self.image
|
||||
@@ -259,8 +210,8 @@ class QCOMProgram(HCQProgram):
|
||||
self.max_threads = min(1024, ((384 * 32) // (max(1, (self.fregs + round_up(self.hregs, 2) // 2)) * 128)) * 128)
|
||||
dev._ensure_stack_size(self.hw_stack_offset * 4)
|
||||
|
||||
kernargs_alloc_size = round_up(2048 + (self.tex_cnt + self.ibo_cnt) * 0x40 + len(self.samplers) * 4, 0x100)
|
||||
super().__init__(IR3ArgsState if self.NIR else QCOMArgsState, self.dev, self.name, kernargs_alloc_size=kernargs_alloc_size)
|
||||
kernargs_alloc_size = round_up(2048 + (self.tex_cnt + self.ibo_cnt) * 0x40 + self.samp_cnt * 0x10, 0x100)
|
||||
super().__init__(QCOMArgsState, self.dev, self.name, kernargs_alloc_size=kernargs_alloc_size)
|
||||
weakref.finalize(self, self._fini, self.dev, self.lib_gpu, buf_spec)
|
||||
|
||||
def __call__(self, *bufs, global_size:tuple[int,int,int]=(1,1,1), local_size:tuple[int,int,int]=(1,1,1), vals:tuple[int, ...]=(), wait=False):
|
||||
@@ -270,26 +221,27 @@ class QCOMProgram(HCQProgram):
|
||||
return super().__call__(*bufs, global_size=global_size, local_size=local_size, vals=vals, wait=wait)
|
||||
|
||||
def _parse_lib(self):
|
||||
def _read_lib(off) -> int: return struct.unpack("I", self.lib[off:off+4])[0]
|
||||
|
||||
# Extract image binary
|
||||
self.image_size = _read_lib(self.lib, 0x100)
|
||||
self.image = bytearray(self.lib[(image_offset:=_read_lib(self.lib, 0xc0)):image_offset+self.image_size])
|
||||
self.image_size = _read_lib(0x100)
|
||||
self.image = bytearray(self.lib[(image_offset:=_read_lib(0xc0)):image_offset+self.image_size])
|
||||
|
||||
# Parse image descriptors
|
||||
image_desc_off = _read_lib(self.lib, 0x110)
|
||||
self.prg_offset, self.brnchstck = _read_lib(self.lib, image_desc_off+0xc4), _read_lib(self.lib, image_desc_off+0x108) // 2
|
||||
self.pvtmem, self.shmem = _read_lib(self.lib, image_desc_off+0xc8), _read_lib(self.lib, image_desc_off+0xd8)
|
||||
image_desc_off = _read_lib(0x110)
|
||||
self.prg_offset, self.brnchstck = _read_lib(image_desc_off+0xc4), _read_lib(image_desc_off+0x108) // 2
|
||||
self.pvtmem, self.shmem = _read_lib(image_desc_off+0xc8), _read_lib(image_desc_off+0xd8)
|
||||
|
||||
# Fill up constants and buffers info
|
||||
self.buf_info, self.consts_info = [], []
|
||||
|
||||
# Collect sampler info.
|
||||
self.samp_cnt = samp_cnt_in_file = _read_lib(self.lib, image_desc_off + 0xdc)
|
||||
self.samp_cnt = samp_cnt_in_file = _read_lib(image_desc_off + 0xdc)
|
||||
assert self.samp_cnt <= 1, "Up to one sampler supported"
|
||||
if self.samp_cnt:
|
||||
self.samp_cnt += 1
|
||||
self.samplers = [qreg.a6xx_tex_samp_0(wrap_s=(clamp_mode:=mesa.A6XX_TEX_CLAMP_TO_BORDER), wrap_t=clamp_mode, wrap_r=clamp_mode),
|
||||
self.samplers = [qreg.a6xx_tex_samp_0(wrap_s=(clamp_mode:=adreno.A6XX_TEX_CLAMP_TO_BORDER), wrap_t=clamp_mode, wrap_r=clamp_mode),
|
||||
qreg.a6xx_tex_samp_1(unnorm_coords=True, cubemapseamlessfiltoff=True), 0, 0, 0, 0, 0, 0]
|
||||
else: self.samplers = []
|
||||
|
||||
# Collect kernel arguments (buffers) info.
|
||||
bdoff = round_up(image_desc_off + 0x158 + len(self.name), 4) + 8 * samp_cnt_in_file
|
||||
@@ -307,16 +259,16 @@ class QCOMProgram(HCQProgram):
|
||||
if x.type is BUFTYPE_IBO: x.offset, cur_ibo_off = cur_ibo_off, cur_ibo_off + 0x40
|
||||
elif x.type is BUFTYPE_TEX: x.offset, cur_tex_off = cur_tex_off, cur_tex_off + 0x40
|
||||
|
||||
if _read_lib(self.lib, 0xb0) != 0: # check if we have constants.
|
||||
cdoff = _read_lib(self.lib, 0xac)
|
||||
if _read_lib(0xb0) != 0: # check if we have constants.
|
||||
cdoff = _read_lib(0xac)
|
||||
while cdoff + 40 <= image_offset:
|
||||
cnst, offset_words, _, is32 = struct.unpack("I", self.lib[cdoff:cdoff+4])[0], *struct.unpack("III", self.lib[cdoff+16:cdoff+28])
|
||||
self.consts_info.append((cnst, offset_words * (sz_bytes:=(2 << is32)), sz_bytes))
|
||||
cdoff += 40
|
||||
|
||||
# Registers info
|
||||
reg_desc_off = _read_lib(self.lib, 0x34)
|
||||
self.fregs, self.hregs = _read_lib(self.lib, reg_desc_off + 0x14), _read_lib(self.lib, reg_desc_off + 0x18)
|
||||
reg_desc_off = _read_lib(0x34)
|
||||
self.fregs, self.hregs = _read_lib(reg_desc_off + 0x14), _read_lib(reg_desc_off + 0x18)
|
||||
|
||||
class QCOMTextureInfo:
|
||||
def __init__(self, pitch:int, real_stride:int, desc:list[int], ibo:list[int]):
|
||||
@@ -338,9 +290,9 @@ class QCOMAllocator(HCQAllocatorBase):
|
||||
buf = self.dev._gpu_map(options.external_ptr, size) if options.external_ptr else self.dev._gpu_alloc(size)
|
||||
|
||||
if options.image is not None:
|
||||
tex_fmt = mesa.FMT6_32_32_32_32_FLOAT if options.image.itemsize == 4 else mesa.FMT6_16_16_16_16_FLOAT
|
||||
tex_fmt = adreno.FMT6_32_32_32_32_FLOAT if options.image.itemsize == 4 else adreno.FMT6_16_16_16_16_FLOAT
|
||||
desc = [qreg.a6xx_tex_const_0(0x8, swiz_x=0, swiz_y=1, swiz_z=2, swiz_w=3, fmt=tex_fmt), qreg.a6xx_tex_const_1(width=imgw, height=imgh),
|
||||
qreg.a6xx_tex_const_2(type=mesa.A6XX_TEX_2D, pitch=pitch, pitchalign=pitchalign-6), 0,
|
||||
qreg.a6xx_tex_const_2(type=adreno.A6XX_TEX_2D, pitch=pitch, pitchalign=pitchalign-6), 0,
|
||||
*data64_le(buf.va_addr), qreg.a6xx_tex_const_6(plane_pitch=0x400000), qreg.a6xx_tex_const_7(13)]
|
||||
|
||||
buf.texture_info = QCOMTextureInfo(pitch, real_stride, desc, [desc[0] & (~0xffff), *desc[1:len(desc)]])
|
||||
@@ -366,7 +318,10 @@ class QCOMAllocator(HCQAllocatorBase):
|
||||
self.dev.synchronize()
|
||||
return to_mv(src.cpu_view().addr, src.size)
|
||||
|
||||
def _do_free(self, opaque, options:BufferSpec): self.dev._gpu_free(opaque)
|
||||
@suppress_finalizing
|
||||
def _free(self, opaque, options:BufferSpec):
|
||||
self.dev.synchronize()
|
||||
self.dev._gpu_free(opaque)
|
||||
|
||||
def flag(nm, val): return (val << getattr(kgsl, f"{nm}_SHIFT")) & getattr(kgsl, f"{nm}_MASK")
|
||||
|
||||
@@ -401,10 +356,8 @@ class QCOMDevice(HCQCompiled):
|
||||
if PROFILE and self.gpu_id[:2] < (7, 3):
|
||||
System.write_sysfs("/sys/class/kgsl/kgsl-3d0/idle_timer", value="4000000000", msg="Failed to disable suspend mode", expected="4294967276")
|
||||
|
||||
compilers = CompilerSet(ctrl_var=QCOM_CC, cset=[CompilerPair(QCOMRenderer, functools.partial(QCOMCompiler, device)),
|
||||
CompilerPair(functools.partial(IR3Renderer, self), functools.partial(IR3Compiler, info.chip_id), QCOM_IR3)])
|
||||
super().__init__(device, QCOMAllocator(self), compilers, functools.partial(QCOMProgram, self), QCOMSignal,
|
||||
functools.partial(QCOMComputeQueue, self), None)
|
||||
super().__init__(device, QCOMAllocator(self), CompilerSet([CompilerPair(QCOMRenderer, functools.partial(QCOMCompiler, device))]),
|
||||
functools.partial(QCOMProgram, self), QCOMSignal, functools.partial(QCOMComputeQueue, self), None)
|
||||
|
||||
def _gpu_alloc(self, size:int, flags:int=0, uncached=False, fill_zeroes=False) -> HCQBuffer:
|
||||
flags |= flag("KGSL_MEMALIGN", alignment_hint:=12) | kgsl.KGSL_MEMFLAGS_USE_CPU_MAP
|
||||
|
||||
@@ -41,62 +41,40 @@ class AMFirmware:
|
||||
self.ucode_start: dict[str, int] = {}
|
||||
self.descs: list[tuple[list[int], memoryview]] = []
|
||||
|
||||
# SMU firmware
|
||||
blob, hdr = self.load_fw(f"smu_{fmt_ver(am.MP1_HWIP)}.bin", versioned_header="struct_smc_firmware_header")
|
||||
if self.adev.ip_ver[am.GC_HWIP] >= (11,0,0):
|
||||
self.smu_psp_desc = self.desc(blob, hdr.v1_0.header.ucode_array_offset_bytes, hdr.v1_0.header.ucode_size_bytes, am.GFX_FW_TYPE_SMU)
|
||||
else:
|
||||
p2stables = (am.struct_smc_soft_pptable_entry * hdr.pptable_count).from_buffer(blob[hdr.pptable_entry_offset:])
|
||||
for p2stable in p2stables:
|
||||
if p2stable.id == (__P2S_TABLE_ID_X:=0x50325358):
|
||||
self.descs += [self.desc(blob, p2stable.ppt_offset_bytes, p2stable.ppt_size_bytes, am.GFX_FW_TYPE_P2S_TABLE)]
|
||||
blob, hdr = self.load_fw(f"smu_{fmt_ver(am.MP1_HWIP)}.bin", am.struct_smc_firmware_header_v1_0)
|
||||
self.smu_psp_desc = self.desc(blob, hdr.header.ucode_array_offset_bytes, hdr.header.ucode_size_bytes, am.GFX_FW_TYPE_SMU)
|
||||
|
||||
# SDMA firmware
|
||||
blob, hdr = self.load_fw(f"sdma_{fmt_ver(am.SDMA0_HWIP)}.bin", versioned_header="struct_sdma_firmware_header")
|
||||
if hdr.header.header_version_major == 1:
|
||||
self.descs += [self.desc(blob, hdr.header.ucode_array_offset_bytes, hdr.header.ucode_size_bytes, am.GFX_FW_TYPE_SDMA0)]
|
||||
elif hdr.header.header_version_major == 2:
|
||||
blob, hdr = self.load_fw(f"sdma_{fmt_ver(am.SDMA0_HWIP)}.bin", versioned_header='struct_sdma_firmware_header')
|
||||
if hdr.header.header_version_major < 3:
|
||||
self.descs += [self.desc(blob, hdr.ctl_ucode_offset, hdr.ctl_ucode_size_bytes, am.GFX_FW_TYPE_SDMA_UCODE_TH1)]
|
||||
self.descs += [self.desc(blob, hdr.header.ucode_array_offset_bytes, hdr.ctx_ucode_size_bytes, am.GFX_FW_TYPE_SDMA_UCODE_TH0)]
|
||||
else: self.descs += [self.desc(blob, hdr.header.ucode_array_offset_bytes, hdr.ucode_size_bytes, am.GFX_FW_TYPE_SDMA_UCODE_TH0)]
|
||||
|
||||
# PFP, ME, MEC firmware
|
||||
for (fw_name, fw_cnt) in ([('PFP', 1), ('ME', 1)] if self.adev.ip_ver[am.GC_HWIP] >= (12,0,0) else []) + [('MEC', 1)]:
|
||||
blob, hdr = self.load_fw(f"gc_{fmt_ver(am.GC_HWIP)}_{fw_name.lower()}.bin", versioned_header="struct_gfx_firmware_header")
|
||||
blob, hdr = self.load_fw(f"gc_{fmt_ver(am.GC_HWIP)}_{fw_name.lower()}.bin", am.struct_gfx_firmware_header_v2_0)
|
||||
|
||||
ucode_off = hdr.header.ucode_array_offset_bytes
|
||||
if hdr.header.header_version_major == 1:
|
||||
# Code
|
||||
self.descs += [self.desc(blob, ucode_off, hdr.header.ucode_size_bytes - hdr.jt_size * 4, getattr(am, f'GFX_FW_TYPE_CP_{fw_name}'))]
|
||||
# JT
|
||||
self.descs += [self.desc(blob, ucode_off + hdr.jt_offset * 4, hdr.jt_size * 4, getattr(am, f'GFX_FW_TYPE_CP_{fw_name}_ME1'))]
|
||||
else:
|
||||
# Code
|
||||
self.descs += [self.desc(blob, ucode_off, hdr.ucode_size_bytes, getattr(am, f'GFX_FW_TYPE_RS64_{fw_name}'))]
|
||||
# Stack
|
||||
stack_fws = [getattr(am, f'GFX_FW_TYPE_RS64_{fw_name}_P{fwnum}_STACK') for fwnum in range(fw_cnt)]
|
||||
self.descs += [self.desc(blob, hdr.data_offset_bytes, hdr.data_size_bytes, *stack_fws)]
|
||||
self.ucode_start[fw_name] = hdr.ucode_start_addr_lo | (hdr.ucode_start_addr_hi << 32)
|
||||
# Code part
|
||||
self.descs += [self.desc(blob, hdr.header.ucode_array_offset_bytes, hdr.ucode_size_bytes, getattr(am, f'GFX_FW_TYPE_RS64_{fw_name}'))]
|
||||
|
||||
# Stack
|
||||
stack_fws = [getattr(am, f'GFX_FW_TYPE_RS64_{fw_name}_P{fwnum}_STACK') for fwnum in range(fw_cnt)]
|
||||
self.descs += [self.desc(blob, hdr.data_offset_bytes, hdr.data_size_bytes, *stack_fws)]
|
||||
self.ucode_start[fw_name] = hdr.ucode_start_addr_lo | (hdr.ucode_start_addr_hi << 32)
|
||||
|
||||
# IMU firmware
|
||||
if self.adev.ip_ver[am.GC_HWIP] >= (11,0,0):
|
||||
blob, hdr = self.load_fw(f"gc_{fmt_ver(am.GC_HWIP)}_imu.bin", am.struct_imu_firmware_header_v1_0)
|
||||
imu_i_off, imu_i_sz, imu_d_sz = hdr.header.ucode_array_offset_bytes, hdr.imu_iram_ucode_size_bytes, hdr.imu_dram_ucode_size_bytes
|
||||
self.descs += [self.desc(blob, imu_i_off, imu_i_sz, am.GFX_FW_TYPE_IMU_I), self.desc(blob, imu_i_off+imu_i_sz, imu_d_sz, am.GFX_FW_TYPE_IMU_D)]
|
||||
blob, hdr = self.load_fw(f"gc_{fmt_ver(am.GC_HWIP)}_imu.bin", am.struct_imu_firmware_header_v1_0)
|
||||
imu_i_off, imu_i_sz, imu_d_sz = hdr.header.ucode_array_offset_bytes, hdr.imu_iram_ucode_size_bytes, hdr.imu_dram_ucode_size_bytes
|
||||
self.descs += [self.desc(blob, imu_i_off, imu_i_sz, am.GFX_FW_TYPE_IMU_I), self.desc(blob, imu_i_off + imu_i_sz, imu_d_sz, am.GFX_FW_TYPE_IMU_D)]
|
||||
|
||||
# RLC firmware
|
||||
blob, hdr0, hdr1, hdr2, hdr3 = self.load_fw(f"gc_{fmt_ver(am.GC_HWIP)}_rlc.bin", am.struct_rlc_firmware_header_v2_0,
|
||||
blob, hdr0, _hdr1, hdr2, hdr3 = self.load_fw(f"gc_{fmt_ver(am.GC_HWIP)}_rlc.bin", am.struct_rlc_firmware_header_v2_0,
|
||||
am.struct_rlc_firmware_header_v2_1, am.struct_rlc_firmware_header_v2_2, am.struct_rlc_firmware_header_v2_3)
|
||||
|
||||
if hdr0.header.header_version_minor == 1:
|
||||
for mem,fmem in [('LIST_SRM_CNTL', 'list_cntl'), ('LIST_GPM_MEM', 'list_gpm'), ('LIST_SRM_MEM', 'list_srm')]:
|
||||
off, sz = getattr(hdr1, f'save_restore_{fmem}_offset_bytes'), getattr(hdr1, f'save_restore_{fmem}_size_bytes')
|
||||
self.descs += [self.desc(blob, off, sz, getattr(am, f'GFX_FW_TYPE_RLC_RESTORE_{mem}'))]
|
||||
|
||||
if hdr0.header.header_version_minor >= 2:
|
||||
for mem,fmem in [('IRAM', 'iram'), ('DRAM_BOOT', 'dram')]:
|
||||
off, sz = getattr(hdr2, f'rlc_{fmem}_ucode_offset_bytes'), getattr(hdr2, f'rlc_{fmem}_ucode_size_bytes')
|
||||
self.descs += [self.desc(blob, off, sz, getattr(am, f'GFX_FW_TYPE_RLC_{mem}'))]
|
||||
for mem,fmem in [('IRAM', 'iram'), ('DRAM_BOOT', 'dram')]:
|
||||
off, sz = getattr(hdr2, f'rlc_{fmem}_ucode_offset_bytes'), getattr(hdr2, f'rlc_{fmem}_ucode_size_bytes')
|
||||
self.descs += [self.desc(blob, off, sz, getattr(am, f'GFX_FW_TYPE_RLC_{mem}'))]
|
||||
|
||||
if hdr0.header.header_version_minor == 3:
|
||||
for mem in ['P', 'V']:
|
||||
@@ -120,16 +98,13 @@ class AMPageTableEntry:
|
||||
def __init__(self, adev, paddr, lv): self.adev, self.paddr, self.lv, self.entries = adev, paddr, lv, adev.vram.view(paddr, 0x1000, fmt='Q')
|
||||
|
||||
def set_entry(self, entry_id:int, paddr:int, table=False, uncached=False, system=False, snooped=False, frag=0, valid=True):
|
||||
if not system: paddr = self.adev.paddr2xgmi(paddr)
|
||||
assert paddr & self.adev.gmc.address_space_mask == paddr, f"Invalid physical address {paddr:#x}"
|
||||
self.entries[entry_id] = self.adev.gmc.get_pte_flags(self.lv, table, frag, uncached, system, snooped, valid) | (paddr & 0x0000FFFFFFFFF000)
|
||||
|
||||
def entry(self, entry_id:int) -> int: return self.entries[entry_id]
|
||||
def valid(self, entry_id:int) -> bool: return (self.entries[entry_id] & am.AMDGPU_PTE_VALID) != 0
|
||||
def address(self, entry_id:int) -> int:
|
||||
assert self.entries[entry_id] & am.AMDGPU_PTE_SYSTEM == 0, "should not be system address"
|
||||
return self.adev.xgmi2paddr(self.entries[entry_id] & 0x0000FFFFFFFFF000)
|
||||
def is_page(self, entry_id:int) -> bool: return self.lv == am.AMDGPU_VM_PTB or self.adev.gmc.is_pte_huge_page(self.lv, self.entries[entry_id])
|
||||
def address(self, entry_id:int) -> int: return self.entries[entry_id] & 0x0000FFFFFFFFF000
|
||||
def is_page(self, entry_id:int) -> bool: return self.lv == am.AMDGPU_VM_PTB or self.adev.gmc.is_pte_huge_page(self.entries[entry_id])
|
||||
def supports_huge_page(self, paddr:int): return self.lv >= am.AMDGPU_VM_PDB2
|
||||
|
||||
class AMMemoryManager(MemoryManager):
|
||||
@@ -143,7 +118,7 @@ class AMMemoryManager(MemoryManager):
|
||||
class AMDev(PCIDevImplBase):
|
||||
Version = 0xA0000006
|
||||
|
||||
def __init__(self, pci_dev:PCIDevice, dma_regions:list[tuple[int, MMIOInterface]]|None=None, reset_mode=False):
|
||||
def __init__(self, pci_dev:PCIDevice, dma_regions:list[tuple[int, MMIOInterface]]|None=None):
|
||||
self.pci_dev, self.devfmt, self.dma_regions = pci_dev, pci_dev.pcibus, dma_regions
|
||||
self.vram, self.doorbell64, self.mmio = self.pci_dev.map_bar(0), self.pci_dev.map_bar(2, fmt='Q'), self.pci_dev.map_bar(5, fmt='I')
|
||||
|
||||
@@ -169,11 +144,7 @@ class AMDev(PCIDevImplBase):
|
||||
|
||||
# Init hw for IP blocks where it is needed
|
||||
if not self.partial_boot:
|
||||
if self.psp.is_sos_alive() and self.smu.is_smu_alive():
|
||||
if self.gmc.xgmi_seg_sz > 0:
|
||||
if reset_mode: return # in reset mode, do not raise
|
||||
raise RuntimeError("Malformed state. Use extra/amdpci/hive_reset.py to reset the hive")
|
||||
self.smu.mode1_reset()
|
||||
if self.psp.is_sos_alive() and self.smu.is_smu_alive(): self.smu.mode1_reset()
|
||||
for ip in [self.soc, self.gmc, self.ih, self.psp, self.smu]:
|
||||
ip.init_hw()
|
||||
if DEBUG >= 2: print(f"am {self.devfmt}: {ip.__class__.__name__} initialized")
|
||||
@@ -219,38 +190,32 @@ class AMDev(PCIDevImplBase):
|
||||
self.ih.interrupt_handler()
|
||||
|
||||
def paddr2mc(self, paddr:int) -> int: return self.gmc.mc_base + paddr
|
||||
def paddr2xgmi(self, paddr:int) -> int: return self.gmc.paddr_base + paddr
|
||||
def xgmi2paddr(self, xgmi_paddr:int) -> int: return xgmi_paddr - self.gmc.paddr_base
|
||||
|
||||
def reg(self, reg:str) -> AMRegister: return self.__dict__[reg]
|
||||
|
||||
def rreg(self, reg:int) -> int:
|
||||
val = self.indirect_rreg(reg) if reg > len(self.mmio) else self.mmio[reg]
|
||||
val = self.indirect_rreg(reg * 4) if reg > len(self.mmio) else self.mmio[reg]
|
||||
if AM_DEBUG >= 4 and getattr(self, '_prev_rreg', None) != (reg, val): print(f"am {self.devfmt}: Reading register {reg:#x} with value {val:#x}")
|
||||
self._prev_rreg = (reg, val)
|
||||
return val
|
||||
|
||||
def wreg(self, reg:int, val:int):
|
||||
if AM_DEBUG >= 4: print(f"am {self.devfmt}: Writing register {reg:#x} with value {val:#x}")
|
||||
if reg > len(self.mmio): self.indirect_wreg(reg, val)
|
||||
if reg > len(self.mmio): self.indirect_wreg(reg * 4, val)
|
||||
else: self.mmio[reg] = val
|
||||
|
||||
def wreg_pair(self, reg_base:str, lo_suffix:str, hi_suffix:str, val:int, inst:int=0):
|
||||
self.reg(f"{reg_base}{lo_suffix}").write(val & 0xffffffff, inst=inst)
|
||||
self.reg(f"{reg_base}{hi_suffix}").write(val >> 32, inst=inst)
|
||||
def wreg_pair(self, reg_base:str, lo_suffix:str, hi_suffix:str, val:int):
|
||||
self.reg(f"{reg_base}{lo_suffix}").write(val & 0xffffffff)
|
||||
self.reg(f"{reg_base}{hi_suffix}").write(val >> 32)
|
||||
|
||||
def indirect_rreg(self, reg:int) -> int:
|
||||
self.reg("regBIF_BX_PF0_RSMU_INDEX").write(reg * 4)
|
||||
self.reg("regBIF_BX_PF0_RSMU_INDEX").write(reg)
|
||||
return self.reg("regBIF_BX_PF0_RSMU_DATA").read()
|
||||
|
||||
def indirect_wreg(self, reg:int, val:int):
|
||||
self.reg("regBIF_BX_PF0_RSMU_INDEX").write(reg * 4)
|
||||
self.reg("regBIF_BX_PF0_RSMU_INDEX").write(reg)
|
||||
self.reg("regBIF_BX_PF0_RSMU_DATA").write(val)
|
||||
|
||||
def indirect_wreg_pcie(self, reg:int, val:int, aid:int=0):
|
||||
self.reg("regBIF_BX0_PCIE_INDEX2").write(reg * 4 + ((((aid & 0b11) << 32) | (1 << 34)) if aid > 0 else 0))
|
||||
self.reg("regBIF_BX0_PCIE_DATA2").write(val)
|
||||
|
||||
def _read_vram(self, addr, size) -> bytes:
|
||||
assert addr % 4 == 0 and size % 4 == 0, f"Invalid address {addr:#x} or size {size:#x}"
|
||||
res = []
|
||||
@@ -298,7 +263,6 @@ class AMDev(PCIDevImplBase):
|
||||
def _build_regs(self):
|
||||
mods = [("mp", am.MP0_HWIP), ("hdp", am.HDP_HWIP), ("gc", am.GC_HWIP), ("mmhub", am.MMHUB_HWIP), ("osssys", am.OSSSYS_HWIP),
|
||||
("nbio" if self.ip_ver[am.GC_HWIP] < (12,0,0) else "nbif", am.NBIO_HWIP)]
|
||||
if self.ip_ver[am.SDMA0_HWIP] == (4,4,2): mods += [("sdma", am.SDMA0_HWIP)]
|
||||
|
||||
for prefix, hwip in mods:
|
||||
self.__dict__.update(import_asic_regs(prefix, self.ip_ver[hwip], cls=functools.partial(AMRegister, adev=self, bases=self.regs_offset[hwip])))
|
||||
|
||||
+171
-255
@@ -15,55 +15,35 @@ class AM_SOC(AM_IP):
|
||||
def init_sw(self): self.module = import_soc(self.adev.ip_ver[am.GC_HWIP])
|
||||
|
||||
def init_hw(self):
|
||||
if self.adev.ip_ver[am.NBIO_HWIP] == (7,9,0):
|
||||
self.adev.regXCC_DOORBELL_FENCE.write(0x0)
|
||||
self.adev.regBIFC_GFX_INT_MONITOR_MASK.write(0x7ff)
|
||||
self.adev.regBIFC_DOORBELL_ACCESS_EN_PF.write(0xfffff)
|
||||
else: self.adev.regRCC_DEV0_EPF2_STRAP2.update(strap_no_soft_reset_dev0_f2=0x0)
|
||||
self.adev.regRCC_DEV0_EPF2_STRAP2.update(strap_no_soft_reset_dev0_f2=0x0)
|
||||
self.adev.regRCC_DEV0_EPF0_RCC_DOORBELL_APER_EN.write(0x1)
|
||||
def set_clockgating_state(self):
|
||||
if self.adev.ip_ver[am.HDP_HWIP] >= (5,2,1): self.adev.regHDP_MEM_POWER_CTRL.update(atomic_mem_power_ctrl_en=1, atomic_mem_power_ds_en=1)
|
||||
def set_clockgating_state(self): self.adev.regHDP_MEM_POWER_CTRL.update(atomic_mem_power_ctrl_en=1, atomic_mem_power_ds_en=1)
|
||||
|
||||
def doorbell_enable(self, port, awid=0, awaddr_31_28_value=0, offset=0, size=0):
|
||||
reg = self.adev.reg(f"{'regGDC_S2A0_S2A' if self.adev.ip_ver[am.GC_HWIP] >= (12,0,0) else 'regS2A'}_DOORBELL_ENTRY_{port}_CTRL")
|
||||
val = reg.encode(**{f"s2a_doorbell_port{port}_enable":1, f"s2a_doorbell_port{port}_awid":awid, f"s2a_doorbell_port{port}_range_size":size,
|
||||
f"s2a_doorbell_port{port}_awaddr_31_28_value":awaddr_31_28_value, f"s2a_doorbell_port{port}_range_offset":offset})
|
||||
|
||||
if self.adev.ip_ver[am.NBIO_HWIP] == (7,9,0): self.adev.indirect_wreg_pcie(reg.addr[0], val)
|
||||
else: reg.write(val)
|
||||
self.adev.reg(f"{'regGDC_S2A0_S2A' if self.adev.ip_ver[am.GC_HWIP] >= (12,0,0) else 'regS2A'}_DOORBELL_ENTRY_{port}_CTRL").update(
|
||||
**{f"s2a_doorbell_port{port}_enable":1, f"s2a_doorbell_port{port}_awid":awid, f"s2a_doorbell_port{port}_awaddr_31_28_value":awaddr_31_28_value,
|
||||
f"s2a_doorbell_port{port}_range_offset":offset, f"s2a_doorbell_port{port}_range_size":size})
|
||||
|
||||
class AM_GMC(AM_IP):
|
||||
def init_sw(self):
|
||||
self.vmhubs = len(self.adev.regs_offset[am.MMHUB_HWIP])
|
||||
|
||||
# XGMI (for supported systems)
|
||||
self.xgmi_phys_id = self.adev.regMMMC_VM_XGMI_LFB_CNTL.read_bitfields()['pf_lfb_region'] if hasattr(self.adev, 'regMMMC_VM_XGMI_LFB_CNTL') else 0
|
||||
self.xgmi_seg_sz = self.adev.regMMMC_VM_XGMI_LFB_SIZE.read_bitfields()['pf_lfb_size']<<24 if hasattr(self.adev, 'regMMMC_VM_XGMI_LFB_SIZE') else 0
|
||||
|
||||
self.paddr_base = self.xgmi_phys_id * self.xgmi_seg_sz
|
||||
|
||||
self.fb_base = (self.adev.regMMMC_VM_FB_LOCATION_BASE.read() & 0xFFFFFF) << 24
|
||||
self.fb_end = (self.adev.regMMMC_VM_FB_LOCATION_TOP.read() & 0xFFFFFF) << 24
|
||||
|
||||
# Memory controller aperture
|
||||
self.mc_base = self.fb_base + self.paddr_base
|
||||
self.mc_base = (self.adev.regMMMC_VM_FB_LOCATION_BASE.read() & 0xFFFFFF) << 24
|
||||
self.mc_end = self.mc_base + self.adev.mm.vram_size - 1
|
||||
|
||||
# VM aperture
|
||||
self.vm_base = self.adev.mm.va_base
|
||||
self.vm_base = self.adev.mm.va_allocator.base
|
||||
self.vm_end = min(self.vm_base + (1 << self.adev.mm.va_bits) - 1, 0x7fffffffffff)
|
||||
|
||||
self.trans_futher = self.adev.ip_ver[am.GC_HWIP] < (10, 0, 0)
|
||||
|
||||
# GFX11/GFX12 has 44-bit address space
|
||||
self.address_space_mask = (1 << 44) - 1
|
||||
|
||||
self.memscratch_xgmi_paddr = self.adev.paddr2xgmi(self.adev.mm.palloc(0x1000, zero=False, boot=True))
|
||||
self.dummy_page_xgmi_paddr = self.adev.paddr2xgmi(self.adev.mm.palloc(0x1000, zero=False, boot=True))
|
||||
self.memscratch_paddr = self.adev.mm.palloc(0x1000, zero=False, boot=True)
|
||||
self.dummy_page_paddr = self.adev.mm.palloc(0x1000, zero=False, boot=True)
|
||||
self.hub_initted = {"MM": False, "GC": False}
|
||||
|
||||
self.pf_status_reg = lambda ip: f"reg{ip}VM_L2_PROTECTION_FAULT_STATUS{'_LO32' if self.adev.ip_ver[am.GC_HWIP] >= (12,0,0) else ''}"
|
||||
|
||||
def init_hw(self): self.init_hub("MM", inst_cnt=self.vmhubs)
|
||||
def init_hw(self): self.init_hub("MM")
|
||||
|
||||
def flush_hdp(self): self.adev.wreg(self.adev.reg("regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL").read() // 4, 0x0)
|
||||
def flush_tlb(self, ip:Literal["MM", "GC"], vmid, flush_type=0):
|
||||
@@ -72,65 +52,65 @@ class AM_GMC(AM_IP):
|
||||
# Can't issue TLB invalidation if the hub isn't initialized.
|
||||
if not self.hub_initted[ip]: return
|
||||
|
||||
for inst in range(self.adev.gmc.vmhubs if ip == "MM" else self.adev.gfx.xccs):
|
||||
if ip == "MM": wait_cond(lambda: self.adev.regMMVM_INVALIDATE_ENG17_SEM.read(inst=inst) & 0x1, value=1, msg="mm flush_tlb timeout")
|
||||
if ip == "MM": wait_cond(lambda: self.adev.regMMVM_INVALIDATE_ENG17_SEM.read() & 0x1, value=1, msg="mm flush_tlb timeout")
|
||||
|
||||
self.adev.reg(f"reg{ip}VM_INVALIDATE_ENG17_REQ").write(flush_type=flush_type, per_vmid_invalidate_req=(1 << vmid), invalidate_l2_ptes=1,
|
||||
invalidate_l2_pde0=1, invalidate_l2_pde1=1, invalidate_l2_pde2=1, invalidate_l1_ptes=1, clear_protection_fault_status_addr=0, inst=inst)
|
||||
self.adev.reg(f"reg{ip}VM_INVALIDATE_ENG17_REQ").write(flush_type=flush_type, per_vmid_invalidate_req=(1 << vmid), invalidate_l2_ptes=1,
|
||||
invalidate_l2_pde0=1, invalidate_l2_pde1=1, invalidate_l2_pde2=1, invalidate_l1_ptes=1, clear_protection_fault_status_addr=0)
|
||||
|
||||
wait_cond(lambda: self.adev.reg(f"reg{ip}VM_INVALIDATE_ENG17_ACK").read(inst=inst) & (1 << vmid), value=(1 << vmid), msg="flush_tlb timeout")
|
||||
wait_cond(lambda: self.adev.reg(f"reg{ip}VM_INVALIDATE_ENG17_ACK").read() & (1 << vmid), value=(1 << vmid), msg="flush_tlb timeout")
|
||||
|
||||
if ip == "MM": self.adev.regMMVM_INVALIDATE_ENG17_SEM.write(0x0, inst=inst)
|
||||
if self.adev.ip_ver[am.GC_HWIP] >= (11,0,0) and ip == "MM":
|
||||
self.adev.regMMVM_L2_BANK_SELECT_RESERVED_CID2.update(reserved_cache_private_invalidation=1, inst=inst)
|
||||
if ip == "MM":
|
||||
self.adev.regMMVM_INVALIDATE_ENG17_SEM.write(0x0)
|
||||
self.adev.regMMVM_L2_BANK_SELECT_RESERVED_CID2.update(reserved_cache_private_invalidation=1)
|
||||
|
||||
# Read back the register to ensure the invalidation is complete
|
||||
self.adev.regMMVM_L2_BANK_SELECT_RESERVED_CID2.read(inst=inst)
|
||||
# Read back the register to ensure the invalidation is complete
|
||||
self.adev.regMMVM_L2_BANK_SELECT_RESERVED_CID2.read()
|
||||
|
||||
def enable_vm_addressing(self, page_table, ip:Literal["MM", "GC"], vmid, inst):
|
||||
self.adev.wreg_pair(f"reg{ip}VM_CONTEXT{vmid}_PAGE_TABLE_START_ADDR", "_LO32", "_HI32", self.vm_base >> 12, inst=inst)
|
||||
self.adev.wreg_pair(f"reg{ip}VM_CONTEXT{vmid}_PAGE_TABLE_END_ADDR", "_LO32", "_HI32", self.vm_end >> 12, inst=inst)
|
||||
self.adev.wreg_pair(f"reg{ip}VM_CONTEXT{vmid}_PAGE_TABLE_BASE_ADDR", "_LO32", "_HI32", self.adev.paddr2xgmi(page_table.paddr) | 1, inst=inst)
|
||||
def enable_vm_addressing(self, page_table, ip:Literal["MM", "GC"], vmid):
|
||||
self.adev.wreg_pair(f"reg{ip}VM_CONTEXT{vmid}_PAGE_TABLE_START_ADDR", "_LO32", "_HI32", self.vm_base >> 12)
|
||||
self.adev.wreg_pair(f"reg{ip}VM_CONTEXT{vmid}_PAGE_TABLE_END_ADDR", "_LO32", "_HI32", self.vm_end >> 12)
|
||||
self.adev.wreg_pair(f"reg{ip}VM_CONTEXT{vmid}_PAGE_TABLE_BASE_ADDR", "_LO32", "_HI32", page_table.paddr | 1)
|
||||
self.adev.reg(f"reg{ip}VM_CONTEXT{vmid}_CNTL").write(0x1800000, pde0_protection_fault_enable_interrupt=1, pde0_protection_fault_enable_default=1,
|
||||
dummy_page_protection_fault_enable_interrupt=1, dummy_page_protection_fault_enable_default=1,
|
||||
range_protection_fault_enable_interrupt=1, range_protection_fault_enable_default=1,
|
||||
valid_protection_fault_enable_interrupt=1, valid_protection_fault_enable_default=1,
|
||||
read_protection_fault_enable_interrupt=1, read_protection_fault_enable_default=1,
|
||||
write_protection_fault_enable_interrupt=1, write_protection_fault_enable_default=1,
|
||||
execute_protection_fault_enable_interrupt=1, execute_protection_fault_enable_default=1,
|
||||
enable_context=1, page_table_depth=(3 - page_table.lv))
|
||||
|
||||
fault_flags = {f'{x}_protection_fault_enable_interrupt':1 for x in ['pde0', 'dummy_page', 'range', 'valid', 'read', 'write', 'execute']}
|
||||
en_def_flags = {f'{x}_protection_fault_enable_default':1 for x in ['pde0', 'dummy_page', 'range', 'valid', 'read', 'write', 'execute']}
|
||||
self.adev.reg(f"reg{ip}VM_CONTEXT{vmid}_CNTL").write(0x1800000, **fault_flags, **en_def_flags, enable_context=1,
|
||||
page_table_depth=((2 if self.trans_futher else 3) - page_table.lv), page_table_block_size=9 if self.trans_futher else 0, inst=inst)
|
||||
|
||||
def init_hub(self, ip:Literal["MM", "GC"], inst_cnt:int):
|
||||
def init_hub(self, ip:Literal["MM", "GC"]):
|
||||
# Init system apertures
|
||||
for inst in range(inst_cnt):
|
||||
self.adev.reg(f"reg{ip}MC_VM_AGP_BASE").write(0, inst=inst)
|
||||
self.adev.reg(f"reg{ip}MC_VM_AGP_BOT").write(0xffffffffffff >> 24, inst=inst) # disable AGP
|
||||
self.adev.reg(f"reg{ip}MC_VM_AGP_TOP").write(0, inst=inst)
|
||||
self.adev.reg(f"reg{ip}MC_VM_AGP_BASE").write(0)
|
||||
self.adev.reg(f"reg{ip}MC_VM_AGP_BOT").write(0xffffffffffff >> 24) # disable AGP
|
||||
self.adev.reg(f"reg{ip}MC_VM_AGP_TOP").write(0)
|
||||
|
||||
self.adev.reg(f"reg{ip}MC_VM_SYSTEM_APERTURE_LOW_ADDR").write(self.fb_base >> 18, inst=inst)
|
||||
self.adev.reg(f"reg{ip}MC_VM_SYSTEM_APERTURE_HIGH_ADDR").write(self.fb_end >> 18, inst=inst)
|
||||
self.adev.wreg_pair(f"reg{ip}MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR", "_LSB", "_MSB", self.memscratch_xgmi_paddr >> 12, inst=inst)
|
||||
self.adev.wreg_pair(f"reg{ip}VM_L2_PROTECTION_FAULT_DEFAULT_ADDR", "_LO32", "_HI32", self.dummy_page_xgmi_paddr >> 12, inst=inst)
|
||||
self.adev.reg(f"reg{ip}MC_VM_SYSTEM_APERTURE_LOW_ADDR").write(self.mc_base >> 18)
|
||||
self.adev.reg(f"reg{ip}MC_VM_SYSTEM_APERTURE_HIGH_ADDR").write(self.mc_end >> 18)
|
||||
self.adev.wreg_pair(f"reg{ip}MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR", "_LSB", "_MSB", self.memscratch_paddr >> 12)
|
||||
self.adev.wreg_pair(f"reg{ip}VM_L2_PROTECTION_FAULT_DEFAULT_ADDR", "_LO32", "_HI32", self.dummy_page_paddr >> 12)
|
||||
|
||||
self.adev.reg(f"reg{ip}VM_L2_PROTECTION_FAULT_CNTL2").update(active_page_migration_pte_read_retry=1, inst=inst)
|
||||
self.adev.reg(f"reg{ip}VM_L2_PROTECTION_FAULT_CNTL2").update(active_page_migration_pte_read_retry=1)
|
||||
|
||||
# Init TLB and cache
|
||||
self.adev.reg(f"reg{ip}MC_VM_MX_L1_TLB_CNTL").update(enable_l1_tlb=1, system_access_mode=3, enable_advanced_driver_model=1,
|
||||
system_aperture_unmapped_access=0, mtype=self.adev.soc.module.MTYPE_UC, inst=inst)
|
||||
# Init TLB and cache
|
||||
self.adev.reg(f"reg{ip}MC_VM_MX_L1_TLB_CNTL").update(enable_l1_tlb=1, system_access_mode=3, enable_advanced_driver_model=1,
|
||||
system_aperture_unmapped_access=0, eco_bits=0, mtype=self.adev.soc.module.MTYPE_UC)
|
||||
|
||||
self.adev.reg(f"reg{ip}VM_L2_CNTL").update(enable_l2_cache=1, enable_l2_fragment_processing=0, enable_default_page_out_to_system_memory=1,
|
||||
l2_pde0_cache_tag_generation_mode=0, pde_fault_classification=0, context1_identity_access_mode=1, identity_mode_fragment_size=0, inst=inst)
|
||||
self.adev.reg(f"reg{ip}VM_L2_CNTL2").update(invalidate_all_l1_tlbs=1, invalidate_l2_cache=1, inst=inst)
|
||||
self.adev.reg(f"reg{ip}VM_L2_CNTL3").write(l2_cache_4k_associativity=1, l2_cache_bigk_associativity=1,
|
||||
bank_select=12 if self.trans_futher else 9, l2_cache_bigk_fragment_size=9 if self.trans_futher else 6, inst=inst)
|
||||
self.adev.reg(f"reg{ip}VM_L2_CNTL4").write(l2_cache_4k_partition_count=1, inst=inst)
|
||||
if self.adev.ip_ver[am.GC_HWIP] >= (10,0,0): self.adev.reg(f"reg{ip}VM_L2_CNTL5").write(walker_priority_client_id=0x1ff, inst=inst)
|
||||
self.adev.reg(f"reg{ip}VM_L2_CNTL").update(enable_l2_cache=1, enable_l2_fragment_processing=0, enable_default_page_out_to_system_memory=1,
|
||||
l2_pde0_cache_tag_generation_mode=0, pde_fault_classification=0, context1_identity_access_mode=1, identity_mode_fragment_size=0)
|
||||
self.adev.reg(f"reg{ip}VM_L2_CNTL2").update(invalidate_all_l1_tlbs=1, invalidate_l2_cache=1)
|
||||
self.adev.reg(f"reg{ip}VM_L2_CNTL3").write(bank_select=9, l2_cache_bigk_fragment_size=6,l2_cache_4k_associativity=1,l2_cache_bigk_associativity=1)
|
||||
self.adev.reg(f"reg{ip}VM_L2_CNTL4").write(l2_cache_4k_partition_count=1)
|
||||
self.adev.reg(f"reg{ip}VM_L2_CNTL5").write(walker_priority_client_id=0x1ff)
|
||||
|
||||
self.enable_vm_addressing(self.adev.mm.root_page_table, ip, vmid=0, inst=inst)
|
||||
self.enable_vm_addressing(self.adev.mm.root_page_table, ip, vmid=0)
|
||||
|
||||
# Disable identity aperture
|
||||
self.adev.wreg_pair(f"reg{ip}VM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR", "_LO32", "_HI32", 0xfffffffff, inst=inst)
|
||||
self.adev.wreg_pair(f"reg{ip}VM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR", "_LO32", "_HI32", 0x0, inst=inst)
|
||||
self.adev.wreg_pair(f"reg{ip}VM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET", "_LO32", "_HI32", 0x0, inst=inst)
|
||||
# Disable identity aperture
|
||||
self.adev.wreg_pair(f"reg{ip}VM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR", "_LO32", "_HI32", 0xfffffffff)
|
||||
self.adev.wreg_pair(f"reg{ip}VM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR", "_LO32", "_HI32", 0x0)
|
||||
self.adev.wreg_pair(f"reg{ip}VM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET", "_LO32", "_HI32", 0x0)
|
||||
|
||||
for eng_i in range(18): self.adev.wreg_pair(f"reg{ip}VM_INVALIDATE_ENG{eng_i}_ADDR_RANGE", "_LO32", "_HI32", 0x1fffffffff, inst=inst)
|
||||
for eng_i in range(18): self.adev.wreg_pair(f"reg{ip}VM_INVALIDATE_ENG{eng_i}_ADDR_RANGE", "_LO32", "_HI32", 0x1fffffffff)
|
||||
self.hub_initted[ip] = True
|
||||
|
||||
@functools.cache # pylint: disable=method-cache-max-size-none
|
||||
@@ -140,18 +120,11 @@ class AM_GMC(AM_IP):
|
||||
if self.adev.ip_ver[am.GC_HWIP] >= (12,0,0):
|
||||
extra |= am.AMDGPU_PTE_MTYPE_GFX12(0, self.adev.soc.module.MTYPE_UC if uncached else 0)
|
||||
extra |= (am.AMDGPU_PDE_PTE_GFX12 if not is_table and pte_lv != am.AMDGPU_VM_PTB else (am.AMDGPU_PTE_IS_PTE if not is_table else 0))
|
||||
elif self.adev.ip_ver[am.GC_HWIP] >= (10,0,0):
|
||||
else:
|
||||
extra |= am.AMDGPU_PTE_MTYPE_NV10(0, self.adev.soc.module.MTYPE_UC if uncached else 0)
|
||||
extra |= (am.AMDGPU_PDE_PTE if not is_table and pte_lv != am.AMDGPU_VM_PTB else 0)
|
||||
else:
|
||||
extra |= am.AMDGPU_PTE_MTYPE_VG10(0, self.adev.soc.module.MTYPE_UC if uncached else 0)
|
||||
if is_table and pte_lv == am.AMDGPU_VM_PDB1: extra |= am.AMDGPU_PDE_BFS(0x9)
|
||||
if is_table and pte_lv == am.AMDGPU_VM_PDB0: extra |= am.AMDGPU_PTE_TF
|
||||
if not is_table and pte_lv not in {am.AMDGPU_VM_PTB, am.AMDGPU_VM_PDB0}: extra |= am.AMDGPU_PDE_PTE
|
||||
return extra
|
||||
def is_pte_huge_page(self, pte_lv, pte):
|
||||
if self.adev.ip_ver[am.GC_HWIP] < (10,0,0): return (pte & am.AMDGPU_PDE_PTE) if pte_lv != am.AMDGPU_VM_PDB0 else not (pte & am.AMDGPU_PTE_TF)
|
||||
return pte & (am.AMDGPU_PDE_PTE_GFX12 if self.adev.ip_ver[am.GC_HWIP] >= (12,0,0) else am.AMDGPU_PDE_PTE)
|
||||
def is_pte_huge_page(self, pte): return pte & (am.AMDGPU_PDE_PTE_GFX12 if self.adev.ip_ver[am.GC_HWIP] >= (12,0,0) else am.AMDGPU_PDE_PTE)
|
||||
|
||||
def on_interrupt(self):
|
||||
for ip in ["MM", "GC"]:
|
||||
@@ -170,13 +143,12 @@ class AM_SMU(AM_IP):
|
||||
self._send_msg(self.smu_mod.PPSMC_MSG_EnableAllSmuFeatures, 0)
|
||||
|
||||
def is_smu_alive(self):
|
||||
with contextlib.suppress(TimeoutError): self._send_msg(self.smu_mod.PPSMC_MSG_GetSmuVersion, 0, timeout=100)
|
||||
with contextlib.suppress(RuntimeError): self._send_msg(self.smu_mod.PPSMC_MSG_GetSmuVersion, 0, timeout=100)
|
||||
return self.adev.mmMP1_SMN_C2PMSG_90.read() != 0
|
||||
|
||||
def mode1_reset(self):
|
||||
if DEBUG >= 2: print(f"am {self.adev.devfmt}: mode1 reset")
|
||||
if self.adev.ip_ver[am.MP0_HWIP] >= (14,0,0): self._send_msg(__DEBUGSMC_MSG_Mode1Reset:=2, 0, debug=True)
|
||||
elif self.adev.ip_ver[am.MP0_HWIP] == (13,0,6): self._send_msg(self.smu_mod.PPSMC_MSG_GfxDriverReset, 1)
|
||||
else: self._send_msg(self.smu_mod.PPSMC_MSG_Mode1Reset, 0)
|
||||
time.sleep(0.5) # 500ms
|
||||
|
||||
@@ -186,8 +158,6 @@ class AM_SMU(AM_IP):
|
||||
def read_metrics(self): return self.read_table(self.smu_mod.SmuMetricsExternal_t, self.smu_mod.TABLE_SMU_METRICS)
|
||||
|
||||
def set_clocks(self, level):
|
||||
if self.adev.ip_ver[am.MP0_HWIP] == (13,0,6): return # TODO
|
||||
|
||||
if not hasattr(self, 'clcks'):
|
||||
self.clcks = {}
|
||||
for clck in [self.smu_mod.PPCLK_GFXCLK, self.smu_mod.PPCLK_UCLK, self.smu_mod.PPCLK_FCLK, self.smu_mod.PPCLK_SOCCLK]:
|
||||
@@ -210,146 +180,118 @@ class AM_SMU(AM_IP):
|
||||
return (self.adev.mmMP1_SMN_C2PMSG_82 if not debug else self.adev.mmMP1_SMN_C2PMSG_53).read() if read_back_arg else None
|
||||
|
||||
class AM_GFX(AM_IP):
|
||||
def init_sw(self): self.xccs = len(self.adev.regs_offset[am.GC_HWIP])
|
||||
|
||||
def init_hw(self):
|
||||
# Wait for RLC autoload to complete
|
||||
while self.adev.regCP_STAT.read() != 0 and self.adev.regRLC_RLCS_BOOTLOAD_STATUS.read_bitfields()['bootload_complete'] != 0: pass
|
||||
|
||||
self._config_gfx_rs64()
|
||||
self.adev.gmc.init_hub("GC", inst_cnt=self.xccs)
|
||||
self.adev.gmc.init_hub("GC")
|
||||
|
||||
# NOTE: Golden reg for gfx11. No values for this reg provided. The kernel just ors 0x20000000 to this reg.
|
||||
for xcc in range(self.xccs): self.adev.regTCP_CNTL.write(self.adev.regTCP_CNTL.read() | 0x20000000, inst=xcc)
|
||||
self.adev.regTCP_CNTL.write(self.adev.regTCP_CNTL.read() | 0x20000000)
|
||||
|
||||
for xcc in range(self.xccs): self.adev.regRLC_CNTL.write(0x1, inst=xcc)
|
||||
self.adev.regRLC_SRM_CNTL.update(srm_enable=1, auto_incr_addr=1)
|
||||
|
||||
for xcc in range(self.xccs): self.adev.regRLC_SRM_CNTL.update(srm_enable=1, auto_incr_addr=1, inst=xcc)
|
||||
self.adev.soc.doorbell_enable(port=0, awid=0x3, awaddr_31_28_value=0x3)
|
||||
self.adev.soc.doorbell_enable(port=3, awid=0x6, awaddr_31_28_value=0x3)
|
||||
|
||||
for xcc in range(self.xccs): self.adev.regRLC_SPM_MC_CNTL.write(0xf, inst=xcc)
|
||||
self.adev.regGRBM_CNTL.update(read_timeout=0xff)
|
||||
for i in range(0, 16):
|
||||
self._grbm_select(vmid=i)
|
||||
self.adev.regSH_MEM_CONFIG.write(address_mode=self.adev.soc.module.SH_MEM_ADDRESS_MODE_64,
|
||||
alignment_mode=self.adev.soc.module.SH_MEM_ALIGNMENT_MODE_UNALIGNED, initial_inst_prefetch=3)
|
||||
|
||||
if self.adev.ip_ver[am.NBIO_HWIP] != (7,9,0):
|
||||
self.adev.soc.doorbell_enable(port=0, awid=0x3, awaddr_31_28_value=0x3)
|
||||
self.adev.soc.doorbell_enable(port=3, awid=0x6, awaddr_31_28_value=0x3)
|
||||
# Configure apertures:
|
||||
# LDS: 0x10000000'00000000 - 0x10000001'00000000 (4GB)
|
||||
# Scratch: 0x20000000'00000000 - 0x20000001'00000000 (4GB)
|
||||
self.adev.regSH_MEM_BASES.write(shared_base=0x1, private_base=0x2)
|
||||
self._grbm_select()
|
||||
|
||||
for xcc in range(self.xccs):
|
||||
if self.adev.ip_ver[am.GC_HWIP] == (9,4,3):
|
||||
self.adev.regGB_ADDR_CONFIG.write(0x2a114042, inst=xcc) # Golden value for mi300
|
||||
self.adev.regTCP_UTCL1_CNTL2.update(spare=1, inst=xcc)
|
||||
# Configure MEC doorbell range
|
||||
self.adev.regCP_MEC_DOORBELL_RANGE_LOWER.write(0x0)
|
||||
self.adev.regCP_MEC_DOORBELL_RANGE_UPPER.write(0x450)
|
||||
|
||||
self.adev.regGRBM_CNTL.update(read_timeout=0xff, inst=xcc)
|
||||
for i in range(0, 16):
|
||||
self._grbm_select(vmid=i, inst=xcc)
|
||||
self.adev.regSH_MEM_CONFIG.write(**({'initial_inst_prefetch':3} if self.adev.ip_ver[am.GC_HWIP][0] >= 10 else {}),
|
||||
address_mode=self.adev.soc.module.SH_MEM_ADDRESS_MODE_64, alignment_mode=self.adev.soc.module.SH_MEM_ALIGNMENT_MODE_UNALIGNED, inst=xcc)
|
||||
# Enable MEC
|
||||
self.adev.regCP_MEC_RS64_CNTL.update(mec_invalidate_icache=0, mec_pipe0_reset=0, mec_pipe0_active=1, mec_halt=0)
|
||||
|
||||
# Configure apertures:
|
||||
# LDS: 0x10000000'00000000 - 0x10000001'00000000 (4GB)
|
||||
# Scratch: 0x20000000'00000000 - 0x20000001'00000000 (4GB)
|
||||
self.adev.regSH_MEM_BASES.write(shared_base=0x1, private_base=0x2, inst=xcc)
|
||||
self._grbm_select(inst=xcc)
|
||||
|
||||
# Configure MEC doorbell range
|
||||
self.adev.regCP_MEC_DOORBELL_RANGE_LOWER.write(0x100 * xcc, inst=xcc)
|
||||
self.adev.regCP_MEC_DOORBELL_RANGE_UPPER.write(0x100 * xcc + 0xf8, inst=xcc)
|
||||
|
||||
# Enable MEC
|
||||
if self.adev.ip_ver[am.GC_HWIP] < (10,0,0): self.adev.regCP_MEC_CNTL.write(0x0, inst=xcc)
|
||||
else: self.adev.regCP_MEC_RS64_CNTL.update(mec_invalidate_icache=0, mec_pipe0_reset=0, mec_pipe0_active=1, mec_halt=0, inst=xcc)
|
||||
# NOTE: Wait for MEC to be ready. The kernel does udelay here as well.
|
||||
time.sleep(0.05)
|
||||
|
||||
# Set 1 partition
|
||||
if self.xccs > 1 and not self.adev.partial_boot: self.adev.psp._spatial_partition_cmd(1)
|
||||
|
||||
def fini_hw(self):
|
||||
for xcc in range(self.xccs):
|
||||
self._grbm_select(me=1, pipe=0, queue=0, inst=xcc)
|
||||
if self.adev.regCP_HQD_ACTIVE.read(inst=xcc) & 1: self.adev.regCP_HQD_DEQUEUE_REQUEST.write(0x2, inst=xcc) # 1 - DRAIN_PIPE; 2 - RESET_WAVES
|
||||
self._grbm_select(inst=xcc)
|
||||
|
||||
# TODO: fix warm boot on mi300
|
||||
if self.adev.ip_ver[am.GC_HWIP] != (9,4,3):
|
||||
for xcc in range(self.xccs): self.adev.regGCVM_CONTEXT0_CNTL.write(0, inst=xcc)
|
||||
self._grbm_select(me=1, pipe=0, queue=0)
|
||||
self.adev.regCP_HQD_DEQUEUE_REQUEST.write(0x2) # 1 - DRAIN_PIPE; 2 - RESET_WAVES
|
||||
self.adev.regSPI_COMPUTE_QUEUE_RESET.write(1)
|
||||
self._grbm_select()
|
||||
self.adev.regGCVM_CONTEXT0_CNTL.write(0)
|
||||
|
||||
def setup_ring(self, ring_addr:int, ring_size:int, rptr_addr:int, wptr_addr:int, eop_addr:int, eop_size:int, doorbell:int, pipe:int, queue:int,
|
||||
aql:bool):
|
||||
for xcc in range(self.xccs if aql else 1):
|
||||
mqd = self.adev.mm.valloc(0x1000, uncached=True, contiguous=True)
|
||||
mqd = self.adev.mm.valloc(0x1000, uncached=True, contiguous=True)
|
||||
|
||||
struct_t = getattr(am, f"struct_v{self.adev.ip_ver[am.GC_HWIP][0]}{'_compute' if self.adev.ip_ver[am.GC_HWIP][0] >= 10 else ''}_mqd")
|
||||
mqd_struct = struct_t(header=0xC0310800, cp_mqd_base_addr_lo=lo32(mqd.va_addr), cp_mqd_base_addr_hi=hi32(mqd.va_addr),
|
||||
cp_hqd_persistent_state=self.adev.regCP_HQD_PERSISTENT_STATE.encode(preload_size=0x55, preload_req=1),
|
||||
cp_hqd_pipe_priority=0x2, cp_hqd_queue_priority=0xf, cp_hqd_quantum=0x111,
|
||||
cp_hqd_pq_base_lo=lo32(ring_addr>>8), cp_hqd_pq_base_hi=hi32(ring_addr>>8),
|
||||
cp_hqd_pq_rptr_report_addr_lo=lo32(rptr_addr), cp_hqd_pq_rptr_report_addr_hi=hi32(rptr_addr),
|
||||
cp_hqd_pq_wptr_poll_addr_lo=lo32(wptr_addr), cp_hqd_pq_wptr_poll_addr_hi=hi32(wptr_addr),
|
||||
cp_hqd_pq_doorbell_control=self.adev.regCP_HQD_PQ_DOORBELL_CONTROL.encode(doorbell_offset=doorbell*2, doorbell_en=1),
|
||||
cp_hqd_pq_control=self.adev.regCP_HQD_PQ_CONTROL.encode(rptr_block_size=5, unord_dispatch=0, queue_size=(ring_size//4).bit_length()-2,
|
||||
**({'queue_full_en':1, 'slot_based_wptr':2, 'no_update_rptr':xcc==0} if aql else {})),
|
||||
cp_hqd_ib_control=self.adev.regCP_HQD_IB_CONTROL.encode(min_ib_avail_size=0x3), cp_hqd_hq_status0=0x20004000,
|
||||
cp_mqd_control=self.adev.regCP_MQD_CONTROL.encode(priv_state=1), cp_hqd_vmid=0, cp_hqd_aql_control=int(aql),
|
||||
cp_hqd_eop_base_addr_lo=lo32(eop_addr>>8), cp_hqd_eop_base_addr_hi=hi32(eop_addr>>8),
|
||||
cp_hqd_eop_control=self.adev.regCP_HQD_EOP_CONTROL.encode(eop_size=(eop_size//4).bit_length()-2),
|
||||
**({'compute_tg_chunk_size':1, 'compute_current_logic_xcc_id':xcc} if aql and self.xccs > 1 else {}))
|
||||
for se in range(8 if self.adev.ip_ver[am.GC_HWIP][0] >= 10 else 4): setattr(mqd_struct, f'compute_static_thread_mgmt_se{se}', 0xffffffff)
|
||||
struct_t = getattr(am, f"struct_v{self.adev.ip_ver[am.GC_HWIP][0]}_compute_mqd")
|
||||
mqd_struct = struct_t(header=0xC0310800, cp_mqd_base_addr_lo=lo32(mqd.va_addr), cp_mqd_base_addr_hi=hi32(mqd.va_addr),
|
||||
cp_hqd_persistent_state=self.adev.regCP_HQD_PERSISTENT_STATE.encode(preload_size=0x55, preload_req=1),
|
||||
cp_hqd_pipe_priority=0x2, cp_hqd_queue_priority=0xf, cp_hqd_quantum=0x111,
|
||||
cp_hqd_pq_base_lo=lo32(ring_addr>>8), cp_hqd_pq_base_hi=hi32(ring_addr>>8),
|
||||
cp_hqd_pq_rptr_report_addr_lo=lo32(rptr_addr), cp_hqd_pq_rptr_report_addr_hi=hi32(rptr_addr),
|
||||
cp_hqd_pq_wptr_poll_addr_lo=lo32(wptr_addr), cp_hqd_pq_wptr_poll_addr_hi=hi32(wptr_addr),
|
||||
cp_hqd_pq_doorbell_control=self.adev.regCP_HQD_PQ_DOORBELL_CONTROL.encode(doorbell_offset=doorbell*2, doorbell_en=1),
|
||||
cp_hqd_pq_control=self.adev.regCP_HQD_PQ_CONTROL.encode(rptr_block_size=5, unord_dispatch=0, queue_size=(ring_size//4).bit_length()-2,
|
||||
**({'queue_full_en':1, 'slot_based_wptr':2, 'no_update_rptr':1} if aql else {})),
|
||||
cp_hqd_ib_control=self.adev.regCP_HQD_IB_CONTROL.encode(min_ib_avail_size=0x3), cp_hqd_hq_status0=0x20004000,
|
||||
cp_mqd_control=self.adev.regCP_MQD_CONTROL.encode(priv_state=1), cp_hqd_vmid=0, cp_hqd_aql_control=int(aql),
|
||||
cp_hqd_eop_base_addr_lo=lo32(eop_addr>>8), cp_hqd_eop_base_addr_hi=hi32(eop_addr>>8),
|
||||
cp_hqd_eop_control=self.adev.regCP_HQD_EOP_CONTROL.encode(eop_size=(eop_size//4).bit_length()-2))
|
||||
for se in range(8): setattr(mqd_struct, f'compute_static_thread_mgmt_se{se}', 0xffffffff)
|
||||
|
||||
# Copy mqd into memory
|
||||
self.adev.vram.view(mqd.paddrs[0][0], ctypes.sizeof(mqd_struct))[:] = memoryview(mqd_struct).cast('B')
|
||||
self.adev.gmc.flush_hdp()
|
||||
# Copy mqd into memory
|
||||
self.adev.vram.view(mqd.paddrs[0][0], ctypes.sizeof(mqd_struct))[:] = memoryview(mqd_struct).cast('B')
|
||||
self.adev.gmc.flush_hdp()
|
||||
|
||||
self._grbm_select(me=1, pipe=pipe, queue=queue, inst=xcc)
|
||||
self._grbm_select(me=1, pipe=pipe, queue=queue)
|
||||
|
||||
mqd_st_mv = to_mv(ctypes.addressof(mqd_struct), ctypes.sizeof(mqd_struct)).cast('I')
|
||||
for i, reg in enumerate(range(self.adev.regCP_MQD_BASE_ADDR.addr[xcc], self.adev.regCP_HQD_PQ_WPTR_HI.addr[xcc] + 1)):
|
||||
self.adev.wreg(reg, mqd_st_mv[0x80 + i])
|
||||
self.adev.regCP_HQD_ACTIVE.write(0x1, inst=xcc)
|
||||
mqd_st_mv = to_mv(ctypes.addressof(mqd_struct), ctypes.sizeof(mqd_struct)).cast('I')
|
||||
for i, reg in enumerate(range(self.adev.regCP_MQD_BASE_ADDR.addr[0], self.adev.regCP_HQD_PQ_WPTR_HI.addr[0] + 1)):
|
||||
self.adev.wreg(reg, mqd_st_mv[0x80 + i])
|
||||
self.adev.regCP_HQD_ACTIVE.write(0x1)
|
||||
|
||||
self._grbm_select(inst=xcc)
|
||||
self._grbm_select()
|
||||
|
||||
self.adev.reg(f"regCP_ME1_PIPE{pipe}_INT_CNTL").update(time_stamp_int_enable=1, generic0_int_enable=1, inst=xcc)
|
||||
self.adev.reg(f"regCP_ME1_PIPE{pipe}_INT_CNTL").update(time_stamp_int_enable=1, generic0_int_enable=1)
|
||||
|
||||
def set_clockgating_state(self):
|
||||
if hasattr(self.adev, 'regMM_ATC_L2_MISC_CG'): self.adev.regMM_ATC_L2_MISC_CG.write(enable=1, mem_ls_enable=1)
|
||||
|
||||
for xcc in range(self.xccs):
|
||||
self.adev.regRLC_SAFE_MODE.write(message=1, cmd=1, inst=xcc)
|
||||
wait_cond(lambda: self.adev.regRLC_SAFE_MODE.read(inst=xcc) & 0x1, value=0, msg="RLC safe mode timeout")
|
||||
self.adev.regRLC_SAFE_MODE.write(message=1, cmd=1)
|
||||
wait_cond(lambda: self.adev.regRLC_SAFE_MODE.read() & 0x1, value=0, msg="RLC safe mode timeout")
|
||||
|
||||
self.adev.regRLC_CGCG_CGLS_CTRL.update(cgcg_gfx_idle_threshold=0x36, cgcg_en=1, cgls_rep_compansat_delay=0xf, cgls_en=1, inst=xcc)
|
||||
self.adev.regRLC_CGCG_CGLS_CTRL.update(cgcg_gfx_idle_threshold=0x36, cgcg_en=1, cgls_rep_compansat_delay=0xf, cgls_en=1)
|
||||
|
||||
self.adev.regCP_RB_WPTR_POLL_CNTL.update(poll_frequency=0x100, idle_poll_count=0x90, inst=xcc)
|
||||
self.adev.regCP_INT_CNTL.update(cntx_busy_int_enable=1, cntx_empty_int_enable=1, cmp_busy_int_enable=1, gfx_idle_int_enable=1, inst=xcc)
|
||||
if self.adev.ip_ver[am.GC_HWIP] >= (10,0,0):
|
||||
self.adev.regSDMA0_RLC_CGCG_CTRL.update(cgcg_int_enable=1, inst=xcc)
|
||||
self.adev.regSDMA1_RLC_CGCG_CTRL.update(cgcg_int_enable=1, inst=xcc)
|
||||
self.adev.regCP_RB_WPTR_POLL_CNTL.update(poll_frequency=0x100, idle_poll_count=0x90)
|
||||
self.adev.regCP_INT_CNTL.update(cntx_busy_int_enable=1, cntx_empty_int_enable=1, cmp_busy_int_enable=1, gfx_idle_int_enable=1)
|
||||
self.adev.regSDMA0_RLC_CGCG_CTRL.update(cgcg_int_enable=1)
|
||||
self.adev.regSDMA1_RLC_CGCG_CTRL.update(cgcg_int_enable=1)
|
||||
|
||||
feats_gfx11 = {'perfmon_clock_state':1, 'gfxip_repeater_fgcg_override':0} if self.adev.ip_ver[am.GC_HWIP] >= (11,0,0) else {}
|
||||
self.adev.regRLC_CGTT_MGCG_OVERRIDE.update(**feats_gfx11, gfxip_fgcg_override=0, grbm_cgtt_sclk_override=0, rlc_cgtt_sclk_override=0,
|
||||
gfxip_mgcg_override=0, gfxip_cgls_override=0, gfxip_cgcg_override=0, inst=xcc)
|
||||
self.adev.regRLC_CGTT_MGCG_OVERRIDE.update(perfmon_clock_state=1, gfxip_fgcg_override=0, gfxip_repeater_fgcg_override=0,
|
||||
grbm_cgtt_sclk_override=0, rlc_cgtt_sclk_override=0, gfxip_mgcg_override=0, gfxip_cgls_override=0, gfxip_cgcg_override=0)
|
||||
|
||||
self.adev.regRLC_SAFE_MODE.write(message=0, cmd=1, inst=xcc)
|
||||
self.adev.regRLC_SAFE_MODE.write(message=0, cmd=1)
|
||||
|
||||
def _grbm_select(self, me=0, pipe=0, queue=0, vmid=0, inst=0):
|
||||
self.adev.regGRBM_GFX_CNTL.write(meid=me, pipeid=pipe, vmid=vmid, queueid=queue, inst=inst)
|
||||
def _grbm_select(self, me=0, pipe=0, queue=0, vmid=0): self.adev.regGRBM_GFX_CNTL.write(meid=me, pipeid=pipe, vmid=vmid, queueid=queue)
|
||||
|
||||
def _config_gfx_rs64(self):
|
||||
def _config_helper(eng_name, cntl_reg, eng_reg, pipe_cnt, me=0, xcc=0):
|
||||
def _config_helper(eng_name, cntl_reg, eng_reg, pipe_cnt, me=0):
|
||||
for pipe in range(pipe_cnt):
|
||||
self._grbm_select(me=me, pipe=pipe, inst=xcc)
|
||||
self.adev.wreg_pair(f"regCP_{eng_reg}_PRGRM_CNTR_START", "", "_HI", self.adev.fw.ucode_start[eng_name] >> 2, inst=xcc)
|
||||
self._grbm_select(inst=xcc)
|
||||
self.adev.reg(f"regCP_{cntl_reg}_CNTL").update(**{f"{eng_name.lower()}_pipe{pipe}_reset": 1 for pipe in range(pipe_cnt)}, inst=xcc)
|
||||
self.adev.reg(f"regCP_{cntl_reg}_CNTL").update(**{f"{eng_name.lower()}_pipe{pipe}_reset": 0 for pipe in range(pipe_cnt)}, inst=xcc)
|
||||
self._grbm_select(me=me, pipe=pipe)
|
||||
self.adev.wreg_pair(f"regCP_{eng_reg}_PRGRM_CNTR_START", "", "_HI", self.adev.fw.ucode_start[eng_name] >> 2)
|
||||
self._grbm_select()
|
||||
self.adev.reg(f"regCP_{cntl_reg}_CNTL").update(**{f"{eng_name.lower()}_pipe{pipe}_reset": 1 for pipe in range(pipe_cnt)})
|
||||
self.adev.reg(f"regCP_{cntl_reg}_CNTL").update(**{f"{eng_name.lower()}_pipe{pipe}_reset": 0 for pipe in range(pipe_cnt)})
|
||||
|
||||
for xcc in range(self.adev.gfx.xccs):
|
||||
if self.adev.ip_ver[am.GC_HWIP] < (10,0,0):
|
||||
self.adev.regCP_MEC_CNTL.update(mec_invalidate_icache=1, mec_me1_pipe0_reset=1, mec_me2_pipe0_reset=1, mec_me1_halt=1,mec_me2_halt=1,inst=xcc)
|
||||
if self.adev.ip_ver[am.GC_HWIP] >= (12,0,0):
|
||||
_config_helper(eng_name="PFP", cntl_reg="ME", eng_reg="PFP", pipe_cnt=1, xcc=xcc)
|
||||
_config_helper(eng_name="ME", cntl_reg="ME", eng_reg="ME", pipe_cnt=1, xcc=xcc)
|
||||
if self.adev.ip_ver[am.GC_HWIP] >= (10,0,0):
|
||||
_config_helper(eng_name="MEC", cntl_reg="MEC_RS64", eng_reg="MEC_RS64", pipe_cnt=1, me=1, xcc=xcc)
|
||||
if self.adev.ip_ver[am.GC_HWIP] >= (12,0,0):
|
||||
_config_helper(eng_name="PFP", cntl_reg="ME", eng_reg="PFP", pipe_cnt=1)
|
||||
_config_helper(eng_name="ME", cntl_reg="ME", eng_reg="ME", pipe_cnt=1)
|
||||
_config_helper(eng_name="MEC", cntl_reg="MEC_RS64", eng_reg="MEC_RS64", pipe_cnt=1, me=1)
|
||||
|
||||
class AM_IH(AM_IP):
|
||||
def init_sw(self):
|
||||
@@ -371,17 +313,15 @@ class AM_IH(AM_IP):
|
||||
|
||||
self.adev.reg(f"regIH_DOORBELL_RPTR{suf}").write(offset=(am.AMDGPU_NAVI10_DOORBELL_IH + ring_id) * 2, enable=1)
|
||||
|
||||
if self.adev.ip_ver[am.OSSSYS_HWIP] != (4,4,2):
|
||||
self.adev.regIH_STORM_CLIENT_LIST_CNTL.update(client18_is_storm_client=1)
|
||||
self.adev.regIH_INT_FLOOD_CNTL.update(flood_cntl_enable=1)
|
||||
self.adev.regIH_MSI_STORM_CTRL.update(delay=3)
|
||||
self.adev.regIH_STORM_CLIENT_LIST_CNTL.update(client18_is_storm_client=1)
|
||||
self.adev.regIH_INT_FLOOD_CNTL.update(flood_cntl_enable=1)
|
||||
self.adev.regIH_MSI_STORM_CTRL.update(delay=3)
|
||||
|
||||
# toggle interrupts
|
||||
for _, rwptr_vm, suf, ring_id in self.rings:
|
||||
self.adev.reg(f"regIH_RB_CNTL{suf}").update(rb_enable=1, **({'enable_intr': 1} if ring_id == 0 else {}))
|
||||
|
||||
if self.adev.ip_ver[am.NBIO_HWIP] != (7,9,0):
|
||||
self.adev.soc.doorbell_enable(port=1, awid=0x0, awaddr_31_28_value=0x0, offset=am.AMDGPU_NAVI10_DOORBELL_IH*2, size=2)
|
||||
self.adev.soc.doorbell_enable(port=1, awid=0x0, awaddr_31_28_value=0x0, offset=am.AMDGPU_NAVI10_DOORBELL_IH*2, size=2)
|
||||
|
||||
def interrupt_handler(self):
|
||||
_, rwptr_vm, suf, _ = self.rings[0]
|
||||
@@ -396,52 +336,37 @@ class AM_IH(AM_IP):
|
||||
class AM_SDMA(AM_IP):
|
||||
def init_sw(self): self.sdma_name = "F32" if self.adev.ip_ver[am.SDMA0_HWIP] < (7,0,0) else "MCU"
|
||||
def init_hw(self):
|
||||
for pipe_id in range(1):
|
||||
pipe = "" if self.adev.ip_ver[am.SDMA0_HWIP] < (5,0,0) else str(pipe_id)
|
||||
for pipe in range(2):
|
||||
self.adev.reg(f"regSDMA{pipe}_WATCHDOG_CNTL").update(queue_hang_count=100) # 10s, 100ms per unit
|
||||
self.adev.reg(f"regSDMA{pipe}_UTCL1_CNTL").update(resp_mode=3, redo_delay=9)
|
||||
|
||||
if self.adev.ip_ver[am.SDMA0_HWIP] >= (6,0,0):
|
||||
self.adev.reg(f"regSDMA{pipe}_WATCHDOG_CNTL").update(queue_hang_count=100) # 10s, 100ms per unit
|
||||
self.adev.reg(f"regSDMA{pipe}_UTCL1_CNTL").update(resp_mode=3, redo_delay=9)
|
||||
|
||||
# rd=noa, wr=bypass
|
||||
self.adev.reg(f"regSDMA{pipe}_UTCL1_PAGE").update(rd_l2_policy=2, wr_l2_policy=3, **({'llc_noalloc':1} if self.sdma_name == "F32" else {}))
|
||||
self.adev.reg(f"regSDMA{pipe}_{self.sdma_name}_CNTL").update(halt=0, **{f"{'th1_' if self.sdma_name == 'F32' else ''}reset":0})
|
||||
|
||||
self.adev.reg(f"regSDMA{pipe}_CNTL").update(ctxempty_int_enable=1, trap_enable=1,
|
||||
**({'utc_l1_enable':1} if self.adev.ip_ver[am.SDMA0_HWIP] <= (5,2,0) else {}))
|
||||
|
||||
if self.adev.ip_ver[am.NBIO_HWIP] == (7,9,0):
|
||||
self.adev.regDOORBELL0_CTRL_ENTRY_1.write(bif_doorbell1_range_offset_entry=am.AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE0*2,
|
||||
bif_doorbell1_range_size_entry=4)
|
||||
self.adev.soc.doorbell_enable(port=2, awid=0xe, awaddr_31_28_value=0x1, offset=0xe, size=4)
|
||||
else: self.adev.soc.doorbell_enable(port=2, awid=0xe, awaddr_31_28_value=0x3, offset=am.AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE0*2, size=4)
|
||||
# rd=noa, wr=bypass
|
||||
self.adev.reg(f"regSDMA{pipe}_UTCL1_PAGE").update(rd_l2_policy=0x2, wr_l2_policy=0x3, **({'llc_noalloc':1} if self.sdma_name == "F32" else {}))
|
||||
self.adev.reg(f"regSDMA{pipe}_{self.sdma_name}_CNTL").update(halt=0, **{f"{'th1_' if self.sdma_name == 'F32' else ''}reset":0})
|
||||
self.adev.reg(f"regSDMA{pipe}_CNTL").update(ctxempty_int_enable=1, trap_enable=1)
|
||||
self.adev.soc.doorbell_enable(port=2, awid=0xe, awaddr_31_28_value=0x3, offset=am.AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE0*2, size=4)
|
||||
|
||||
def fini_hw(self):
|
||||
reg, inst = ("regSDMA_GFX", 0) if self.adev.ip_ver[am.SDMA0_HWIP] == (4,4,2) else ("regSDMA0_QUEUE0", 0)
|
||||
|
||||
self.adev.reg(f"{reg}_RB_CNTL").update(rb_enable=0, inst=inst)
|
||||
self.adev.reg(f"{reg}_IB_CNTL").update(ib_enable=0, inst=inst)
|
||||
if self.adev.ip_ver[am.SDMA0_HWIP] >= (6,0,0):
|
||||
self.adev.regGRBM_SOFT_RESET.write(soft_reset_sdma0=1)
|
||||
time.sleep(0.01)
|
||||
self.adev.regGRBM_SOFT_RESET.write(0x0)
|
||||
self.adev.regSDMA0_QUEUE0_RB_CNTL.update(rb_enable=0)
|
||||
self.adev.regSDMA0_QUEUE0_IB_CNTL.update(ib_enable=0)
|
||||
self.adev.regGRBM_SOFT_RESET.write(soft_reset_sdma0=1)
|
||||
time.sleep(0.01)
|
||||
self.adev.regGRBM_SOFT_RESET.write(0x0)
|
||||
|
||||
def setup_ring(self, ring_addr:int, ring_size:int, rptr_addr:int, wptr_addr:int, doorbell:int, pipe:int, queue:int):
|
||||
# Setup the ring
|
||||
reg, inst = ("regSDMA_GFX", pipe*4+queue) if self.adev.ip_ver[am.SDMA0_HWIP] == (4,4,2) else (f"regSDMA{pipe}_QUEUE{queue}", 0)
|
||||
|
||||
self.adev.reg(f"{reg}_MINOR_PTR_UPDATE").write(0x1, inst=inst)
|
||||
self.adev.wreg_pair(f"{reg}_RB_RPTR", "", "_HI", 0, inst=inst)
|
||||
self.adev.wreg_pair(f"{reg}_RB_WPTR", "", "_HI", 0, inst=inst)
|
||||
self.adev.wreg_pair(f"{reg}_RB_BASE", "", "_HI", ring_addr >> 8, inst=inst)
|
||||
self.adev.wreg_pair(f"{reg}_RB_RPTR_ADDR", "_LO", "_HI", rptr_addr, inst=inst)
|
||||
self.adev.wreg_pair(f"{reg}_RB_WPTR_POLL_ADDR", "_LO", "_HI", wptr_addr, inst=inst)
|
||||
self.adev.reg(f"{reg}_DOORBELL_OFFSET").update(offset=doorbell * 2, inst=inst)
|
||||
self.adev.reg(f"{reg}_DOORBELL").update(enable=1, inst=inst)
|
||||
self.adev.reg(f"{reg}_MINOR_PTR_UPDATE").write(0x0, inst=inst)
|
||||
self.adev.reg(f"{reg}_RB_CNTL").write(**({f'{self.sdma_name.lower()}_wptr_poll_enable':1} if self.adev.ip_ver[am.SDMA0_HWIP] != (4,4,2) else {}),
|
||||
rb_vmid=0, rptr_writeback_enable=1, rptr_writeback_timer=4, rb_enable=1, rb_priv=1, rb_size=(ring_size//4).bit_length()-1, inst=inst)
|
||||
self.adev.reg(f"{reg}_IB_CNTL").update(ib_enable=1, inst=inst)
|
||||
self.adev.reg(f"regSDMA{pipe}_QUEUE{queue}_MINOR_PTR_UPDATE").write(0x1)
|
||||
self.adev.wreg_pair(f"regSDMA{pipe}_QUEUE{queue}_RB_RPTR", "", "_HI", 0)
|
||||
self.adev.wreg_pair(f"regSDMA{pipe}_QUEUE{queue}_RB_WPTR", "", "_HI", 0)
|
||||
self.adev.wreg_pair(f"regSDMA{pipe}_QUEUE{queue}_RB_BASE", "", "_HI", ring_addr >> 8)
|
||||
self.adev.wreg_pair(f"regSDMA{pipe}_QUEUE{queue}_RB_RPTR_ADDR", "_LO", "_HI", rptr_addr)
|
||||
self.adev.wreg_pair(f"regSDMA{pipe}_QUEUE{queue}_RB_WPTR_POLL_ADDR", "_LO", "_HI", wptr_addr)
|
||||
self.adev.reg(f"regSDMA{pipe}_QUEUE{queue}_DOORBELL_OFFSET").update(offset=doorbell * 2)
|
||||
self.adev.reg(f"regSDMA{pipe}_QUEUE{queue}_DOORBELL").update(enable=1)
|
||||
self.adev.reg(f"regSDMA{pipe}_QUEUE{queue}_MINOR_PTR_UPDATE").write(0x0)
|
||||
self.adev.reg(f"regSDMA{pipe}_QUEUE{queue}_RB_CNTL").write(rb_vmid=0, rptr_writeback_enable=1, rptr_writeback_timer=4,
|
||||
**{f'{self.sdma_name.lower()}_wptr_poll_enable':1}, rb_size=(ring_size//4).bit_length()-1, rb_enable=1, rb_priv=1)
|
||||
self.adev.reg(f"regSDMA{pipe}_QUEUE{queue}_IB_CNTL").update(ib_enable=1)
|
||||
|
||||
class AM_PSP(AM_IP):
|
||||
def init_sw(self):
|
||||
@@ -461,10 +386,10 @@ class AM_PSP(AM_IP):
|
||||
self.ring_size = 0x10000
|
||||
self.ring_paddr = self.adev.mm.palloc(self.ring_size, zero=False, boot=True)
|
||||
|
||||
self.max_tmr_size, self.tmr_size = 0x1300000, 0
|
||||
self.boot_time_tmr = self.adev.ip_ver[am.MP0_HWIP] in {(13,0,6), (13,0,14), (14,0,2), (14,0,3)}
|
||||
self.autoload_tmr = self.adev.ip_ver[am.MP0_HWIP] not in {(13,0,6), (13,0,14)}
|
||||
self.tmr_paddr = self.adev.mm.palloc(self.max_tmr_size, align=am.PSP_TMR_ALIGNMENT, zero=False, boot=True) if not self.boot_time_tmr else 0
|
||||
self.max_tmr_size = 0x1300000
|
||||
self.boot_time_tmr = self.adev.ip_ver[am.GC_HWIP] >= (12,0,0)
|
||||
if not self.boot_time_tmr:
|
||||
self.tmr_paddr = self.adev.mm.palloc(self.max_tmr_size, align=am.PSP_TMR_ALIGNMENT, zero=False, boot=True)
|
||||
|
||||
def init_hw(self):
|
||||
spl_key = am.PSP_FW_TYPE_PSP_SPL if self.adev.ip_ver[am.MP0_HWIP] >= (14,0,0) else am.PSP_FW_TYPE_PSP_KDB
|
||||
@@ -478,16 +403,14 @@ class AM_PSP(AM_IP):
|
||||
while not self.is_sos_alive(): time.sleep(0.01)
|
||||
|
||||
self._ring_create()
|
||||
if am.PSP_FW_TYPE_PSP_TOC in self.adev.fw.sos_fw: self._tmr_init()
|
||||
self._tmr_init()
|
||||
|
||||
# SMU fw should be loaded before TMR.
|
||||
if hasattr(self.adev.fw, 'smu_psp_desc'): self._load_ip_fw_cmd(*self.adev.fw.smu_psp_desc)
|
||||
if not self.boot_time_tmr or not self.autoload_tmr: self._tmr_load_cmd()
|
||||
self._load_ip_fw_cmd(*self.adev.fw.smu_psp_desc)
|
||||
if not self.boot_time_tmr: self._tmr_load_cmd()
|
||||
|
||||
for psp_desc in self.adev.fw.descs: self._load_ip_fw_cmd(*psp_desc)
|
||||
|
||||
if self.adev.ip_ver[am.GC_HWIP] >= (11,0,0): self._rlc_autoload_cmd()
|
||||
else: self._load_ip_fw_cmd([am.GFX_FW_TYPE_REG_LIST], self.adev.fw.sos_fw[am.PSP_FW_TYPE_PSP_RL])
|
||||
self._rlc_autoload_cmd()
|
||||
|
||||
def is_sos_alive(self): return self.adev.reg(f"{self.reg_pref}_81").read() != 0x0
|
||||
|
||||
@@ -567,13 +490,11 @@ class AM_PSP(AM_IP):
|
||||
self._ring_submit(cmd)
|
||||
|
||||
def _tmr_load_cmd(self) -> am.struct_psp_gfx_cmd_resp:
|
||||
tmr_paddr = self.adev.paddr2xgmi(self.tmr_paddr) if self.tmr_paddr else 0
|
||||
|
||||
cmd = am.struct_psp_gfx_cmd_resp(cmd_id=am.GFX_CMD_ID_SETUP_TMR)
|
||||
cmd.cmd.cmd_setup_tmr.buf_phy_addr_hi, cmd.cmd.cmd_setup_tmr.buf_phy_addr_lo = data64(self.adev.paddr2mc(self.tmr_paddr) if self.tmr_paddr else 0)
|
||||
cmd.cmd.cmd_setup_tmr.system_phy_addr_hi, cmd.cmd.cmd_setup_tmr.system_phy_addr_lo = data64(tmr_paddr)
|
||||
cmd.cmd.cmd_setup_tmr.buf_phy_addr_hi, cmd.cmd.cmd_setup_tmr.buf_phy_addr_lo = data64(self.adev.paddr2mc(self.tmr_paddr))
|
||||
cmd.cmd.cmd_setup_tmr.system_phy_addr_hi, cmd.cmd.cmd_setup_tmr.system_phy_addr_lo = data64(self.tmr_paddr)
|
||||
cmd.cmd.cmd_setup_tmr.bitfield.virt_phy_addr = 1
|
||||
cmd.cmd.cmd_setup_tmr.buf_size = self.tmr_size if self.tmr_paddr else 0
|
||||
cmd.cmd.cmd_setup_tmr.buf_size = self.tmr_size
|
||||
return self._ring_submit(cmd)
|
||||
|
||||
def _load_toc_cmd(self, toc_size:int) -> am.struct_psp_gfx_cmd_resp:
|
||||
@@ -582,9 +503,4 @@ class AM_PSP(AM_IP):
|
||||
cmd.cmd.cmd_load_toc.toc_size = toc_size
|
||||
return self._ring_submit(cmd)
|
||||
|
||||
def _spatial_partition_cmd(self, mode):
|
||||
cmd = am.struct_psp_gfx_cmd_resp(cmd_id=am.GFX_CMD_ID_SRIOV_SPATIAL_PART)
|
||||
cmd.cmd.cmd_spatial_part.mode = mode
|
||||
return self._ring_submit(cmd)
|
||||
|
||||
def _rlc_autoload_cmd(self): return self._ring_submit(am.struct_psp_gfx_cmd_resp(cmd_id=am.GFX_CMD_ID_AUTOLOAD_RLC))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import functools, re, urllib, tinygrad.runtime.autogen
|
||||
import functools, importlib, re, urllib
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
from tinygrad.helpers import getbits, fetch
|
||||
@@ -53,8 +53,8 @@ def import_header(path:str, url=AMDGPU_URL):
|
||||
|
||||
def import_module(name:str, version:tuple[int, ...], version_prefix:str=""):
|
||||
for ver in fixup_ip_version(name, version):
|
||||
try: return getattr(tinygrad.runtime.autogen.am, f"{name}_{version_prefix}{'_'.join(map(str, ver))}")
|
||||
except AttributeError: pass
|
||||
try: return importlib.import_module(f"tinygrad.runtime.autogen.am.{name}_{version_prefix}{'_'.join(map(str, ver))}")
|
||||
except ImportError: pass
|
||||
raise ImportError(f"Failed to load autogen module for {name.upper()} {'.'.join(map(str, version))}")
|
||||
|
||||
def import_soc(ip):
|
||||
@@ -79,12 +79,7 @@ def import_pmc(ip) -> dict[str, tuple[str, int]]:
|
||||
def import_asic_regs(prefix:str, version:tuple[int, ...], cls=AMDReg) -> dict[str, AMDReg]:
|
||||
def _split_name(name): return name[:(pos:=next((i for i,c in enumerate(name) if c.isupper()), len(name)))], name[pos:]
|
||||
def _extract_regs(txt):
|
||||
x = {}
|
||||
for k,v in {m.group(1): int(m.group(2), 0) for line in txt.splitlines() if (m:=re.match(r'#define\s+(\S+)\s+(0x[\da-fA-F]+|\d+)', line))}.items():
|
||||
if k.startswith('VM_') or k.startswith('MC_'): x[prefix.upper()[:2]+k] = v
|
||||
elif k.startswith('regVM_') or k.startswith('regMC_'): x["reg"+prefix.upper()[:2]+k[3:]] = v
|
||||
else: x[k] = v
|
||||
return x
|
||||
return {m.group(1): int(m.group(2), 0) for line in txt.splitlines() if (m:=re.match(r'#define\s+(\S+)\s+(0x[\da-fA-F]+|\d+)', line))}
|
||||
def _download_file(ver, suff) -> str:
|
||||
dir_prefix = {"osssys": "oss"}.get(prefix, prefix)
|
||||
fetch_name, file_name = f"{prefix}_{'_'.join(map(str, ver))}_{suff}.h", f"{prefix}_{'_'.join(map(str, version))}_{suff}.h"
|
||||
@@ -103,7 +98,6 @@ def import_asic_regs(prefix:str, version:tuple[int, ...], cls=AMDReg) -> dict[st
|
||||
for field_name, field_mask in sh_masks.items():
|
||||
if not ('__' in field_name and field_name.endswith('_MASK')): continue
|
||||
reg_name, reg_field_name = field_name[:-len('_MASK')].split('__')
|
||||
if reg_name.startswith('MC_') or reg_name.startswith('VM_'): reg_name = f"{prefix.upper()[:2]}{reg_name}"
|
||||
fields[reg_name][reg_field_name.lower()] = ((field_mask & -field_mask).bit_length()-1, field_mask.bit_length()-1)
|
||||
|
||||
# NOTE: Some registers like regGFX_IMU_FUSESTRAP in gc_11_0_0 are missing base idx, just skip them
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import ctypes, itertools, re, functools, os
|
||||
from tinygrad.helpers import flatten, unwrap
|
||||
from tinygrad.runtime.autogen import libclang as clang # use REGEN=1 to regenerate libclang bindings
|
||||
from tinygrad.runtime.autogen import libclang as clang # hmmm
|
||||
from typing import Iterator
|
||||
|
||||
def unwrap_cursor(c: clang.CXCursor) -> clang.CXCursor:
|
||||
assert c != clang.clang_getNullCursor()
|
||||
@@ -26,13 +27,9 @@ def fields(t: clang.CXType) -> list[clang.CXCursor]:
|
||||
clang.clang_Type_visitFields(t, visitor, None)
|
||||
return ret
|
||||
|
||||
# flattens anonymous fields
|
||||
def all_fields(t, kind):
|
||||
for f in fields(t):
|
||||
if (clang.clang_Cursor_isAnonymousRecordDecl(clang.clang_getTypeDeclaration(clang.clang_getCursorType(f))) and
|
||||
clang.clang_getTypeDeclaration(clang.clang_getCursorType(f)).kind == kind):
|
||||
yield from all_fields(clang.clang_getCursorType(f), kind)
|
||||
else: yield f
|
||||
def walk(c: clang.CXCursor) -> Iterator[clang.CXCursor]:
|
||||
yield c
|
||||
for child in children(c): yield from walk(child)
|
||||
|
||||
def arguments(c: clang.CXCursor|clang.CXType):
|
||||
yield from ((clang.clang_Cursor_getArgument if isinstance(c, clang.CXCursor) else clang.clang_getArgType)(c, i)
|
||||
@@ -61,15 +58,23 @@ def cxs(fn):
|
||||
return wrap
|
||||
|
||||
# TODO: caching this would be nice?
|
||||
nm = cxs(lambda c: getattr(clang, f"clang_get{c.__class__.__name__[2:]}Spelling")(*([c._tu, c] if isinstance(c, clang.CXToken) else [c])))
|
||||
def extent(c): return getattr(clang, f"clang_get{c.__class__.__name__[2:]}Extent")(*([c._tu, c] if isinstance(c, clang.CXToken) else [c]))
|
||||
def loc(c): return getattr(clang, f"clang_get{c.__class__.__name__[2:]}Location")(*([c._tu, c] if isinstance(c, clang.CXToken) else [c]))
|
||||
def gel(loc: clang.CXSourceLocation):
|
||||
clang.clang_getExpansionLocation(loc, file:=clang.CXFile(), line:=ctypes.c_uint32(), None, offset:=ctypes.c_uint32())
|
||||
return {"file":clang.clang_getFileName(file), "line":line.value, "offset":offset.value}
|
||||
loc_file = cxs(lambda loc: gel(loc)['file'])
|
||||
def loc_off(loc: clang.CXSourceLocation) -> int: return gel(loc)['offset']
|
||||
def loc_line(loc: clang.CXSourceLocation) -> int: return gel(loc)['line']
|
||||
@cxs
|
||||
def nm(c: clang.CXCursor|clang.CXToken|clang.CXType) -> str:
|
||||
return clang.clang_getTokenSpelling(c._tu, c) if isinstance(c, clang.CXToken) else getattr(clang, f"clang_get{c.__class__.__name__[2:]}Spelling")(c)
|
||||
def extent(c: clang.CXCursor|clang.CXToken|clang.CXType) -> clang.CXSourceRange:
|
||||
return clang.clang_getTokenExtent(c._tu, c) if isinstance(c, clang.CXToken) else getattr(clang, f"clang_get{c.__class__.__name__[2:]}Extent")(c)
|
||||
def loc(c: clang.CXCursor|clang.CXToken|clang.CXType) -> clang.CXSourceLocation:
|
||||
return clang.clang_getTokenLocation(c._tu, c) if isinstance(c, clang.CXToken) else getattr(clang, f"clang_get{c.__class__.__name__[2:]}Location")(c)
|
||||
@cxs
|
||||
def loc_file(loc: clang.CXSourceLocation) -> str:
|
||||
clang.clang_getExpansionLocation(loc, f:=clang.CXFile(), None, None, None)
|
||||
return clang.clang_getFileName(f)
|
||||
def loc_off(loc: clang.CXSourceLocation) -> int:
|
||||
clang.clang_getExpansionLocation(loc, None, None, None, off:=ctypes.c_uint32())
|
||||
return off.value
|
||||
def loc_line(loc: clang.CXSourceLocation) -> int:
|
||||
clang.clang_getExpansionLocation(loc, None, line:=ctypes.c_uint32(), None, None)
|
||||
return line.value
|
||||
|
||||
def readext(f, fst, snd=None):
|
||||
with open(f, "r") as f: # reopening this every time is dumb...
|
||||
@@ -87,7 +92,8 @@ base_rules = [(r'\s*\\\n\s*', ' '), (r'\s*\n\s*', ' '), (r'//.*', ''), (r'/\*.*?
|
||||
|
||||
uints = (clang.CXType_Char_U, clang.CXType_UChar, clang.CXType_UShort, clang.CXType_UInt, clang.CXType_ULong, clang.CXType_ULongLong)
|
||||
ints = uints + (clang.CXType_Char_S, clang.CXType_Short, clang.CXType_Int, clang.CXType_ULong, clang.CXType_LongLong)
|
||||
fns, specs = (clang.CXType_FunctionProto, clang.CXType_FunctionNoProto), (clang.CXCursor_ObjCSuperClassRef,) # this could include protocols
|
||||
fns = (clang.CXType_FunctionProto, clang.CXType_FunctionNoProto)
|
||||
specs = (clang.CXCursor_ObjCSuperClassRef,)
|
||||
# https://clang.llvm.org/docs/AutomaticReferenceCounting.html#arc-method-families
|
||||
arc_families = ['alloc', 'copy', 'mutableCopy', 'new']
|
||||
|
||||
@@ -121,26 +127,24 @@ def gen(dll, files, args=[], prolog=[], rules=[], epilog=[], recsym=False, use_e
|
||||
return types[nm(t)][0]
|
||||
case clang.CXType_Record:
|
||||
# TODO: packed unions
|
||||
# libclang does not use CXType_Elaborated for function parameters with type qualifiers (eg. void (*)(const struct foo))
|
||||
if (_nm:=re.sub(r"^const ", "", nm(t))) in types and types[_nm][1]: return types[_nm][0]
|
||||
# check for forward declaration
|
||||
if _nm in types: types[_nm] = (tnm:=types[_nm][0]), len(fields(t)) != 0
|
||||
if nm(t) in types: types[nm(t)] = (tnm:=types[nm(t)][0]), len(fields(t)) != 0
|
||||
else:
|
||||
if clang.clang_Cursor_isAnonymous(decl):
|
||||
types[_nm] = (tnm:=(suggested_name or (f"_anon{'struct' if decl.kind==clang.CXCursor_StructDecl else 'union'}{anoncnt()}")), True)
|
||||
else: types[_nm] = (tnm:=_nm.replace(' ', '_').replace('::', '_')), len(fields(t)) != 0
|
||||
types[nm(t)] = (tnm:=(suggested_name or (f"_anon{'struct' if decl.kind==clang.CXCursor_StructDecl else 'union'}{anoncnt()}")), True)
|
||||
else: types[nm(t)] = (tnm:=nm(t).replace(' ', '_').replace('::', '_')), len(fields(t)) != 0
|
||||
lines.append(f"class {tnm}({'Struct' if decl.kind==clang.CXCursor_StructDecl else 'ctypes.Union'}): pass")
|
||||
if typedef: lines.append(f"{typedef} = {tnm}")
|
||||
if ((is_packed:=(clang.CXCursor_PackedAttr in attrs(decl)) or
|
||||
((N:=clang.clang_Type_getAlignOf(t)) != max([clang.clang_Type_getAlignOf(clang.clang_getCursorType(f)) for f in fields(t)], default=N)))):
|
||||
if clang.clang_Type_getAlignOf(t) != 1:
|
||||
print(f"WARNING: ignoring alignment={clang.clang_Type_getAlignOf(t)} on {_nm}")
|
||||
print(f"WARNING: ignoring alignment={clang.clang_Type_getAlignOf(t)} on {nm(t)}")
|
||||
is_packed = False
|
||||
acnt = itertools.count().__next__
|
||||
def is_anon(f): return clang.clang_Cursor_isAnonymousRecordDecl(clang.clang_getTypeDeclaration(clang.clang_getCursorType(f)))
|
||||
ll=[" ("+((fn:=f"'_{acnt()}'")+f", {tname(clang.clang_getCursorType(f), tnm+fn[1:-1])}" if is_anon(f) else f"'{nm(f)}', "+
|
||||
tname(clang.clang_getCursorType(f), f'{tnm}_{nm(f)}'))+(f',{clang.clang_getFieldDeclBitWidth(f)}' * clang.clang_Cursor_isBitField(f))+"),"
|
||||
for f in all_fields(t, decl.kind)]
|
||||
for f in fields(t)]
|
||||
lines.extend(([f"{tnm}._anonymous_ = ["+", ".join(f"'_{i}'" for i in range(n))+"]"] if (n:=acnt()) else [])+
|
||||
([f"{tnm}._packed_ = True"] * is_packed)+([f"{tnm}._fields_ = [",*ll,"]"] if ll else []))
|
||||
return tnm
|
||||
@@ -218,10 +222,10 @@ def gen(dll, files, args=[], prolog=[], rules=[], epilog=[], recsym=False, use_e
|
||||
aa = ctypes.cast((ctypes.c_char_p * len(args))(*[x.encode() for x in args]), ctypes.POINTER(ctypes.POINTER(ctypes.c_char))) if len(args) else None
|
||||
tu = clang.clang_parseTranslationUnit(idx:=clang.clang_createIndex(False, 0), os.fspath(f).encode(), aa, len(args), None, 0,
|
||||
clang.CXTranslationUnit_DetailedPreprocessingRecord)
|
||||
q = list(children(unwrap_cursor(clang.clang_getTranslationUnitCursor(tu))))[::-1]
|
||||
while q:
|
||||
c = q.pop()
|
||||
if loc_file(loc(c)) != str(f) and (not recsym or c.kind not in (clang.CXCursor_FunctionDecl,)): continue
|
||||
# FIXME: deep walk is not neccesary...
|
||||
for c in walk(unwrap_cursor(clang.clang_getTranslationUnitCursor(tu))):
|
||||
if loc_file(loc(c)) != str(f) and (not recsym or c.kind not in (clang.CXCursor_FunctionDecl,)):
|
||||
continue
|
||||
rollback = lines, types
|
||||
try:
|
||||
match c.kind:
|
||||
@@ -251,7 +255,6 @@ def gen(dll, files, args=[], prolog=[], rules=[], epilog=[], recsym=False, use_e
|
||||
case clang.CXCursor_VarDecl if clang.clang_getCursorLinkage(c) == clang.CXLinkage_External and dll:
|
||||
lines.append(f"try: {nm(c)} = {tname(clang.clang_getCursorType(c))}.in_dll(dll, '{nm(c)}')\nexcept (ValueError,AttributeError): pass")
|
||||
case clang.CXCursor_ObjCProtocolDecl: proto(c)
|
||||
case clang.CXCursor_Namespace | clang.CXCursor_LinkageSpec: q.extend(list(children(c))[::-1])
|
||||
except NotImplementedError as e:
|
||||
print(f"skipping {nm(c)}: {e}")
|
||||
lines, types = rollback
|
||||
|
||||
@@ -77,8 +77,7 @@ else:
|
||||
if hasattr(cls, '_anonymous_'):
|
||||
for anm, aty in [(a, get_aty(a)) for a in cls._anonymous_]:
|
||||
for fnm in (get_fnms(aty) + flatten([get_fnms(get_aty(aanm, pget(aty, 'fields'))) for aanm in pget(aty, 'anonymous')])):
|
||||
setattr(cls, fnm, property(functools.partial(lambda self, anm, fnm: getattr(getattr(self, anm), fnm), anm=anm, fnm=fnm),
|
||||
functools.partial(lambda self, v, anm, fnm: setattr(getattr(self, anm), fnm, v), anm=anm, fnm=fnm)))
|
||||
setattr(cls, fnm, property(lambda self: getattr(getattr(self, anm), fnm), lambda self, v: setattr(getattr(self, anm), fnm, v)))
|
||||
setattr(cls, '_packed_anonymous_', cls._anonymous_)
|
||||
setattr(cls, '_anonymous_', [])
|
||||
type(ctypes.Structure).__setattr__(cls, '_fields_', [('_data', ctypes.c_ubyte * ((offset + 7) // 8))])
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import base64, ctypes, pathlib, tempfile, hashlib, sys
|
||||
import base64, ctypes, pathlib, tempfile, hashlib
|
||||
from tinygrad.device import Compiler
|
||||
from tinygrad.helpers import cpu_objdump, system, data64
|
||||
from tinygrad.helpers import cpu_objdump, system
|
||||
from tinygrad.runtime.autogen import mesa
|
||||
from tinygrad.runtime.support.compiler_cpu import CPULLVMCompiler, expect, cerr
|
||||
try: from tinygrad.runtime.autogen import llvm
|
||||
except (ImportError, FileNotFoundError): llvm = None #type:ignore[assignment]
|
||||
|
||||
def rzalloc(typ, ctx=None, **kwargs):
|
||||
s = ctypes.cast(mesa.rzalloc_size(ctypes.cast(ctx, ctypes.c_void_p), ctypes.sizeof(typ)), ctypes.POINTER(typ))
|
||||
for k,v in kwargs.items(): setattr(s.contents, k, v)
|
||||
return s
|
||||
|
||||
def deserialize(enc_src, opts):
|
||||
blobreader = mesa.struct_blob_reader()
|
||||
mesa.blob_reader_init(blobreader, src:=base64.b64decode(enc_src), len(src))
|
||||
@@ -89,56 +84,3 @@ class NAKCompiler(NIRCompiler):
|
||||
with open(fn, "wb") as f: f.write(lib[ctypes.sizeof(mesa.struct_nak_shader_info):])
|
||||
print(system(f"nvdisasm -b SM{self.arch[3:]} {fn}"))
|
||||
except Exception as e: print("Failed to generate SASS", str(e), "Make sure your PATH contains nvdisasm binary of compatible version.")
|
||||
|
||||
def disas_adreno(lib:bytes, gpu_id=630):
|
||||
with tempfile.TemporaryFile('w+', buffering=1) as tf:
|
||||
@ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_uint32, ctypes.c_void_p)
|
||||
def hd(data, n, instr):
|
||||
fst, snd = data64(ctypes.cast(instr, ctypes.POINTER(ctypes.c_uint64)).contents.value)
|
||||
print(f"{n:04} [{fst:08x}_{snd:08x}] ", end="", flush=True, file=tf)
|
||||
|
||||
ctypes.CDLL(None).setlinebuf(fp:=ctypes.cast(ctypes.CDLL(None).fdopen(tf.fileno(), b"w"), ctypes.POINTER(mesa.struct__IO_FILE)))
|
||||
mesa.ir3_isa_disasm(lib, len(lib), fp, mesa.struct_isa_decode_options(gpu_id, True, 0, True, pre_instr_cb=hd))
|
||||
tf.seek(0)
|
||||
print(tf.read())
|
||||
|
||||
class IR3Compiler(NIRCompiler):
|
||||
def __init__(self, chip_id, cache_key="ir3"):
|
||||
assert sys.version_info >= (3,14), "IR3 requires python 3.14's bitfield fixes"
|
||||
self.dev_id = mesa.struct_fd_dev_id(((chip_id >> 24) & 0xFF) * 100 + ((chip_id >> 16) & 0xFF) * 10 + ((chip_id >> 8) & 0xFF), chip_id)
|
||||
self.cc = mesa.ir3_compiler_create(None, self.dev_id, mesa.fd_dev_info(self.dev_id),
|
||||
mesa.struct_ir3_compiler_options(disable_cache=True)).contents
|
||||
self.cc.has_preamble = False
|
||||
self.nir_options = bytes(mesa.ir3_get_compiler_options(self.cc).contents)
|
||||
super().__init__(f"compile_{cache_key}")
|
||||
|
||||
def __del__(self):
|
||||
mesa.ir3_compiler_destroy(self.cc)
|
||||
super().__del__()
|
||||
|
||||
def __reduce__(self): return IR3Compiler, (self.dev_id.chip_id,)
|
||||
|
||||
# ir3_shader_variant info: https://elixir.bootlin.com/mesa/mesa-25.3.0/source/src/freedreno/ir3/ir3_shader.c#L1099
|
||||
def compile(self, src) -> bytes:
|
||||
nir_shader = deserialize(src, self.nir_options)
|
||||
mesa.ir3_nir_lower_io_vars_to_temporaries(nir_shader)
|
||||
mesa.ir3_finalize_nir(self.cc, mesa.struct_ir3_shader_nir_options(), nir_shader)
|
||||
shader = rzalloc(mesa.struct_ir3_shader, compiler=ctypes.pointer(self.cc), type=mesa.MESA_SHADER_COMPUTE, nir=nir_shader).contents
|
||||
mesa.ir3_nir_post_finalize(shader)
|
||||
v = rzalloc(mesa.struct_ir3_shader_variant, type=shader.type, compiler=ctypes.pointer(self.cc), key=mesa.struct_ir3_shader_key()).contents
|
||||
v.const_state, shader.variants, shader.variant_count = rzalloc(mesa.struct_ir3_const_state, ctypes.pointer(v)), ctypes.pointer(v), 1
|
||||
v.num_uavs = (info:=nir_shader.contents.info).num_ssbos + info.num_images
|
||||
assert not mesa.ir3_compile_shader_nir(self.cc, shader, v), "compilation failed"
|
||||
lib = ctypes.cast(mesa.ir3_shader_assemble(v), ctypes.POINTER(ctypes.c_uint32))
|
||||
# NB: bytes(v) means the pointers in v are no longer safe! a custom __reduce__ that supports pointers for c.Struct would make this simpler
|
||||
ret = bytes(v) + bytes(v.const_state.contents) + ctypes.string_at(v.imm_state.values, v.imm_state.count * 4) + ctypes.string_at(lib, v.info.size)
|
||||
mesa.ralloc_free(ctypes.pointer(v))
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def unpack_lib(lib: bytes) -> tuple[mesa.struct_ir3_shader_variant, mesa.struct_ir3_const_state, bytes, bytes]:
|
||||
shifted = lib[ctypes.sizeof(v:=mesa.struct_ir3_shader_variant.from_buffer_copy(lib)):]
|
||||
shifted = shifted[ctypes.sizeof(cs:=mesa.struct_ir3_const_state.from_buffer_copy(shifted)):]
|
||||
return v, cs, shifted[:v.imm_state.count * 4], shifted[v.imm_state.count * 4:]
|
||||
|
||||
def disassemble(self, lib: bytes): disas_adreno(self.unpack_lib(lib)[3], self.dev_id.gpu_id)
|
||||
|
||||
@@ -3,7 +3,7 @@ from typing import cast, Callable, Type, TypeVar, Generic, Any
|
||||
import contextlib, decimal, statistics, time, ctypes, array, os, struct, collections, functools
|
||||
try: import fcntl # windows misses that
|
||||
except ImportError: fcntl = None #type:ignore[assignment]
|
||||
from tinygrad.helpers import PROFILE, getenv, to_mv, ProfileRangeEvent, select_first_inited, unwrap, suppress_finalizing
|
||||
from tinygrad.helpers import PROFILE, getenv, to_mv, ProfileRangeEvent, select_first_inited, unwrap
|
||||
from tinygrad.device import BufferSpec, Compiled, LRUAllocator, ProfileDeviceEvent, ProfileProgramEvent, CompilerSet
|
||||
from tinygrad.uop.ops import sym_infer, sint, UOp
|
||||
from tinygrad.runtime.autogen import libc
|
||||
@@ -15,7 +15,7 @@ class MMIOInterface:
|
||||
def __getitem__(self, k): return (bytes(self.mv[k]) if self.fmt == 'B' else self.mv[k].tolist()) if isinstance(k, slice) else self.mv[k]
|
||||
def __setitem__(self, k, v): self.mv[k] = v
|
||||
def view(self, offset:int=0, size:int|None=None, fmt=None) -> MMIOInterface:
|
||||
return MMIOInterface(self.addr+offset, (self.nbytes - offset) if size is None else size, fmt=fmt or self.fmt)
|
||||
return MMIOInterface(self.addr+offset, size or (self.nbytes - offset), fmt=fmt or self.fmt)
|
||||
|
||||
class FileIOInterface:
|
||||
"""
|
||||
@@ -497,11 +497,6 @@ class HCQAllocatorBase(LRUAllocator[HCQDeviceType], Generic[HCQDeviceType]):
|
||||
if (mb:=self._map(buf)) is not None: buf.mappings[self.dev] = mb
|
||||
buf.mapped_devs.append(self.dev)
|
||||
|
||||
@suppress_finalizing
|
||||
def _free(self, buf:HCQBuffer, options:BufferSpec|None=None):
|
||||
for dev in buf.mapped_devs: dev.synchronize()
|
||||
if hasattr(self, '_do_free'): self._do_free(buf, options)
|
||||
|
||||
def _offset(self, buf, size:int, offset:int) -> HCQBuffer: return buf.offset(offset=offset, size=size)
|
||||
|
||||
class HCQAllocator(HCQAllocatorBase, Generic[HCQDeviceType]):
|
||||
|
||||
@@ -102,8 +102,6 @@ def mstack_early_shrink(ms:UOp, shrink:UOp):
|
||||
replace_allreduce = PatternMatcher([
|
||||
(UPat(Ops.ALLREDUCE, src=(UPat.var("buf"), UPat()), name="red"), handle_allreduce_multirank),
|
||||
(UPat(Ops.ALLREDUCE, src=(UPat.var("buf"), UPat()), name="red"), handle_allreduce),
|
||||
(UPat(Ops.COPY, src=(UPat(Ops.BUFFER, name="buf"), UPat(Ops.DEVICE, name="dev"))),lambda buf,dev: UOp.new_buffer(dev.arg, buf.arg, buf.dtype)
|
||||
if buf.device not in {"DISK", "NPY"} and isinstance(dev.arg, tuple) and isinstance(buf.device, str) else None),
|
||||
# BROADCAST: explicitly expand broadcast copies and combine with MSTACK
|
||||
(UPat(Ops.COPY, name="c", src=(UPat(GroupOp.All-{Ops.CONST}, name="x"), UPat(Ops.DEVICE))), lambda c,x:
|
||||
UOp(Ops.MSTACK, c.dtype, tuple(x.copy_to_device(d) for d in c.device)) if isinstance(c.device, tuple) and isinstance(x.device, str) else None),
|
||||
|
||||
+1
-13
@@ -312,12 +312,6 @@ class Tensor(OpMixin):
|
||||
assert all_int(self.shape), f"no data if shape is symbolic, {self.shape=}"
|
||||
return self._buffer().as_typed_buffer(self.shape)
|
||||
|
||||
def tobytes(self) -> bytes:
|
||||
"""
|
||||
Returns the data of this tensor as bytes, like numpy's `.tobytes()`.
|
||||
"""
|
||||
return bytes(self.data())
|
||||
|
||||
def item(self) -> ConstType:
|
||||
"""
|
||||
Returns the value of this tensor as a standard Python number.
|
||||
@@ -1024,8 +1018,7 @@ class Tensor(OpMixin):
|
||||
# clear contexts
|
||||
for t,g in zip(tensors_need_grad, self.gradient(*tensors_need_grad, gradient=gradient, materialize_grads=True)):
|
||||
assert g.shape == t.shape, f"grad shape must match tensor shape, {g.shape!r} != {t.shape!r}"
|
||||
if t.grad is None: t.grad = g
|
||||
else: t.grad.assign(t.grad + g)
|
||||
t.grad = g if t.grad is None else (t.grad + g)
|
||||
return self
|
||||
|
||||
# ***** movement low level ops *****
|
||||
@@ -3719,11 +3712,6 @@ class Tensor(OpMixin):
|
||||
"""
|
||||
# NOTE: it also works when `key` and `value` have symbolic shape.
|
||||
assert all_int(self.shape), f"does not support symbolic shape {self.shape}"
|
||||
|
||||
if getenv("FLASH_ATTENTION"):
|
||||
from extra.thunder.tiny.fa import flash_attention
|
||||
return flash_attention(self, key, value, attn_mask=attn_mask, is_causal=is_causal)
|
||||
|
||||
# GQA: https://docs.pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html
|
||||
if enable_gqa:
|
||||
key = key.repeat_interleave(self.shape[-3] // key.shape[-3], dim=-3)
|
||||
|
||||
+14
-13
@@ -64,15 +64,16 @@ def consumer_map_from_toposort(lst:Iterable[UOp]):
|
||||
for s in u.src: ret[s][u] = None
|
||||
return ret
|
||||
|
||||
def pretty_print(x:UOp, cache=None, d=0)->str:
|
||||
def dfs(x:UOp, cache:dict):
|
||||
for s in x.src:
|
||||
# used for UOp and UPat
|
||||
def pretty_print(x:Any, rep:Callable, srcfn=lambda x: x.src, cache=None, d=0)->str:
|
||||
def dfs(x:Any, cache:dict):
|
||||
for s in srcfn(x) or []:
|
||||
cache.setdefault(s, [len(cache), 0, False])[1] += 1
|
||||
if cache[s][1] == 1: dfs(s, cache)
|
||||
if cache is None: dfs(x, cache:={})
|
||||
if (cx:=cache.setdefault(x, [0,0,False]))[2]: return f"{' '*d} x{cx[0]}"
|
||||
cx[2], srcs = True, (''.join(f'\n{pretty_print(s, cache, d+2)},' for s in x.src))
|
||||
return f"{' '*d}{f'x{cx[0]}:=' * (cx[1]>1)}{type(x).__name__}({x.op}, {x.dtype}, arg={x.argstr()}{x.tagstr()}, src=({srcs}))"
|
||||
cx[2], srcs = True, ('None' if srcfn(x) is None else ''.join(f'\n{pretty_print(s, rep, srcfn, cache, d+2)},' for s in srcfn(x)))
|
||||
return f"{' '*d}{f'x{cx[0]}:=' * (cx[1]>1)}{rep(x)}" % srcs
|
||||
|
||||
class UOpMetaClass(type):
|
||||
ucache:dict[tuple, weakref.ReferenceType[UOp]] = {}
|
||||
@@ -144,7 +145,7 @@ class UOp(OpMixin, metaclass=UOpMetaClass):
|
||||
@functools.cached_property
|
||||
def key(self) -> bytes:
|
||||
return hashlib.sha256(str((self.op, self.dtype, self.arg)).encode() + b"".join([s.key for s in self.src])).digest()
|
||||
def __repr__(self): return pretty_print(self)
|
||||
def __repr__(self): return pretty_print(self, lambda x: f"{type(self).__name__}({x.op}, {x.dtype}, arg={x.argstr()}{x.tagstr()}, src=(%s))")
|
||||
def argstr(self): return f'({", ".join(map(str, self.arg))})' if self.op is Ops.REDUCE_AXIS else repr(self.arg)
|
||||
def tagstr(self): return f", tag={self.tag}" if self.tag is not None else ""
|
||||
|
||||
@@ -158,9 +159,7 @@ class UOp(OpMixin, metaclass=UOpMetaClass):
|
||||
|
||||
@property
|
||||
def backward_slice_with_self(self:UOp) -> dict[UOp, None]: return {self:None, **self.backward_slice}
|
||||
def op_in_backward_slice_with_self(self, *ops:Ops) -> bool:
|
||||
# Check self first, then iterate backward_slice (avoids creating intermediate dict)
|
||||
return self.op in ops or any(x.op in ops for x in self.backward_slice)
|
||||
def op_in_backward_slice_with_self(self, *ops:Ops): return any(x.op in ops for x in self.backward_slice_with_self)
|
||||
|
||||
def toposort(self, gate:Callable|None=None) -> dict[UOp, None]:
|
||||
cache: dict[UOp, None] = {}
|
||||
@@ -342,7 +341,6 @@ class UOp(OpMixin, metaclass=UOpMetaClass):
|
||||
# *** uop evaluation ***
|
||||
|
||||
def simplify(self, tracked=False):
|
||||
if self.op in {Ops.CONST, Ops.VCONST}: return self
|
||||
# late import!
|
||||
from tinygrad.uop.symbolic import symbolic
|
||||
with Context(TRACK_MATCH_STATS=0 if not tracked else TRACK_MATCH_STATS.value):
|
||||
@@ -1194,13 +1192,16 @@ class BottomUpGate(Exception): pass
|
||||
class RewriteContext:
|
||||
def __init__(self, pm, bpm, ctx=None):
|
||||
self.pm: PatternMatcher|None = pm
|
||||
self.pm_cache: dict[UOp, UOp|None] = {}
|
||||
self.bpm: PatternMatcher|None = bpm
|
||||
self.bpm_cache: dict[UOp, UOp|None] = {}
|
||||
self.ctx = ctx
|
||||
self.replace: dict[UOp, UOp] = {}
|
||||
|
||||
# no cache needed: pm_rewrite is called at most once per UOp due to the replace dict check in unified_rewrite
|
||||
def pm_rewrite(self, x:UOp) -> UOp|None: return unwrap(self.pm).rewrite(x, self.ctx)
|
||||
def cached_pm_rewrite(self, x:UOp) -> UOp|None:
|
||||
if (ret:=self.pm_cache.get(x,SENTINEL)) is not SENTINEL: return ret
|
||||
ret = self.pm_cache[x] = unwrap(self.pm).rewrite(x, self.ctx)
|
||||
return ret
|
||||
|
||||
def cached_bpm_rewrite(self, x:UOp) -> UOp|None:
|
||||
if (ret:=self.bpm_cache.get(x,SENTINEL)) is not SENTINEL: return ret
|
||||
@@ -1247,7 +1248,7 @@ class RewriteContext:
|
||||
# in stage 1, once all srcs are rewritten, rebuild (if changed) or run top-down rewrite
|
||||
if (new_src:=tuple(tmp)) == new_n.src:
|
||||
# if top down, do the rewrite. if no rewrite or bottom up, we are done rewriting this node so we add it to the dict
|
||||
if self.pm is None or (new_src_n:=self.pm_rewrite(new_n)) is None:
|
||||
if self.pm is None or (new_src_n:=self.cached_pm_rewrite(new_n)) is None:
|
||||
self.replace[n] = new_n
|
||||
continue
|
||||
else:
|
||||
|
||||
@@ -83,8 +83,6 @@ _tensor_spec = PatternMatcher([
|
||||
|
||||
# Tensor variable bindings
|
||||
(UPat(Ops.BIND, (dtypes.int,dtypes.index,), (UPat(Ops.DEFINE_VAR), UPat.cvar(dtype=(dtypes.int,dtypes.index,))), arg=None), lambda: True),
|
||||
# single-src BIND used for schedule cache key normalization
|
||||
(UPat(Ops.BIND, (dtypes.int,dtypes.index,), (UPat(Ops.DEFINE_VAR),), arg=None), lambda: True),
|
||||
|
||||
# device or unique
|
||||
(UPat(Ops.CONST, src=(UPat(Ops.DEVICE),)), lambda: True),
|
||||
|
||||
@@ -10,5 +10,6 @@ fetch "dagrejs.github.io/project/dagre/latest/dagre.min.js"
|
||||
fetch "cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/default.min.css"
|
||||
fetch "cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js"
|
||||
fetch "cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/python.min.js"
|
||||
fetch "cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/x86asm.min.js"
|
||||
fetch "cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/cpp.min.js"
|
||||
fetch "unpkg.com/@highlightjs/[email protected]/styles/tokyo-night-dark.min.css"
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<script src="assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js"></script>
|
||||
<script src="assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/python.min.js"></script>
|
||||
<script src="assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/cpp.min.js"></script>
|
||||
<script src="assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/x86asm.min.js"></script>
|
||||
<link rel="stylesheet" href="assets/unpkg.com/@highlightjs/[email protected]/styles/tokyo-night-dark.min.css" />
|
||||
<style>
|
||||
* {
|
||||
|
||||
+26
-45
@@ -636,9 +636,6 @@ hljs.registerLanguage("cpp", (hljs) => ({
|
||||
...hljs.getLanguage('cpp'),
|
||||
contains: [{ begin: '\\b(?:float|half)[0-9]+\\b', className: 'type' }, ...hljs.getLanguage('cpp').contains]
|
||||
}));
|
||||
hljs.registerLanguage("amdgpu", (hljs) => ({
|
||||
contains: [hljs.COMMENT("//", "$"), { begin:/\b(?:s_|v_|global_|buffer_|scratch_|flat_|ds_)[a-z0-9_]*\b/, className:"code" }]
|
||||
}));
|
||||
|
||||
async function fetchValue(path) {
|
||||
const res = await fetch(path);
|
||||
@@ -698,29 +695,6 @@ const toggleLabel = d3.create("label").text("Show indexing (r)").node();
|
||||
const toggle = d3.create("input").attr("type", "checkbox").attr("id", "show-indexing").property("checked", true).node();
|
||||
toggleLabel.prepend(toggle);
|
||||
|
||||
function appendSteps(root, idx, steps) {
|
||||
const stack = [];
|
||||
for (const [j,u] of steps.entries()) {
|
||||
while (stack.length && stack.at(-1).depth >= u.depth) stack.pop();
|
||||
const list = stack.length > 0 ? stack.at(-1).li : root;
|
||||
u.li = list.appendChild(document.createElement("ul"));
|
||||
u.li.id = `step-${idx}-${j}`
|
||||
const p = u.li.appendChild(document.createElement("p"));
|
||||
p.appendChild(colored(`${u.name}`+(u.match_count ? ` - ${u.match_count}` : '')));
|
||||
p.onclick = (e) => {
|
||||
e.stopPropagation();
|
||||
const subrewrites = getSubrewrites(e.currentTarget.parentElement);
|
||||
if (subrewrites.length) { e.currentTarget.parentElement.classList.toggle("expanded"); }
|
||||
setState({ currentStep:j, currentCtx:idx, currentRewrite:0 });
|
||||
}
|
||||
stack.push(u);
|
||||
}
|
||||
for (const l of root.querySelectorAll("ul > ul > p")) {
|
||||
const subrewrites = getSubrewrites(l.parentElement);
|
||||
if (subrewrites.length > 0) { l.appendChild(d3.create("span").text(` (${subrewrites.length})`).node()); l.parentElement.classList.add("has-children"); }
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
// ** left sidebar context list
|
||||
if (ctxs == null) {
|
||||
@@ -735,7 +709,26 @@ async function main() {
|
||||
p.onclick = () => {
|
||||
setState(i === state.currentCtx ? { expandSteps:!state.expandSteps } : { expandSteps:true, currentCtx:i, currentStep:0, currentRewrite:0 });
|
||||
}
|
||||
appendSteps(ul, i, steps);
|
||||
const stack = []; let list = ul;
|
||||
for (const [j,u] of steps.entries()) {
|
||||
while (stack.length && stack.at(-1).depth >= u.depth) stack.pop();
|
||||
const list = stack.length > 0 ? stack.at(-1).li : ul;
|
||||
u.li = list.appendChild(document.createElement("ul"));
|
||||
u.li.id = `step-${i}-${j}`
|
||||
const p = u.li.appendChild(document.createElement("p"));
|
||||
p.appendChild(colored(`${u.name}`+(u.match_count ? ` - ${u.match_count}` : '')));
|
||||
p.onclick = (e) => {
|
||||
e.stopPropagation();
|
||||
const subrewrites = getSubrewrites(e.currentTarget.parentElement);
|
||||
if (subrewrites.length) { e.currentTarget.parentElement.classList.toggle("expanded"); }
|
||||
setState({ currentStep:j, currentCtx:i, currentRewrite:0 });
|
||||
}
|
||||
stack.push(u);
|
||||
}
|
||||
for (const l of ul.querySelectorAll("ul > ul > p")) {
|
||||
const subrewrites = getSubrewrites(l.parentElement);
|
||||
if (subrewrites.length > 0) { l.appendChild(d3.create("span").text(` (${subrewrites.length})`).node()); l.parentElement.classList.add("has-children"); }
|
||||
}
|
||||
}
|
||||
return setState({ currentCtx:-1 });
|
||||
}
|
||||
@@ -760,15 +753,6 @@ async function main() {
|
||||
// ** Disassembly view
|
||||
if (!ckey.startsWith("/rewrites")) {
|
||||
if (!(ckey in cache)) cache[ckey] = ret = await fetchValue(ckey);
|
||||
if (ret.steps?.length > 0) {
|
||||
const el = select(state.currentCtx, state.currentStep);
|
||||
if (el.step.querySelectorAll("ul").length === ret.steps.length) return;
|
||||
// re render the list with new items
|
||||
ctx.steps.push(...ret.steps);
|
||||
while (el.ctx.children.length > 1) el.ctx.children[1].remove();
|
||||
appendSteps(el.ctx, state.currentCtx, ctx.steps);
|
||||
return setState({ currentStep:state.currentStep+1, expandSteps:true });
|
||||
}
|
||||
// cycles on the x axis
|
||||
if (ret instanceof ArrayBuffer) {
|
||||
opts = {heightScale:0.5, hideLabels:true, levelKey:(e) => parseInt(e.name.split(" ")[1].split(":")[1])};
|
||||
@@ -800,7 +784,7 @@ async function main() {
|
||||
}
|
||||
const td = tr.append("td").classed(ret.cols[i], true);
|
||||
// string format scalar values
|
||||
if (!Array.isArray(value)) { td.text(typeof value === "string" ? value : ret.cols[i] === "Duration" ? formatMicroseconds(value) : formatUnit(value)); continue; }
|
||||
if (!Array.isArray(value)) { td.text(typeof value === "string" ? value : formatUnit(value)); continue; }
|
||||
// display arrays in a bar graph
|
||||
td.classed("pct-row", true);
|
||||
const bar = td.append("div");
|
||||
@@ -812,14 +796,11 @@ async function main() {
|
||||
}
|
||||
if (ret.cols != null) {
|
||||
renderTable(root, ret);
|
||||
} else root.append(() => codeBlock(ret.src, ret.lang || "txt"));
|
||||
ret.metadata?.forEach(m => {
|
||||
if (Array.isArray(m)) return metadata.appendChild(tabulate(m.map(({ label, value, idx }) => {
|
||||
const div = d3.create("div").style("background", cycleColors(colorScheme.CATEGORICAL, idx)).style("width", "100%").style("height", "100%");
|
||||
return [label.trim(), div.text(typeof value === "string" ? value : formatUnit(value)).node()];
|
||||
metadata.appendChild(tabulate(ret.summary.map(s => {
|
||||
const div = d3.create("div").style("background", cycleColors(colorScheme.CATEGORICAL, s.idx)).style("width", "100%").style("height", "100%");
|
||||
return [s.label.trim(), div.text(s.value.toLocaleString()).node()];
|
||||
})).node());
|
||||
metadata.appendChild(codeBlock(m.src, "txt")).classList.add("full-height")
|
||||
});
|
||||
} else root.append(() => codeBlock(ret.src, ret.lang || "txt"));
|
||||
return document.querySelector("#custom").replaceChildren(root.node());
|
||||
}
|
||||
// ** UOp view (default)
|
||||
@@ -830,7 +811,7 @@ async function main() {
|
||||
const eventSource = new EventSource(ckey);
|
||||
evtSources.push(eventSource);
|
||||
eventSource.onmessage = (e) => {
|
||||
if (e.data === "[DONE]") return eventSource.close();
|
||||
if (e.data === "END") return eventSource.close();
|
||||
const chunk = JSON.parse(e.data);
|
||||
ret.push(chunk);
|
||||
// if it's the first one render this new rgaph
|
||||
|
||||
+116
-143
@@ -1,15 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
import multiprocessing, pickle, difflib, os, threading, json, time, sys, webbrowser, socket, argparse, functools, codecs, io, struct
|
||||
import multiprocessing, pickle, difflib, os, threading, json, time, sys, webbrowser, socket, argparse, socketserver, functools, codecs, io, struct
|
||||
import ctypes, pathlib, traceback, itertools
|
||||
from contextlib import redirect_stdout, redirect_stderr, contextmanager
|
||||
from contextlib import redirect_stdout, redirect_stderr
|
||||
from decimal import Decimal
|
||||
from http.server import BaseHTTPRequestHandler
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
from typing import Any, TypedDict, TypeVar, Generator, Callable
|
||||
from tinygrad.helpers import colored, getenv, tqdm, unwrap, word_wrap, TRACEMETA, ProfileEvent, ProfileRangeEvent, TracingKey, ProfilePointEvent, temp
|
||||
from tinygrad.helpers import printable, system, TCPServerWithReuse, HTTPRequestHandler
|
||||
from tinygrad.helpers import printable, system
|
||||
from tinygrad.uop.ops import TrackedGraphRewrite, RewriteTrace, UOp, Ops, GroupOp, srender, sint, sym_infer, range_str, pyrender
|
||||
from tinygrad.uop.ops import print_uops, range_start, multirange_str
|
||||
from tinygrad.device import ProfileDeviceEvent, ProfileGraphEvent, ProfileGraphEntry, Device, ProfileProgramEvent
|
||||
from tinygrad.device import ProfileDeviceEvent, ProfileGraphEvent, ProfileGraphEntry, Device
|
||||
from tinygrad.renderer import ProgramSpec
|
||||
from tinygrad.dtype import dtypes
|
||||
|
||||
@@ -58,8 +59,7 @@ class GraphRewriteDetails(TypedDict):
|
||||
|
||||
def shape_to_str(s:tuple[sint, ...]): return "(" + ','.join(srender(x) for x in s) + ")"
|
||||
def mask_to_str(s:tuple[tuple[sint, sint], ...]): return "(" + ','.join(shape_to_str(x) for x in s) + ")"
|
||||
def pystr(u:UOp) -> str:
|
||||
# pyrender may check for shape mismatch
|
||||
def pystr(u:UOp, i:int) -> str:
|
||||
try: return pyrender(u)
|
||||
except Exception: return str(u)
|
||||
|
||||
@@ -112,18 +112,19 @@ def _reconstruct(a:int):
|
||||
arg = type(arg)(_reconstruct(arg.ast), arg.metadata) if op is Ops.KERNEL else arg
|
||||
return UOp(op, dtype, tuple(_reconstruct(s) for s in src), arg, *rest)
|
||||
|
||||
def get_full_rewrite(ctx:TrackedGraphRewrite) -> Generator[GraphRewriteDetails, None, None]:
|
||||
def get_full_rewrite(ctx:TrackedGraphRewrite, i:int=0) -> Generator[GraphRewriteDetails, None, None]:
|
||||
next_sink = _reconstruct(ctx.sink)
|
||||
# in the schedule graph we don't show indexing ops (unless it's in a kernel AST or rewriting dtypes.index sink)
|
||||
yield {"graph":uop_to_json(next_sink), "uop":pystr(next_sink), "changed_nodes":None, "diff":None, "upat":None}
|
||||
yield {"graph":uop_to_json(next_sink), "uop":pystr(next_sink,i), "changed_nodes":None, "diff":None, "upat":None}
|
||||
replaces: dict[UOp, UOp] = {}
|
||||
for u0_num,u1_num,upat_loc,dur in tqdm(ctx.matches):
|
||||
replaces[u0:=_reconstruct(u0_num)] = u1 = _reconstruct(u1_num)
|
||||
try: new_sink = next_sink.substitute(replaces)
|
||||
except RuntimeError as e: new_sink = UOp(Ops.NOOP, arg=str(e))
|
||||
match_repr = f"# {dur*1e6:.2f} us\n"+printable(upat_loc)
|
||||
yield {"graph":(sink_json:=uop_to_json(new_sink)), "uop":pystr(new_sink), "changed_nodes":[id(x) for x in u1.toposort() if id(x) in sink_json],
|
||||
"diff":list(difflib.unified_diff(pystr(u0).splitlines(), pystr(u1).splitlines())), "upat":(upat_loc, match_repr)}
|
||||
yield {"graph":(sink_json:=uop_to_json(new_sink)), "uop":pystr(new_sink,i),
|
||||
"changed_nodes":[id(x) for x in u1.toposort() if id(x) in sink_json],
|
||||
"diff":list(difflib.unified_diff(pystr(u0,i).splitlines(),pystr(u1,i).splitlines())), "upat":(upat_loc, match_repr)}
|
||||
if not ctx.bottom_up: next_sink = new_sink
|
||||
|
||||
# encoder helpers
|
||||
@@ -209,91 +210,80 @@ def mem_layout(dev_events:list[tuple[int, int, float, DevEvent]], start_ts:int,
|
||||
peaks.append(peak)
|
||||
return struct.pack("<BIQ", 1, len(events), peak)+b"".join(events) if events else None
|
||||
|
||||
# by default, VIZ does not start when there is an error
|
||||
# use this to instead display the traceback to the user
|
||||
@contextmanager
|
||||
def soft_err(fn:Callable):
|
||||
try: yield
|
||||
except Exception: fn({"src":traceback.format_exc()})
|
||||
def err(name:str, msg:str|None=None) -> None:
|
||||
ctxs.append({"name":"ERR", "steps":[create_step(name, ("render",len(ctxs),0), {"src":msg or traceback.format_exc()})]})
|
||||
|
||||
def row_tuple(row:str) -> tuple[int, ...]: return tuple(int(x.split(":")[1]) for x in row.split())
|
||||
|
||||
# *** Performance counters
|
||||
|
||||
def unpack_pmc(e) -> dict:
|
||||
agg_cols = ["Name", "Sum"]
|
||||
sample_cols = ["XCC", "INST", "SE", "SA", "WGP", "Value"]
|
||||
rows:list[list] = []
|
||||
view, ptr = memoryview(e.blob).cast('Q'), 0
|
||||
for s in e.sched:
|
||||
row:list = [s.name, 0, {"cols":sample_cols, "rows":[]}]
|
||||
for sample in itertools.product(range(s.xcc), range(s.inst), range(s.se), range(s.sa), range(s.wgp)):
|
||||
row[1] += (val:=int(view[ptr]))
|
||||
row[2]["rows"].append(sample+(val,))
|
||||
ptr += 1
|
||||
rows.append(row)
|
||||
return {"rows":rows, "cols":agg_cols}
|
||||
|
||||
# ** on startup, list all the performance counter traces
|
||||
|
||||
def load_counters(profile:list[ProfileEvent]) -> None:
|
||||
def load_sqtt(profile:list[ProfileEvent]) -> None:
|
||||
from tinygrad.runtime.ops_amd import ProfileSQTTEvent, ProfilePMCEvent
|
||||
counter_events:dict[tuple[str, int], dict] = {}
|
||||
durations:dict[str, list[float]] = {}
|
||||
prg_events:dict[str, ProfileProgramEvent] = {}
|
||||
dev_events:dict[str, ProfileDeviceEvent] = {}
|
||||
counter_events:dict[tuple[str, int], list[ProfileSQTTEvent|ProfilePMCEvent]] = {}
|
||||
for e in profile:
|
||||
if isinstance(e, (ProfilePMCEvent, ProfileSQTTEvent)): counter_events.setdefault((e.kern, e.exec_tag), {}).setdefault(type(e), []).append(e)
|
||||
if isinstance(e, ProfileRangeEvent) and e.device.startswith("AMD") and e.en is not None:
|
||||
durations.setdefault(str(e.name), []).append(float(e.en-e.st))
|
||||
if isinstance(e, ProfileProgramEvent): prg_events[str(e.name)] = e
|
||||
if isinstance(e, ProfileDeviceEvent): dev_events[e.device] = e
|
||||
ctxs.append({"name":"All Counters", "steps":[create_step("PMC", ("/all-pmc", len(ctxs), 0), \
|
||||
(durations, {k:v[ProfilePMCEvent][0] for k,v in counter_events.items()}))]})
|
||||
run_number = {n:0 for n,_ in counter_events}
|
||||
for k,v in counter_events.items():
|
||||
prg = trace.keys[r].ret if (r:=ref_map.get(k[0])) else None
|
||||
name = prg.name if prg is not None else k[0]
|
||||
run_number[k[0]] += 1
|
||||
steps:list[dict] = []
|
||||
if (pmc:=v.get(ProfilePMCEvent)): steps.append(create_step("PMC", ("/prg-pmc", len(ctxs), len(steps)), pmc))
|
||||
if (sqtt:=v.get(ProfileSQTTEvent)):
|
||||
# to decode a SQTT trace, we need the raw stream, program binary and device properties
|
||||
steps.append(create_step("SQTT", ("/prg-sqtt", len(ctxs), len(steps)), (k, [*sqtt, prg_events[k[0]], dev_events[sqtt[0].device]])))
|
||||
if getenv("SQTT_PARSE"):
|
||||
# run our decoder on startup, we don't use this since it only works on gfx11
|
||||
from extra.sqtt.attempt_sqtt_parse import parse_sqtt_print_packets
|
||||
for e in sqtt: parse_sqtt_print_packets(e.blob)
|
||||
ctxs.append({"name":f"Exec {name} n{run_number[k[0]]}", "steps":steps})
|
||||
|
||||
# ** SQTT OCC only unpacks wave start, end time and SIMD location
|
||||
|
||||
def unpack_sqtt(key:tuple[str, int], profile:list[ProfileEvent]) -> tuple[dict[str, list[ProfileEvent]], list[str], dict[str, dict[str, dict]]]:
|
||||
# * init decoder
|
||||
from extra.sqtt.roc import decode
|
||||
rctx = decode(profile)
|
||||
disasm = rctx.disasms[key[0]]
|
||||
cu_events:dict[str, list[ProfileEvent]] = {}
|
||||
# * INST waves
|
||||
wave_insts:dict[str, dict[str, dict]] = {}
|
||||
inst_units:dict[str, itertools.count] = {}
|
||||
for w in rctx.inst_execs.get(key, []):
|
||||
if (u:=w.wave_loc) not in inst_units: inst_units[u] = itertools.count(0)
|
||||
n = next(inst_units[u])
|
||||
if (events:=cu_events.get(w.cu_loc)) is None: cu_events[w.cu_loc] = events = []
|
||||
events.append(ProfileRangeEvent(w.simd_loc, loc:=f"INST WAVE:{w.wave_id} N:{n}", Decimal(w.begin_time), Decimal(w.end_time)))
|
||||
wave_insts.setdefault(w.cu_loc, {})[f"{u} N:{n}"] = {"wave":w, "disasm":disasm, "run_number":n, "loc":loc}
|
||||
# * OCC waves
|
||||
units:dict[str, itertools.count] = {}
|
||||
wave_start:dict[str, int] = {}
|
||||
for occ in rctx.occ_events.get(key, []):
|
||||
if (u:=occ.wave_loc) not in units: units[u] = itertools.count(0)
|
||||
if u in inst_units: continue
|
||||
if occ.start: wave_start[u] = occ.time
|
||||
else:
|
||||
if (events:=cu_events.get(occ.cu_loc)) is None: cu_events[occ.cu_loc] = events = []
|
||||
events.append(ProfileRangeEvent(occ.simd_loc, f"OCC WAVE:{occ.wave_id} N:{next(units[u])}", Decimal(wave_start.pop(u)), Decimal(occ.time)))
|
||||
return cu_events, list(units), wave_insts
|
||||
if isinstance(e, (ProfilePMCEvent, ProfileSQTTEvent)): counter_events.setdefault((e.kern, e.exec_tag), []).append(e)
|
||||
if not counter_events: return
|
||||
# ** init decoder
|
||||
try: from extra.sqtt.roc import decode
|
||||
except Exception: return err("DECODER IMPORT ISSUE")
|
||||
try: rctx = decode(profile)
|
||||
except Exception: return err("DECODER ERROR")
|
||||
if getenv("SQTT_PARSE"):
|
||||
from extra.sqtt.attempt_sqtt_parse import parse_sqtt_print_packets
|
||||
for counters in counter_events.values():
|
||||
for e in counters:
|
||||
if isinstance(e, ProfileSQTTEvent): parse_sqtt_print_packets(e.blob)
|
||||
# ** decode traces for each run
|
||||
steps:list[dict] = []
|
||||
for key,counters in counter_events.items():
|
||||
# ** Run summary
|
||||
program = trace.keys[r].ret if (r:=ref_map.get(key[0])) else None
|
||||
summary = [f"{program.global_size=} {program.local_size=}"] if program else [repr(key)]
|
||||
# ** SQTT events
|
||||
disasm = rctx.disasms[key[0]]
|
||||
cu_events:dict[str, list[ProfileEvent]] = {}
|
||||
# * INST waves
|
||||
wave_insts:dict[str, dict[str, dict]] = {}
|
||||
inst_units:dict[str, itertools.count] = {}
|
||||
for w in rctx.inst_execs.get(key, []):
|
||||
if (u:=w.wave_loc) not in inst_units: inst_units[u] = itertools.count(0)
|
||||
n = next(inst_units[u])
|
||||
if (events:=cu_events.get(w.cu_loc)) is None: cu_events[w.cu_loc] = events = []
|
||||
events.append(ProfileRangeEvent(w.simd_loc, loc:=f"INST WAVE:{w.wave_id} N:{n}", Decimal(w.begin_time), Decimal(w.end_time)))
|
||||
wave_insts.setdefault(w.cu_loc, {})[f"{u} N:{n}"] = {"wave":w, "disasm":disasm, "run_number":n, "loc":loc}
|
||||
# * OCC waves
|
||||
units:dict[str, itertools.count] = {}
|
||||
wave_start:dict[str, int] = {}
|
||||
for occ in rctx.occ_events.get(key, []):
|
||||
if (u:=occ.wave_loc) not in units: units[u] = itertools.count(0)
|
||||
if u in inst_units: continue
|
||||
if occ.start: wave_start[u] = occ.time
|
||||
else:
|
||||
if (events:=cu_events.get(occ.cu_loc)) is None: cu_events[occ.cu_loc] = events = []
|
||||
events.append(ProfileRangeEvent(occ.simd_loc, f"OCC WAVE:{occ.wave_id} N:{next(units[u])}", Decimal(wave_start.pop(u)), Decimal(occ.time)))
|
||||
prg_cu = sorted(cu_events, key=row_tuple)
|
||||
if cu_events: summary.append(f"Scheduled on {len(prg_cu)} CUs")
|
||||
steps.append(create_step(program.name if program else key[0], ("/counters", len(ctxs), len(steps)), {"src":"\n\n".join(summary)}, depth=1))
|
||||
# ** PMC events
|
||||
if (pmc_event:=next((e for e in counters if isinstance(e, ProfilePMCEvent)), None)) is not None:
|
||||
agg_cols = ["Name", "Sum"]
|
||||
sample_cols = ["XCC", "INST", "SE", "SA", "WGP", "Value"]
|
||||
rows:list[list] = []
|
||||
view, ptr = memoryview(pmc_event.blob).cast('Q'), 0
|
||||
for s in pmc_event.sched:
|
||||
row:list = [s.name, 0, {"cols":sample_cols, "rows":[]}]
|
||||
for sample in itertools.product(range(s.xcc), range(s.inst), range(s.se), range(s.sa), range(s.wgp)):
|
||||
row[1] += (val:=int(view[ptr]))
|
||||
row[2]["rows"].append(sample+(val,))
|
||||
ptr += 1
|
||||
rows.append(row)
|
||||
steps.append(create_step("PMC", ("/pmc", len(ctxs), len(steps)), {"rows":rows, "cols":agg_cols, "summary":[]}, depth=2))
|
||||
for cu in prg_cu:
|
||||
events = [ProfilePointEvent(unit, "start", unit, ts=Decimal(0)) for unit in units]+cu_events[cu]
|
||||
steps.append(create_step(f"{cu} {len(cu_events[cu])}", ("/counters", len(ctxs), len(steps)),
|
||||
{"value":get_profile(events, sort_fn=row_tuple), "content_type":"application/octet-stream"}, depth=2))
|
||||
for k in sorted(wave_insts.get(cu, []), key=row_tuple):
|
||||
data = wave_insts[cu][k]
|
||||
steps.append(create_step(k.replace(cu, ""), ("/sqtt-insts", len(ctxs), len(steps)), data, loc=data["loc"], depth=3))
|
||||
ctxs.append({"name":"Counters", "steps":steps})
|
||||
|
||||
def device_sort_fn(k:str) -> tuple[int, str, int]:
|
||||
order = {"GC": 0, "USER": 1, "TINY": 2, "DISK": 999}
|
||||
@@ -303,12 +293,13 @@ def device_sort_fn(k:str) -> tuple[int, str, int]:
|
||||
|
||||
def get_profile(profile:list[ProfileEvent], sort_fn:Callable[[str], Any]=device_sort_fn) -> bytes|None:
|
||||
# start by getting the time diffs
|
||||
device_decoders:dict[str, Callable[[list[ProfileEvent]], None]] = {}
|
||||
for ev in profile:
|
||||
if isinstance(ev, ProfileDeviceEvent):
|
||||
device_ts_diffs[ev.device] = (ev.comp_tdiff,ev.copy_tdiff if ev.copy_tdiff is not None else ev.comp_tdiff)
|
||||
if (d:=ev.device.split(":")[0]) == "AMD": device_decoders[d] = load_counters
|
||||
if isinstance(ev,ProfileDeviceEvent): device_ts_diffs[ev.device] = (ev.comp_tdiff, ev.copy_tdiff if ev.copy_tdiff is not None else ev.comp_tdiff)
|
||||
# load device specific counters
|
||||
device_decoders:dict[str, Callable[[list[ProfileEvent]], None]] = {}
|
||||
for device in device_ts_diffs:
|
||||
d = device.split(":")[0]
|
||||
if d == "AMD": device_decoders[d] = load_sqtt
|
||||
for fxn in device_decoders.values(): fxn(profile)
|
||||
# map events per device
|
||||
dev_events:dict[str, list[tuple[int, int, float, DevEvent]]] = {}
|
||||
@@ -335,7 +326,7 @@ def get_profile(profile:list[ProfileEvent], sort_fn:Callable[[str], Any]=device_
|
||||
index = json.dumps({"strings":list(scache), "dtypeSize":dtype_size, "markers":[{"ts":int(e.ts-start_ts), **e.arg} for e in markers]}).encode()
|
||||
return struct.pack("<IQII", unwrap(end_ts)-start_ts, max(peaks,default=0), len(index), len(ret))+index+b"".join(ret)
|
||||
|
||||
# ** Assembly static analyzers
|
||||
# ** Assembly analyzers
|
||||
|
||||
def get_llvm_mca(asm:str, mtriple:str, mcpu:str) -> dict:
|
||||
target_args = f"-mtriple={mtriple} -mcpu={mcpu}"
|
||||
@@ -355,7 +346,7 @@ def get_llvm_mca(asm:str, mtriple:str, mcpu:str) -> dict:
|
||||
summary = [{"idx":k, "label":resource_labels[k], "value":v} for k,v in instr_usage.pop(len(rows), {}).items()]
|
||||
max_usage = max([sum(v.values()) for i,v in instr_usage.items() if i<len(rows)], default=0)
|
||||
for i,usage in instr_usage.items(): rows[i].append([[k, v, (v/max_usage)*100] for k,v in usage.items()])
|
||||
return {"rows":rows, "cols":["Instruction", "Latency", {"title":"HW Resources", "labels":resource_labels}], "metadata":[summary]}
|
||||
return {"rows":rows, "cols":["Instruction", "Latency", {"title":"HW Resources", "labels":resource_labels}], "summary":summary}
|
||||
|
||||
def get_stdout(f: Callable) -> str:
|
||||
buf = io.StringIO()
|
||||
@@ -364,20 +355,6 @@ def get_stdout(f: Callable) -> str:
|
||||
except Exception: traceback.print_exc(file=buf)
|
||||
return buf.getvalue()
|
||||
|
||||
def amd_readelf(lib:bytes) -> list[dict]:
|
||||
from tinygrad.runtime.support.elf import elf_loader
|
||||
import msgpack
|
||||
_, sections, __ = elf_loader(lib)
|
||||
data = next((s for s in sections if s.name.startswith(".note"))).content
|
||||
namesz, descsz, typ = struct.unpack_from(hdr:="<III", data, 0)
|
||||
offset = (struct.calcsize(hdr)+namesz+3) & -4
|
||||
notes = msgpack.unpackb(data[offset:offset+descsz])
|
||||
keys = {".sgpr_count":"SGPRs", ".vgpr_count":"VGPRs", ".max_flat_workgroup_size":"Max WGP size",
|
||||
".group_segment_fixed_size":"LDS size", ".private_segment_fixed_size":"Scratch size"}
|
||||
return [{"label":label, "value":v} for k,label in keys.items() if (v:=notes["amdhsa.kernels"][0][k]) > 0]
|
||||
|
||||
# ** Main render function to get the complete details about a trace event
|
||||
|
||||
def get_render(i:int, j:int, fmt:str) -> dict:
|
||||
data = ctxs[i]["steps"][j]["data"]
|
||||
if fmt == "uops": return {"src":get_stdout(lambda: print_uops(data.uops or [])), "lang":"txt"}
|
||||
@@ -389,35 +366,9 @@ def get_render(i:int, j:int, fmt:str) -> dict:
|
||||
if isinstance(compiler, LLVMCompiler):
|
||||
return get_llvm_mca(disasm_str, ctypes.string_at(llvm.LLVMGetTargetMachineTriple(tm:=compiler.target_machine)).decode(),
|
||||
ctypes.string_at(llvm.LLVMGetTargetMachineCPU(tm)).decode())
|
||||
metadata:list = []
|
||||
if data.device.startswith("AMD"):
|
||||
with soft_err(lambda err: metadata.append(err)):
|
||||
metadata.append(amd_readelf(compiler.compile(data.src)))
|
||||
return {"src":disasm_str, "lang":"amdgpu" if data.device.startswith("AMD") else None, "metadata":metadata}
|
||||
if fmt == "all-pmc":
|
||||
durations, pmc = data
|
||||
ret:dict = {"cols":{}, "rows":[]}
|
||||
for (prg,_),events in pmc.items():
|
||||
pmc_table = unpack_pmc(events)
|
||||
ret["cols"].update([(r[0], None) for r in pmc_table["rows"]])
|
||||
ret["rows"].append((prg, durations[prg].pop(0), *[r[1] for r in pmc_table["rows"]]))
|
||||
ret["cols"] = ["Kernel", "Duration", *ret["cols"]]
|
||||
return ret
|
||||
if fmt == "prg-pmc": return unpack_pmc(data[0])
|
||||
if fmt == "prg-sqtt":
|
||||
ret = {}
|
||||
if len((steps:=ctxs[i]["steps"])[j+1:]) == 0:
|
||||
with soft_err(lambda err: ret.update(err)):
|
||||
cu_events, units, wave_insts = unpack_sqtt(*data)
|
||||
for cu in sorted(cu_events, key=row_tuple):
|
||||
steps.append(create_step(f"{cu} {len(cu_events[cu])}", ("/cu-sqtt", i, len(steps)), depth=1,
|
||||
data=[ProfilePointEvent(unit, "start", unit, ts=Decimal(0)) for unit in units]+cu_events[cu]))
|
||||
for k in sorted(wave_insts.get(cu, []), key=row_tuple):
|
||||
steps.append(create_step(k.replace(cu, ""), ("/sqtt-insts", i, len(steps)), loc=(data:=wave_insts[cu][k])["loc"], depth=2, data=data))
|
||||
return {**ret, "steps":[{k:v for k,v in s.items() if k != "data"} for s in steps[j+1:]]}
|
||||
if fmt == "cu-sqtt": return {"value":get_profile(data, sort_fn=row_tuple), "content_type":"application/octet-stream"}
|
||||
return {"src":disasm_str, "lang":"x86asm"}
|
||||
if fmt == "sqtt-insts":
|
||||
columns = ["PC", "Instruction", "Hits", "Cycles", "Stall", "Type"]
|
||||
columns = ["PC", "Instruction", "Hits", "Duration", "Stall", "Type"]
|
||||
inst_columns = ["N", "Clk", "Idle", "Dur", "Stall"]
|
||||
# Idle: The total time gap between the completion of previous instruction and the beginning of the current instruction.
|
||||
# The idle time can be caused by:
|
||||
@@ -442,14 +393,14 @@ def get_render(i:int, j:int, fmt:str) -> dict:
|
||||
prev_instr = max(prev_instr, e.time + e.dur)
|
||||
summary = [{"label":"Total Cycles", "value":w.end_time-w.begin_time}, {"label":"SE", "value":w.se}, {"label":"CU", "value":w.cu},
|
||||
{"label":"SIMD", "value":w.simd}, {"label":"Wave ID", "value":w.wave_id}, {"label":"Run number", "value":data["run_number"]}]
|
||||
return {"rows":[tuple(v.values()) for v in rows.values()], "cols":columns, "metadata":[summary]}
|
||||
return {"rows":[tuple(v.values()) for v in rows.values()], "cols":columns, "summary":summary}
|
||||
return data
|
||||
|
||||
# ** HTTP server
|
||||
|
||||
def get_int(query:dict[str, list[str]], k:str) -> int: return int(query.get(k,["0"])[0])
|
||||
|
||||
class Handler(HTTPRequestHandler):
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
ret, status_code, content_type = b"", 200, "text/html"
|
||||
|
||||
@@ -464,7 +415,7 @@ class Handler(HTTPRequestHandler):
|
||||
elif (query:=parse_qs(url.query)):
|
||||
i, j = get_int(query, "ctx"), get_int(query, "step")
|
||||
if (fmt:=url.path.lstrip("/")) == "rewrites":
|
||||
try: return self.stream_json(get_full_rewrite(trace.rewrites[i][j]))
|
||||
try: return self.stream_json(get_full_rewrite(trace.rewrites[i][j], i))
|
||||
except (KeyError, IndexError): status_code = 404
|
||||
else:
|
||||
render_src = get_render(i, j, fmt)
|
||||
@@ -476,7 +427,25 @@ class Handler(HTTPRequestHandler):
|
||||
elif url.path == "/get_profile" and profile_ret: ret, content_type = profile_ret, "application/octet-stream"
|
||||
else: status_code = 404
|
||||
|
||||
return self.send_data(ret, content_type, status_code)
|
||||
# send response
|
||||
self.send_response(status_code)
|
||||
self.send_header('Content-Type', content_type)
|
||||
self.send_header('Content-Length', str(len(ret)))
|
||||
self.end_headers()
|
||||
return self.wfile.write(ret)
|
||||
|
||||
def stream_json(self, source:Generator):
|
||||
try:
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", "text/event-stream")
|
||||
self.send_header("Cache-Control", "no-cache")
|
||||
self.end_headers()
|
||||
for r in source:
|
||||
self.wfile.write(f"data: {json.dumps(r)}\n\n".encode("utf-8"))
|
||||
self.wfile.flush()
|
||||
self.wfile.write("data: END\n\n".encode("utf-8"))
|
||||
# pass if client closed connection
|
||||
except (BrokenPipeError, ConnectionResetError): return
|
||||
|
||||
# ** main loop
|
||||
|
||||
@@ -493,6 +462,9 @@ def load_pickle(path:pathlib.Path, default:T) -> T:
|
||||
if not path.exists(): return default
|
||||
with path.open("rb") as f: return pickle.load(f)
|
||||
|
||||
# NOTE: using HTTPServer forces a potentially slow socket.getfqdn
|
||||
class TCPServerWithReuse(socketserver.TCPServer): allow_reuse_address = True
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--kernels', type=pathlib.Path, help='Path to kernels', default=pathlib.Path(temp("rewrites.pkl", append_user=True)))
|
||||
@@ -507,12 +479,13 @@ if __name__ == "__main__":
|
||||
st = time.perf_counter()
|
||||
print("*** viz is starting")
|
||||
|
||||
ctxs:list[dict] = get_rewrites(trace:=load_pickle(args.kernels, default=RewriteTrace([], [], {})))
|
||||
ctxs = get_rewrites(trace:=load_pickle(args.kernels, default=RewriteTrace([], [], {})))
|
||||
profile_ret = get_profile(load_pickle(args.profile, default=[]))
|
||||
|
||||
server = TCPServerWithReuse(('', PORT), Handler)
|
||||
reloader_thread = threading.Thread(target=reloader)
|
||||
reloader_thread.start()
|
||||
print(f"*** started viz on {HOST}:{PORT}")
|
||||
print(colored(f"*** ready in {(time.perf_counter()-st)*1e3:4.2f}ms", "green"), flush=True)
|
||||
if len(getenv("BROWSER", "")) > 0: webbrowser.open(f"{HOST}:{PORT}")
|
||||
try: server.serve_forever()
|
||||
|
||||
Reference in New Issue
Block a user