mirror of
https://github.com/tinygrad/tinygrad.git
synced 2026-08-16 17:38:26 +00:00
Compare commits
129
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d8a2bd212 | ||
|
|
8e8fec408e | ||
|
|
249553a119 | ||
|
|
f46bc31156 | ||
|
|
cc5e6323ac | ||
|
|
18cfb54736 | ||
|
|
2d53029be3 | ||
|
|
2a9bd12700 | ||
|
|
63a931ff76 | ||
|
|
677db34eba | ||
|
|
712c7a6448 | ||
|
|
9d7a17ee39 | ||
|
|
474a631877 | ||
|
|
da0aa57a3b | ||
|
|
320ed78803 | ||
|
|
c1838c71fc | ||
|
|
5110409339 | ||
|
|
92170d0ff1 | ||
|
|
423b76a852 | ||
|
|
9d6cf3472e | ||
|
|
310da2a201 | ||
|
|
c14033e10f | ||
|
|
1655fdb6de | ||
|
|
903eec3754 | ||
|
|
3a42680e22 | ||
|
|
1f8b24a6b9 | ||
|
|
4c0f4226b9 | ||
|
|
1f648bb1ba | ||
|
|
054477a44f | ||
|
|
cb29265f23 | ||
|
|
fdfe83880b | ||
|
|
a6c9b4ff6a | ||
|
|
114bb94c55 | ||
|
|
87c248eafa | ||
|
|
0de1b24154 | ||
|
|
dabb02767f | ||
|
|
e1051d00d7 | ||
|
|
fa3def2f12 | ||
|
|
895ec7417e | ||
|
|
a74f6020d5 | ||
|
|
647fde64e6 | ||
|
|
1313250e0d | ||
|
|
de3593957f | ||
|
|
1220072328 | ||
|
|
26ccbf7040 | ||
|
|
c46f608703 | ||
|
|
4043489803 | ||
|
|
0251a8e628 | ||
|
|
0901a40685 | ||
|
|
91e289cb14 | ||
|
|
1058748440 | ||
|
|
58d85d4bab | ||
|
|
9dbc550692 | ||
|
|
ebcdf68bab | ||
|
|
0b0ea4981c | ||
|
|
9dcd52287a | ||
|
|
cb38c704c3 | ||
|
|
8919c994b7 | ||
|
|
ac7559e33d | ||
|
|
050682ab40 | ||
|
|
0dc2ff431d | ||
|
|
56b2540349 | ||
|
|
ab7df42c78 | ||
|
|
986d113024 | ||
|
|
05ccc69248 | ||
|
|
90e5752199 | ||
|
|
8e17bd6791 | ||
|
|
b5309a5043 | ||
|
|
3d82b83cec | ||
|
|
a91f00925b | ||
|
|
7711bbac7f | ||
|
|
6fdbd03104 | ||
|
|
bd88a72149 | ||
|
|
957cf717e7 | ||
|
|
fc19ea76b5 | ||
|
|
385618d45b | ||
|
|
fba4535289 | ||
|
|
225eb1500f | ||
|
|
1a72ac16a6 | ||
|
|
79055ddb8b | ||
|
|
0c9fbf87e1 | ||
|
|
f2221130bb | ||
|
|
be72b78dcb | ||
|
|
e4fbde5b3b | ||
|
|
1a332afa76 | ||
|
|
a438c277de | ||
|
|
722e7a16ed | ||
|
|
1afa3c0877 | ||
|
|
46cb65e692 | ||
|
|
9c59b3d19e | ||
|
|
a647c9eca6 | ||
|
|
06e39a88a9 | ||
|
|
805de27e07 | ||
|
|
05294bc648 | ||
|
|
5623e765c8 | ||
|
|
331f70aa75 | ||
|
|
583560ab72 | ||
|
|
8e8e53c886 | ||
|
|
e4fead8a86 | ||
|
|
8894a5409d | ||
|
|
6d3385c284 | ||
|
|
b637093be9 | ||
|
|
98e9e73286 | ||
|
|
e7e1935225 | ||
|
|
33773fda87 | ||
|
|
e2cee64050 | ||
|
|
646372490c | ||
|
|
a37f221e44 | ||
|
|
f63ded5817 | ||
|
|
50a443f558 | ||
|
|
9bb17c53ea | ||
|
|
55be95da15 | ||
|
|
cabd4add48 | ||
|
|
13efdf8c31 | ||
|
|
295600dc5a | ||
|
|
a9ed241172 | ||
|
|
c70b06ec19 | ||
|
|
8f0e747b3a | ||
|
|
6372c95094 | ||
|
|
61625a3898 | ||
|
|
acbe6361ab | ||
|
|
ef42334239 | ||
|
|
e8844853ed | ||
|
|
5b823af696 | ||
|
|
df53c62a9f | ||
|
|
d37e1fe065 | ||
|
|
22c08b470c | ||
|
|
567066f51f | ||
|
|
6c5fa349e1 |
@@ -61,7 +61,7 @@ runs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.venv
|
||||
key: venv-${{ runner.os }}-python-${{ steps.setup-python.outputs.python-version }}-${{ inputs.deps }}-${{ inputs.pydeps }}-${{ hashFiles('**/pyproject.toml') }}-${{ env.CACHE_VERSION }}
|
||||
key: venv-${{ runner.os }}-python-${{ steps.setup-python.outputs.python-version }}-${{ inputs.deps }}-${{ inputs.pydeps }}-${{ env.CACHE_VERSION }}
|
||||
|
||||
# **** Caching downloads ****
|
||||
|
||||
@@ -221,7 +221,7 @@ runs:
|
||||
sudo mkdir -p /usr/local/lib
|
||||
curl -s -H "Authorization: token $GH_TOKEN" curl -s https://api.github.com/repos/nimlgen/amdcomgr_dylib/releases/latest | \
|
||||
jq -r '.assets[] | select(.name == "libamd_comgr.dylib").browser_download_url' | \
|
||||
sudo xargs curl -L -o /usr/local/lib/libamd_comgr.dylib
|
||||
sudo xargs curl -fL -o /usr/local/lib/libamd_comgr.dylib
|
||||
cargo build --release --manifest-path ./extra/remu/Cargo.toml
|
||||
|
||||
# **** gpuocelot ****
|
||||
@@ -278,7 +278,7 @@ runs:
|
||||
if: inputs.webgpu == 'true' && runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
sudo curl -L https://github.com/wpmed92/pydawn/releases/download/v0.1.6/libwebgpu_dawn.so -o /usr/local/lib/libwebgpu_dawn.so
|
||||
sudo curl -fL https://github.com/wpmed92/pydawn/releases/download/v0.1.6/libwebgpu_dawn.so -o /usr/local/lib/libwebgpu_dawn.so
|
||||
sudo ldconfig
|
||||
- name: Install WebGPU dawn (macOS)
|
||||
if: inputs.webgpu == 'true' && runner.os == 'macOS'
|
||||
@@ -298,7 +298,7 @@ runs:
|
||||
- name: Install mesa (linux)
|
||||
if: inputs.mesa == 'true' && runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: sudo curl -L https://github.com/sirhcm/tinymesa/releases/download/tinymesa-32dc66c/libtinymesa_cpu-mesa-25.2.4-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
|
||||
|
||||
@@ -13,9 +13,11 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'tinygrad/runtime/autogen/**/*'
|
||||
- 'tinygrad/runtime/support/autogen.py'
|
||||
workflow_dispatch:
|
||||
paths:
|
||||
- 'tinygrad/runtime/autogen/**/*'
|
||||
- 'tinygrad/runtime/support/autogen.py'
|
||||
|
||||
jobs:
|
||||
autogen:
|
||||
@@ -34,7 +36,7 @@ jobs:
|
||||
llvm: 'true'
|
||||
webgpu: 'true'
|
||||
mesa: 'true'
|
||||
pydeps: 'clang>=20 pyyaml mako'
|
||||
pydeps: 'pyyaml mako'
|
||||
- name: Install autogen support packages
|
||||
run: sudo apt-get install -y --no-install-recommends libclang-20-dev llvm-20-dev hip-dev libusb-1.0-0-dev
|
||||
- name: Verify OpenCL autogen
|
||||
@@ -132,8 +134,8 @@ jobs:
|
||||
diff /tmp/mesa.py.bak tinygrad/runtime/autogen/mesa.py
|
||||
- name: Verify libclang autogen
|
||||
run: |
|
||||
mv tinygrad/runtime/autogen/libclang.py /tmp/libclang.py.bak
|
||||
python3 -c "from tinygrad.runtime.autogen import libclang"
|
||||
cp tinygrad/runtime/autogen/libclang.py /tmp/libclang.py.bak
|
||||
REGEN=1 python3 -c "from tinygrad.runtime.autogen import libclang"
|
||||
diff /tmp/libclang.py.bak tinygrad/runtime/autogen/libclang.py
|
||||
autogen-mac:
|
||||
name: In-tree Autogen (macos)
|
||||
@@ -146,7 +148,6 @@ jobs:
|
||||
uses: ./.github/actions/setup-tinygrad
|
||||
with:
|
||||
llvm: 'true'
|
||||
pydeps: 'clang>=20'
|
||||
- name: Verify macos autogen
|
||||
run: |
|
||||
mv tinygrad/runtime/autogen/metal.py /tmp/metal.py.bak
|
||||
@@ -161,8 +162,6 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Environment
|
||||
uses: ./.github/actions/setup-tinygrad
|
||||
with:
|
||||
pydeps: 'clang>=20'
|
||||
- name: Install autogen support packages
|
||||
run: |
|
||||
wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | gpg --dearmor | sudo tee /etc/apt/keyrings/rocm.gpg > /dev/null
|
||||
|
||||
@@ -56,15 +56,15 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: base
|
||||
- name: Set up Python 3.10
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: '3.12'
|
||||
- name: Count Line Diff
|
||||
run: |
|
||||
pip install tabulate
|
||||
BASE="$GITHUB_WORKSPACE/base"
|
||||
PR="$GITHUB_WORKSPACE/pr"
|
||||
pip install tabulate $BASE
|
||||
cp "$BASE/sz.py" .
|
||||
echo "loc_content<<EOF" >> "$GITHUB_ENV"
|
||||
python sz.py "$BASE" "$PR" >> "$GITHUB_ENV"
|
||||
|
||||
+65
-60
@@ -86,65 +86,67 @@ jobs:
|
||||
clang -O2 recognize.c -lm -o recognize
|
||||
cat test/models/efficientnet/Chicken.jpg | ./recognize | grep cock
|
||||
|
||||
# TODO: fix the torch backend and reenable
|
||||
# torchbackend:
|
||||
# name: Torch Backend Tests
|
||||
# runs-on: ubuntu-latest
|
||||
# timeout-minutes: 15
|
||||
# steps:
|
||||
# - name: Checkout Code
|
||||
# uses: actions/checkout@v4
|
||||
# - name: Setup Environment
|
||||
# uses: ./.github/actions/setup-tinygrad
|
||||
# with:
|
||||
# key: torch-backend-pillow-torchvision-et-pt
|
||||
# deps: testing_minimal
|
||||
# pydeps: "pillow torchvision expecttest"
|
||||
# llvm: 'true'
|
||||
# - name: Install ninja
|
||||
# run: |
|
||||
# sudo apt update || true
|
||||
# sudo apt install -y --no-install-recommends ninja-build
|
||||
# - name: Lint with ruff
|
||||
# run: |
|
||||
# pip3 install --upgrade --force-reinstall ruff==0.11.0
|
||||
# python3 -m ruff check extra/torch_backend/backend.py
|
||||
# - name: Test one op
|
||||
# run: FORWARD_ONLY=1 TINY_BACKEND=1 python3 test/test_ops.py TestOps.test_add
|
||||
# - name: Test ResNet-18
|
||||
# run: DEBUG=2 python3 extra/torch_backend/example.py
|
||||
# - name: My (custom) tests
|
||||
# run: python3 extra/torch_backend/test.py
|
||||
# - name: Test one op in torch tests
|
||||
# run: DEBUG=2 python3 extra/torch_backend/torch_tests.py TestTinyBackendPRIVATEUSE1.test_unary_log_tiny_float32
|
||||
# - name: Test Ops with TINY_BACKEND
|
||||
# run: CPU=1 CPU_LLVM=1 LLVMOPT=0 TINY_BACKEND=1 python3 -m pytest -n auto test/test_ops.py --durations=20
|
||||
# - name: Test in-place operations on views
|
||||
# run: TORCH_DEBUG=1 python3 extra/torch_backend/test_inplace.py
|
||||
# - name: Test multi-gpu
|
||||
# run: CPU=1 CPU_LLVM=1 GPUS=4 TORCH_DEBUG=1 python3 extra/torch_backend/test_multigpu.py
|
||||
torchbackend:
|
||||
name: Torch Backend Tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Environment
|
||||
uses: ./.github/actions/setup-tinygrad
|
||||
with:
|
||||
key: torch-backend-pillow-torchvision-et-pt
|
||||
deps: testing_minimal
|
||||
pydeps: "pillow torchvision expecttest"
|
||||
llvm: 'true'
|
||||
- name: Install ninja
|
||||
run: |
|
||||
sudo apt update || true
|
||||
sudo apt install -y --no-install-recommends ninja-build
|
||||
- name: Lint with ruff
|
||||
run: |
|
||||
pip3 install --upgrade --force-reinstall ruff==0.11.0
|
||||
python3 -m ruff check extra/torch_backend/backend.py
|
||||
- name: Test one op
|
||||
run: FORWARD_ONLY=1 TINY_BACKEND=1 python3 test/test_ops.py TestOps.test_add
|
||||
- name: Test ResNet-18
|
||||
run: DEBUG=2 python3 extra/torch_backend/example.py
|
||||
- name: My (custom) tests
|
||||
run: python3 extra/torch_backend/test.py
|
||||
- name: Test one op in torch tests
|
||||
run: DEBUG=2 python3 extra/torch_backend/torch_tests.py TestTinyBackendPRIVATEUSE1.test_unary_log_tiny_float32
|
||||
- name: Test Ops with TINY_BACKEND
|
||||
run: CPU=1 CPU_LLVM=1 LLVMOPT=0 TINY_BACKEND=1 python3 -m pytest -n auto test/test_ops.py --durations=20
|
||||
- name: Test in-place operations on views
|
||||
run: TORCH_DEBUG=1 python3 extra/torch_backend/test_inplace.py
|
||||
- name: Test multi-gpu
|
||||
run: CPU=1 CPU_LLVM=1 GPUS=4 TORCH_DEBUG=1 python3 extra/torch_backend/test_multigpu.py
|
||||
- name: Test kernel fusion
|
||||
run: python3 extra/torch_backend/test_kernel_fusion.py
|
||||
|
||||
# torchbackendmore:
|
||||
# name: Torch Backend Tests More
|
||||
# runs-on: ubuntu-latest
|
||||
# timeout-minutes: 15
|
||||
# steps:
|
||||
# - name: Checkout Code
|
||||
# uses: actions/checkout@v4
|
||||
# - name: Setup Environment
|
||||
# uses: ./.github/actions/setup-tinygrad
|
||||
# with:
|
||||
# key: torch-backend-pillow-torchvision-et-pt
|
||||
# deps: testing_minimal
|
||||
# llvm: 'true'
|
||||
# - name: Install ninja
|
||||
# run: |
|
||||
# sudo apt update || true
|
||||
# sudo apt install -y --no-install-recommends ninja-build
|
||||
# - name: Test beautiful_mnist in torch with TINY_BACKEND
|
||||
# run: STEPS=20 CPU=1 TARGET_EVAL_ACC_PCT=90.0 TINY_BACKEND=1 python3 examples/other_mnist/beautiful_mnist_torch.py
|
||||
# - name: Test some torch tests (expect failure)
|
||||
# run: python3 -m pytest extra/torch_backend/torch_tests.py -v --tb=no || true
|
||||
|
||||
torchbackendmore:
|
||||
name: Torch Backend Tests More
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Environment
|
||||
uses: ./.github/actions/setup-tinygrad
|
||||
with:
|
||||
key: torch-backend-pillow-torchvision-et-pt
|
||||
deps: testing_minimal
|
||||
llvm: 'true'
|
||||
- name: Install ninja
|
||||
run: |
|
||||
sudo apt update || true
|
||||
sudo apt install -y --no-install-recommends ninja-build
|
||||
- name: Test beautiful_mnist in torch with TINY_BACKEND
|
||||
run: STEPS=20 CPU=1 TARGET_EVAL_ACC_PCT=90.0 TINY_BACKEND=1 python3 examples/other_mnist/beautiful_mnist_torch.py
|
||||
- name: Test some torch tests (expect failure)
|
||||
run: python3 -m pytest extra/torch_backend/torch_tests.py -v --tb=no || true
|
||||
|
||||
bepython:
|
||||
name: Python Backend
|
||||
@@ -287,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 < 18500 lines
|
||||
run: MAX_LINE_COUNT=18500 python sz.py
|
||||
- name: Repo line count < 19000 lines
|
||||
run: MAX_LINE_COUNT=19000 python sz.py
|
||||
|
||||
spec:
|
||||
strategy:
|
||||
@@ -306,6 +308,7 @@ jobs:
|
||||
with:
|
||||
key: spec-unit
|
||||
deps: testing_unit
|
||||
python-version: '3.14'
|
||||
- name: Test SPEC=2
|
||||
run: IGNORE_OOB=0 SPEC=2 PYTHONPATH="." pytest --maxfail=10 -n auto --durations=30 --ignore=test/models --ignore test/unit/test_hashing.py --timeout 60 -k "not test_setitem_big" --splits 2 --group ${{ matrix.group }}
|
||||
|
||||
@@ -323,6 +326,8 @@ jobs:
|
||||
deps: testing_unit
|
||||
- name: Fuzz Test symbolic
|
||||
run: python test/external/fuzz_symbolic.py
|
||||
- name: Fuzz Test symbolic (symbolic divisors)
|
||||
run: python test/external/fuzz_symbolic_symbolic_div.py
|
||||
- name: Fuzz Test fast idiv
|
||||
run: python test/external/fuzz_fast_idiv.py
|
||||
- name: Fuzz Test shape ops
|
||||
|
||||
-293
@@ -1,293 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# this file is a "ramp" for people new to tinygrad to think about how to approach it
|
||||
# it is runnable and editable.
|
||||
# whenever you see stuff like DEBUG=2 or CPU=1 discussed, these are environment variables
|
||||
# in a unix shell like bash `DEBUG=2 CPU=1 python docs/ramp.py`
|
||||
|
||||
# this pip installs tinygrad master for the system
|
||||
# the -e allows you to edit the tinygrad folder and update system tinygrad
|
||||
# tinygrad is pure Python, so you are encouraged to do this
|
||||
# git pull in the tinygrad directory will also get you the latest
|
||||
"""
|
||||
git clone https://github.com/tinygrad/tinygrad.git
|
||||
cd tinygrad
|
||||
python3 -m pip install -e .
|
||||
"""
|
||||
|
||||
# %% ********
|
||||
print("******* PART 1 *******")
|
||||
|
||||
# we start with a Device.
|
||||
# a Device is where Tensors are stored and compute is run
|
||||
# tinygrad autodetects the best device on your system and makes it the DEFAULT
|
||||
from tinygrad import Device
|
||||
print(Device.DEFAULT) # on Mac, you can see this prints METAL
|
||||
|
||||
# now, lets create a Tensor
|
||||
from tinygrad import Tensor, dtypes
|
||||
t = Tensor([1,2,3,4])
|
||||
|
||||
# you can see this Tensor is on the DEFAULT device with int dtype and shape (4,)
|
||||
assert t.device == Device.DEFAULT
|
||||
assert t.dtype == dtypes.int
|
||||
assert t.shape == (4,)
|
||||
|
||||
# unlike in torch, if we print it, it doesn't print the contents
|
||||
# this is because tinygrad is lazy
|
||||
# this Tensor has not been computed yet
|
||||
print(t)
|
||||
# <Tensor <UOp METAL (4,) int (<Ops.COPY: 7>, None)> on METAL with grad None>
|
||||
|
||||
# the ".uop" property on Tensor contains the specification of how to compute it
|
||||
print(t.uop)
|
||||
"""
|
||||
UOp(Ops.COPY, dtypes.int, arg=None, src=(
|
||||
UOp(Ops.BUFFER, dtypes.int, arg=4, src=(
|
||||
UOp(Ops.UNIQUE, dtypes.void, arg=0, src=()),
|
||||
UOp(Ops.DEVICE, dtypes.void, arg='PYTHON', src=()),)),
|
||||
UOp(Ops.DEVICE, dtypes.void, arg='METAL', src=()),))
|
||||
"""
|
||||
# as you can see, it's specifying a copy from PYTHON device
|
||||
# which is where the [1,2,3,4] array lives
|
||||
|
||||
# UOps are the specification language in tinygrad
|
||||
# they are immutable and form a DAG
|
||||
# they have a "Ops", a "dtype", a tuple of srcs (parents), and an arg
|
||||
|
||||
t.realize()
|
||||
# if we want to "realize" a tensor, we can with the "realize" method
|
||||
# now when we look at the uop, it's changed
|
||||
print(t.uop)
|
||||
"""
|
||||
UOp(Ops.BUFFER, dtypes.int, arg=4, src=(
|
||||
UOp(Ops.UNIQUE, dtypes.void, arg=1, src=()),
|
||||
UOp(Ops.DEVICE, dtypes.void, arg='METAL', src=()),))
|
||||
"""
|
||||
# the copy was actually run, and now the "uop" of the Tensor is just a BUFFER
|
||||
# if you run this script with DEBUG=2 in the environment, you can see the copy happen
|
||||
# *** METAL 1 copy 16, METAL <- PYTHON ...
|
||||
|
||||
# now let's do some compute
|
||||
# we look at the uop to see the specification of the compute
|
||||
t_times_2 = t * 2
|
||||
print(t_times_2.uop)
|
||||
"""
|
||||
UOp(Ops.MUL, dtypes.int, arg=None, src=(
|
||||
UOp(Ops.BUFFER, dtypes.int, arg=4, src=(
|
||||
UOp(Ops.UNIQUE, dtypes.void, arg=1, src=()),
|
||||
x2:=UOp(Ops.DEVICE, dtypes.void, arg='METAL', src=()),)),
|
||||
UOp(Ops.EXPAND, dtypes.int, arg=(4,), src=(
|
||||
UOp(Ops.RESHAPE, dtypes.int, arg=(1,), src=(
|
||||
UOp(Ops.CONST, dtypes.int, arg=2, src=(
|
||||
UOp(Ops.VIEW, dtypes.void, arg=ShapeTracker(views=(View(shape=(), strides=(), offset=0, mask=None, contiguous=True),)), src=(
|
||||
x2,)),)),)),)),))
|
||||
"""
|
||||
# the BUFFER from above is being multiplied by a CONST 2
|
||||
# it's RESHAPEd and EXPANDed to broadcast the CONST to the BUFFER
|
||||
|
||||
# we can check the result with
|
||||
assert t_times_2.tolist() == [2, 4, 6, 8]
|
||||
|
||||
# UOps are both immutable and globally unique
|
||||
# if i multiply the Tensor by 4 twice, these result Tensors will have the same uop specification
|
||||
t_times_4_try_1 = t * 4
|
||||
t_times_4_try_2 = t * 4
|
||||
assert t_times_4_try_1.uop is t_times_4_try_2.uop
|
||||
# the specification isn't just the same, it's the exact same Python object
|
||||
assert t_times_4_try_1 is not t_times_4_try_2
|
||||
# the Tensor is a different Python object
|
||||
|
||||
# if we realize `t_times_4_try_1` ...
|
||||
t_times_4_try_1.realize()
|
||||
print(t_times_4_try_2.uop)
|
||||
"""
|
||||
UOp(Ops.BUFFER, dtypes.int, arg=4, src=(
|
||||
UOp(Ops.UNIQUE, dtypes.void, arg=4, src=()),
|
||||
UOp(Ops.DEVICE, dtypes.void, arg='METAL', src=()),))
|
||||
"""
|
||||
# ... `t_times_4_try_2` also becomes the same BUFFER
|
||||
assert t_times_4_try_1.uop is t_times_4_try_2.uop
|
||||
# so this print doesn't require any computation, just a copy back to the CPU so we can print it
|
||||
print("** only the copy start")
|
||||
print(t_times_4_try_2.tolist()) # [4, 8, 12, 16]
|
||||
print("** only the copy end")
|
||||
# you can confirm this with DEBUG=2, seeing what's printed in between the "**" prints
|
||||
|
||||
# tinygrad has an auto differentiation engine that operates according to these same principles
|
||||
# the derivative of "log(x)" is "1/x", and you can see this on line 20 of gradient.py
|
||||
t_float = Tensor([3.0])
|
||||
t_log = t_float.log()
|
||||
t_log_grad, = t_log.sum().gradient(t_float)
|
||||
# due to how log is implemented, this gradient contains a lot of UOps
|
||||
print(t_log_grad.uop)
|
||||
# ...not shown here...
|
||||
# but if you run with DEBUG=4 (CPU=1 used here for simpler code), you can see the generated code
|
||||
"""
|
||||
void E_(float* restrict data0, float* restrict data1) {
|
||||
float val0 = *(data1+0);
|
||||
*(data0+0) = (1/val0);
|
||||
}
|
||||
"""
|
||||
# the derivative is close to 1/3
|
||||
assert (t_log_grad.item() - 1/3) < 1e-6
|
||||
|
||||
# %% ********
|
||||
print("******* PART 2 *******")
|
||||
|
||||
# we redefine the same t here so this cell can run on it's own
|
||||
from tinygrad import Tensor
|
||||
t = Tensor([1,2,3,4])
|
||||
|
||||
# what's above gives you enough of an understanding to go use tinygrad as a library
|
||||
# however, a lot of the beauty of tinygrad is in how easy it is to interact with the internals
|
||||
# NOTE: the APIs here are subject to change
|
||||
|
||||
t_plus_3_plus_4 = t + 3 + 4
|
||||
print(t_plus_3_plus_4.uop)
|
||||
"""
|
||||
UOp(Ops.ADD, dtypes.int, arg=None, src=(
|
||||
UOp(Ops.ADD, dtypes.int, arg=None, src=(
|
||||
UOp(Ops.BUFFER, dtypes.int, arg=4, src=(
|
||||
UOp(Ops.UNIQUE, dtypes.void, arg=1, src=()),
|
||||
x3:=UOp(Ops.DEVICE, dtypes.void, arg='CPU', src=()),)),
|
||||
UOp(Ops.EXPAND, dtypes.int, arg=(4,), src=(
|
||||
UOp(Ops.RESHAPE, dtypes.int, arg=(1,), src=(
|
||||
UOp(Ops.CONST, dtypes.int, arg=3, src=(
|
||||
x7:=UOp(Ops.VIEW, dtypes.void, arg=ShapeTracker(views=(View(shape=(), strides=(), offset=0, mask=None, contiguous=True),)), src=(
|
||||
x3,)),)),)),)),)),
|
||||
UOp(Ops.EXPAND, dtypes.int, arg=(4,), src=(
|
||||
UOp(Ops.RESHAPE, dtypes.int, arg=(1,), src=(
|
||||
UOp(Ops.CONST, dtypes.int, arg=4, src=(
|
||||
x7,)),)),)),))
|
||||
"""
|
||||
# you can see it's adding both 3 and 4
|
||||
|
||||
# but by the time we are actually running the code, it's adding 7
|
||||
# `kernelize` will simplify and group the operations in the graph into kernels
|
||||
t_plus_3_plus_4.kernelize()
|
||||
print(t_plus_3_plus_4.uop)
|
||||
"""
|
||||
UOp(Ops.ASSIGN, dtypes.int, arg=None, src=(
|
||||
x0:=UOp(Ops.BUFFER, dtypes.int, arg=4, src=(
|
||||
UOp(Ops.UNIQUE, dtypes.void, arg=7, src=()),
|
||||
x2:=UOp(Ops.DEVICE, dtypes.void, arg='CPU', src=()),)),
|
||||
UOp(Ops.KERNEL, dtypes.void, arg=<Kernel 12 SINK(<Ops.STORE: 48>,) (__add__,)>, src=(
|
||||
x0,
|
||||
UOp(Ops.BUFFER, dtypes.int, arg=4, src=(
|
||||
UOp(Ops.UNIQUE, dtypes.void, arg=1, src=()),
|
||||
x2,)),)),))
|
||||
"""
|
||||
# ASSIGN has two srcs, src[0] is the BUFFER that's assigned to, and src[1] is the thing to assign
|
||||
# src[1] is the GPU Kernel that's going to be run
|
||||
# we can get the ast of the Kernel as follows
|
||||
kernel_ast = t_plus_3_plus_4.uop.src[1].arg.ast
|
||||
|
||||
# almost everything in tinygrad functions as a rewrite of the UOps
|
||||
# the codegen rewrites the ast to a simplified form ready for "rendering"
|
||||
from tinygrad.codegen import full_rewrite_to_sink
|
||||
rewritten_ast = full_rewrite_to_sink(kernel_ast)
|
||||
print(rewritten_ast)
|
||||
"""
|
||||
UOp(Ops.SINK, dtypes.void, arg=None, src=(
|
||||
UOp(Ops.STORE, dtypes.void, arg=None, src=(
|
||||
UOp(Ops.INDEX, dtypes.int.ptr(4), arg=None, src=(
|
||||
UOp(Ops.DEFINE_GLOBAL, dtypes.int.ptr(4), arg=0, src=()),
|
||||
x3:=UOp(Ops.SPECIAL, dtypes.int, arg=('gidx0', 4), src=()),)),
|
||||
UOp(Ops.ADD, dtypes.int, arg=None, src=(
|
||||
UOp(Ops.LOAD, dtypes.int, arg=None, src=(
|
||||
UOp(Ops.INDEX, dtypes.int.ptr(4), arg=None, src=(
|
||||
UOp(Ops.DEFINE_GLOBAL, dtypes.int.ptr(4), arg=1, src=()),
|
||||
x3,)),)),
|
||||
UOp(Ops.CONST, dtypes.int, arg=7, src=()),)),)),))
|
||||
"""
|
||||
# you can see at this point we are adding 7, not 3 and 4
|
||||
|
||||
# with DEBUG=4, we can see the code.
|
||||
# since optimizations are on, it UPCASTed the operation, explicitly writing out all 4 +7s
|
||||
t_plus_3_plus_4.realize()
|
||||
"""
|
||||
void E_4n2(int* restrict data0, int* restrict data1) {
|
||||
int val0 = *(data1+0);
|
||||
int val1 = *(data1+1);
|
||||
int val2 = *(data1+2);
|
||||
int val3 = *(data1+3);
|
||||
*(data0+0) = (val0+7);
|
||||
*(data0+1) = (val1+7);
|
||||
*(data0+2) = (val2+7);
|
||||
*(data0+3) = (val3+7);
|
||||
}
|
||||
"""
|
||||
# the function name E_4n2 is "E" for elementwise op (as opposed to "r" for reduce op)
|
||||
# "4" for the size, and "n2" for name deduping (it's the 3rd function with the same E and 4 in this session)
|
||||
# when you print the name with DEBUG=2, you'll see the 4 is yellow, meaning that it's upcasted
|
||||
# if you run with NOOPT=1 ...
|
||||
"""
|
||||
void E_4n2(int* restrict data0, int* restrict data1) {
|
||||
for (int ridx0 = 0; ridx0 < 4; ridx0++) {
|
||||
int val0 = *(data1+ridx0);
|
||||
*(data0+ridx0) = (val0+7);
|
||||
}
|
||||
}
|
||||
"""
|
||||
# ... you get this unoptimized code with a loop and the 4 is blue (for global). the color code is in kernel.py
|
||||
|
||||
# %% ********
|
||||
print("******* PART 3 *******")
|
||||
|
||||
# now, we go even lower and understand UOps better and how the graph rewrite engine works.
|
||||
# it's much simpler than what's in LLVM or MLIR
|
||||
|
||||
from tinygrad import dtypes
|
||||
from tinygrad.uop.ops import UOp, Ops
|
||||
|
||||
# first, we'll construct some const UOps
|
||||
a = UOp(Ops.CONST, dtypes.int, arg=2)
|
||||
b = UOp(Ops.CONST, dtypes.int, arg=2)
|
||||
|
||||
# if you have been paying attention, you should know these are the same Python object
|
||||
assert a is b
|
||||
|
||||
# UOps support normal Python math operations, so a_plus_b expresses the spec for 2 + 2
|
||||
a_plus_b = a + b
|
||||
print(a_plus_b)
|
||||
"""
|
||||
UOp(Ops.ADD, dtypes.int, arg=None, src=(
|
||||
x0:=UOp(Ops.CONST, dtypes.int, arg=2, src=()),
|
||||
x0,))
|
||||
"""
|
||||
|
||||
# we could actually render this 2+2 into a language like c and run it
|
||||
# or, we can use tinygrad's graph rewrite engine to "constant fold"
|
||||
|
||||
from tinygrad.uop.ops import graph_rewrite, UPat, PatternMatcher
|
||||
|
||||
# a `PatternMatcher` is a list of tuples. for each element in the list:
|
||||
# [0] is the pattern to match, and [1] is the function to run.
|
||||
# this function can return either a UOp to replace the pattern with, or None to not replace
|
||||
simple_pm = PatternMatcher([
|
||||
(UPat(Ops.ADD, src=(UPat(Ops.CONST, name="c1"), UPat(Ops.CONST, name="c2"))),
|
||||
lambda c1,c2: UOp(Ops.CONST, dtype=c1.dtype, arg=c1.arg+c2.arg)),
|
||||
])
|
||||
# this pattern matches the addition of two CONST and rewrites it into a single CONST UOp
|
||||
|
||||
# to actually apply the pattern to a_plus_b, we use graph_rewrite
|
||||
a_plus_b_simplified = graph_rewrite(a_plus_b, simple_pm)
|
||||
print(a_plus_b_simplified)
|
||||
"""
|
||||
UOp(Ops.CONST, dtypes.int, arg=4, src=())
|
||||
"""
|
||||
# 2+2 is in fact, 4
|
||||
|
||||
# we can also use syntactic sugar to write the pattern nicer
|
||||
simpler_pm = PatternMatcher([
|
||||
(UPat.cvar("c1")+UPat.cvar("c2"), lambda c1,c2: c1.const_like(c1.arg+c2.arg))
|
||||
])
|
||||
assert graph_rewrite(a_plus_b, simple_pm) is graph_rewrite(a_plus_b, simpler_pm)
|
||||
# note again the use of is, UOps are immutable and globally unique
|
||||
|
||||
# %% ********
|
||||
|
||||
# that brings you to an understanding of the most core concepts in tinygrad
|
||||
# you can run this with VIZ=1 to use the web based graph rewrite explorer
|
||||
# hopefully now you understand it. the nodes in the graph are just UOps
|
||||
+1
-1
@@ -41,7 +41,7 @@ The BMC also has a web interface you can use if you find that easier.
|
||||
It is recommended that you change the BMC password after setting up the box, as the password on the screen is only the initial password.
|
||||
|
||||
If you do decide to change the BMC password and no longer want the initial password to be displayed, remove the `/root/.bmc_password` file.
|
||||
Reboot after making these changes or restart the `displayservice.service` service.
|
||||
Reboot after making these changes or restart the `tinybox-display.service` service.
|
||||
|
||||
## What do I use it for?
|
||||
|
||||
|
||||
+2
-2
@@ -1,8 +1,6 @@
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
import json, argparse, random, time, os
|
||||
import tiktoken
|
||||
from tiktoken.load import load_tiktoken_bpe
|
||||
from extra.models.llama import Transformer, convert_from_huggingface, convert_from_gguf, fix_bf16
|
||||
from tinygrad.nn.state import safe_load, torch_load, load_state_dict, get_parameters, gguf_load
|
||||
from tinygrad import Tensor, dtypes, nn, Context, Device, GlobalCounters
|
||||
@@ -12,6 +10,8 @@ from extra.bench_log import BenchEvent, WallTimeEvent
|
||||
class Tokenizer:
|
||||
pat_str = r"(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s*[\r\n]+|\s+(?!\S)|\s+"
|
||||
def __init__(self, model_path: str):
|
||||
import tiktoken
|
||||
from tiktoken.load import load_tiktoken_bpe
|
||||
mergeable_ranks = load_tiktoken_bpe(model_path)
|
||||
self.num_base_tokens = len(mergeable_ranks)
|
||||
special_tokens = [
|
||||
|
||||
@@ -9,7 +9,7 @@ from typing import Dict, Any
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
from tinygrad import Device, GlobalCounters, dtypes, Tensor, TinyJit
|
||||
from tinygrad.helpers import Timing, Context, getenv, fetch, colored, tqdm, flatten
|
||||
from tinygrad.helpers import Timing, Context, getenv, fetch, colored, tqdm, flatten, profile_marker
|
||||
from tinygrad.nn import Conv2d, GroupNorm
|
||||
from tinygrad.nn.state import torch_load, load_state_dict, get_state_dict
|
||||
from extra.models.clip import Closed, Tokenizer, FrozenOpenClipEmbedder
|
||||
@@ -266,13 +266,16 @@ if __name__ == "__main__":
|
||||
parser.add_argument('--fakeweights', action='store_true', help="Skip loading checkpoints and use fake weights")
|
||||
args = parser.parse_args()
|
||||
|
||||
profile_marker("create model")
|
||||
model = StableDiffusion()
|
||||
|
||||
# load in weights
|
||||
profile_marker("load in weights")
|
||||
with WallTimeEvent(BenchEvent.LOAD_WEIGHTS):
|
||||
if not args.fakeweights:
|
||||
model_bin = fetch('https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt', 'sd-v1-4.ckpt')
|
||||
load_state_dict(model, torch_load(model_bin)['state_dict'], verbose=False, strict=False, realize=False)
|
||||
state_dict = torch_load(model_bin)['state_dict']
|
||||
profile_marker("state dict loaded")
|
||||
load_state_dict(model, state_dict, verbose=False, strict=False, realize=False)
|
||||
|
||||
if args.fp16:
|
||||
for k,v in get_state_dict(model).items():
|
||||
@@ -281,12 +284,13 @@ if __name__ == "__main__":
|
||||
|
||||
Tensor.realize(*get_state_dict(model).values())
|
||||
|
||||
# run through CLIP to get context
|
||||
profile_marker("run clip (conditional)")
|
||||
tokenizer = Tokenizer.ClipTokenizer()
|
||||
prompt = Tensor([tokenizer.encode(args.prompt)])
|
||||
context = model.cond_stage_model.transformer.text_model(prompt).realize()
|
||||
print("got CLIP context", context.shape)
|
||||
|
||||
profile_marker("run clip (unconditional)")
|
||||
prompt = Tensor([tokenizer.encode("")])
|
||||
unconditional_context = model.cond_stage_model.transformer.text_model(prompt).realize()
|
||||
print("got unconditional CLIP context", unconditional_context.shape)
|
||||
@@ -310,6 +314,7 @@ if __name__ == "__main__":
|
||||
step_times = []
|
||||
with Context(BEAM=getenv("LATEBEAM")):
|
||||
for index, timestep in (t:=tqdm(list(enumerate(timesteps))[::-1])):
|
||||
profile_marker(f"step {len(timesteps)-index-1}")
|
||||
GlobalCounters.reset()
|
||||
st = time.perf_counter_ns()
|
||||
t.set_description("%3d %3d" % (index, timestep))
|
||||
@@ -319,24 +324,26 @@ if __name__ == "__main__":
|
||||
latent = run(model, unconditional_context, context, latent, Tensor([timestep]), alphas[tid], alphas_prev[tid], Tensor([args.guidance]))
|
||||
if args.timing: Device[Device.DEFAULT].synchronize()
|
||||
step_times.append((time.perf_counter_ns() - st)*1e-6)
|
||||
# done with diffusion model
|
||||
del run
|
||||
del model.model
|
||||
|
||||
if (assert_time:=getenv("ASSERT_MIN_STEP_TIME")):
|
||||
min_time = min(step_times)
|
||||
assert min_time < assert_time, f"Speed regression, expected min step time of < {assert_time} ms but took: {min_time} ms"
|
||||
# upsample latent space to image with autoencoder
|
||||
x = model.decode(latent)
|
||||
profile_marker("run decoder") # upsample latent space to image with autoencoder
|
||||
x = model.decode(latent).realize()
|
||||
print(x.shape)
|
||||
|
||||
# save image
|
||||
profile_marker("save image")
|
||||
im = Image.fromarray(x.numpy())
|
||||
print(f"saving {args.out}")
|
||||
im.save(args.out)
|
||||
# Open image.
|
||||
if not args.noshow: im.show()
|
||||
|
||||
# validation!
|
||||
if args.prompt == default_prompt and args.steps == 6 and args.seed == 0 and args.guidance == 7.5:
|
||||
profile_marker("validate")
|
||||
ref_image = Tensor(np.array(Image.open(Path(__file__).parent / "stable_diffusion_seed0.png")))
|
||||
distance = (((x.cast(dtypes.float) - ref_image.cast(dtypes.float)) / ref_image.max())**2).mean().item()
|
||||
assert distance < 3e-3, colored(f"validation failed with {distance=}", "red") # higher distance with WINO
|
||||
|
||||
@@ -4,9 +4,9 @@ from tinygrad.engine.realize import ExecItem, get_runner
|
||||
from tinygrad.dtype import AddrSpace
|
||||
from tinygrad.helpers import getenv
|
||||
|
||||
N = 4096
|
||||
N = getenv("N", 4096)
|
||||
M = K = N
|
||||
run_count = 5
|
||||
run_count = getenv("CNT", 5)
|
||||
|
||||
# ---------------------------
|
||||
# launch/config constants
|
||||
@@ -155,14 +155,15 @@ def test_matmul(sink:UOp, N=N):
|
||||
ets.append(ei.run(wait=True))
|
||||
print(f"REAL TFLOPS {N * N * N * 2 / min(ets) * 1e-12:.2f}")
|
||||
|
||||
GlobalCounters.reset()
|
||||
with Context(DEBUG=2):
|
||||
tc = (a @ b).realize()
|
||||
with Context(DEBUG=0):
|
||||
err = (hc - tc).square().mean().item()
|
||||
print(f"mean squared error {err}")
|
||||
if err > 1e-06:
|
||||
raise RuntimeError("matmul is wrong!")
|
||||
if getenv("VERIFY", 1):
|
||||
GlobalCounters.reset()
|
||||
with Context(DEBUG=2):
|
||||
tc = (a @ b).realize()
|
||||
with Context(DEBUG=0):
|
||||
err = (hc - tc).square().mean().item()
|
||||
print(f"mean squared error {err}")
|
||||
if err > 1e-06:
|
||||
raise RuntimeError("matmul is wrong!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_matmul(hand_spec_kernel3(), N=N)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import pathlib
|
||||
import os, pathlib
|
||||
|
||||
# TODO: there is a timing bug without this
|
||||
os.environ["AMD_AQL"] = "1"
|
||||
|
||||
from tinygrad.device import Device
|
||||
from tinygrad.runtime.ops_amd import AMDProgram, HIPCompiler
|
||||
import time
|
||||
import os
|
||||
|
||||
NUM_WORKGROUPS = 96
|
||||
WAVE_SIZE = 32
|
||||
@@ -44,9 +46,9 @@ if __name__=="__main__":
|
||||
raise RuntimeError("Error while initiating AMD device")
|
||||
|
||||
COMPILER = HIPCompiler(DEV.arch)
|
||||
if DEV.arch in {'gfx1100', 'gfx1103'}:
|
||||
if DEV.arch == 'gfx1103':
|
||||
NUM_WORKGROUPS = 8
|
||||
if DEV.arch in {'gfx1100', 'gfx1103', 'gfx1151'}:
|
||||
if DEV.arch == 'gfx1103': NUM_WORKGROUPS = 8
|
||||
if DEV.arch == 'gfx1151': NUM_WORKGROUPS = 40
|
||||
launchBenchmark("v_wmma_bf16_16x16x16_bf16", (7,8,15))
|
||||
launchBenchmark("v_wmma_f16_16x16x16_f16", (7,8,15))
|
||||
launchBenchmark("v_wmma_f32_16x16x16_bf16", (7,8,15))
|
||||
|
||||
@@ -64,14 +64,17 @@ nvcmds = {getattr(nv_gpu, x):(x, getattr(nv_gpu, "struct_"+x+"_PARAMS", getattr(
|
||||
x.startswith("NV") and x[6:].startswith("_CTRL_") and isinstance(getattr(nv_gpu, x), int)}
|
||||
|
||||
def get_classes():
|
||||
hdrpy = (pathlib.Path(__file__).parent.parent.parent / "tinygrad/runtime/autogen/nv_570.py").read_text()
|
||||
clss = re.search(r'NV01_ROOT.*?NV_SEMAPHORE_SURFACE = \(0x000000da\) # macro', hdrpy, re.DOTALL).group()
|
||||
pattern = r'([0-9a-zA-Z_]*) = +\((0x[0-9a-fA-F]+)\)'
|
||||
matches = re.findall(pattern, clss, re.MULTILINE)
|
||||
return {int(num, base=16):name for name, num in matches}
|
||||
res = {}
|
||||
known_classes = {"NV01_DEVICE_0", "NV01_ROOT", "NV1_MEMORY_SYSTEM", "NV01_MEMORY_VIRTUAL", "NV1_MEMORY_USER", "NV50_MEMORY_VIRTUAL", "NV_FERMI_VASPACE_A",
|
||||
"NV20_SUBDEVICE_0"}
|
||||
for nm,val in nv_gpu.__dict__.items():
|
||||
if not isinstance(val, int): continue
|
||||
if 0x3000 < val < 0xffff: res[val] = nm
|
||||
if nm in known_classes: res[val] = nm
|
||||
return res
|
||||
nvclasses = get_classes()
|
||||
nvuvms = {getattr(nv_gpu, x):x for x in dir(nv_gpu) if x.startswith("UVM_") and nv_gpu.__dict__.get(x+"_PARAMS")}
|
||||
nvqcmds = {int(getattr(nv_gpu, x)):x for x in dir(nv_gpu) if x[:7] in {"NVC6C0_", "NVC56F_", "NVC6B5_"} and isinstance(getattr(nv_gpu, x), int)}
|
||||
nvqcmds = {int(getattr(nv_gpu, x)):x for x in dir(nv_gpu) if x[:7] in {"NVC9B0_", "NVC6C0_", "NVC56F_", "NVC6B5_"} and isinstance(getattr(nv_gpu, x), int)}
|
||||
|
||||
global_ioctl_id = 0
|
||||
gpus_user_modes = []
|
||||
|
||||
@@ -8,10 +8,10 @@ from sz import NONCORE_DIRS
|
||||
# llama 3 tokenizer
|
||||
tokenizer = Tokenizer(fetch("https://huggingface.co/bofenghuang/Meta-Llama-3-8B/resolve/main/original/tokenizer.model").as_posix())
|
||||
|
||||
def read_code(base_path):
|
||||
def read_code(base_path, full=False):
|
||||
ret = []
|
||||
for path, _, files in os.walk(os.path.join(base_path, "tinygrad")):
|
||||
if not getenv("CORE") and any(path.split("./")[1].startswith(x) for x in NONCORE_DIRS): continue
|
||||
if not full and any(path.split("./")[1].startswith(x) for x in NONCORE_DIRS): continue
|
||||
for name in files:
|
||||
if not name.endswith(".py"): continue
|
||||
if 'tinygrad/runtime/autogen' in path.replace('\\', '/'): continue
|
||||
@@ -23,9 +23,10 @@ def read_code(base_path):
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Analyze and optionally save tinygrad code.")
|
||||
parser.add_argument("--output", help="Output file to write the combined code to.")
|
||||
parser.add_argument("--full", action="store_true", help="All directories")
|
||||
args = parser.parse_args()
|
||||
|
||||
ret = read_code(".")
|
||||
ret = read_code(".", args.full)
|
||||
|
||||
table = []
|
||||
for name,code in ret:
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
import os
|
||||
os.environ["PYTHONPATH"] = "."
|
||||
os.environ["SQTT"] = "1"
|
||||
if "DEV" not in os.environ: os.environ["DEV"] = "AMD"
|
||||
os.environ["PROFILE"] = "1"
|
||||
os.environ["AMD_LLVM"] = "0"
|
||||
|
||||
from dataclasses import replace
|
||||
import atexit, contextlib
|
||||
from tinygrad import Tensor
|
||||
from tinygrad.helpers import system, OSX
|
||||
from tinygrad.runtime.ops_amd import AMDProgram
|
||||
from extra.sqtt.roc import decode, WaveExec, ProfileSQTTEvent
|
||||
from tinygrad.device import Device, ProfileDeviceEvent
|
||||
|
||||
from extra.sqtt.attempt_sqtt_parse import parse_sqtt_print_packets
|
||||
|
||||
dev = Device["AMD"]
|
||||
|
||||
@contextlib.contextmanager
|
||||
def save_sqtt():
|
||||
# clear the old traces
|
||||
dev.profile_events.clear()
|
||||
sqtt:dict[str, list[WaveExec]] = {}
|
||||
yield sqtt
|
||||
events = dev.profile_events+[ProfileDeviceEvent("AMD", props=dev.device_props())]
|
||||
|
||||
#rctx = decode(events)
|
||||
#assert len(rctx.inst_execs) > 0, "empty sqtt output"
|
||||
#sqtt.update(rctx.inst_execs)
|
||||
|
||||
for e in events:
|
||||
if isinstance(e, ProfileSQTTEvent):
|
||||
print(replace(e, blob=b''))
|
||||
if e.se == 0:
|
||||
parse_sqtt_print_packets(e.blob)
|
||||
|
||||
template = """.text
|
||||
.globl matmul
|
||||
.p2align 8
|
||||
.type matmul,@function
|
||||
matmul:
|
||||
INSTRUCTION
|
||||
|
||||
.rodata
|
||||
.p2align 6
|
||||
.amdhsa_kernel matmul
|
||||
.amdhsa_user_sgpr_kernarg_segment_ptr 1
|
||||
.amdhsa_next_free_vgpr .amdgcn.next_free_vgpr
|
||||
.amdhsa_next_free_sgpr .amdgcn.next_free_sgpr
|
||||
.amdhsa_wavefront_size32 1
|
||||
.end_amdhsa_kernel
|
||||
|
||||
.amdgpu_metadata
|
||||
---
|
||||
amdhsa.version:
|
||||
- 1
|
||||
- 0
|
||||
amdhsa.kernels:
|
||||
- .name: matmul
|
||||
.symbol: matmul.kd
|
||||
.group_segment_fixed_size: 0
|
||||
.private_segment_fixed_size: 0
|
||||
.wavefront_size: 32
|
||||
.sgpr_count: 8
|
||||
.vgpr_count: 8
|
||||
.max_flat_workgroup_size: 1024
|
||||
.kernarg_segment_align: 8
|
||||
.kernarg_segment_size: 8
|
||||
.args:
|
||||
- .address_space: global
|
||||
.name: a
|
||||
.offset: 0
|
||||
.size: 8
|
||||
.type_name: 'float*'
|
||||
.value_kind: global_buffer
|
||||
...
|
||||
.end_amdgpu_metadata
|
||||
"""
|
||||
|
||||
def run_asm(src, num_workgroups=1, num_waves=1):
|
||||
WAVE_SIZE = 32
|
||||
t = Tensor.empty(0x1000).realize()
|
||||
buf = t.uop.buffer.ensure_allocated()
|
||||
lib = dev.compiler.compile(template.replace("INSTRUCTION", '\n'.join(src)))
|
||||
dev.compiler.disassemble(lib)
|
||||
fxn = AMDProgram(dev, "matmul", lib)
|
||||
fxn(buf._buf, global_size=(num_workgroups,1,1), local_size=(WAVE_SIZE*num_waves,1,1), wait=True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
with save_sqtt() as sqtt:
|
||||
run_asm([
|
||||
"s_nop 100",
|
||||
"s_nop 100",
|
||||
"s_load_b64 s[0:1], s[0:1], null",
|
||||
"s_waitcnt lgkmcnt(0)",
|
||||
"s_nop 100",
|
||||
"s_nop 100",
|
||||
"s_add_i32 s2, s2, 10",
|
||||
"s_add_i32 s2, s2, 10",
|
||||
"s_nop 100",
|
||||
"s_nop 100",
|
||||
"v_mov_b32_e32 v0, 0",
|
||||
"v_mov_b32_e32 v0, 0",
|
||||
"s_nop 100",
|
||||
"s_nop 100",
|
||||
"v_dual_fmac_f32 v2, v48, v24 :: v_dual_fmac_f32 v9, v37, v51",
|
||||
"v_dual_fmac_f32 v2, v48, v24 :: v_dual_fmac_f32 v9, v37, v51",
|
||||
"s_nop 100",
|
||||
"s_nop 100",
|
||||
"global_load_b128 v[2:5], v0, s[0:1]",
|
||||
"global_load_b128 v[2:5], v0, s[0:1]",
|
||||
"s_nop 100",
|
||||
"s_nop 100",
|
||||
"s_sendmsg sendmsg(MSG_DEALLOC_VGPRS)",
|
||||
"s_endpgm",
|
||||
], num_workgroups=1, num_waves=1)
|
||||
exit(0)
|
||||
|
||||
with save_sqtt() as sqtt:
|
||||
#(Tensor.empty(16,16) @ Tensor.empty(16,16)).elu().realize()
|
||||
#Tensor.empty(1, 64).sum(axis=1).realize()
|
||||
Tensor.empty(1).log2().realize()
|
||||
exit(0)
|
||||
|
||||
with save_sqtt() as sqtt:
|
||||
# what's in v0?
|
||||
run_asm([
|
||||
"v_mov_b32_e32 v0, 0",
|
||||
"v_mov_b32_e32 v1, 0",
|
||||
"s_clause 0x1",
|
||||
"s_load_b64 s[0:1], s[0:1], null",
|
||||
"s_waitcnt lgkmcnt(0)",
|
||||
]+[
|
||||
"global_load_b32 v1, v0, s[0:1]",
|
||||
]*10+[
|
||||
"global_load_b32 v10, v1, s[0:1]",
|
||||
"s_waitcnt vmcnt(0)",
|
||||
|
||||
#"v_rcp_f32 v1, v0"
|
||||
#"v_add_f32_e32 v1 v0 v0",
|
||||
#"v_add_f32_e32 v5 v4 v4",
|
||||
#"v_add_f32_e32 v7 v6 v6",
|
||||
#"v_add_f32_e32 v1 v0 v0",
|
||||
#"v_add_f32_e32 v2 v1 v1",
|
||||
#"s_nop 1"
|
||||
]*5+[
|
||||
"v_add_f32_e32 v3 v2 v2",
|
||||
]*5+[
|
||||
"v_mul_f32_e32 v3 v2 v2",
|
||||
]*7)
|
||||
@@ -0,0 +1,548 @@
|
||||
import pickle, sys
|
||||
from tinygrad.helpers import getenv, Timing, colored
|
||||
from extra.sqtt.roc import decode, ProfileSQTTEvent
|
||||
|
||||
# do these enums match fields in the packets?
|
||||
#from tinygrad.runtime.support.amd import import_soc
|
||||
#soc = import_soc([11])
|
||||
#perf_sel = {getattr(soc, k):k for k in dir(soc) if k.startswith("SQ_PERF_")}
|
||||
|
||||
# Instruction packets (one per ISA op)
|
||||
# NOTE: these are bad guesses and may be wrong! feel free to update if you know better
|
||||
# some names were taken from SQ_TT_TOKEN_MASK_TOKEN_EXCLUDE_SHIFT
|
||||
|
||||
# we see 18 opcodes
|
||||
# opcodes(18): 1 2 3 4 5 6 8 9 F 10 11 12 14 15 16 17 18 19
|
||||
# if you exclude everything, you are left with 6
|
||||
# opcodes( 6): 10 11 14 15 16 17
|
||||
# sometimes we see a lot of B, but not repeatable
|
||||
|
||||
# not seen
|
||||
# 7 A C
|
||||
|
||||
# NOTE: INST runs before EXEC
|
||||
|
||||
OPCODE_COLORS = {
|
||||
# dispatches are BLACK
|
||||
0x1: "BLACK",
|
||||
0x18: "BLACK",
|
||||
|
||||
# execs are yellow
|
||||
0x2: "yellow",
|
||||
0x3: "yellow",
|
||||
0x4: "YELLOW",
|
||||
0x5: "YELLOW",
|
||||
|
||||
# waves are blue
|
||||
0x8: "blue",
|
||||
0x9: "blue",
|
||||
0x6: "cyan",
|
||||
0xb: "cyan",
|
||||
}
|
||||
|
||||
OPCODE_NAMES = {
|
||||
# gated by SQ_TT_TOKEN_EXCLUDE_VALUINST_SHIFT (but others must be enabled for it to show)
|
||||
0x01: "VALUINST",
|
||||
# gated by SQ_TT_TOKEN_EXCLUDE_VMEMEXEC_SHIFT
|
||||
0x02: "VMEMEXEC",
|
||||
# gated by SQ_TT_TOKEN_EXCLUDE_ALUEXEC_SHIFT
|
||||
0x03: "ALUEXEC",
|
||||
# gated by SQ_TT_TOKEN_EXCLUDE_IMMEDIATE_SHIFT
|
||||
0x04: "IMMEDIATE",
|
||||
0x05: "IMMEDIATE_MASK",
|
||||
|
||||
# gated by SQ_TT_TOKEN_EXCLUDE_WAVERDY_SHIFT
|
||||
0x06: "WAVERDY",
|
||||
# gated by SQ_TT_TOKEN_EXCLUDE_WAVESTARTEND_SHIFT
|
||||
0x08: "WAVEEND",
|
||||
0x09: "WAVESTART",
|
||||
# gated by SQ_TT_TOKEN_EXCLUDE_WAVEALLOC_SHIFT
|
||||
0x0B: "WAVEALLOC", # FFF00
|
||||
|
||||
# gated by NOT SQ_TT_TOKEN_EXCLUDE_PERF_SHIFT
|
||||
0x0D: "PERF",
|
||||
# gated by SQ_TT_TOKEN_EXCLUDE_EVENT_SHIFT
|
||||
0x12: "EVENT",
|
||||
0x13: "EVENT_BIG", # FFFFF800
|
||||
# some gated by SQ_TT_TOKEN_EXCLUDE_REG_SHIFT, some always there. something is broken with the timing on this
|
||||
0x14: "REG",
|
||||
# gated by SQ_TT_TOKEN_EXCLUDE_INST_SHIFT
|
||||
0x18: "INST",
|
||||
# gated by SQ_TT_TOKEN_EXCLUDE_UTILCTR_SHIFT
|
||||
0x19: "UTILCTR",
|
||||
|
||||
# this is the first (8 byte) packet in the bitstream
|
||||
0x17: "LAYOUT_HEADER", # layout/mode/group + selectors A/B (reversed)
|
||||
|
||||
# pure time (no extra bits)
|
||||
0x0F: "TS_DELTA_SHORT",
|
||||
0x10: "NOP",
|
||||
0x11: "TS_WAVE_STATE", # almost pure time, has a small flag
|
||||
|
||||
# not a good name, but seen and understood mostly
|
||||
0x15: "SNAPSHOT", # small delta + 50-ish bits of snapshot
|
||||
0x16: "TS_DELTA_OR_MARK", # 36-bit long delta or 36-bit marker
|
||||
|
||||
# packets we haven't seen / rarely see 0x0b
|
||||
0x07: "TS_DELTA_S8_W3_7", # shift=8, width=3 (small delta)
|
||||
0x0A: "TS_DELTA_S5_W2_A", # shift=5, width=2
|
||||
0x0C: "TS_DELTA_S5_W3_B", # shift=5, width=3 (different consumer)
|
||||
}
|
||||
|
||||
# SALU = 0x0 / s_mov_b32
|
||||
# SMEM = 0x1 / s_load_b*
|
||||
# JUMP = 0x3 / s_cbranch_scc0
|
||||
# NEXT = 0x4 / s_cbranch_execz
|
||||
# MESSAGE = 0x9 / s_sendmsg
|
||||
# VALU = 0xb / v_(exp,log)_f32_e32
|
||||
# VALU = 0xd / v_lshlrev_b64
|
||||
# VALU = 0xe / v_mad_u64_u32
|
||||
# VMEM = 0x21 / global_load_b32
|
||||
# VMEM = 0x22 / global_load_b32
|
||||
# VMEM = 0x24 / global_store_b32
|
||||
# VMEM = 0x25 / global_store_b64
|
||||
# VMEM = 0x27 / global_store
|
||||
# VMEM = 0x28 / global_store_b64
|
||||
# LDS = 0x29 / ds_load_b128
|
||||
# LDS = 0x2b / ds_store_b32
|
||||
# LDS = 0x2e / ds_store_b128
|
||||
# ???? = 0x5a / hidden global_load instruction
|
||||
# ???? = 0x5b / hidden global_load instruction
|
||||
# ???? = 0x5c / hidden global_store instruction
|
||||
# VALU = 0x73 / v_cmpx_eq_u32_e32 (not normal VALUINST)
|
||||
OPNAME = {
|
||||
0x0: "SALU",
|
||||
0x1: "SMEM",
|
||||
0x3: "JUMP",
|
||||
0x4: "NEXT",
|
||||
0x9: "MESSAGE",
|
||||
0xb: "VALU",
|
||||
0xd: "VALU",
|
||||
0xe: "VALU",
|
||||
0x10: "__END",
|
||||
0x21: "VMEM_LOAD",
|
||||
0x22: "VMEM_LOAD",
|
||||
0x24: "VMEM_STORE",
|
||||
0x25: "VMEM_STORE",
|
||||
0x26: "VMEM_STORE",
|
||||
0x27: "VMEM_STORE",
|
||||
0x28: "VMEM_STORE",
|
||||
0x29: "LDS_LOAD",
|
||||
0x2b: "LDS_STORE",
|
||||
0x2e: "LDS_STORE",
|
||||
0x50: "__SIMD_LDS_LOAD",
|
||||
0x51: "__SIMD_LDS_LOAD",
|
||||
0x54: "__SIMD_LDS_STORE",
|
||||
0x5a: "__SIMD_VMEM_LOAD",
|
||||
0x5b: "__SIMD_VMEM_LOAD",
|
||||
0x5c: "__SIMD_VMEM_STORE",
|
||||
0x5d: "__SIMD_VMEM_STORE",
|
||||
0x5e: "__SIMD_VMEM_STORE",
|
||||
0x5f: "__SIMD_VMEM_STORE",
|
||||
0x72: "SALU_OR",
|
||||
0x73: "VALU_CMPX",
|
||||
}
|
||||
|
||||
ALUSRC = {
|
||||
1: "SALU",
|
||||
2: "VALU",
|
||||
3: "VALU_ALT",
|
||||
}
|
||||
|
||||
MEMSRC = {
|
||||
0: "LDS",
|
||||
1: "__LDS",
|
||||
2: "VMEM",
|
||||
3: "__VMEM",
|
||||
}
|
||||
|
||||
|
||||
# these tables are from rocprof trace decoder
|
||||
# rocprof_trace_decoder_parse_data-0x11c6a0
|
||||
# parse_sqtt_180 = b *rocprof_trace_decoder_parse_data-0x11c6a0+0x110040
|
||||
|
||||
# ---------- 1. local_138: 256-byte state->opcode table ----------
|
||||
|
||||
STATE_TO_OPCODE: bytes = bytes([
|
||||
0x10, 0x16, 0x18, 0x01, 0x05, 0x0b, 0x0c, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x09, 0x04, 0x03, 0x02,
|
||||
0x10, 0x17, 0x18, 0x01, 0x06, 0x08, 0x0d, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x0a, 0x04, 0x03, 0x02,
|
||||
0x10, 0x07, 0x18, 0x01, 0x05, 0x0b, 0x0c, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x09, 0x04, 0x03, 0x02,
|
||||
0x10, 0x19, 0x18, 0x01, 0x06, 0x08, 0x0d, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x0a, 0x04, 0x03, 0x02,
|
||||
0x10, 0x00, 0x18, 0x01, 0x05, 0x0b, 0x0c, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x09, 0x04, 0x03, 0x02,
|
||||
0x10, 0x11, 0x18, 0x01, 0x06, 0x08, 0x0d, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x0a, 0x04, 0x03, 0x02,
|
||||
0x10, 0x12, 0x18, 0x01, 0x05, 0x0b, 0x0c, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x09, 0x04, 0x03, 0x02,
|
||||
0x10, 0x15, 0x18, 0x01, 0x06, 0x08, 0x0d, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x0a, 0x04, 0x03, 0x02,
|
||||
0x10, 0x16, 0x18, 0x01, 0x05, 0x0b, 0x0c, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x09, 0x04, 0x03, 0x02,
|
||||
0x10, 0x17, 0x18, 0x01, 0x06, 0x08, 0x0d, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x0a, 0x04, 0x03, 0x02,
|
||||
0x10, 0x07, 0x18, 0x01, 0x05, 0x0b, 0x0c, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x09, 0x04, 0x03, 0x02,
|
||||
0x10, 0x19, 0x18, 0x01, 0x06, 0x08, 0x0d, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x0a, 0x04, 0x03, 0x02,
|
||||
0x10, 0x00, 0x18, 0x01, 0x05, 0x0b, 0x0c, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x09, 0x04, 0x03, 0x02,
|
||||
0x10, 0x11, 0x18, 0x01, 0x06, 0x08, 0x0d, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x0a, 0x04, 0x03, 0x02,
|
||||
0x10, 0x13, 0x18, 0x01, 0x05, 0x0b, 0x0c, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x09, 0x04, 0x03, 0x02,
|
||||
0x10, 0x15, 0x18, 0x01, 0x06, 0x08, 0x0d, 0x00, 0x0f, 0x14, 0x18, 0x01, 0x0a, 0x04, 0x03, 0x02,
|
||||
])
|
||||
|
||||
# opcode mask (the bits used to determine the opcode, worked out by looking at the repeats in STATE_TO_OPCODE)
|
||||
|
||||
opcode_mask = {
|
||||
0x10: 0b1111,
|
||||
|
||||
0x16: 0b1111111,
|
||||
0x17: 0b1111111,
|
||||
0x07: 0b1111111,
|
||||
0x19: 0b1111111,
|
||||
0x11: 0b1111111,
|
||||
0x12: 0b11111111,
|
||||
0x13: 0b11111111,
|
||||
0x15: 0b1111111,
|
||||
|
||||
0x18: 0b111,
|
||||
0x1: 0b111,
|
||||
|
||||
0x5: 0b11111,
|
||||
0x6: 0b11111,
|
||||
0xb: 0b11111,
|
||||
0x8: 0b11111,
|
||||
0xc: 0b11111,
|
||||
0xd: 0b11111,
|
||||
|
||||
0xf: 0b1111,
|
||||
0x14: 0b1111,
|
||||
|
||||
0x9: 0b11111,
|
||||
0xa: 0b11111,
|
||||
|
||||
0x4: 0b1111,
|
||||
0x3: 0b1111,
|
||||
0x2: 0b1111,
|
||||
}
|
||||
|
||||
# ---------- 2. DAT_0012e280: nibble budget per opcode&0x1F ----------
|
||||
|
||||
NIBBLE_BUDGET = [
|
||||
0x08, 0x0C, 0x08, 0x08, 0x0C, 0x18, 0x18, 0x40, 0x14, 0x20, 0x30, 0x14, 0x34, 0x1C, 0x30, 0x08,
|
||||
0x04, 0x18, 0x18, 0x20, 0x40, 0x40, 0x30, 0x40, 0x14, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
]
|
||||
|
||||
# ---------- 3. delta_map from your hash nodes ----------
|
||||
|
||||
# opcode -> (shift, width)
|
||||
DELTA_MAP_DEFAULT = {
|
||||
0x01: (3, 3), # shift=3, end=6
|
||||
0x02: (4, 2), # shift=4, end=6
|
||||
0x03: (4, 2), # shift=4, end=6
|
||||
0x04: (4, 3), # shift=4, end=7
|
||||
0x05: (5, 3), # shift=5, end=8
|
||||
0x06: (5, 3), # shift=5, end=8
|
||||
0x07: (8, 3), # shift=8, end=11
|
||||
0x08: (5, 3), # shift=5, end=8
|
||||
0x09: (5, 2), # shift=5, end=7
|
||||
0x0A: (5, 2), # shift=5, end=7
|
||||
0x0B: (5, 3), # shift=5, end=8
|
||||
0x0C: (5, 3), # shift=5, end=8
|
||||
0x0D: (5, 3), # shift=5, end=8
|
||||
# NOTE: 0x0e can never be decoded, it's not in the STATE_TO_OPCODE table
|
||||
#0x0E: (7, 2), # shift=7, end=9
|
||||
0x0F: (4, 4), # shift=4, end=8
|
||||
0x10: (0, 0), # shift=0, end=0 (no delta)
|
||||
0x11: (7, 9), # shift=7, end=16
|
||||
0x12: (8, 3), # shift=8, end=11
|
||||
0x13: (8, 3), # shift=8, end=11
|
||||
0x14: (4, 3), # shift=4, end=7
|
||||
0x15: (7, 3), # shift=7, end=10
|
||||
0x16: (12, 36), # shift=12, end=48 (36-bit field, matches the 0x16 special-case)
|
||||
0x17: (0, 0), # shift=0, end=0 (no delta)
|
||||
0x18: (4, 3), # shift=4, end=7
|
||||
0x19: (7, 2), # shift=7, end=9
|
||||
}
|
||||
|
||||
# ---------- 4. One-line-per-packet parser ----------
|
||||
|
||||
def reg_mask(opcode):
|
||||
nb_bits = NIBBLE_BUDGET[opcode & 0x1F]
|
||||
shift, width = DELTA_MAP_DEFAULT[opcode]
|
||||
delta_mask = ((1 << width) - 1) << shift
|
||||
assert delta_mask & opcode_mask[opcode] == 0, "masks shouldn't overlap"
|
||||
return ((1 << nb_bits) - 1) & ~(delta_mask | opcode_mask[opcode])
|
||||
|
||||
def decode_packet_fields(opcode: int, reg: int) -> str:
|
||||
"""
|
||||
Decode packet payloads conservatively, using:
|
||||
- NIBBLE_BUDGET[opcode & 0x1F] to mask reg down to true width.
|
||||
- DELTA_MAP_DEFAULT[opcode] to expose the "primary" field (often delta).
|
||||
- Per-opcode layouts derived from rocprof's decompiled consumers.
|
||||
"""
|
||||
# --- 0. Restrict to real packet bits not used in delta ---------------------------------
|
||||
pkt = reg & reg_mask(opcode)
|
||||
fields: list[str] = []
|
||||
|
||||
match opcode:
|
||||
case 0x01: # VALUINST
|
||||
# 6 bit field
|
||||
flag = (pkt >> 6) & 1
|
||||
wave = pkt >> 7
|
||||
fields.append(f"wave={wave:x}")
|
||||
if flag: fields.append("flag")
|
||||
case 0x02: # VMEMEXEC
|
||||
# 2 bit field (pipe is a guess)
|
||||
src = pkt>>6
|
||||
fields.append(f"src={src} [{MEMSRC.get(src, '')}]")
|
||||
case 0x03: # ALUEXEC
|
||||
# 2 bit field
|
||||
src = pkt>>6
|
||||
fields.append(f"src={src} [{ALUSRC.get(src, '')}]")
|
||||
case 0x04: # IMMEDIATE_4
|
||||
# 5 bit field (actually 4)
|
||||
wave = pkt >> 7
|
||||
fields.append(f"wave={wave:x}")
|
||||
case 0x05: # IMMEDIATE_5
|
||||
# 16 bit field
|
||||
# 1 bit per wave
|
||||
fields.append(f"mask={pkt>>8:016b}")
|
||||
case 0x6:
|
||||
# wave ready FFFF00
|
||||
# 16 bit field
|
||||
# 1 bit per wave
|
||||
fields.append(f"mask={pkt>>8:016b}")
|
||||
case 0x0d:
|
||||
# 20 bit field
|
||||
fields.append(f"arg = {pkt>>8:X}")
|
||||
case 0x12:
|
||||
fields.append(f"event = {pkt>>11:X}")
|
||||
case 0x15:
|
||||
fields.append(f"snap = {pkt>>10:X}")
|
||||
case 0x19:
|
||||
# wave end
|
||||
fields.append(f"ctr = {pkt>>9:X}")
|
||||
case 0xf:
|
||||
extracted_delta = (reg >> 4) & 0xF
|
||||
fields.append(f"strange_delta=0x{extracted_delta:x}")
|
||||
case 0x11:
|
||||
# DELTA_MAP_DEFAULT: shift=7, width=9 -> small delta.
|
||||
# FF0000 is the mask
|
||||
coarse = pkt >> 16
|
||||
fields.append(f"coarse=0x{coarse:02x}")
|
||||
# From decomp:
|
||||
# - when layout<3 and coarse&1, it sets a "has interesting wave" flag
|
||||
# - when coarse&8, it marks all live waves as "terminated"
|
||||
if coarse & 0x01:
|
||||
fields.append("flag_wave_interest=1")
|
||||
if coarse & 0x08:
|
||||
fields.append("flag_terminate_all=1")
|
||||
case 0x8:
|
||||
# wave end, this is 20 bits (FFF00)
|
||||
flag7 = (pkt >> 8) & 1
|
||||
simd = (pkt >> 9) & 3
|
||||
cu = ((pkt >> 11) & 0x7) | (flag7 << 3)
|
||||
wave = (pkt >> 15) & 0x1f
|
||||
fields.append(f"wave={wave:x}")
|
||||
fields.append(f"simd={simd}")
|
||||
fields.append(f"cu={cu}")
|
||||
case 0x9:
|
||||
# From case 9 (WAVESTART) in multiple consumers:
|
||||
# flag7 = (w >> 7) & 1 (low bit of uVar41)
|
||||
# cls2 = (w >> 8) & 3 (class / group)
|
||||
# slot4 = (w >> 10) & 0xf (slot / group index)
|
||||
# idx_lo = (w >> 0xd) & 0x1f (low index, layout<4 path)
|
||||
# idx_hi = (w >> 0xf) & 0x1f (high index, layout>=4 path)
|
||||
# id7 = (w >> 0x19) & 0x7f (7-bit id)
|
||||
flag7 = (pkt >> 7) & 1
|
||||
simd = (pkt >> 8) & 3
|
||||
cu = ((pkt >> 10) & 0x7) | (flag7 << 3)
|
||||
wave = (pkt >> 13) & 0x1F
|
||||
id7 = (pkt >> 17)
|
||||
fields.append(f"wave={wave:x}")
|
||||
fields.append(f"simd={simd}")
|
||||
fields.append(f"cu={cu}")
|
||||
fields.append(f"id7=0x{id7:x}")
|
||||
case 0x18:
|
||||
# FFF88 is the mask
|
||||
# From case 0x18:
|
||||
# low3 = w & 7
|
||||
# grp3 = (w >> 3) or (w >> 4) & 7 (layout-dependent)
|
||||
# flags = bits 6 (B6) and 7 (B7)
|
||||
# hi8 = (w >> 0xc) & 0xff (layout 4 path)
|
||||
# hi7 = (w >> 0xd) & 0x7f (other layouts)
|
||||
# idx5 = (w >> 7) or (w >> 8) & 0x1f, used as wave index
|
||||
flag1 = (pkt >> 3) & 1
|
||||
flag2 = (pkt >> 7) & 1
|
||||
wave = (pkt >> 8) & 0x1F
|
||||
op = (pkt >> 13)
|
||||
fields.append(f"wave={wave:x}")
|
||||
fields.append(f"op=0x{op:02x} [{OPNAME.get(op, '')}]")
|
||||
if flag1: fields.append("flag1")
|
||||
if flag2: fields.append("flag2")
|
||||
case 0x14:
|
||||
subop = (pkt >> 16) & 0xFFFF # (short)(w >> 0x10)
|
||||
val32 = (pkt >> 32) & 0xFFFFFFFF # (uint)(w >> 0x20)
|
||||
slot = (pkt >> 7) & 0x7 # index in local_168[...] tables
|
||||
hi_byte = (pkt >> 8) & 0xFF # determines config vs marker
|
||||
|
||||
fields.append(f"subop=0x{subop:04x}")
|
||||
fields.append(f"slot={slot}")
|
||||
fields.append(f"val32=0x{val32:08x}")
|
||||
|
||||
if hi_byte & 0x80:
|
||||
# Config flavour: writes config words into per-slot state arrays.
|
||||
fields.append("kind=config")
|
||||
if subop == 0x000C:
|
||||
fields.append("slot=lo")
|
||||
elif subop == 0x000D:
|
||||
fields.append("slot=hi")
|
||||
else:
|
||||
# COR marker: subop 0xC342, payload "COR\0" → start of a COR region.
|
||||
if subop == 0xC342:
|
||||
fields.append("kind=cor_stream")
|
||||
if val32 == 0x434F5200:
|
||||
fields.append("cor_magic='COR\\0'")
|
||||
case 0x16:
|
||||
# Bits:
|
||||
# bit8 -> 0x100
|
||||
# bit9 -> 0x200
|
||||
# bits 12..47 -> 36-bit field used as delta or marker
|
||||
bit8 = bool(pkt & 0x100)
|
||||
bit9 = bool(pkt & 0x200)
|
||||
if not bit9:
|
||||
mode = "delta"
|
||||
elif not bit8:
|
||||
mode = "marker"
|
||||
else:
|
||||
mode = "other"
|
||||
# need to use reg here
|
||||
val36 = (reg >> 12) & ((1 << 36) - 1)
|
||||
fields.append(f"mode={mode}")
|
||||
if mode != "delta":
|
||||
fields.append(f"val36=0x{val36:x}")
|
||||
case 0x17:
|
||||
# From decomp (two sites with identical logic):
|
||||
# layout = (w >> 7) & 0x3f
|
||||
# mode = (w >> 0xd) & 3
|
||||
# group = (w >> 0xf) & 7
|
||||
# sel_a = (w >> 0x1c) & 0xf
|
||||
# sel_b = (w >> 0x21) & 7
|
||||
# flag4 = (w >> 0x3b) & 1 (only meaningful when layout == 4)
|
||||
layout = (pkt >> 7) & 0x3F
|
||||
simd = (pkt >> 13) & 0x3 # you can change this by changing traced simd
|
||||
group = (pkt >> 15) & 0x7
|
||||
sel_a = (pkt >> 0x1C) & 0xF
|
||||
sel_b = (pkt >> 0x21) & 0x7
|
||||
flag4 = (pkt >> 0x3B) & 0x1
|
||||
|
||||
fields.append(f"layout={layout}")
|
||||
fields.append(f"group={group}")
|
||||
fields.append(f"simd={simd}")
|
||||
fields.append(f"sel_a={sel_a}")
|
||||
fields.append(f"sel_b={sel_b}")
|
||||
if layout == 4:
|
||||
fields.append(f"layout4_flag={flag4}")
|
||||
case _:
|
||||
fields.append(f"{pkt:X} & {reg_mask(opcode):X}")
|
||||
return ",".join(fields)
|
||||
|
||||
FILTER_LEVEL = getenv("FILTER", 1)
|
||||
|
||||
DEFAULT_FILTER: tuple[int, ...] = tuple()
|
||||
# NOP + pure time + "sample"
|
||||
if FILTER_LEVEL >= 0: DEFAULT_FILTER += (0x10, 0xf, 0x11)
|
||||
# reg + event + sample + marker
|
||||
# TODO: events are probably good
|
||||
if FILTER_LEVEL >= 1: DEFAULT_FILTER += (0x14, 0x12, 0x16)
|
||||
# instruction runs + valuinst
|
||||
if FILTER_LEVEL >= 2: DEFAULT_FILTER += (0x01, 0x02, 0x03)
|
||||
# instructions dispatch (inst, immed)
|
||||
if FILTER_LEVEL >= 3: DEFAULT_FILTER += (0x4, 0x5, 0x18)
|
||||
# waves
|
||||
if FILTER_LEVEL >= 4: DEFAULT_FILTER += (0x6, 0x8, 0x9)
|
||||
|
||||
def parse_sqtt_print_packets(data: bytes, filter=DEFAULT_FILTER, verbose=True) -> None:
|
||||
"""
|
||||
Minimal debug: print ONE LINE per decoded token (packet).
|
||||
|
||||
Now prints only the actual nibbles that belong to each packet, instead of
|
||||
the full 64-bit shift register.
|
||||
"""
|
||||
n = len(data)
|
||||
time = 0
|
||||
last_printed_time = 0
|
||||
reg = 0 # shift register
|
||||
offset = 0 # bit offset, in steps of 4 (one nibble)
|
||||
nib_budget = 0x40
|
||||
flags = 0
|
||||
token_index = 0
|
||||
opcodes_seen = set()
|
||||
|
||||
while (offset >> 3) < n:
|
||||
# 1) Fill register with nibbles according to nib_budget
|
||||
if nib_budget != 0:
|
||||
target = offset + 4 + ((nib_budget - 1) & ~3)
|
||||
while offset != target and (offset >> 3) < n:
|
||||
byte = data[offset >> 3]
|
||||
nib = (byte >> (offset & 4)) & 0xF
|
||||
reg = ((reg >> 4) | (nib << 60)) & ((1 << 64) - 1)
|
||||
offset += 4
|
||||
|
||||
# 2) Decode token from low 8 bits
|
||||
opcode = STATE_TO_OPCODE[reg & 0xFF]
|
||||
opcodes_seen.add(opcode)
|
||||
|
||||
# 4) Set next nibble budget based on opcode
|
||||
nib_budget = NIBBLE_BUDGET[opcode & 0x1F]
|
||||
|
||||
# 5) Get delta
|
||||
shift, width = DELTA_MAP_DEFAULT[opcode]
|
||||
delta = (reg >> shift) & ((1 << width) - 1)
|
||||
|
||||
# 6) Update time and handle special opcodes 0xF/0x16
|
||||
if opcode == 0x16:
|
||||
two_bits = (reg >> 8) & 0x3
|
||||
if two_bits == 1:
|
||||
flags |= 0x01
|
||||
|
||||
# Common 36-bit field at bits [12..47]
|
||||
if (reg & 0x200) == 0:
|
||||
# delta mode: add 36-bit delta to time
|
||||
pass
|
||||
elif (reg & 0x100) == 0:
|
||||
# marker / other modes: no time advance
|
||||
# real marker: bit9=1, bit8=0, non-zero payload
|
||||
# "other" 0x16 variants, ignored for timing
|
||||
delta = 0
|
||||
else:
|
||||
raise RuntimeError("unknown 0x16 delta")
|
||||
elif opcode == 0x0F:
|
||||
# opcode 0x0F has an offset of 4 to the delta
|
||||
# update: it's actually computed to be 8 to match WAVESTART
|
||||
delta = delta + 8
|
||||
|
||||
# Append extra decoded fields into the note string
|
||||
note = decode_packet_fields(opcode, reg)
|
||||
|
||||
# this delta happens before the instruction
|
||||
time += delta
|
||||
token_index += 1
|
||||
|
||||
if verbose and (filter is None or opcode not in filter):
|
||||
print(f"{time:8d} +{time-last_printed_time:8d} : "+colored(f"{OPCODE_NAMES[opcode]:18s} ", OPCODE_COLORS.get(opcode, "white"))+f"{note}")
|
||||
last_printed_time = time
|
||||
|
||||
# Optional summary at the end
|
||||
print(f"# done: tokens={token_index:_}, final_time={time}, flags=0x{flags:02x}")
|
||||
if verbose:
|
||||
print(f"opcodes({len(opcodes_seen):2d}):",
|
||||
' '.join([colored(f"{op:2X}", "WHITE" if op in opcodes_seen else "BLACK") for op in sorted(opcode_mask)]))
|
||||
|
||||
|
||||
def parse(fn:str):
|
||||
with Timing(f"unpickle {fn}: "): dat = pickle.load(open(fn, "rb"))
|
||||
if getenv("ROCM", 0):
|
||||
with Timing(f"decode {fn}: "): ctx = decode(dat)
|
||||
dat_sqtt = [x for x in dat if isinstance(x, ProfileSQTTEvent)]
|
||||
print(f"got {len(dat_sqtt)} SQTT events in {fn}")
|
||||
return dat_sqtt
|
||||
|
||||
if __name__ == "__main__":
|
||||
fn = "extra/sqtt/examples/profile_gemm_run_0.pkl"
|
||||
dat_sqtt = parse(sys.argv[1] if len(sys.argv) > 1 else fn)
|
||||
for i,dat in enumerate(dat_sqtt):
|
||||
with Timing(f"decode pkt {i} with len {len(dat.blob):_}: "):
|
||||
parse_sqtt_print_packets(dat.blob, verbose=getenv("V", 1))
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+52
-26
@@ -1,4 +1,5 @@
|
||||
import ctypes, pathlib, argparse, pickle, re, functools, dataclasses, itertools
|
||||
import ctypes, pathlib, argparse, pickle, re, functools, dataclasses, itertools, threading
|
||||
from typing import Generator
|
||||
from tinygrad.helpers import temp, unwrap, DEBUG
|
||||
from tinygrad.device import ProfileEvent, ProfileDeviceEvent, ProfileProgramEvent
|
||||
from tinygrad.runtime.ops_amd import ProfileSQTTEvent, ProfilePMCEvent
|
||||
@@ -31,30 +32,50 @@ def llvm_disasm(arch:str, lib:bytes) -> dict[int, tuple[str, int]]:
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class InstExec:
|
||||
typ:str
|
||||
inst:str
|
||||
pc:int
|
||||
stall:int
|
||||
dur:int
|
||||
time:int
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class WaveExec:
|
||||
class WaveSlot:
|
||||
wave_id:int
|
||||
cu:int
|
||||
simd:int
|
||||
se:int
|
||||
@property
|
||||
def simd_loc(self) -> str: return f"SE:{self.se} CU:{self.cu} SIMD:{self.simd}"
|
||||
@property
|
||||
def wave_loc(self) -> str: return f"{self.simd_loc} WAVE:{self.wave_id}"
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class WaveExec(WaveSlot):
|
||||
begin_time:int
|
||||
end_time:int
|
||||
insts:list[InstExec]
|
||||
insts:bytearray
|
||||
def unpack_insts(self) -> Generator[InstExec, None, None]:
|
||||
sz = ctypes.sizeof(struct:=rocprof.rocprofiler_thread_trace_decoder_inst_t)
|
||||
insts_array = (struct*(len(self.insts)//sz)).from_buffer(self.insts)
|
||||
for inst in insts_array:
|
||||
inst_typ = rocprof.enum_rocprofiler_thread_trace_decoder_inst_category_t.get(inst.category)
|
||||
yield InstExec(inst_typ, inst.pc.address, inst.stall, inst.duration, inst.time)
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class OccEvent(WaveSlot):
|
||||
time:int
|
||||
start:int
|
||||
|
||||
class _ROCParseCtx:
|
||||
def __init__(self, dev_evs:dict[str, ProfileDeviceEvent], sqtt_evs:list[ProfileSQTTEvent], prog_evs:list[ProfileProgramEvent]):
|
||||
self.dev_evs, self.sqtt_evs, self.prog_evs = dev_evs, iter(sqtt_evs), prog_evs
|
||||
self.disasms:dict[tuple[str, int], tuple[str, int]] = {}
|
||||
self.disasms:dict[str, dict[int, tuple[str, int]]] = {}
|
||||
self.inst_execs:dict[str, list[WaveExec]] = {}
|
||||
self.occ_events:dict[str, list[OccEvent]] = {}
|
||||
|
||||
for prog in prog_evs:
|
||||
arch = "gfx%d%x%x" % ((trgt:=unwrap(dev_evs[prog.device].props)['gfx_target_version']) // 10000, (trgt // 100) % 100, trgt % 100)
|
||||
for addr, info in llvm_disasm(arch, unwrap(prog.lib)).items():
|
||||
self.disasms[(prog.name, unwrap(prog.base) + addr)] = info
|
||||
base = unwrap(prog.base)
|
||||
self.disasms[prog.name] = asm = {base+addr:info for addr,info in llvm_disasm(arch, unwrap(prog.lib)).items()}
|
||||
|
||||
def next_sqtt(self):
|
||||
x = next(self.sqtt_evs, None)
|
||||
@@ -63,21 +84,20 @@ class _ROCParseCtx:
|
||||
self.active_blob = (ctypes.c_ubyte * len(x.blob)).from_buffer_copy(x.blob) if x is not None else None
|
||||
return self.active_blob
|
||||
|
||||
def on_occupancy_ev(self, ev):
|
||||
if DEBUG >= 5: print("OCC", ev.time, self.active_se, ev.cu, ev.simd, ev.wave_id, ev.start)
|
||||
def on_occupancy_ev(self, ev:rocprof.rocprofiler_thread_trace_decoder_occupancy_t):
|
||||
if DEBUG >= 5: print(f"OCC {ev.time=} {self.active_se=} {ev.cu=} {ev.simd=} {ev.wave_id=} {ev.start=}")
|
||||
self.occ_events.setdefault(unwrap(self.active_kern), []).append(OccEvent(ev.wave_id, ev.cu, ev.simd, unwrap(self.active_se), ev.time, ev.start))
|
||||
|
||||
def on_wave_ev(self, ev):
|
||||
if DEBUG >= 5: print("WAVE", ev.wave_id, self.active_se, ev.cu, ev.simd, ev.contexts, ev.begin_time, ev.end_time)
|
||||
def on_wave_ev(self, ev:rocprof.rocprofiler_thread_trace_decoder_wave_t):
|
||||
if DEBUG >= 5: print(f"WAVE {ev.wave_id=} {self.active_se=} {ev.cu=} {ev.simd=} {ev.contexts=} {ev.begin_time=} {ev.end_time=}")
|
||||
# Skip wave events without instruction timings, occupancy events give the start and duration.
|
||||
if ev.instructions_size == 0: return
|
||||
|
||||
inst_execs:list[InstExec] = []
|
||||
for j in range(ev.instructions_size):
|
||||
inst_ev = ev.instructions_array[j]
|
||||
inst_typ = rocprof.enum_rocprofiler_thread_trace_decoder_inst_category_t.get(inst_ev.category)
|
||||
inst_disasm = self.disasms[(unwrap(self.active_kern), unwrap(inst_ev.pc.address))][0]
|
||||
inst_execs.append(InstExec(inst_typ, inst_disasm, inst_ev.stall, inst_ev.duration, inst_ev.time))
|
||||
insts_blob = bytearray(sz:=ev.instructions_size * ctypes.sizeof(rocprof.rocprofiler_thread_trace_decoder_inst_t))
|
||||
ctypes.memmove((ctypes.c_char * sz).from_buffer(insts_blob), ev.instructions_array, sz)
|
||||
|
||||
if ev.instructions_size > 0:
|
||||
self.inst_execs.setdefault(unwrap(self.active_kern), []).append(WaveExec(ev.wave_id, ev.cu, ev.simd, ev.begin_time, ev.end_time, inst_execs))
|
||||
self.inst_execs.setdefault(unwrap(self.active_kern), []).append(WaveExec(ev.wave_id, ev.cu, ev.simd, unwrap(self.active_se), ev.begin_time,
|
||||
ev.end_time, insts_blob))
|
||||
|
||||
def decode(profile:list[ProfileEvent]) -> _ROCParseCtx:
|
||||
dev_events:dict[str, ProfileDeviceEvent] = {}
|
||||
@@ -91,26 +111,30 @@ def decode(profile:list[ProfileEvent]) -> _ROCParseCtx:
|
||||
ROCParseCtx = _ROCParseCtx(dev_events, sqtt_events, prog_events)
|
||||
|
||||
@rocprof.rocprof_trace_decoder_se_data_callback_t
|
||||
def copy_cb(buf, buf_size, data_ptr):
|
||||
def copy_cb(buf, buf_size, _):
|
||||
if (prof_info:=ROCParseCtx.next_sqtt()) is None: return 0
|
||||
buf[0] = ctypes.cast(prof_info, ctypes.POINTER(ctypes.c_ubyte))
|
||||
buf_size[0] = len(prof_info)
|
||||
return len(prof_info)
|
||||
|
||||
@rocprof.rocprof_trace_decoder_trace_callback_t
|
||||
def trace_cb(record_type, events_ptr, n, data_ptr):
|
||||
def trace_cb(record_type, events_ptr, n, _):
|
||||
match record_type:
|
||||
case rocprof.ROCPROFILER_THREAD_TRACE_DECODER_RECORD_OCCUPANCY:
|
||||
for ev in (rocprof.rocprofiler_thread_trace_decoder_occupancy_t * n).from_address(events_ptr): ROCParseCtx.on_occupancy_ev(ev)
|
||||
case rocprof.ROCPROFILER_THREAD_TRACE_DECODER_RECORD_WAVE:
|
||||
for ev in (rocprof.rocprofiler_thread_trace_decoder_wave_t * n).from_address(events_ptr): ROCParseCtx.on_wave_ev(ev)
|
||||
case rocprof.ROCPROFILER_THREAD_TRACE_DECODER_RECORD_REALTIME:
|
||||
if DEBUG >= 5:
|
||||
pairs = [(ev.shader_clock, ev.realtime_clock) for ev in (rocprof.rocprofiler_thread_trace_decoder_realtime_t * n).from_address(events_ptr)]
|
||||
print(f"REALTIME {pairs}")
|
||||
case _:
|
||||
if DEBUG >= 5: print(rocprof.enum_rocprofiler_thread_trace_decoder_record_type_t.get(record_type), events_ptr, n)
|
||||
return rocprof.ROCPROFILER_THREAD_TRACE_DECODER_STATUS_SUCCESS
|
||||
|
||||
@rocprof.rocprof_trace_decoder_isa_callback_t
|
||||
def isa_cb(instr_ptr, mem_size_ptr, size_ptr, pc, data_ptr):
|
||||
instr, mem_size_ptr[0] = ROCParseCtx.disasms[(unwrap(ROCParseCtx.active_kern), pc.address)]
|
||||
def isa_cb(instr_ptr, mem_size_ptr, size_ptr, pc, _):
|
||||
instr, mem_size_ptr[0] = ROCParseCtx.disasms[unwrap(ROCParseCtx.active_kern)][pc.address]
|
||||
|
||||
# this is the number of bytes to next instruction, set to 0 for end_pgm
|
||||
if instr == "s_endpgm": mem_size_ptr[0] = 0
|
||||
@@ -123,9 +147,11 @@ def decode(profile:list[ProfileEvent]) -> _ROCParseCtx:
|
||||
|
||||
return rocprof.ROCPROFILER_THREAD_TRACE_DECODER_STATUS_SUCCESS
|
||||
|
||||
try:
|
||||
rocprof.rocprof_trace_decoder_parse_data(copy_cb, trace_cb, isa_cb, None)
|
||||
except AttributeError as e: raise RuntimeError("Failed to find rocprof-trace-decoder. Run sudo ./extra/sqtt/install_sqtt_decoder.py to install") from e
|
||||
def worker():
|
||||
try: rocprof.rocprof_trace_decoder_parse_data(copy_cb, trace_cb, isa_cb, None)
|
||||
except AttributeError as e: raise RuntimeError("Failed to find rocprof-trace-decoder. Run sudo ./extra/sqtt/install_sqtt_decoder.py to install") from e
|
||||
(t:=threading.Thread(target=worker, daemon=True)).start()
|
||||
t.join()
|
||||
return ROCParseCtx
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
+41
-20
@@ -7,11 +7,9 @@ os.environ["AMD_LLVM"] = "0"
|
||||
|
||||
import unittest
|
||||
import sys, contextlib
|
||||
from tinygrad import Tensor
|
||||
from tinygrad.dtype import dtypes
|
||||
from tinygrad.renderer import ProgramSpec
|
||||
from tinygrad.uop.ops import UOp, Ops, KernelInfo, AddrSpace
|
||||
from tinygrad.engine.realize import CompiledRunner
|
||||
from tinygrad import Tensor, dtypes
|
||||
from tinygrad.helpers import getenv
|
||||
from tinygrad.uop.ops import UOp, Ops, KernelInfo
|
||||
from tinygrad.device import Device, ProfileDeviceEvent
|
||||
|
||||
from extra.sqtt.roc import decode, WaveExec
|
||||
@@ -39,10 +37,10 @@ def save_sqtt():
|
||||
sqtt:dict[str, list[WaveExec]] = {}
|
||||
yield sqtt
|
||||
# decode sqtt
|
||||
if os.environ["DEV"] == "AMD":
|
||||
rctx = decode(dev.profile_events+[ProfileDeviceEvent("AMD", props=dev.device_props())])
|
||||
assert len(rctx.inst_execs) > 0, "empty sqtt output"
|
||||
sqtt.update(rctx.inst_execs)
|
||||
if os.environ["DEV"] != "AMD": return
|
||||
rctx = decode(dev.profile_events+[ProfileDeviceEvent("AMD", props=dev.device_props())])
|
||||
assert len(rctx.inst_execs) > 0, "empty sqtt output"
|
||||
sqtt.update(rctx.inst_execs)
|
||||
|
||||
class TestTiming(unittest.TestCase):
|
||||
def test_v_add(self):
|
||||
@@ -75,7 +73,6 @@ class TestTiming(unittest.TestCase):
|
||||
inp = Tensor([-2.0]).realize()
|
||||
with save_sqtt() as sqtt:
|
||||
Tensor.custom_kernel(out, inp, fxn=custom_vrcp)[0].realize()
|
||||
|
||||
wave = list(sqtt.values())[0][0]
|
||||
for i in range(len(wave.insts)):
|
||||
if wave.insts[i].inst.startswith("global_store"):
|
||||
@@ -84,13 +81,17 @@ class TestTiming(unittest.TestCase):
|
||||
|
||||
def test_wmma(self):
|
||||
with save_sqtt() as sqtt:
|
||||
asm_kernel([
|
||||
"v_wmma_f32_16x16x16_f16 v[16:23], v[0:7], v[8:15], v[16:23]",
|
||||
"v_add_f32_e32 v0 v16 v0",
|
||||
], l=32*4).realize()
|
||||
assert len(sqtt) == 2, f"expected two waves, got {len(sqtt)} {list(sqtt.keys())}"
|
||||
wmma = list(sqtt.values())[0][0]
|
||||
self.assertGreater(wmma.dur, 1) # rgp says 32 clocks
|
||||
for tc in dev.renderer.get_tensor_cores(dev.arch):
|
||||
M, K, N = tc.dims
|
||||
s = 32
|
||||
a = Tensor.empty(M*s, K*s, dtype=tc.dtype_in)@Tensor.empty(K*s, N*s, dtype=tc.dtype_in)
|
||||
a.realize()
|
||||
print(a)
|
||||
for p,waves in sqtt.items():
|
||||
for e in waves[0].insts:
|
||||
if (e.inst.startswith("v_wmma")):
|
||||
instruction = e.inst.split(" ")[0]
|
||||
print(f"{instruction:<29} : {e.dur} cycles")
|
||||
|
||||
def test_sleep(self):
|
||||
n = 1
|
||||
@@ -98,15 +99,35 @@ class TestTiming(unittest.TestCase):
|
||||
assert data0.dtype.base == dtypes.ulong
|
||||
op = custom("unsigned long long t0 = __builtin_readcyclecounter();")
|
||||
op = custom(f"__builtin_amdgcn_s_sleep({n});", op)
|
||||
op = custom(f"unsigned long long t1 = __builtin_readcyclecounter();", op)
|
||||
op = custom("unsigned long long t1 = __builtin_readcyclecounter();", op)
|
||||
op = custom(f"data0_{data0.size}[0] = t1 - t0;", op)
|
||||
return UOp.sink(data0, op, arg=KernelInfo(name=f"sleep_{n}"))
|
||||
diff_hw_reg = Tensor.empty(1, dtype=dtypes.ulong)
|
||||
diff_hw_reg = Tensor.custom_kernel(diff_hw_reg, fxn=sleep_kernel)[0]
|
||||
with save_sqtt() as sqtt:
|
||||
diff_hw_reg.realize()
|
||||
diff_sqtt = list(sqtt.values())[0][2]
|
||||
self.assertEqual(diff_sqtt.dur, diff_hw_reg.item()-1) # 1 cycle for reading the counter register
|
||||
sleep = next((e for e in sqtt[f"sleep_{n}"][0].insts if e.inst.startswith("s_sleep")))
|
||||
# cycles = sleep dur + overhead of storing hi/lo REG_SHADER_CYCLES
|
||||
self.assertGreaterEqual(diff_hw_reg.item(), sleep.dur)
|
||||
|
||||
def test_nop(self):
|
||||
with save_sqtt() as sqtt:
|
||||
asm_kernel(["s_nop 1"]*10).realize()
|
||||
wave = list(sqtt.values())[0][0]
|
||||
for e in wave.insts:
|
||||
print(f"{e.inst} {e.dur=} {e.stall=}")
|
||||
|
||||
def test_wave_sched(self):
|
||||
num_waves = getenv("NUM_WAVES", 16)
|
||||
num_wgps = getenv("NUM_WGPS", 2)
|
||||
num_vgpr = getenv("NUM_VGPR", 256)
|
||||
with save_sqtt() as sqtt:
|
||||
# 1 cycle decode, no stall
|
||||
asm_kernel([f"v_mov_b32_e32 v{i} {i}" for i in range(num_vgpr)], l=32*num_waves, g=num_wgps).realize()
|
||||
waves = list(sqtt.values())[0]
|
||||
print(len(waves), "waves decoded")
|
||||
for w in waves:
|
||||
print(f"{w.wave_id:<2} {w.simd=} {w.cu=} {w.se=} @ clk {w.begin_time}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
AMD=1 AMD_LLVM=1 python -m pytest -n=1 test/test_ops.py test/test_dtype.py test/test_dtype_alu.py test/test_linearizer.py test/test_randomness.py test/test_jit.py test/test_graph.py test/test_multitensor.py --durations=20
|
||||
AMD=1 AMD_LLVM=0 python -m pytest -n=1 test/test_ops.py test/test_dtype.py test/test_dtype_alu.py test/test_linearizer.py test/test_randomness.py test/test_jit.py test/test_graph.py test/test_multitensor.py --durations=20
|
||||
|
||||
CNT=1 AMD_LLVM=0 DEBUG=2 FP8E4M3=1 HALF=0 BFLOAT16=0 SHOULD_USE_TC=1 python extra/gemm/simple_matmul.py
|
||||
CNT=1 AMD_LLVM=0 DEBUG=2 FP8E4M3=0 HALF=1 BFLOAT16=0 SHOULD_USE_TC=1 python extra/gemm/simple_matmul.py
|
||||
CNT=1 AMD_LLVM=0 DEBUG=2 FP8E4M3=0 HALF=0 BFLOAT16=1 SHOULD_USE_TC=1 python extra/gemm/simple_matmul.py
|
||||
|
||||
CNT=1 AMD_LLVM=1 DEBUG=2 FP8E4M3=0 HALF=1 BFLOAT16=0 SHOULD_USE_TC=1 python extra/gemm/simple_matmul.py
|
||||
CNT=1 AMD_LLVM=1 DEBUG=2 FP8E4M3=0 HALF=0 BFLOAT16=1 SHOULD_USE_TC=1 python extra/gemm/simple_matmul.py
|
||||
CNT=1 AMD_LLVM=1 DEBUG=2 FP8E4M3=1 HALF=0 BFLOAT16=0 SHOULD_USE_TC=1 python extra/gemm/simple_matmul.py
|
||||
@@ -1 +1,6 @@
|
||||
WARP_THREADS = 32
|
||||
from tinygrad.device import Device
|
||||
|
||||
if Device.DEFAULT == "AMD":
|
||||
WARP_THREADS = 64
|
||||
else:
|
||||
WARP_THREADS = 32
|
||||
|
||||
@@ -56,13 +56,13 @@ class Group:
|
||||
self.ker.push_store(dst_store, dst)
|
||||
return dst.after(dst_store).reshape(dst.shape)
|
||||
|
||||
def mma_AB(self, c:UOp|RT, a:UOp|RT, b:UOp|RT, after=True):
|
||||
def mma_AB(self, c:UOp|RT, a:UOp|RT, b:UOp|RT):
|
||||
c, a, b = cast(UOp, c), cast(UOp, a), cast(UOp, b)
|
||||
assert self.warps == 1
|
||||
|
||||
for height in self.ker.range(c.shape[-3], track=False):
|
||||
for width in self.ker.range(c.shape[-2], track=False):
|
||||
for inner in self.ker.range(a.shape[-2], AxisType.REDUCE, track=False):
|
||||
for inner in self.ker.range(a.shape[-2], axis_type=AxisType.REDUCE, track=False):
|
||||
wmma_arg = ("WMMA_8_16_16_bfloat16_float", (8, 16, 16), dtypes.bfloat16, dtypes.float, "CUDA", 32, (((4, 2), (3, 2), (8, 2)), ((4, 2), (3, 2)), ((4, 2), (3, 2))), ())
|
||||
|
||||
a_in = UOp.vectorize(*[a[height, inner, i] for i in range(8)])
|
||||
@@ -77,15 +77,15 @@ class Group:
|
||||
c_store = UOp.group(*c_i).end(height, width, inner)
|
||||
|
||||
self.ker.push_store(c_store, c)
|
||||
return c.after(c_store).reshape(c.shape) if after else c_store
|
||||
return c.after(c_store).reshape(c.shape)
|
||||
|
||||
def mma_ABt(self, c:UOp|RT, a:UOp|RT, b:UOp|RT, after=True):
|
||||
def mma_ABt(self, c:UOp|RT, a:UOp|RT, b:UOp|RT):
|
||||
c, a, b = cast(UOp, c), cast(UOp, a), cast(UOp, b)
|
||||
assert self.warps == 1
|
||||
|
||||
for height in self.ker.range(c.shape[-3], track=False):
|
||||
for width in self.ker.range(c.shape[-2], track=False):
|
||||
for inner in self.ker.range(a.shape[-2], AxisType.REDUCE, track=False):
|
||||
for inner in self.ker.range(a.shape[-2], axis_type=AxisType.REDUCE, track=False):
|
||||
wmma_arg = ("WMMA_8_16_16_bfloat16_float", (8, 16, 16), dtypes.bfloat16, dtypes.float, "CUDA", 32, (((4, 2), (3, 2), (8, 2)), ((4, 2), (3, 2)), ((4, 2), (3, 2))), ())
|
||||
|
||||
a_in = UOp.vectorize(*[a[height, inner, i] for i in range(8)])
|
||||
@@ -100,7 +100,7 @@ class Group:
|
||||
c_store = UOp.group(*c_i).end(height, width, inner)
|
||||
|
||||
self.ker.push_store(c_store, c)
|
||||
return c.after(c_store).reshape(c.shape) if after else c_store
|
||||
return c.after(c_store).reshape(c.shape)
|
||||
|
||||
map_rid = 400
|
||||
def map(self, a:ALL_TILES, op:Callable[[UOp], UOp]|Callable[[UOp, tuple], UOp]):
|
||||
@@ -135,8 +135,8 @@ class Group:
|
||||
red_reg = red_reg.after(reg_store).reshape(red_reg.shape)
|
||||
|
||||
for outer in self.ker.range(2, track=False):
|
||||
for width in self.ker.range(src.shape[-2], AxisType.REDUCE, track=False):
|
||||
for inner in self.ker.range(4, AxisType.REDUCE, track=False):
|
||||
for width in self.ker.range(src.shape[-2], axis_type=AxisType.REDUCE, track=False):
|
||||
for inner in self.ker.range(4, axis_type=AxisType.REDUCE, track=False):
|
||||
elem_index = inner + 2 * (inner // 2) + outer * 2
|
||||
reg_store = red_reg[outer].store(op(red_reg[outer], src[height, width, elem_index])).end(inner, width, outer)
|
||||
red_reg = red_reg.after(reg_store).reshape(red_reg.shape)
|
||||
@@ -148,7 +148,7 @@ class Group:
|
||||
|
||||
# reduce from shared memory
|
||||
for outer in self.ker.range(2, track=False):
|
||||
for inner in self.ker.range(3, AxisType.REDUCE, track=False):
|
||||
for inner in self.ker.range(3, axis_type=AxisType.REDUCE, track=False):
|
||||
offset = (self.laneid // 4) * 4 + ((self.laneid + inner + 1) % 4)
|
||||
reg_store = red_reg[outer].store(op(red_reg[outer], red_local[offset, outer])).end(inner, outer)
|
||||
red_reg = red_reg.after(reg_store).reshape(red_reg.shape)
|
||||
@@ -162,7 +162,7 @@ class Group:
|
||||
|
||||
# ops that can work across multiple warps
|
||||
|
||||
LOAD_INNER = 8
|
||||
LOAD_INNER = 4
|
||||
def load(self, dst:ALL_TILES, src:ALL_TILES, dst_idxs:tuple[UOp|int,...]=(), idxs:tuple[UOp|int,...]=(), axis:int=0, transpose:bool=False):
|
||||
dst, src = cast(UOp, dst), cast(UOp, src)
|
||||
assert isinstance(dst.dtype, PtrDType) and isinstance(src.dtype, PtrDType)
|
||||
@@ -177,15 +177,18 @@ class Group:
|
||||
for height in self.ker.range(dst.shape[-3], track=False):
|
||||
for width in self.ker.range(dst.shape[-2], track=False):
|
||||
for inner in self.ker.range(RT.BASE_TILE_NEPT, track=False):
|
||||
base_row = (local_warpid * dst.shape[-3] + height) * RT.BASE_TILE_ROWS
|
||||
base_col = width * RT.BASE_TILE_COLS
|
||||
|
||||
if not transpose:
|
||||
row = (local_warpid * dst.shape[-3] + height) * RT.BASE_TILE_ROWS + (warp_laneid // 4)
|
||||
col = width * RT.BASE_TILE_COLS + 2 * (warp_laneid % 4)
|
||||
row = base_row + (warp_laneid // 4)
|
||||
col = base_col + 2 * (warp_laneid % 4)
|
||||
|
||||
row_offset = ((inner % 4) // 2) * 8
|
||||
col_offset = (inner % 2) + (inner // 4) * 8
|
||||
else:
|
||||
row = (local_warpid * dst.shape[-3] + height) * RT.BASE_TILE_ROWS + 2 * (warp_laneid % 4)
|
||||
col = width * RT.BASE_TILE_COLS + (warp_laneid // 4)
|
||||
row = base_row + 2 * (warp_laneid % 4)
|
||||
col = base_col + (warp_laneid // 4)
|
||||
|
||||
row_offset = (inner % 2) + (inner // 4) * 8
|
||||
col_offset = ((inner % 4) // 2) * 8
|
||||
@@ -222,8 +225,8 @@ class Group:
|
||||
|
||||
return dst.after(dst_store.barrier()).reshape(dst.shape)
|
||||
|
||||
STORE_INNER = 8
|
||||
def store(self, dst:ALL_TILES, src:ALL_TILES, idxs:tuple[UOp|int,...]=(), src_idxs:tuple[UOp|int,...]=(), axis=0, after=True):
|
||||
STORE_INNER = 4
|
||||
def store(self, dst:ALL_TILES, src:ALL_TILES, idxs:tuple[UOp|int,...]=(), src_idxs:tuple[UOp|int,...]=(), axis:int=0, transpose:bool=False):
|
||||
dst, src = cast(UOp, dst), cast(UOp, src)
|
||||
assert isinstance(dst.dtype, PtrDType) and isinstance(src.dtype, PtrDType)
|
||||
dst_dtype, src_dtype = cast(PtrDType, dst.dtype), cast(PtrDType, src.dtype)
|
||||
@@ -237,11 +240,21 @@ 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(RT.BASE_TILE_NEPT, track=False):
|
||||
row = (local_warpid * src.shape[-3] + height) * RT.BASE_TILE_ROWS + (warp_laneid // 4)
|
||||
col = width * RT.BASE_TILE_COLS + 2 * (warp_laneid % 4)
|
||||
base_row = (local_warpid * src.shape[-3] + height) * RT.BASE_TILE_ROWS
|
||||
base_col = width * RT.BASE_TILE_COLS
|
||||
|
||||
row_offset = ((inner % 4) // 2) * 8
|
||||
col_offset = (inner % 2) + (inner // 4) * 8
|
||||
if not transpose:
|
||||
row = base_row + (warp_laneid // 4)
|
||||
col = base_col + 2 * (warp_laneid % 4)
|
||||
|
||||
row_offset = ((inner % 4) // 2) * 8
|
||||
col_offset = (inner % 2) + (inner // 4) * 8
|
||||
else:
|
||||
row = base_row + 2 * (warp_laneid % 4)
|
||||
col = base_col + (warp_laneid // 4)
|
||||
|
||||
row_offset = (inner % 2) + (inner // 4) * 8
|
||||
col_offset = ((inner % 4) // 2) * 8
|
||||
|
||||
dst_i_last = (row + row_offset) * dst.shape[-1] + col + col_offset
|
||||
|
||||
@@ -274,4 +287,4 @@ class Group:
|
||||
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.barrier()).reshape(dst.shape) if after else dst_store
|
||||
return dst.after(dst_store.barrier()).reshape(dst.shape)
|
||||
|
||||
@@ -6,13 +6,15 @@ from extra.thunder.tiny.tk.tiles import GL, ST, RT, RV
|
||||
|
||||
class _tk_range:
|
||||
user_rid = 0
|
||||
def __init__(self, end:int, axis_type:AxisType): self.end, self.axis_type, self.done = end, axis_type, False
|
||||
def __init__(self, start:int, end:int, step:int, axis_type:AxisType):
|
||||
self.start, self.end, self.step = start, end, step
|
||||
self.axis_type, self.done = axis_type, False
|
||||
def __iter__(self): return self
|
||||
def __next__(self):
|
||||
if not self.done:
|
||||
self.done = True
|
||||
_tk_range.user_rid += 1
|
||||
self._rng = UOp.range(self.end, _tk_range.user_rid-1, axis_type=self.axis_type)
|
||||
self._rng = UOp.range(self.end // self.step, _tk_range.user_rid-1, axis_type=self.axis_type) * self.step + self.start
|
||||
return self._rng
|
||||
raise StopIteration
|
||||
|
||||
@@ -43,8 +45,9 @@ class Kernel(AbstractContextManager):
|
||||
@property
|
||||
def warpgroup(self): return self.group(4)
|
||||
|
||||
def range(self, end:int, axis_type:AxisType=AxisType.LOOP, track:bool=True):
|
||||
rng = _tk_range(end, axis_type)
|
||||
def range(self, start:int, end:int=0, step:int=1, axis_type:AxisType=AxisType.LOOP, track:bool=True):
|
||||
if end == 0: start, end = 0, start
|
||||
rng = _tk_range(start, end, step, axis_type)
|
||||
if track: self.range_stack.append(rng)
|
||||
return rng
|
||||
|
||||
@@ -80,7 +83,11 @@ class Kernel(AbstractContextManager):
|
||||
rngs = []
|
||||
while self.range_stack: rngs.append(self.range_stack.pop(0)._rng)
|
||||
|
||||
return self.store_stack.pop()[0]._uop.end(*rngs).sink(arg=KernelInfo(opts_to_apply=())).simplify()
|
||||
last_store = self.store_stack.pop()[0]
|
||||
if hasattr(last_store, '_uop'): uop = last_store._uop
|
||||
else: uop = last_store
|
||||
|
||||
return uop.end(*rngs).sink(arg=KernelInfo(opts_to_apply=())).simplify()
|
||||
|
||||
def endrange(self):
|
||||
last_store = self.store_stack.pop()
|
||||
|
||||
@@ -11,9 +11,9 @@ def unwrap(x):
|
||||
if isinstance(x, dict): return {k: unwrap(v) for k,v in x.items()}
|
||||
return x
|
||||
|
||||
def wrap(x, ker, cls):
|
||||
if isinstance(x, UOp): return cls(x, ker)
|
||||
if isinstance(x, (list, tuple)): return type(x)(wrap(y, ker, cls) for y in x)
|
||||
def wrap(x, s):
|
||||
if isinstance(x, UOp): return s.ruop(x)
|
||||
if isinstance(x, (list, tuple)): return type(x)(wrap(y, s) for y in x)
|
||||
return x
|
||||
|
||||
def autowrap(source_cls, blacklist=None):
|
||||
@@ -31,10 +31,10 @@ def autowrap(source_cls, blacklist=None):
|
||||
if callable(val):
|
||||
@functools.wraps(val)
|
||||
def proxy(*args, **kwargs):
|
||||
return wrap(val(*unwrap(args), **unwrap(kwargs)), self.ker, cls)
|
||||
return wrap(val(*unwrap(args), **unwrap(kwargs)), self)
|
||||
return proxy
|
||||
if name in UOp.__slots__: return val
|
||||
return wrap(val, self.ker, cls)
|
||||
return wrap(val, self)
|
||||
cls.__getattr__ = __getattr__
|
||||
|
||||
for name in dir(source_cls):
|
||||
@@ -46,9 +46,9 @@ def autowrap(source_cls, blacklist=None):
|
||||
else:
|
||||
original = getattr(source_cls, name)
|
||||
if callable(original):
|
||||
def make_proxy(op_name, func):
|
||||
def make_proxy(_, func):
|
||||
def proxy(self, *args, **kwargs):
|
||||
return wrap(func(self._uop, *unwrap(args), **unwrap(kwargs)), self.ker, cls)
|
||||
return wrap(func(self._uop, *unwrap(args), **unwrap(kwargs)), self)
|
||||
return proxy
|
||||
setattr(cls, name, make_proxy(name, original))
|
||||
|
||||
@@ -69,7 +69,7 @@ class TileMathMixin(MathMixin):
|
||||
if isinstance(self, RT) and isinstance(src[0], RV): uop = self.ker.warp.map(self._uop, lambda x, idx: UOp.alu(x, op, inner_op(src[0]._uop[idx[0], 0, (idx[2]%4)//2])))
|
||||
else: uop = self.ker.warp.map(self._uop, lambda x, idx: UOp.alu(x, op, inner_op(src[0]._uop[*idx])))
|
||||
else: raise NotImplementedError
|
||||
return type(self)(uop, self.ker)
|
||||
return self.ruop(uop)
|
||||
def const_like(self, b): return b
|
||||
|
||||
# override ops that do compute on the src uop
|
||||
@@ -83,6 +83,9 @@ class GL:
|
||||
def __init__(self, uop, ker):
|
||||
self._uop, self.ker = uop, ker
|
||||
|
||||
def ruop(self, uop):
|
||||
return GL(uop, self.ker)
|
||||
|
||||
@classmethod
|
||||
def create(cls, shape, dtype, ker):
|
||||
uop = ker.alloc(shape, dtype, AddrSpace.GLOBAL)
|
||||
@@ -93,6 +96,9 @@ class ST:
|
||||
def __init__(self, uop, ker):
|
||||
self._uop, self.ker = uop, ker
|
||||
|
||||
def ruop(self, uop):
|
||||
return ST(uop, self.ker)
|
||||
|
||||
@classmethod
|
||||
def create(cls, shape, dtype, ker):
|
||||
uop = ker.alloc(shape, dtype, AddrSpace.LOCAL)
|
||||
@@ -107,6 +113,9 @@ class RT(TileMathMixin):
|
||||
def __init__(self, uop, ker):
|
||||
self._uop, self.ker = uop, ker
|
||||
|
||||
def ruop(self, uop):
|
||||
return RT(uop, self.ker)
|
||||
|
||||
@classmethod
|
||||
def create(cls, shape, dtype, ker):
|
||||
assert len(shape) == 2
|
||||
@@ -121,8 +130,11 @@ class RT(TileMathMixin):
|
||||
|
||||
@autowrap(UOp)
|
||||
class RV(TileMathMixin):
|
||||
def __init__(self, uop, ker):
|
||||
self._uop, self.ker = uop, ker
|
||||
def __init__(self, uop, layout, ker):
|
||||
self._uop, self.layout, self.ker = uop, layout, ker
|
||||
|
||||
def ruop(self, uop):
|
||||
return RV(uop, self.layout, self.ker)
|
||||
|
||||
@classmethod
|
||||
def create(cls, length, dtype, layout, ker):
|
||||
@@ -138,6 +150,6 @@ class RV(TileMathMixin):
|
||||
case _: raise NotImplementedError(f"rv layout {layout} not implemented")
|
||||
|
||||
uop = ker.alloc((outer_dim, inner_dim, 2), dtype, AddrSpace.REG)
|
||||
return RV(uop, ker)
|
||||
return RV(uop, layout, ker)
|
||||
|
||||
ALL_TILES = UOp | GL | ST | RT | RV
|
||||
|
||||
@@ -8,4 +8,4 @@ if __name__ == "__main__":
|
||||
parser.add_argument("--dest", type=str, required=True, help="destination path to save the file")
|
||||
args = parser.parse_args()
|
||||
|
||||
Tensor(bytes.fromhex(args.hash), device="CPU").load(args.len).to(f"disk:{args.dest}").realize()
|
||||
Tensor(bytes.fromhex(args.hash), device="CPU").fs_load(args.len).to(f"disk:{args.dest}").realize()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import json, multiprocessing
|
||||
import json, multiprocessing, functools
|
||||
from pathlib import Path
|
||||
|
||||
from tinygrad.tensor import Tensor
|
||||
@@ -14,23 +14,25 @@ def fetch_file(item):
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
pt = Tensor(bytes.fromhex(h), device="CPU").load(size).to(f"disk:{path.as_posix()}").realize()
|
||||
pt = Tensor(bytes.fromhex(h), device="CPU").fs_load(size).to(f"disk:{path.as_posix()}").realize()
|
||||
except Exception as e:
|
||||
print(f"error fetching {path}, {h}, {size}: {e}")
|
||||
raise
|
||||
|
||||
pt.uop.buffer.deallocate()
|
||||
|
||||
def fetch_mapping():
|
||||
mapping_tensor = Tensor(bytes.fromhex("d734f5e3be9f1e9d863bfaa4fc6c1ef2")).load(175866113).realize()
|
||||
def fetch_mapping(h, l):
|
||||
mapping_tensor = Tensor(bytes.fromhex(h)).fs_load(l).realize()
|
||||
mapping = mapping_tensor.data().tobytes().decode()
|
||||
mapping = json.loads(mapping)
|
||||
mapped_files = mapping.items()
|
||||
return list(mapped_files)
|
||||
|
||||
if __name__ == "__main__":
|
||||
h, l = getenv("HASH", "d734f5e3be9f1e9d863bfaa4fc6c1ef2"), getenv("LENGTH", 175866113)
|
||||
|
||||
with multiprocessing.Pool(processes=1) as pool:
|
||||
mapped_files = pool.apply(fetch_mapping)
|
||||
mapped_files = pool.apply(functools.partial(fetch_mapping, h, l))
|
||||
|
||||
print(f"fetched mapping for {len(mapped_files)} files")
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ raid_root = Path("/raid")
|
||||
|
||||
def upload_file(path: Path):
|
||||
pt = Tensor(path).realize()
|
||||
h = pt.store().realize()
|
||||
h = pt.fs_store().realize()
|
||||
pt.uop.realized.deallocate()
|
||||
return h.data().hex(), path, pt.nbytes()
|
||||
|
||||
@@ -26,6 +26,6 @@ if __name__ == "__main__":
|
||||
|
||||
mapping = json.dumps(mapping).encode()
|
||||
mapping_tensor = Tensor(mapping, device="CPU")
|
||||
h = mapping_tensor.store().realize()
|
||||
h = mapping_tensor.fs_store().realize()
|
||||
|
||||
print(f"final hash: {h.data().hex()}, size: {len(mapping)}")
|
||||
|
||||
+258
-161
@@ -4,10 +4,10 @@
|
||||
# A006 Lambda argument `input` is shadowing a Python builtin
|
||||
from tinygrad import Tensor, dtypes, Device
|
||||
from tinygrad.uop.ops import Ops
|
||||
from tinygrad.helpers import getenv, prod
|
||||
from tinygrad.helpers import getenv, prod, strides_for_shape, argfix
|
||||
import torch.lib
|
||||
TORCH_DEBUG = getenv("TORCH_DEBUG")
|
||||
import torch, pathlib, math, operator, functools, inspect
|
||||
import torch, pathlib, math, operator, functools, weakref
|
||||
torch.autograd.grad_mode.set_multithreading_enabled(False)
|
||||
from tinygrad.dtype import _from_torch_dtype, _to_torch_dtype
|
||||
|
||||
@@ -18,7 +18,17 @@ def _to_torch_device(device: str): return torch.device("tiny", int(device.partit
|
||||
|
||||
import torch.utils.cpp_extension
|
||||
mod = torch.utils.cpp_extension.load(name="custom_device_extension", sources=[str(pathlib.Path(__file__).parent / "wrapped_tensor.cpp")])
|
||||
def wrap(x:Tensor) -> torch.Tensor: return mod.wrap(x, _to_torch_dtype(x.dtype), _to_torch_device(x.device).index)
|
||||
def calculate_storage_offset(x: Tensor) -> int:
|
||||
offset = 0
|
||||
for u in x.uop.toposort():
|
||||
if u.op == Ops.SHRINK:
|
||||
u_strides = strides_for_shape(u.src[0].shape)
|
||||
for i, (start, _) in enumerate(u.marg): offset += start * u_strides[i]
|
||||
return offset
|
||||
def wrap(x: Tensor) -> torch.Tensor:
|
||||
x._strides = strides_for_shape(x.shape) # always recalculate
|
||||
if (not hasattr(x, '_storage_offset')) or (not x.uop.is_realized): x._storage_offset = calculate_storage_offset(x)
|
||||
return mod.wrap(x, _to_torch_dtype(x.dtype), _to_torch_device(x.device).index)
|
||||
def unwrap(x:torch.Tensor) -> Tensor:
|
||||
assert isinstance(x, torch.Tensor), f"x isn't {type(x)}"
|
||||
return mod.unwrap(x)
|
||||
@@ -35,17 +45,20 @@ torch.utils.generate_methods_for_privateuse1_backend()
|
||||
aten = torch.ops.aten
|
||||
|
||||
# track view relationships for in place operations
|
||||
def is_view(tensor: Tensor): return hasattr(tensor, "_view_base")
|
||||
def canonical_base(view: Tensor): return getattr(view, "_view_base", view)
|
||||
def derived_views(base: Tensor): return [t for tref in getattr(base, "_views", set()) if (t:=tref()) is not None]
|
||||
def unwrap_args(args, kwargs):
|
||||
return [unwrap(x) if isinstance(x, torch.Tensor) else x for x in args], {k:unwrap(v) if isinstance(v, torch.Tensor) else v for k,v in kwargs.items()}
|
||||
def wrap_view_op(fn):
|
||||
def _wrap(*args,**kwargs):
|
||||
args = [unwrap(x) if isinstance(x, torch.Tensor) else x for x in args]
|
||||
kwargs = {k:unwrap(v) if isinstance(v, torch.Tensor) else v for k,v in kwargs.items()}
|
||||
ret = fn(*args,**kwargs)
|
||||
ret._view_base = base = canonical_base(args[0])
|
||||
if not hasattr(base, "_views"): base._views = set()
|
||||
@functools.wraps(fn)
|
||||
def _wrap(*args, **kwargs):
|
||||
args, kwargs = unwrap_args(args, kwargs)
|
||||
ret = fn(*args, **kwargs)
|
||||
base = canonical_base(args[0])
|
||||
ret._view_base = base
|
||||
base._views = getattr(base, "_views", set())
|
||||
base._views.add(weakref.ref(ret))
|
||||
ret._view_ops = _get_view_ops(args[0]) + [(fn, args[1:], kwargs)]
|
||||
return wrap(ret)
|
||||
return _wrap
|
||||
|
||||
@@ -58,48 +71,83 @@ view_ops = {
|
||||
"aten.transpose.int": Tensor.transpose,
|
||||
"aten.squeeze.dim": Tensor.squeeze,
|
||||
"aten.unsqueeze": Tensor.unsqueeze,
|
||||
"aten.detach": Tensor.detach,
|
||||
"aten.select.int": lambda self, dim, idx: self[(slice(None),) * (dim%self.ndim) + (idx,)],
|
||||
}
|
||||
"aten.permute": Tensor.permute,
|
||||
"aten.alias": lambda self: self,
|
||||
}
|
||||
|
||||
# torch 2.10 handles this natively
|
||||
if tuple(map(int, torch.__version__.split('.')[:2])) < (2, 10): view_ops.update({"aten.detach": Tensor.detach})
|
||||
|
||||
for k,v in view_ops.items(): torch.library.impl(k.replace("aten.", "aten::"), "privateuseone")(wrap_view_op(v))
|
||||
|
||||
# in place operations with views
|
||||
def realize_with_views(self: Tensor, views: Tensor):
|
||||
if not self.uop.st.contiguous: self.replace(self.contiguous())
|
||||
self.replace(self.clone().realize())
|
||||
for v in views:
|
||||
if v.uop.base.op is Ops.BUFFER_VIEW: continue # skip subbuffer, we just use the real buffer view
|
||||
ret = self
|
||||
st = ShapeTracker(self.uop.st.views + v.uop.st.views) # TODO: is this right?
|
||||
for mo in cached_to_movement_ops(self.shape, st): ret = apply_mop(ret, mo)
|
||||
v.replace(ret)
|
||||
def maybe_realize_storage(self: Tensor) -> bool:
|
||||
if realize:=is_view(self): realize_with_views((base:=canonical_base(self)), derived_views(base))
|
||||
return realize
|
||||
def inplace_fn(outvars: str|list[str]):
|
||||
if type(outvars) is str: outvars = [outvars]
|
||||
def decorator(fn):
|
||||
sig = inspect.signature(fn)
|
||||
def wrapper(*args, **kwargs):
|
||||
bound = sig.bind(*args, **kwargs)
|
||||
outs = [kwargs.get(v, bound.arguments.get(v)) for v in outvars]
|
||||
outs = [unwrap(o) if isinstance(o, torch.Tensor) else o for o in outs]
|
||||
realize = any(maybe_realize_storage(o) for o in outs)
|
||||
ret = fn(*args, **kwargs)
|
||||
if realize: Tensor.realize(*(o for o in outs))
|
||||
return ret
|
||||
return wrapper
|
||||
return decorator
|
||||
def _get_view_ops(view): return getattr(view, "_view_ops", [])
|
||||
|
||||
def _apply_view_ops(target, ops):
|
||||
for fn, args, kwargs in ops: target = fn(target, *args, **kwargs)
|
||||
return target
|
||||
|
||||
# similar to https://github.com/pytorch/pytorch/blob/main/aten/src/ATen/InferSize.h
|
||||
def _reshape_target_shape(shape:tuple[int, ...], args) -> tuple[int, ...]|None:
|
||||
if not (req := argfix(*args)): return None
|
||||
new_shape, infer_idx = [], -1
|
||||
for i, s in enumerate(req):
|
||||
if s is None: s = shape[i] if i < len(shape) else None
|
||||
if not isinstance(s, int): return None
|
||||
if s == -1:
|
||||
if infer_idx != -1: return None
|
||||
infer_idx = len(new_shape)
|
||||
new_shape.append(s)
|
||||
total = prod(shape)
|
||||
if infer_idx != -1:
|
||||
known = prod(x for x in new_shape if x != -1)
|
||||
if known == 0:
|
||||
if total != 0: return None
|
||||
new_shape[infer_idx] = 0
|
||||
else: new_shape[infer_idx] = total // known
|
||||
return tuple(new_shape) if prod(new_shape) == total else None
|
||||
|
||||
# TODO: can we get rid of this? only for test_flatten_reshape_add
|
||||
def _try_simple_reshape_view_write(base: Tensor, view: Tensor, val: Tensor) -> bool:
|
||||
if not (ops := _get_view_ops(view)): return False
|
||||
shapes = [base.shape]
|
||||
for fn, args, _ in ops:
|
||||
if fn is Tensor.reshape:
|
||||
if not (next_shape := _reshape_target_shape(shapes[-1], args)): return False
|
||||
shapes.append(next_shape)
|
||||
if shapes[-1] != view.shape: return False
|
||||
for s in reversed(shapes[:-1]): val = val.reshape(s)
|
||||
base.assign(val)
|
||||
return True
|
||||
|
||||
def _view_write(base: Tensor, view: Tensor, value: Tensor) -> None:
|
||||
val = value if value.dtype == base.dtype else value.cast(base.dtype)
|
||||
if view.shape == base.shape: return base.assign(val)
|
||||
if _try_simple_reshape_view_write(base, view, val): return
|
||||
idx_base = Tensor.arange(base.numel(), device=base.device, dtype=dtypes.int32).reshape(base.shape)
|
||||
idx_view = _apply_view_ops(idx_base, _get_view_ops(view)).reshape(-1)
|
||||
flat_base = base.reshape(base.numel()).contiguous()
|
||||
flat_base[idx_view] = val.reshape(-1)
|
||||
base.assign(flat_base.reshape(base.shape))
|
||||
|
||||
def _apply_inplace(target: Tensor, value: Tensor) -> None:
|
||||
val = value if value.dtype == target.dtype else value.cast(target.dtype)
|
||||
base = canonical_base(target)
|
||||
views = derived_views(base)
|
||||
if not views: return target.assign(val)
|
||||
view_ops_map = {v: _get_view_ops(v) for v in views}
|
||||
if target is base or target.uop is base.uop: base.assign(val)
|
||||
else: _view_write(base, target, val)
|
||||
for v in views: v.replace(_apply_view_ops(base, view_ops_map[v]))
|
||||
|
||||
# *** bad functions on CPU ***
|
||||
|
||||
@torch.library.impl("aten::_index_put_impl_", "privateuseone")
|
||||
@inplace_fn("self")
|
||||
def _index_put_impl_(self, indices, values, accumulate=False, unsafe=False):
|
||||
# TODO: move to tinygrad
|
||||
ret = aten._index_put_impl_(self.cpu(), [x.cpu() if isinstance(x, torch.Tensor) else None for x in indices], values.cpu(), accumulate, unsafe).to(self.device)
|
||||
return wrap(unwrap(self).assign(unwrap(ret)))
|
||||
unwrap(self).assign(unwrap(ret))
|
||||
return self
|
||||
|
||||
@torch.library.impl("aten::index_put", "privateuseone")
|
||||
def index_put(self, indices, values, accumulate=False):
|
||||
@@ -150,43 +198,23 @@ for i in [
|
||||
def index_tensor(x, y):
|
||||
return wrap(unwrap(x)[[unwrap(_y.to(x.device)) if _y is not None else slice(None) for _y in y]])
|
||||
|
||||
@torch.library.impl("aten::zero_", "privateuseone")
|
||||
@inplace_fn("x")
|
||||
def zero_(x):
|
||||
if TORCH_DEBUG: print(f"zero_ {x.shape}")
|
||||
tt = unwrap(x)
|
||||
tt.assign(tt.zeros_like())
|
||||
|
||||
@torch.library.impl("aten::fill_.Scalar", "privateuseone")
|
||||
@inplace_fn("x")
|
||||
def fill_scalar(x, y):
|
||||
if TORCH_DEBUG: print(f"fill_.Scalar {x.shape} {y}")
|
||||
tt = unwrap(x)
|
||||
tt.assign(tt.full_like(y))
|
||||
|
||||
@torch.library.impl("aten::_local_scalar_dense", "privateuseone")
|
||||
def _local_scalar_dense(tensor): return unwrap(tensor).item()
|
||||
|
||||
@functools.cache
|
||||
def cached_to_movement_ops(shape, st) -> list:
|
||||
mops = to_movement_ops(st)
|
||||
if mops[0] == (MovementOps.RESHAPE, shape): mops = mops[1:]
|
||||
return mops
|
||||
|
||||
from tinygrad.shape.shapetracker import ShapeTracker, View
|
||||
from extra.to_movement_ops import to_movement_ops, apply_mop, MovementOps
|
||||
|
||||
@wrap_view_op
|
||||
def _as_strided(tensor:Tensor, size, stride, storage_offset=None):
|
||||
# multiple as_strided do not compound
|
||||
base = canonical_base(tensor)
|
||||
# TODO: this is heavyweight
|
||||
st = ShapeTracker(base.uop.st.views + (View.create(tuple(size), tuple(stride), storage_offset),))
|
||||
ret = base
|
||||
if TORCH_DEBUG >= 1: print("**** as_strided", tensor.shape, size, stride, st)
|
||||
if prod(size) == 1: return ret.flatten()[storage_offset].reshape(size)
|
||||
for mo in cached_to_movement_ops(tuple(base.shape), st): ret = apply_mop(ret, mo)
|
||||
return ret
|
||||
def _as_strided(tensor:Tensor, size, stride, storage_offset=0):
|
||||
base = getattr(tensor, "_as_strided_base", canonical_base(tensor)).flatten()
|
||||
if prod(size) == 1: return base[storage_offset].reshape(size)
|
||||
indices = Tensor.zeros(size, dtype=dtypes.int32, device=base.device) + storage_offset
|
||||
for dim, (sz, st) in enumerate(zip(size, stride)):
|
||||
if st != 0:
|
||||
dim_range = Tensor.arange(sz, device=base.device, dtype=dtypes.int32) * st
|
||||
shape_for_broadcast = [1] * dim + [sz] + [1] * (len(size) - dim - 1)
|
||||
indices = indices + dim_range.reshape(shape_for_broadcast)
|
||||
result = base[indices.flatten()].reshape(size)
|
||||
result._as_strided_base = base
|
||||
return result
|
||||
|
||||
@torch.library.impl("aten::as_strided", "privateuseone")
|
||||
def as_strided(tensor:torch.Tensor, size, stride, storage_offset=None):
|
||||
@@ -245,15 +273,14 @@ def convolution_overrideable(input, weight, bias, stride, padding, dilation, tra
|
||||
if TORCH_DEBUG >= 1:
|
||||
print(f"convolution {input.shape=} {weight.shape=} {stride=} {padding=} {dilation=} {transposed=} {output_padding=} {groups=}")
|
||||
input, weight, bias = unwrap(input), unwrap(weight), unwrap(bias) if bias is not None else None
|
||||
# TODO: fix test_biased_conv2d fails without realize()
|
||||
if not transposed: return wrap(input.conv2d(weight, bias, groups=groups, stride=stride, dilation=dilation, padding=padding).realize())
|
||||
return wrap(input.conv_transpose2d(weight, bias, groups=groups, stride=stride, dilation=dilation, padding=padding, output_padding=output_padding).realize())
|
||||
if not transposed: return wrap(input.conv2d(weight, bias, groups=groups, stride=stride, dilation=dilation, padding=padding))
|
||||
return wrap(input.conv_transpose2d(weight, bias, groups=groups, stride=stride, dilation=dilation, padding=padding, output_padding=output_padding))
|
||||
|
||||
@torch.library.impl("aten::convolution_backward_overrideable", "privateuseone")
|
||||
def convolution_backward_overrideable(grad_out, input, weight, stride, padding, dilation, transposed, output_padding, groups, output_mask):
|
||||
if TORCH_DEBUG >= 1:
|
||||
print(f"convolution_backward {input.shape=} {weight.shape=} {stride=} {padding=} {dilation=} {transposed=} {output_padding=} {groups=}")
|
||||
grad_out, input, weight, bias = unwrap(grad_out), unwrap(input), unwrap(weight), Tensor.zeros(weight.shape[0], device=_from_torch_device(weight.device))
|
||||
grad_out, input, weight, bias = unwrap(grad_out).detach(), unwrap(input).detach(), unwrap(weight).detach(), Tensor.zeros(weight.shape[0], device=_from_torch_device(weight.device))
|
||||
if not transposed: out = Tensor.conv2d(input, weight, bias, groups=groups, stride=stride, dilation=dilation, padding=padding)
|
||||
else:
|
||||
bias = Tensor.zeros(weight.shape[1] * groups)
|
||||
@@ -315,55 +342,57 @@ for i,pre in enumerate(["", "bi", "tri"]):
|
||||
torch.library.impl(f"aten::_upsample_nearest_exact{i+1}d", "privateuseone")(functools.partial(upsample, mode="nearest-exact"))
|
||||
|
||||
@torch.library.impl("aten::scatter_add.out", "privateuseone")
|
||||
@inplace_fn("out")
|
||||
def scatter_add(self, dim, index, src, out):
|
||||
self, index, src, out = unwrap(self), unwrap(index), unwrap(src), unwrap(out)
|
||||
if self.shape == (): return wrap(out.assign(src))
|
||||
return wrap(out.assign(Tensor.scatter_reduce(self, dim, index, src, reduce='sum')))
|
||||
self, index, src, out_unwrapped = unwrap(self), unwrap(index), unwrap(src), unwrap(out)
|
||||
if self.shape == (): _apply_inplace(out_unwrapped, src)
|
||||
else: _apply_inplace(out_unwrapped, Tensor.scatter_reduce(self, dim, index, src, reduce='sum'))
|
||||
return out
|
||||
|
||||
@torch.library.impl("aten::_copy_from", "privateuseone")
|
||||
def _copy_from(src: torch.Tensor, dest, non_blocking=False):
|
||||
realize = dest.is_tiny and maybe_realize_storage(unwrap(dest))
|
||||
cast_dtype = _from_torch_dtype(dest.dtype)
|
||||
def _copy_between_devices(src, dest, cast_dtype, to_device, non_blocking=False):
|
||||
if src.is_tiny and dest.is_tiny:
|
||||
to_device = _from_torch_device(dest.device)
|
||||
src,dest = unwrap(src),unwrap(dest)
|
||||
# TODO we need to properly match dest shape and strides, not blindly assign
|
||||
if dest.uop.st.contiguous or dest.uop.is_realized: src = src.contiguous() # this only solves some cases
|
||||
dest.assign(src.cast(cast_dtype).to(to_device))
|
||||
if realize: Tensor.realize(dest)
|
||||
src_t, dest_t = unwrap(src), unwrap(dest)
|
||||
if dest_t.uop.is_contiguous() or dest_t.uop.is_realized: src_t = src_t.contiguous()
|
||||
_apply_inplace(dest_t, src_t.cast(cast_dtype).to(to_device))
|
||||
elif src.is_tiny and dest.is_cpu:
|
||||
# TODO: is there a better way?
|
||||
dest.resize_(src.numel()).resize_(src.shape)
|
||||
dest.copy_(torch.from_numpy(unwrap(src).cast(cast_dtype).numpy()))
|
||||
elif src.is_cpu and dest.is_tiny:
|
||||
to_device = _from_torch_device(dest.device)
|
||||
# TODO we need to properly match dest shape and strides, not blindly assign
|
||||
unwrap(dest).assign(Tensor(src.numpy()).cast(cast_dtype).to(to_device))
|
||||
if realize: Tensor.realize(unwrap(dest))
|
||||
else:
|
||||
raise NotImplementedError(f"can't copy from {src.device} -> {dest.device}")
|
||||
|
||||
@torch.library.impl("aten::_copy_from", "privateuseone")
|
||||
def _copy_from(src: torch.Tensor, dest, non_blocking=False):
|
||||
cast_dtype = _from_torch_dtype(dest.dtype)
|
||||
to_device = _from_torch_device(dest.device)
|
||||
_copy_between_devices(src, dest, cast_dtype, to_device, non_blocking)
|
||||
return dest
|
||||
|
||||
@torch.library.impl("aten::copy_", "privateuseone")
|
||||
def copy_(self, src, non_blocking=False):
|
||||
cast_dtype = _from_torch_dtype(self.dtype)
|
||||
to_device = _from_torch_device(self.device)
|
||||
_copy_between_devices(src, self, cast_dtype, to_device, non_blocking)
|
||||
return self
|
||||
|
||||
@torch.library.impl("aten::cat.out", "privateuseone")
|
||||
@inplace_fn("out")
|
||||
def cat_out(tensors, dim=0, out=None):
|
||||
unwrap(out).assign(Tensor.cat(*[unwrap(x) for x in tensors], dim=dim))
|
||||
_apply_inplace(unwrap(out), Tensor.cat(*[unwrap(x) for x in tensors], dim=dim))
|
||||
return out
|
||||
|
||||
@torch.library.impl("aten::topk.values", "privateuseone")
|
||||
@inplace_fn(["values", "indices"])
|
||||
def topk_values(input, k, dim=None, largest=True, sorted=True, values=None, indices=None):
|
||||
out_values, out_indices = unwrap(input).topk(k, dim if dim is not None else -1, largest, sorted)
|
||||
unwrap(values).assign(out_values)
|
||||
unwrap(indices).assign(out_indices.cast(dtypes.int64))
|
||||
return wrap(out_values), wrap(out_indices)
|
||||
_apply_inplace(unwrap(values), out_values)
|
||||
_apply_inplace(unwrap(indices), out_indices.cast(dtypes.int64))
|
||||
return values, indices
|
||||
|
||||
@torch.library.impl("aten::sort.values_stable", "privateuseone")
|
||||
@inplace_fn(["values", "indices"])
|
||||
def sort_values(input, dim=-1, descending=False, stable=True, values=None, indices=None):
|
||||
out_values, out_indices = unwrap(input).sort(dim, descending)
|
||||
unwrap(values).assign(out_values)
|
||||
unwrap(indices).assign(out_indices.cast(dtypes.int64))
|
||||
return wrap(out_values), wrap(out_indices)
|
||||
_apply_inplace(unwrap(values), out_values)
|
||||
_apply_inplace(unwrap(indices), out_indices.cast(dtypes.int64))
|
||||
return values, indices
|
||||
|
||||
@torch.library.impl("aten::_linalg_svd", "privateuseone")
|
||||
def _linalg_svd(self, full_matrices=False):
|
||||
@@ -373,7 +402,6 @@ def _linalg_svd(self, full_matrices=False):
|
||||
# register some decompositions
|
||||
from torch._decomp import get_decompositions
|
||||
decomps = [
|
||||
aten.native_batch_norm, aten.native_batch_norm_backward,
|
||||
aten.native_layer_norm_backward,
|
||||
aten.linalg_cross,
|
||||
aten.addmm,
|
||||
@@ -510,7 +538,6 @@ tiny_backend_out = {**{f"aten.{x}.out":getattr(Tensor,x) for x in simple_tensor_
|
||||
|
||||
# we add the "out" here
|
||||
def wrap_out(f):
|
||||
@inplace_fn("out")
|
||||
def _wrap_out(*args, **kwargs):
|
||||
out = kwargs.pop('out')
|
||||
assigned = f(*args, **kwargs)
|
||||
@@ -518,22 +545,33 @@ def wrap_out(f):
|
||||
assert out.shape == assigned.shape, f"shape mismatch: {assigned.shape} -> {out.shape}"
|
||||
assert out.device == assigned.device, f"device mismatch: {assigned.device} -> {out.device}"
|
||||
assert out.dtype == assigned.dtype, f"dtype mismatch: {assigned.dtype} -> {out.dtype}"
|
||||
if out.uop.is_realized: assigned = assigned.contiguous() # TODO: how does this map to torch's semantics
|
||||
return out.assign(assigned)
|
||||
return _wrap_out
|
||||
|
||||
def _inplace_op(t, new_value):
|
||||
if not hasattr(t, "_view_base") and not getattr(canonical_base(t), "_views", set()): t.replace(new_value)
|
||||
else: _apply_inplace(t, new_value)
|
||||
return t
|
||||
|
||||
tiny_backend = {**{k:wrap_out(v) for k,v in tiny_backend_out.items()}, **{
|
||||
"aten.remainder.Scalar_Tensor": lambda x,y: x%y,
|
||||
"aten.floor_divide": lambda x,y: x//y,
|
||||
"aten.floor_divide_.Tensor": inplace_fn("x")(lambda x,y: x.assign(x//y)),
|
||||
"aten.floor_divide_.Tensor": lambda x,y: x//y,
|
||||
# TODO: use tinygrad methods, but they require x to be unsigned
|
||||
"aten.__lshift__.Scalar": lambda x,y: x*(2**y),
|
||||
"aten.__ilshift__.Scalar": inplace_fn("x")(lambda x,y: x.assign(x*(2**y))),
|
||||
"aten.__ilshift__.Scalar": lambda x,y: x*(2**y),
|
||||
"aten.__rshift__.Scalar": lambda x,y: x//(2**y),
|
||||
"aten.__irshift__.Scalar": inplace_fn("x")(lambda x,y: x.assign(x//(2**y))),
|
||||
"aten.__irshift__.Scalar": lambda x,y: x//(2**y),
|
||||
# inplace ops using replace for fusion
|
||||
"aten.zero_": lambda x: x.zeros_like(),
|
||||
"aten.fill_.Scalar": lambda x, y: x.full_like(y),
|
||||
"aten.add_.Tensor": lambda self, other, alpha=1.0: self + other * alpha,
|
||||
"aten.add_.Scalar": lambda self, other, alpha=1.0: self + other * alpha,
|
||||
"aten.mul_.Tensor": lambda self, other: self * other,
|
||||
"aten.mul_.Scalar": lambda self, other: self * other,
|
||||
# relu doesn't have an out form?
|
||||
"aten.relu": Tensor.relu,
|
||||
"aten.relu_": inplace_fn("x")(lambda x: x.assign(x.relu())),
|
||||
"aten.relu_": lambda x: x.relu(),
|
||||
"aten.mean": Tensor.mean,
|
||||
"aten.mean.dim": Tensor.mean,
|
||||
"aten.min": Tensor.min,
|
||||
@@ -554,19 +592,17 @@ tiny_backend = {**{k:wrap_out(v) for k,v in tiny_backend_out.items()}, **{
|
||||
"aten.repeat": lambda x,*repeats: Tensor.repeat(x,*repeats).contiguous(), # not a view
|
||||
"aten._softmax": lambda self,dim,half_to_float: self.softmax(dim),
|
||||
"aten._log_softmax": lambda self,dim,half_to_float: self.log_softmax(dim),
|
||||
"aten.random_": inplace_fn("self")(lambda self:
|
||||
self.assign(Tensor.randint(*self.shape, low=dtypes.min(self.dtype), high=dtypes.max(self.dtype), device=self.device, dtype=self.dtype))),
|
||||
"aten.random_.from": inplace_fn("self")(lambda self, from_, to:
|
||||
self.assign(Tensor.randint(*self.shape, low=from_, high=to, device=self.device, dtype=self.dtype))),
|
||||
"aten.uniform_": inplace_fn("self")(lambda self, low=0, high=1: self.assign(Tensor.uniform(*self.shape, low=low, high=high, dtype=self.dtype))),
|
||||
"aten.normal_": inplace_fn("self")(lambda self, mean=0, std=1: self.assign(Tensor.normal(*self.shape, mean=mean, std=std, dtype=self.dtype))),
|
||||
"aten.random_": lambda self: Tensor.randint(*self.shape, low=dtypes.min(self.dtype), high=dtypes.max(self.dtype), device=self.device, dtype=self.dtype),
|
||||
"aten.random_.from": lambda self, from_, to: Tensor.randint(*self.shape, low=from_, high=to, device=self.device, dtype=self.dtype),
|
||||
"aten.uniform_": lambda self, low=0, high=1: Tensor.uniform(*self.shape, low=low, high=high, dtype=self.dtype),
|
||||
"aten.normal_": lambda self, mean=0, std=1: Tensor.normal(*self.shape, mean=mean, std=std, dtype=self.dtype),
|
||||
# these don't work in out form, they have size 0
|
||||
"aten.abs": Tensor.abs,
|
||||
"aten.logical_not": Tensor.logical_not,
|
||||
"aten.logical_or_": inplace_fn("x")(lambda x, y: x.assign(x | y)),
|
||||
"aten.logical_or_": lambda x, y: x | y,
|
||||
"aten.multinomial": Tensor.multinomial,
|
||||
"aten.masked_fill_.Scalar": inplace_fn("self")(lambda self, mask, value: self.assign(self.masked_fill(mask, value))),
|
||||
"aten.masked_fill_.Tensor": inplace_fn("self")(lambda self, mask, value: self.assign(self.masked_fill(mask, value))),
|
||||
"aten.masked_fill_.Scalar": lambda self, mask, value: self.masked_fill(mask, value),
|
||||
"aten.masked_fill_.Tensor": lambda self, mask, value: self.masked_fill(mask, value),
|
||||
"aten.masked_fill.Scalar": Tensor.masked_fill,
|
||||
"aten.masked_fill.Tensor": Tensor.masked_fill,
|
||||
"aten.masked_select": Tensor.masked_select,
|
||||
@@ -580,7 +616,7 @@ tiny_backend = {**{k:wrap_out(v) for k,v in tiny_backend_out.items()}, **{
|
||||
"aten.asinh": Tensor.asinh,
|
||||
"aten.mul": Tensor.mul,
|
||||
"aten.atanh": Tensor.atanh,
|
||||
"aten.fill_.Tensor": Tensor.full, # TODO: looks wrong
|
||||
"aten.fill_.Tensor": lambda self, value: Tensor.full(self.shape, value.reshape(()).item(), device=self.device, dtype=self.dtype),
|
||||
"aten.flip": Tensor.flip,
|
||||
"aten.scatter_reduce.two": Tensor.scatter_reduce,
|
||||
"aten.squeeze_.dim": lambda self, dim: self.replace(self.squeeze(dim), allow_shape_mismatch=True), # TODO: inplace view op, here?
|
||||
@@ -601,20 +637,51 @@ tiny_backend = {**{k:wrap_out(v) for k,v in tiny_backend_out.items()}, **{
|
||||
"aten.unfold": Tensor.unfold,
|
||||
}}
|
||||
|
||||
# operations that need inplace treatment (use _inplace_op instead of wrap_fxn) AKA return original tensor
|
||||
inplace_ops = {
|
||||
"aten.zero_",
|
||||
"aten.fill_.Scalar",
|
||||
"aten.fill_.Tensor",
|
||||
"aten.add_.Tensor",
|
||||
"aten.add_.Scalar",
|
||||
"aten.mul_.Tensor",
|
||||
"aten.mul_.Scalar",
|
||||
"aten.floor_divide_.Tensor",
|
||||
"aten.__ilshift__.Scalar",
|
||||
"aten.__irshift__.Scalar",
|
||||
"aten.relu_",
|
||||
"aten.random_",
|
||||
"aten.random_.from",
|
||||
"aten.uniform_",
|
||||
"aten.normal_",
|
||||
"aten.logical_or_",
|
||||
"aten.masked_fill_.Scalar",
|
||||
"aten.masked_fill_.Tensor",
|
||||
}
|
||||
|
||||
def wrap_fxn(k,f):
|
||||
def nf(*args, **kwargs):
|
||||
if TORCH_DEBUG:
|
||||
print(k, len(args), [x.shape if isinstance(x, torch.Tensor) else x for x in args],
|
||||
{k:v.shape if isinstance(v, torch.Tensor) else v for k,v in kwargs.items()})
|
||||
args = [unwrap(x) if isinstance(x, torch.Tensor) else x for x in args]
|
||||
kwargs = {k:unwrap(v) if isinstance(v, torch.Tensor) else v for k,v in kwargs.items()}
|
||||
args, kwargs = unwrap_args(args, kwargs)
|
||||
out = f(*args, **kwargs)
|
||||
if isinstance(out, Tensor): return wrap(out)
|
||||
elif isinstance(out, tuple): return tuple(wrap(x) for x in out)
|
||||
else: raise RuntimeError(f"unknown output type {type(out)}")
|
||||
return nf
|
||||
|
||||
for k,v in tiny_backend.items(): torch.library.impl(k.replace("aten.", "aten::"), "privateuseone")(wrap_fxn(k,v))
|
||||
def wrap_inplace(k,f):
|
||||
def nf(*args, **kwargs):
|
||||
orig = args[0]
|
||||
args, kwargs = unwrap_args(args, kwargs)
|
||||
_inplace_op(args[0], f(*args, **kwargs))
|
||||
return orig
|
||||
return nf
|
||||
|
||||
for k,v in tiny_backend.items():
|
||||
wrapper = wrap_inplace if k in inplace_ops else wrap_fxn
|
||||
torch.library.impl(k.replace("aten.", "aten::"), "privateuseone")(wrapper(k,v))
|
||||
|
||||
@torch.library.impl("aten::equal", "privateuseone")
|
||||
def equal(x: torch.Tensor, y: torch.Tensor): return (x==y).all().item()
|
||||
@@ -628,42 +695,72 @@ if TORCH_DEBUG:
|
||||
return func(*args, **(kwargs or {}))
|
||||
(_dispatch_log:=DispatchLog()).__enter__() # NOTE: must be kept alive
|
||||
|
||||
# NOTE: patch torch optimizer step to avoid continously growing the computation graph
|
||||
import weakref
|
||||
_torch_modules_with_buffers: weakref.WeakSet[torch.nn.Module] = weakref.WeakSet()
|
||||
def register_torch_buffer(mod, _name, _buffer): _torch_modules_with_buffers.add(mod)
|
||||
def get_real_tinygrad_buffers():
|
||||
res = set()
|
||||
for mod in _torch_modules_with_buffers:
|
||||
for _,b in mod.named_buffers(recurse=False):
|
||||
if b is not None and b.is_tiny:
|
||||
res.add(unwrap(b))
|
||||
return res
|
||||
torch.nn.modules.module.register_module_buffer_registration_hook(register_torch_buffer)
|
||||
# this implementation is needed to allow the batchnorm kernels to fuse in e.g. mnist training
|
||||
# aten::native_batch_norm does more than Tensor.batchnorm
|
||||
@torch.library.impl("aten::native_batch_norm", "privateuseone")
|
||||
def native_batch_norm(input, weight, bias, running_mean, running_var, training, momentum, eps):
|
||||
input_t, weight_t, bias_t = unwrap(input), unwrap(weight) if weight is not None else None, unwrap(bias) if bias is not None else None
|
||||
running_mean_t, running_var_t = unwrap(running_mean) if running_mean is not None else None, unwrap(running_var) if running_var is not None else None
|
||||
if training:
|
||||
batch_var, batch_mean = input_t.var_mean(axis=tuple(x for x in range(input_t.ndim) if x != 1), correction=0)
|
||||
batch_invstd = batch_var.add(eps).rsqrt()
|
||||
out = input_t.batchnorm(weight_t, bias_t, batch_mean, batch_invstd)
|
||||
if running_mean_t is not None and running_var_t is not None:
|
||||
numel_ratio = input_t.numel() / (input_t.numel() - input_t.shape[1])
|
||||
running_mean_t.assign((1 - momentum) * running_mean_t + momentum * batch_mean.detach())
|
||||
running_var_t.assign((1 - momentum) * running_var_t + momentum * numel_ratio * batch_var.detach())
|
||||
return wrap(out), wrap(batch_mean), wrap(batch_invstd)
|
||||
else:
|
||||
out = input_t.batchnorm(weight_t, bias_t, running_mean_t, running_var_t.add(eps).rsqrt())
|
||||
return wrap(out), wrap(running_mean_t), wrap(running_var_t.add(eps).rsqrt())
|
||||
|
||||
from torch.nn.modules import Module
|
||||
def param_hook(_grad):
|
||||
if _grad is not None and _grad.is_tiny: Tensor.realize(unwrap(_grad))
|
||||
def module_hook(module:Module, _name, _submodule):
|
||||
for param in _submodule.parameters(recurse=False):
|
||||
if param.requires_grad: param.register_hook(param_hook)
|
||||
torch.nn.modules.module.register_module_module_registration_hook(module_hook)
|
||||
@torch.library.impl("aten::native_batch_norm_backward", "privateuseone")
|
||||
def native_batch_norm_backward(grad_out, input, weight, running_mean, running_var, save_mean, save_invstd, train, eps, output_mask):
|
||||
grad_out_t, input_t = unwrap(grad_out), unwrap(input)
|
||||
weight_t = unwrap(weight) if weight is not None else None
|
||||
save_mean_t = unwrap(save_mean)
|
||||
save_invstd_t = unwrap(save_invstd)
|
||||
out = input_t.batchnorm(weight_t, None, save_mean_t, save_invstd_t)
|
||||
targets = [t for t, m in zip([input_t, weight_t], output_mask[:2]) if t is not None and m]
|
||||
if targets:
|
||||
grads = out.gradient(*targets, gradient=grad_out_t)
|
||||
grad_input = grads.pop(0) if output_mask[0] else None
|
||||
grad_weight = grads.pop(0) if output_mask[1] and weight_t is not None else None
|
||||
else:
|
||||
grad_input, grad_weight = None, None
|
||||
grad_bias = grad_out_t.sum(axis=tuple(x for x in range(grad_out_t.ndim) if x != 1)) if output_mask[2] else None
|
||||
return (wrap(grad_input) if grad_input is not None else None,
|
||||
wrap(grad_weight) if grad_weight is not None else None,
|
||||
wrap(grad_bias) if grad_bias is not None else None)
|
||||
|
||||
def realize_optimizer_step(optimizer: torch.optim.Optimizer, *args, **kwargs):
|
||||
tinygrad_tensors = []
|
||||
for param_group in optimizer.param_groups:
|
||||
for param in param_group["params"]:
|
||||
if param is None: continue
|
||||
tinygrad_tensors.append(param.data)
|
||||
for state_dict in optimizer.state.values():
|
||||
for _, value in state_dict.items():
|
||||
if torch.is_tensor(value): tinygrad_tensors.append(value)
|
||||
real_tinygrad_tensors = [unwrap(x) for x in tinygrad_tensors if x.is_tiny]
|
||||
real_tinygrad_tensors += get_real_tinygrad_buffers()
|
||||
if len(real_tinygrad_tensors): Tensor.realize(*real_tinygrad_tensors)
|
||||
# _pad_circular is not CompositeImplicitAutograd (unlike reflect/replicate pad)
|
||||
# we need torch.autograd.Function with explicit AutogradPrivateUse1 registration
|
||||
class _PadCircular(torch.autograd.Function):
|
||||
@staticmethod
|
||||
def forward(ctx, input, padding):
|
||||
ctx.save_for_backward(input)
|
||||
ctx.padding = padding
|
||||
return pad_forward(input, padding, mode="circular")
|
||||
@staticmethod
|
||||
def backward(ctx, grad_output):
|
||||
input, = ctx.saved_tensors
|
||||
return pad_backward(grad_output, input, ctx.padding, mode="circular"), None
|
||||
|
||||
_optimizer_init = torch.optim.Optimizer.__init__
|
||||
def _optimizer_patched_init(self, *args, **kwargs):
|
||||
_optimizer_init(self, *args, **kwargs)
|
||||
self.register_step_post_hook(realize_optimizer_step)
|
||||
torch.optim.Optimizer.__init__ = _optimizer_patched_init
|
||||
@torch.library.impl("aten::_pad_circular", "privateuseone")
|
||||
def _pad_circular(self, padding): return _PadCircular.apply(self, padding)
|
||||
|
||||
@torch.library.impl("aten::_pad_circular", "AutogradPrivateUse1")
|
||||
def _pad_circular_autograd(self, padding): return _PadCircular.apply(self, padding)
|
||||
|
||||
# only needed for test_diag_backward_gradient_values
|
||||
# was going through torch before, but now we are using tinygrad directly and tracking views
|
||||
# Tensor.diagonal does not support all cases tests in the tests
|
||||
@torch.library.impl("aten::diagonal", "privateuseone")
|
||||
@wrap_view_op
|
||||
def diagonal(self, offset=0, dim1=0, dim2=1):
|
||||
if offset != 0: raise NotImplementedError(f"diagonal with {offset=} not implemented")
|
||||
dim1, dim2 = dim1 % self.ndim, dim2 % self.ndim
|
||||
if dim1 != self.ndim - 2 or dim2 != self.ndim - 1: raise NotImplementedError(f"diagonal with {dim1=}, {dim2=} not implemented, only last two dims supported")
|
||||
batch_shape, m, n = self.shape[:-2], self.shape[-2], self.shape[-1]
|
||||
diag_len = min(m, n)
|
||||
return self.reshape(*batch_shape, m*n).pad(tuple((0,0) for _ in batch_shape) + ((0, diag_len),)).reshape(*batch_shape, diag_len, n+1)[..., :, 0]
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
from PIL import Image
|
||||
from tinygrad.helpers import getenv
|
||||
import torch, torchvision, pathlib
|
||||
from tinygrad.helpers import getenv, GlobalCounters
|
||||
import torch, torchvision, pathlib, warnings
|
||||
import torchvision.transforms as transforms
|
||||
import extra.torch_backend.backend
|
||||
device = "tiny"
|
||||
torch.set_default_device(device)
|
||||
|
||||
if __name__ == "__main__":
|
||||
GlobalCounters.reset()
|
||||
img = Image.open(pathlib.Path(__file__).parent.parent.parent / "test/models/efficientnet/Chicken.jpg").convert('RGB')
|
||||
transform = transforms.Compose([
|
||||
transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(),
|
||||
@@ -19,3 +20,10 @@ if __name__ == "__main__":
|
||||
out = model(img).detach().cpu().numpy()
|
||||
print("output:", out.shape, out.argmax())
|
||||
assert out.argmax() == 7 # cock
|
||||
|
||||
kernel_count = GlobalCounters.kernel_count
|
||||
assert kernel_count > 0, "No kernels, test failed"
|
||||
expected_kernels = 228
|
||||
expectation = f"ResNet18 kernels are {kernel_count} vs {expected_kernels} expected."
|
||||
if kernel_count < expected_kernels: warnings.warn(f"{expectation} Expectation can be lowered.", UserWarning)
|
||||
assert kernel_count <= expected_kernels, f"{expectation}"
|
||||
+669
-3
@@ -2,7 +2,7 @@
|
||||
import unittest
|
||||
import torch
|
||||
import numpy as np
|
||||
from tinygrad.helpers import getenv, Context, GlobalCounters
|
||||
from tinygrad.helpers import getenv, GlobalCounters
|
||||
if getenv("TINY_BACKEND2"):
|
||||
import extra.torch_backend.backend2
|
||||
device = "cpu"
|
||||
@@ -25,7 +25,7 @@ class TestTorchBackend(unittest.TestCase):
|
||||
a = torch.ones(4, device=device)
|
||||
np.testing.assert_equal(a.cpu().numpy(), [1,1,1,1])
|
||||
|
||||
def test_numpy_ones(self):
|
||||
def test_numpy_ones_int32(self):
|
||||
a = torch.ones(4, dtype=torch.int32, device=device)
|
||||
assert a.dtype == torch.int32
|
||||
np.testing.assert_equal(a.cpu().numpy(), [1,1,1,1])
|
||||
@@ -219,7 +219,6 @@ class TestTorchBackend(unittest.TestCase):
|
||||
a = torch.ones(4, device=device)
|
||||
print(str(a))
|
||||
|
||||
@unittest.skip("failed")
|
||||
def test_floor_div(self):
|
||||
a = torch.tensor([10., 7., 5.], device=device)
|
||||
b = torch.tensor([3., 2., 2.], device=device)
|
||||
@@ -248,5 +247,672 @@ class TestTorchBackend(unittest.TestCase):
|
||||
def test_diagonal_rectangular(self): self._test_diagonal(4, 5, 6)
|
||||
def test_diagonal_4d(self): self._test_diagonal(2, 3, 4, 5)
|
||||
|
||||
def test_pad_circular_simple(self):
|
||||
a = torch.arange(4, dtype=torch.float32, device=device).reshape(1,1,2,2)
|
||||
padded = torch.nn.functional.pad(a, (1,1,1,1), mode="circular")
|
||||
expected = np.array([[[[3.,2.,3.,2.], [1.,0.,1.,0.], [3.,2.,3.,2.], [1.,0.,1.,0.]]]], dtype=np.float32)
|
||||
np.testing.assert_allclose(padded.cpu().numpy(), expected)
|
||||
|
||||
def test_pad_circular_backward(self):
|
||||
a = torch.arange(4, dtype=torch.float32, device=device).reshape(1,1,2,2).requires_grad_(True)
|
||||
padded = torch.nn.functional.pad(a, (1,1,1,1), mode="circular")
|
||||
loss = padded.sum()
|
||||
loss.backward()
|
||||
expected_grad = np.array([[[[4., 4.], [4., 4.]]]], dtype=np.float32)
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected_grad)
|
||||
|
||||
|
||||
def test_matmul_backward(self):
|
||||
x = torch.randn(3, 4, device=device, dtype=torch.float32, requires_grad=True)
|
||||
y = torch.randn(4, 5, device=device, dtype=torch.float32, requires_grad=True)
|
||||
z = (x @ y).sum()
|
||||
z.backward()
|
||||
assert x.grad is not None
|
||||
assert y.grad is not None
|
||||
assert x.grad.shape == x.shape
|
||||
assert y.grad.shape == y.shape
|
||||
|
||||
def test_matmul_broadcast_backward(self):
|
||||
x = torch.randn(2, 3, 4, device=device, dtype=torch.float32, requires_grad=True)
|
||||
y = torch.randn(4, 5, device=device, dtype=torch.float32, requires_grad=True)
|
||||
z = (x @ y).sum()
|
||||
z.backward()
|
||||
assert x.grad is not None
|
||||
assert y.grad is not None
|
||||
assert x.grad.shape == x.shape
|
||||
assert y.grad.shape == y.shape
|
||||
|
||||
def test_diag_vector_to_matrix(self):
|
||||
vec = torch.tensor([1., 2., 3., 4., 5.], dtype=torch.float32, device=device)
|
||||
mat = torch.diag(vec)
|
||||
expected = np.diag([1., 2., 3., 4., 5.])
|
||||
np.testing.assert_allclose(mat.cpu().numpy(), expected, rtol=1e-5)
|
||||
assert mat.shape == (5, 5)
|
||||
|
||||
def test_diagonal_matrix_to_vector(self):
|
||||
mat = torch.tensor([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]], dtype=torch.float32, device=device)
|
||||
vec = torch.linalg.diagonal(mat)
|
||||
expected = np.array([1., 5., 9.])
|
||||
np.testing.assert_allclose(vec.cpu().numpy(), expected, rtol=1e-5)
|
||||
assert vec.shape == (3,)
|
||||
|
||||
def test_permute_2(self):
|
||||
a = torch.randn(2, 3, 4, dtype=torch.float32, device=device)
|
||||
b = a.permute(2, 0, 1)
|
||||
assert b.shape == (4, 2, 3)
|
||||
np.testing.assert_equal(b.cpu().numpy(), a.cpu().numpy().transpose(2, 0, 1))
|
||||
|
||||
def test_batchnorm_unsqueeze(self):
|
||||
bn = torch.nn.BatchNorm2d(4).to(device)
|
||||
x = torch.randn(8, 4, 3, 3, device=device)
|
||||
out = bn(x)
|
||||
self.assertEqual(out.shape, x.shape)
|
||||
|
||||
def test_slice_inplace_zero(self):
|
||||
a = torch.ones((3, 3), device=device)
|
||||
b = a[1:, 1:]
|
||||
b.zero_()
|
||||
expected = np.array([[1., 1., 1.],
|
||||
[1., 0., 0.],
|
||||
[1., 0., 0.]])
|
||||
np.testing.assert_equal(a.cpu().numpy(), expected)
|
||||
|
||||
def test_slice_inplace_fill(self):
|
||||
a = torch.ones((3, 3), device=device)
|
||||
b = a[1:, 1:]
|
||||
b.fill_(5.0)
|
||||
expected = np.array([[1., 1., 1.],
|
||||
[1., 5., 5.],
|
||||
[1., 5., 5.]])
|
||||
np.testing.assert_equal(a.cpu().numpy(), expected)
|
||||
|
||||
def test_fill_tensor_value(self):
|
||||
a = torch.zeros((2, 2), dtype=torch.float32, device=device)
|
||||
value = torch.tensor(3, dtype=torch.int64, device=device)
|
||||
a.fill_(value)
|
||||
expected = np.full((2, 2), 3, dtype=np.float32)
|
||||
np.testing.assert_equal(a.cpu().numpy(), expected)
|
||||
|
||||
def test_slice_inplace_mul(self):
|
||||
a = torch.ones((3, 3), device=device)
|
||||
b = a[1:, 1:]
|
||||
b *= 2
|
||||
expected = np.array([[1., 1., 1.],
|
||||
[1., 2., 2.],
|
||||
[1., 2., 2.]])
|
||||
np.testing.assert_equal(a.cpu().numpy(), expected)
|
||||
|
||||
def test_permute_slice_zero(self):
|
||||
a = torch.ones((3, 3), device=device)
|
||||
b = a[1:, 1:].permute(1, 0)
|
||||
b.zero_()
|
||||
expected = np.array([[1., 1., 1.],
|
||||
[1., 0., 0.],
|
||||
[1., 0., 0.]])
|
||||
np.testing.assert_equal(a.cpu().numpy(), expected)
|
||||
|
||||
def test_permute_slice_mul(self):
|
||||
a = torch.ones((3, 3), device=device)
|
||||
b = a[1:, 1:].permute(1, 0)
|
||||
b *= 2
|
||||
expected = np.array([[1., 1., 1.],
|
||||
[1., 2., 2.],
|
||||
[1., 2., 2.]])
|
||||
np.testing.assert_equal(a.cpu().numpy(), expected)
|
||||
|
||||
def test_simple_slice_setitem(self):
|
||||
a = torch.tensor([10, 20, 30], device=device)
|
||||
a[1] = 99
|
||||
np.testing.assert_equal(a.cpu().numpy(), [10, 99, 30])
|
||||
|
||||
def test_2d_slice_setitem(self):
|
||||
a = torch.zeros((3, 3), device=device)
|
||||
a[1, 2] = 99
|
||||
self.assertEqual(a[1, 2].item(), 99)
|
||||
self.assertEqual(a.sum().item(), 99)
|
||||
|
||||
def test_view_copy(self):
|
||||
a = torch.tensor([10, 20, 30], device=device)
|
||||
view = a[1]
|
||||
view.copy_(torch.tensor(88, device=device))
|
||||
np.testing.assert_equal(a.cpu().numpy(), [10, 88, 30])
|
||||
|
||||
def test_diag_2d_input(self):
|
||||
a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], device=device)
|
||||
d = torch.diag(a)
|
||||
np.testing.assert_equal(d.cpu().numpy(), [1, 5, 9])
|
||||
|
||||
def test_diag_1d_input(self):
|
||||
a = torch.tensor([1, 2, 3], device=device)
|
||||
d = torch.diag(a)
|
||||
expected = [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
|
||||
np.testing.assert_equal(d.cpu().numpy(), expected)
|
||||
|
||||
def test_permute_view_tracking(self):
|
||||
a = torch.ones((2, 3, 4), device=device)
|
||||
b = a.permute(2, 0, 1)
|
||||
self.assertEqual(b.shape, (4, 2, 3))
|
||||
|
||||
def test_detach_view_creation(self):
|
||||
a = torch.tensor([1.0, 2.0, 3.0], device=device)
|
||||
b = a.detach()
|
||||
np.testing.assert_equal(b.cpu().numpy(), [1.0, 2.0, 3.0])
|
||||
|
||||
def test_view_zero_inplace(self):
|
||||
a = torch.ones((4, 4), device=device)
|
||||
view = a[1:3, 1:3]
|
||||
view.zero_()
|
||||
self.assertEqual(view.sum().item(), 0)
|
||||
|
||||
def test_view_fill_inplace(self):
|
||||
a = torch.zeros((4, 4), device=device)
|
||||
view = a[1:3, 1:3]
|
||||
view.fill_(5)
|
||||
self.assertEqual(view.sum().item(), 20)
|
||||
|
||||
def test_permute_contiguous(self):
|
||||
a = torch.tensor([[1, 2], [3, 4]], device=device)
|
||||
b = a.permute(1, 0)
|
||||
c = b.contiguous()
|
||||
expected = [[1, 3], [2, 4]]
|
||||
np.testing.assert_equal(c.cpu().numpy(), expected)
|
||||
|
||||
def test_diag_2d_extract_diagonal(self):
|
||||
a = torch.tensor([[1, 2], [3, 4]], device=device)
|
||||
result = torch.diag(a)
|
||||
np.testing.assert_equal(result.cpu().numpy(), [1, 4])
|
||||
|
||||
def test_slice_inplace_multiply_offset_preservation(self):
|
||||
a = torch.tensor([1, 2, 3], device=device)
|
||||
a[1:] *= 2
|
||||
np.testing.assert_equal(a.cpu().numpy(), [1, 4, 6])
|
||||
|
||||
def test_slice_inplace_mul_pattern(self):
|
||||
a = torch.tensor([1, 2, 3, 4], device=device)
|
||||
a[:2] *= 3
|
||||
a[2:] *= 2
|
||||
np.testing.assert_equal(a.cpu().numpy(), [3, 6, 6, 8])
|
||||
|
||||
def test_chained_slice_column(self):
|
||||
a = torch.arange(16, dtype=torch.float32, device=device).reshape(4, 4)
|
||||
torch_res = a[:, 1:2][:, 0:1].cpu().numpy()
|
||||
cpu_res = torch.arange(16, dtype=torch.float32).reshape(4, 4)[:, 1:2][:, 0:1].numpy()
|
||||
np.testing.assert_equal(torch_res, cpu_res)
|
||||
|
||||
def test_slice_with_step(self):
|
||||
a = torch.arange(20, dtype=torch.float32, device=device)
|
||||
torch_res = a[::2][1:4].cpu().numpy()
|
||||
cpu_res = torch.arange(20, dtype=torch.float32)[::2][1:4].numpy()
|
||||
np.testing.assert_equal(torch_res, cpu_res)
|
||||
|
||||
def test_slice_negative_dim(self):
|
||||
a = torch.arange(13, dtype=torch.int32, device=device).repeat(8, 1)
|
||||
torch_chunks = a.chunk(3, -1)
|
||||
cpu_chunks = torch.arange(13, dtype=torch.int32).repeat(8, 1).chunk(3, -1)
|
||||
assert len(torch_chunks) == len(cpu_chunks)
|
||||
for i in range(len(torch_chunks)):
|
||||
np.testing.assert_equal(torch_chunks[i].cpu().numpy(), cpu_chunks[i].numpy())
|
||||
|
||||
def test_dot_vector_matrix(self):
|
||||
a = torch.arange(65, dtype=torch.float32, device=device)
|
||||
b = torch.arange(65*45, dtype=torch.float32, device=device).reshape(65, 45)
|
||||
torch_res = a.matmul(b).reshape(-1).cpu().numpy()
|
||||
cpu_res = torch.arange(65, dtype=torch.float32).matmul(torch.arange(65*45, dtype=torch.float32).reshape(65, 45)).numpy()
|
||||
np.testing.assert_equal(torch_res, cpu_res)
|
||||
|
||||
def test_alias_passthrough(self):
|
||||
a = torch.randn(3, 3, device=device)
|
||||
alias_view = torch.ops.aten.alias(a)
|
||||
alias_view += 1
|
||||
np.testing.assert_equal(a.cpu().numpy(), alias_view.cpu().numpy())
|
||||
|
||||
def test_split_simple_vector(self):
|
||||
a = torch.arange(10, dtype=torch.float32, device=device)
|
||||
torch_chunks = a.split([1,4,5])
|
||||
cpu_chunks = torch.arange(10, dtype=torch.float32).split([1,4,5])
|
||||
for tc, cc in zip(torch_chunks, cpu_chunks):
|
||||
np.testing.assert_equal(tc.cpu().numpy(), cc.cpu().numpy())
|
||||
|
||||
def test_split_matches_torch(self):
|
||||
a = torch.arange(10, dtype=torch.float32, device=device)
|
||||
torch_chunks = a.split([1,4,5])
|
||||
tiny_chunks = [chunk.cpu().numpy() for chunk in torch_chunks]
|
||||
cpu_chunks = [torch.arange(10, dtype=torch.float32).split([1,4,5])[i].numpy() for i in range(3)]
|
||||
for tr, cr in zip(tiny_chunks, cpu_chunks): np.testing.assert_equal(tr, cr)
|
||||
|
||||
def test_sum_matches_torch(self):
|
||||
a = torch.arange(6, dtype=torch.float32, device=device).reshape(2,3)
|
||||
torch_res = a.sum().cpu().numpy()
|
||||
cpu_res = torch.arange(6, dtype=torch.float32).reshape(2,3).sum().numpy()
|
||||
np.testing.assert_equal(torch_res, cpu_res)
|
||||
|
||||
def test_view_matches_torch(self):
|
||||
a = torch.arange(6, dtype=torch.float32, device=device)
|
||||
torch_res = a.view(2, 3).cpu().numpy()
|
||||
cpu_res = torch.arange(6, dtype=torch.float32).view(2, 3).numpy()
|
||||
np.testing.assert_equal(torch_res, cpu_res)
|
||||
|
||||
def test_view_zero_with_indices(self):
|
||||
a = torch.tensor([1, 2, 3, 4], device=device)
|
||||
a[1:3].zero_()
|
||||
np.testing.assert_equal(a.cpu().numpy(), [1, 0, 0, 4])
|
||||
|
||||
def test_view_fill_with_indices(self):
|
||||
a = torch.tensor([1, 2, 3, 4], device=device)
|
||||
a[::2].fill_(9)
|
||||
np.testing.assert_equal(a.cpu().numpy(), [9, 2, 9, 4])
|
||||
|
||||
def test_nested_slice_inplace_ops(self):
|
||||
a = torch.tensor([1, 2, 3, 4, 5, 6], device=device)
|
||||
a[:3] += 10
|
||||
a[3:] *= 2
|
||||
np.testing.assert_equal(a.cpu().numpy(), [11, 12, 13, 8, 10, 12])
|
||||
|
||||
def test_diag_1d(self):
|
||||
a = torch.tensor([1, 2, 3], device=device)
|
||||
result = torch.diag(a)
|
||||
expected = [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
|
||||
np.testing.assert_equal(result.cpu().numpy(), expected)
|
||||
|
||||
def test_diag_backward(self):
|
||||
a = torch.randn(5, dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.diag(a)
|
||||
b.sum().backward()
|
||||
assert a.grad is not None
|
||||
|
||||
def test_diagonal(self):
|
||||
a = torch.tensor([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.diagonal(a)
|
||||
expected = torch.tensor([1., 5., 9.], dtype=torch.float32)
|
||||
self.assertEqual(b.shape, (3,))
|
||||
np.testing.assert_allclose(b.detach().cpu().numpy(), expected.numpy(), rtol=1e-5)
|
||||
|
||||
def test_diagonal_backward(self):
|
||||
a = torch.randn(5, 5, dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.diagonal(a)
|
||||
b.sum().backward()
|
||||
assert a.grad is not None
|
||||
|
||||
def test_expand_backward(self):
|
||||
a = torch.randn(4, 3, 1, 6, dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = a.expand(4, 3, 2, 6)
|
||||
b.sum().backward()
|
||||
assert a.grad is not None
|
||||
|
||||
def test_einsum_backward(self):
|
||||
a = torch.randn(10, 10, dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.einsum('ij->ji', a)
|
||||
b.sum().backward()
|
||||
assert a.grad is not None
|
||||
|
||||
def test_diag_backward_gradient_values(self):
|
||||
a = torch.tensor([1.0, 2.0, 3.0], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.diag(a)
|
||||
loss = b.sum()
|
||||
loss.backward()
|
||||
expected_grad = torch.ones(3, dtype=torch.float32)
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected_grad.numpy(), rtol=1e-5)
|
||||
|
||||
def test_diag_backward_gradient_values_2d_to_1d(self):
|
||||
a = torch.tensor([[1.0, 2.0, 3.0],
|
||||
[4.0, 5.0, 6.0],
|
||||
[7.0, 8.0, 9.0]], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.diagonal(a)
|
||||
loss = b.sum()
|
||||
loss.backward()
|
||||
expected_grad = torch.tensor([[1.0, 0.0, 0.0],
|
||||
[0.0, 1.0, 0.0],
|
||||
[0.0, 0.0, 1.0]], dtype=torch.float32)
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected_grad.numpy(), rtol=1e-5)
|
||||
|
||||
def test_expand_backward_gradient_values(self):
|
||||
a = torch.tensor([[1.0], [2.0], [3.0]], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = a.expand(3, 4)
|
||||
loss = b.sum()
|
||||
loss.backward()
|
||||
expected_grad = torch.tensor([[4.0], [4.0], [4.0]], dtype=torch.float32)
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected_grad.numpy(), rtol=1e-5)
|
||||
|
||||
def test_expand_backward_with_leading_dims(self):
|
||||
a = torch.tensor([[1.0, 2.0]], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = a.expand(3, 1, 2)
|
||||
loss = b.sum()
|
||||
loss.backward()
|
||||
expected_grad = torch.tensor([[3.0, 3.0]], dtype=torch.float32)
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected_grad.numpy(), rtol=1e-5)
|
||||
|
||||
def test_diag_2d_to_1d_backward(self):
|
||||
a = torch.tensor([[1.0, 2.0], [3.0, 4.0]], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.diag(a)
|
||||
loss = b.sum()
|
||||
loss.backward()
|
||||
expected_grad = torch.tensor([[1.0, 0.0], [0.0, 1.0]], dtype=torch.float32)
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected_grad.numpy(), rtol=1e-5)
|
||||
|
||||
def test_expand_complex_backward(self):
|
||||
a = torch.tensor([[[1.0, 2.0]]], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = a.expand(2, 3, 2)
|
||||
loss = b.sum()
|
||||
loss.backward()
|
||||
expected_grad = torch.tensor([[[6.0, 6.0]]], dtype=torch.float32)
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected_grad.numpy(), rtol=1e-5)
|
||||
|
||||
def test_diag_backward_with_scaling(self):
|
||||
a = torch.tensor([1.0, 2.0, 3.0], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.diag(a)
|
||||
loss = (b * torch.tensor([[2.0, 0.0, 0.0],
|
||||
[0.0, 3.0, 0.0],
|
||||
[0.0, 0.0, 4.0]], device=device)).sum()
|
||||
loss.backward()
|
||||
expected_grad = torch.tensor([2.0, 3.0, 4.0], dtype=torch.float32)
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected_grad.numpy(), rtol=1e-5)
|
||||
|
||||
def test_repeat_basic(self):
|
||||
a = torch.tensor([1, 2, 3], dtype=torch.float32, device=device)
|
||||
b = a.repeat(2, 1)
|
||||
expected = torch.tensor([[1, 2, 3], [1, 2, 3]], dtype=torch.float32)
|
||||
np.testing.assert_equal(b.cpu().numpy(), expected.numpy())
|
||||
|
||||
def test_repeat_multidim(self):
|
||||
a = torch.arange(6, dtype=torch.float32, device=device).reshape(2, 3)
|
||||
b = a.repeat(2, 3)
|
||||
expected = torch.arange(6, dtype=torch.float32).reshape(2, 3).repeat(2, 3)
|
||||
np.testing.assert_equal(b.cpu().numpy(), expected.numpy())
|
||||
|
||||
def test_repeat_backward(self):
|
||||
a = torch.tensor([[1.0, 2.0]], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = a.repeat(3, 2)
|
||||
loss = b.sum()
|
||||
loss.backward()
|
||||
expected_grad = torch.tensor([[6.0, 6.0]], dtype=torch.float32)
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected_grad.numpy(), rtol=1e-5)
|
||||
|
||||
def test_cumsum_1d(self):
|
||||
a = torch.tensor([1, 2, 3, 4], dtype=torch.float32, device=device)
|
||||
b = torch.cumsum(a, dim=0)
|
||||
expected = torch.tensor([1, 3, 6, 10], dtype=torch.float32)
|
||||
np.testing.assert_equal(b.cpu().numpy(), expected.numpy())
|
||||
|
||||
def test_cumsum_2d(self):
|
||||
a = torch.arange(12, dtype=torch.float32, device=device).reshape(3, 4)
|
||||
b = torch.cumsum(a, dim=0)
|
||||
expected = torch.arange(12, dtype=torch.float32).reshape(3, 4).cumsum(dim=0)
|
||||
np.testing.assert_equal(b.cpu().numpy(), expected.numpy())
|
||||
|
||||
c = torch.cumsum(a, dim=1)
|
||||
expected = torch.arange(12, dtype=torch.float32).reshape(3, 4).cumsum(dim=1)
|
||||
np.testing.assert_equal(c.cpu().numpy(), expected.numpy())
|
||||
|
||||
def test_cumsum_backward(self):
|
||||
a = torch.tensor([1.0, 2.0, 3.0, 4.0], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.cumsum(a, dim=0)
|
||||
loss = b.sum()
|
||||
loss.backward()
|
||||
expected_grad = torch.tensor([4.0, 3.0, 2.0, 1.0], dtype=torch.float32)
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected_grad.numpy(), rtol=1e-5)
|
||||
|
||||
def test_constant_pad_nd_1d(self):
|
||||
a = torch.tensor([1, 2, 3], dtype=torch.float32, device=device)
|
||||
b = torch.nn.functional.pad(a, (1, 2), mode='constant', value=0)
|
||||
expected = torch.tensor([0, 1, 2, 3, 0, 0], dtype=torch.float32)
|
||||
np.testing.assert_equal(b.cpu().numpy(), expected.numpy())
|
||||
|
||||
def test_constant_pad_nd_2d(self):
|
||||
a = torch.arange(6, dtype=torch.float32, device=device).reshape(2, 3)
|
||||
b = torch.nn.functional.pad(a, (1, 1, 1, 1), mode='constant', value=0)
|
||||
expected = torch.nn.functional.pad(torch.arange(6, dtype=torch.float32).reshape(2, 3), (1, 1, 1, 1), mode='constant', value=0)
|
||||
np.testing.assert_equal(b.cpu().numpy(), expected.numpy())
|
||||
|
||||
def test_constant_pad_nd_2d_backward(self):
|
||||
a = torch.tensor([[1.0, 2.0], [3.0, 4.0]], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.nn.functional.pad(a, (1, 1, 1, 1), mode='constant', value=0)
|
||||
loss = b.sum()
|
||||
loss.backward()
|
||||
expected_grad = torch.ones((2, 2), dtype=torch.float32)
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected_grad.numpy(), rtol=1e-5)
|
||||
|
||||
def test_negative_strides_cumsum_backward(self):
|
||||
a = torch.randn(5, device=device, requires_grad=True)
|
||||
b = torch.cumsum(a, dim=0)
|
||||
b.sum().backward()
|
||||
grad = a.grad.cpu().numpy()
|
||||
self.assertEqual(len(grad), 5)
|
||||
|
||||
def test_cumsum_fix_gradient_values(self):
|
||||
a = torch.tensor([1.0, 2.0, 3.0, 4.0], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.cumsum(a, dim=0)
|
||||
loss = b.sum()
|
||||
loss.backward()
|
||||
expected = np.array([4.0, 3.0, 2.0, 1.0])
|
||||
np.testing.assert_allclose(a.grad.cpu().numpy(), expected, rtol=1e-5)
|
||||
|
||||
def test_diag_1d_to_2d(self):
|
||||
a = torch.tensor([1.0, 2.0, 3.0], dtype=torch.float32, device=device, requires_grad=True)
|
||||
b = torch.diag(a)
|
||||
expected = [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
|
||||
np.testing.assert_equal(b.detach().cpu().numpy(), expected)
|
||||
|
||||
def test_diag_2d_to_1d(self):
|
||||
c = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=torch.float32, device=device)
|
||||
d = torch.diag(c)
|
||||
np.testing.assert_equal(d.cpu().numpy(), [1, 5, 9])
|
||||
|
||||
def test_biased_conv2d(self):
|
||||
# Test case for two sequential conv2d with same weights/bias and ReLU in between, this is as special case from test_ops.py
|
||||
torch.manual_seed(0)
|
||||
C = 8
|
||||
x_cpu = torch.randn(1, C, 5, 5, requires_grad=True)
|
||||
w_cpu = torch.randn(C, C, 1, 1, requires_grad=True)
|
||||
b_cpu = torch.randn(C, requires_grad=True)
|
||||
x_tiny = x_cpu.detach().to(device).requires_grad_(True)
|
||||
w_tiny = w_cpu.detach().to(device).requires_grad_(True)
|
||||
b_tiny = b_cpu.detach().to(device).requires_grad_(True)
|
||||
out_cpu = torch.nn.functional.conv2d(torch.nn.functional.conv2d(x_cpu, w_cpu, b_cpu).relu(), w_cpu, b_cpu)
|
||||
out_tiny = torch.nn.functional.conv2d(torch.nn.functional.conv2d(x_tiny, w_tiny, b_tiny).relu(), w_tiny, b_tiny)
|
||||
grad_out = torch.randn_like(out_cpu)
|
||||
out_cpu.backward(grad_out)
|
||||
out_tiny.backward(grad_out.to(device))
|
||||
np.testing.assert_allclose(x_tiny.grad.cpu().numpy(), x_cpu.grad.numpy(), atol=1e-4, rtol=1e-3)
|
||||
np.testing.assert_allclose(w_tiny.grad.cpu().numpy(), w_cpu.grad.numpy(), atol=1e-4, rtol=1e-3)
|
||||
np.testing.assert_allclose(b_tiny.grad.cpu().numpy(), b_cpu.grad.numpy(), atol=1e-4, rtol=1e-3)
|
||||
|
||||
|
||||
from tinygrad import Tensor
|
||||
class TestBackendHelpers(unittest.TestCase):
|
||||
|
||||
def test_calculate_storage_offset_no_shrink(self):
|
||||
t = Tensor.ones(3, 4)
|
||||
assert extra.torch_backend.backend.calculate_storage_offset(t) == 0
|
||||
|
||||
def test_calculate_storage_offset_with_shrink(self):
|
||||
t = Tensor.ones(10, 10)[2:5, 3:7]
|
||||
# strides for (10, 10) are [10, 1]
|
||||
# offset = 2*10 + 3*1 = 23
|
||||
assert extra.torch_backend.backend.calculate_storage_offset(t) == 23
|
||||
|
||||
def test_calculate_storage_offset_multiple_shrinks(self):
|
||||
t = Tensor.ones(5, 6, 7)[1:3, 2:4, 3:5]
|
||||
# strides for (5, 6, 7) are [42, 7, 1]
|
||||
# offset = 1*42 + 2*7 + 3*1 = 42 + 14 + 3 = 59
|
||||
assert extra.torch_backend.backend.calculate_storage_offset(t) == 59
|
||||
|
||||
def test_calculate_storage_offset_with_reshape(self):
|
||||
t = Tensor.ones(10, 10)
|
||||
orig_offset = extra.torch_backend.backend.calculate_storage_offset(t)
|
||||
assert orig_offset == 0
|
||||
t = t.reshape(100)
|
||||
assert extra.torch_backend.backend.calculate_storage_offset(t) == orig_offset
|
||||
|
||||
def test_slice_values_match_torch(self):
|
||||
torch_cpu = torch.arange(100, dtype=torch.float32).reshape(10, 10)
|
||||
torch_tiny = torch_cpu.to(device)
|
||||
sliced_cpu = torch_cpu[2:5, 3:7]
|
||||
sliced_tiny = torch_tiny[2:5, 3:7]
|
||||
np.testing.assert_equal(sliced_tiny.cpu().numpy(), sliced_cpu.numpy())
|
||||
|
||||
def test_slice_values_match_torch_3d(self):
|
||||
torch_cpu_3d = torch.arange(210, dtype=torch.float32).reshape(5, 6, 7)
|
||||
torch_tiny_3d = torch_cpu_3d.to(device)
|
||||
sliced_cpu_3d = torch_cpu_3d[1:3, 2:4, 3:5]
|
||||
sliced_tiny_3d = torch_tiny_3d[1:3, 2:4, 3:5]
|
||||
np.testing.assert_equal(sliced_tiny_3d.cpu().numpy(), sliced_cpu_3d.numpy())
|
||||
|
||||
def test_topk_out(self):
|
||||
a = torch.tensor([1, 3, 2, 4], device=device)
|
||||
values = torch.empty(2, device=device)
|
||||
indices = torch.empty(2, dtype=torch.int64, device=device)
|
||||
ret_values, ret_indices = torch.topk(a, k=2, out=(values, indices))
|
||||
np.testing.assert_equal(values.cpu().numpy(), [4, 3])
|
||||
np.testing.assert_equal(indices.cpu().numpy(), [3, 1])
|
||||
assert ret_values is values
|
||||
assert ret_indices is indices
|
||||
|
||||
def test_sort_out(self):
|
||||
a = torch.tensor([3, 1, 4, 2], device=device)
|
||||
values = torch.empty(4, device=device)
|
||||
indices = torch.empty(4, dtype=torch.int64, device=device)
|
||||
ret_values, ret_indices = torch.sort(a, out=(values, indices))
|
||||
np.testing.assert_equal(values.cpu().numpy(), [1, 2, 3, 4])
|
||||
np.testing.assert_equal(indices.cpu().numpy(), [1, 3, 0, 2])
|
||||
assert ret_values is values
|
||||
assert ret_indices is indices
|
||||
|
||||
def test_cat_out(self):
|
||||
a = torch.tensor([1, 2], device=device)
|
||||
b = torch.tensor([3, 4], device=device)
|
||||
out = torch.empty(4, device=device)
|
||||
ret = torch.cat([a, b], out=out)
|
||||
np.testing.assert_equal(out.cpu().numpy(), [1, 2, 3, 4])
|
||||
assert ret is out
|
||||
|
||||
def test_scatter_add_out(self):
|
||||
src = torch.tensor([[1, 2, 3], [4, 5, 6]], device=device, dtype=torch.float32)
|
||||
index = torch.tensor([[0, 1, 2], [0, 1, 2]], device=device)
|
||||
input = torch.zeros(3, 3, device=device, dtype=torch.float32)
|
||||
out = torch.zeros(3, 3, device=device, dtype=torch.float32)
|
||||
ret = torch.scatter_add(input, 0, index, src, out=out)
|
||||
expected = torch.tensor([[5, 0, 0], [0, 7, 0], [0, 0, 9]], dtype=torch.float32)
|
||||
np.testing.assert_allclose(out.cpu().numpy(), expected.cpu().numpy())
|
||||
assert ret is out
|
||||
|
||||
def test_floor_divide_inplace_identity(self):
|
||||
x = torch.tensor([10, 20, 30, 40], dtype=torch.int32, device=device)
|
||||
y = torch.tensor([2, 4, 5, 8], dtype=torch.int32, device=device)
|
||||
ret = x.floor_divide_(y)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [5, 5, 6, 5])
|
||||
|
||||
def test_lshift_inplace_identity(self):
|
||||
x = torch.tensor([1, 2, 3, 4], dtype=torch.int32, device=device)
|
||||
ret = x.__ilshift__(2)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [4, 8, 12, 16])
|
||||
|
||||
def test_rshift_inplace_identity(self):
|
||||
x = torch.tensor([16, 32, 48, 64], dtype=torch.int32, device=device)
|
||||
ret = x.__irshift__(2)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [4, 8, 12, 16])
|
||||
|
||||
def test_relu_inplace_identity(self):
|
||||
x = torch.tensor([-1.0, 2.0, -3.0, 4.0], device=device)
|
||||
ret = x.relu_()
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [0.0, 2.0, 0.0, 4.0])
|
||||
|
||||
def test_random_inplace_identity(self):
|
||||
x = torch.zeros(10, dtype=torch.int32, device=device)
|
||||
ret = x.random_()
|
||||
assert ret is x
|
||||
assert x.shape == (10,)
|
||||
|
||||
def test_random_from_inplace_identity(self):
|
||||
x = torch.zeros(10, dtype=torch.int32, device=device)
|
||||
ret = x.random_(5, 10)
|
||||
assert ret is x
|
||||
# values should be in range [5, 10)
|
||||
assert torch.all(x >= 5).item() and torch.all(x < 10).item()
|
||||
|
||||
def test_uniform_inplace_identity(self):
|
||||
x = torch.zeros(10, device=device)
|
||||
ret = x.uniform_(0.0, 1.0)
|
||||
assert ret is x
|
||||
# values should be in range [0, 1)
|
||||
assert torch.all(x >= 0.0).item() and torch.all(x < 1.0).item()
|
||||
|
||||
def test_normal_inplace_identity(self):
|
||||
x = torch.zeros(100, device=device)
|
||||
ret = x.normal_(0.0, 1.0)
|
||||
assert ret is x
|
||||
# just check that values changed from zeros
|
||||
assert not torch.all(x == 0.0).item()
|
||||
|
||||
def test_logical_or_inplace_identity(self):
|
||||
x = torch.tensor([True, False, True, False], device=device)
|
||||
y = torch.tensor([False, False, True, True], device=device)
|
||||
ret = x.logical_or_(y)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [True, False, True, True])
|
||||
|
||||
def test_masked_fill_scalar_inplace_identity(self):
|
||||
x = torch.tensor([1.0, 2.0, 3.0, 4.0], device=device)
|
||||
mask = torch.tensor([True, False, True, False], device=device)
|
||||
ret = x.masked_fill_(mask, 0.0)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [0.0, 2.0, 0.0, 4.0])
|
||||
|
||||
def test_masked_fill_tensor_inplace_identity(self):
|
||||
x = torch.tensor([1.0, 2.0, 3.0, 4.0], device=device)
|
||||
mask = torch.tensor([True, False, True, False], device=device)
|
||||
value = torch.tensor(99.0, device=device)
|
||||
ret = x.masked_fill_(mask, value)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [99.0, 2.0, 99.0, 4.0])
|
||||
|
||||
def test_zero_inplace_identity(self):
|
||||
x = torch.tensor([1.0, 2.0, 3.0, 4.0], device=device)
|
||||
ret = x.zero_()
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [0.0, 0.0, 0.0, 0.0])
|
||||
|
||||
def test_fill_scalar_inplace_identity(self):
|
||||
x = torch.tensor([1.0, 2.0, 3.0, 4.0], device=device)
|
||||
ret = x.fill_(5.0)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [5.0, 5.0, 5.0, 5.0])
|
||||
|
||||
def test_fill_tensor_inplace_identity(self):
|
||||
x = torch.tensor([1.0, 2.0, 3.0, 4.0], device=device)
|
||||
value = torch.tensor(7.0, device=device)
|
||||
ret = x.fill_(value)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [7.0, 7.0, 7.0, 7.0])
|
||||
|
||||
def test_add_tensor_inplace_identity(self):
|
||||
x = torch.tensor([1.0, 2.0, 3.0, 4.0], device=device)
|
||||
y = torch.tensor([10.0, 20.0, 30.0, 40.0], device=device)
|
||||
ret = x.add_(y)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [11.0, 22.0, 33.0, 44.0])
|
||||
|
||||
def test_add_scalar_inplace_identity(self):
|
||||
x = torch.tensor([1.0, 2.0, 3.0, 4.0], device=device)
|
||||
ret = x.add_(10.0)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [11.0, 12.0, 13.0, 14.0])
|
||||
|
||||
def test_mul_tensor_inplace_identity(self):
|
||||
x = torch.tensor([1.0, 2.0, 3.0, 4.0], device=device)
|
||||
y = torch.tensor([2.0, 3.0, 4.0, 5.0], device=device)
|
||||
ret = x.mul_(y)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [2.0, 6.0, 12.0, 20.0])
|
||||
|
||||
def test_mul_scalar_inplace_identity(self):
|
||||
x = torch.tensor([1.0, 2.0, 3.0, 4.0], device=device)
|
||||
ret = x.mul_(2.0)
|
||||
assert ret is x
|
||||
np.testing.assert_equal(x.cpu().numpy(), [2.0, 4.0, 6.0, 8.0])
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
# simple tests
|
||||
import unittest
|
||||
import torch
|
||||
import warnings
|
||||
from tinygrad.helpers import getenv, GlobalCounters
|
||||
if getenv("TINY_BACKEND2"):
|
||||
import extra.torch_backend.backend2
|
||||
device = "cpu"
|
||||
else:
|
||||
import extra.torch_backend.backend
|
||||
device = "tiny"
|
||||
|
||||
|
||||
class TestKernelFusionRegression(unittest.TestCase):
|
||||
def _realize(self, t): _ = t.detach().cpu().numpy()
|
||||
|
||||
def _check_kernel_count(self, fn, expected_kernels):
|
||||
torch.manual_seed(42)
|
||||
GlobalCounters.reset()
|
||||
fn().detach().cpu().numpy()
|
||||
expectation = f"{GlobalCounters.kernel_count} vs {expected_kernels} expected."
|
||||
if GlobalCounters.kernel_count < expected_kernels: warnings.warn(f"{expectation} Expectation can be lowered.", UserWarning)
|
||||
self.assertLessEqual(GlobalCounters.kernel_count, expected_kernels, f"{expectation}")
|
||||
|
||||
def test_elementwise_fusion(self):
|
||||
def fn():
|
||||
x = torch.randn(128, 128, device=device)
|
||||
return (x + 1.0) * 2.0 - 0.5
|
||||
self._check_kernel_count(fn, 6)
|
||||
|
||||
def test_relu_fusion(self):
|
||||
def fn():
|
||||
x = torch.randn(1, 3, 32, 32, device=device)
|
||||
conv = torch.nn.Conv2d(3, 16, 3, padding=1).to(device)
|
||||
with torch.no_grad():
|
||||
return torch.nn.functional.relu(conv(x))
|
||||
self._check_kernel_count(fn, 8)
|
||||
|
||||
def test_batchnorm_fusion(self):
|
||||
def fn():
|
||||
x = torch.randn(2, 3, 16, 16, device=device)
|
||||
conv = torch.nn.Conv2d(3, 8, 3, padding=1).to(device)
|
||||
bn = torch.nn.BatchNorm2d(8).to(device)
|
||||
bn.eval()
|
||||
with torch.no_grad():
|
||||
return torch.nn.functional.relu(bn(conv(x)))
|
||||
self._check_kernel_count(fn, 16)
|
||||
|
||||
def test_reduce_fusion(self):
|
||||
def fn():
|
||||
x = torch.randn(64, 64, device=device)
|
||||
return (x * 2.0).sum()
|
||||
self._check_kernel_count(fn, 7)
|
||||
|
||||
def test_matmul_elementwise_fusion(self):
|
||||
def fn():
|
||||
x = torch.randn(32, 32, device=device)
|
||||
w = torch.randn(32, 32, device=device)
|
||||
return torch.nn.functional.relu(x @ w + 1.0)
|
||||
self._check_kernel_count(fn, 6)
|
||||
|
||||
def test_pooling_fusion(self):
|
||||
def fn():
|
||||
x = torch.randn(1, 8, 16, 16, device=device)
|
||||
return torch.nn.functional.max_pool2d(x * 2.0, 2)
|
||||
self._check_kernel_count(fn, 5)
|
||||
|
||||
def test_residual_add_relu_fusion(self):
|
||||
def fn():
|
||||
x = torch.randn(1, 8, 16, 16, device=device)
|
||||
identity = torch.randn(1, 8, 16, 16, device=device)
|
||||
out = x + identity
|
||||
return torch.nn.functional.relu(out)
|
||||
self._check_kernel_count(fn, 6)
|
||||
|
||||
def test_inplace_add_relu_fusion(self):
|
||||
def fn():
|
||||
x = torch.randn(1, 16, 32, 32, device=device)
|
||||
y = torch.randn(1, 16, 32, 32, device=device)
|
||||
x += y
|
||||
return torch.nn.functional.relu(x)
|
||||
self._check_kernel_count(fn, 6)
|
||||
|
||||
def test_conv_bn_add_relu_fusion(self):
|
||||
def fn():
|
||||
x = torch.randn(1, 8, 16, 16, device=device)
|
||||
identity = torch.randn(1, 8, 16, 16, device=device)
|
||||
conv = torch.nn.Conv2d(8, 8, 3, padding=1, bias=False).to(device)
|
||||
bn = torch.nn.BatchNorm2d(8).to(device)
|
||||
bn.eval()
|
||||
with torch.no_grad():
|
||||
out = bn(conv(x))
|
||||
out += identity
|
||||
return torch.nn.functional.relu(out)
|
||||
self._check_kernel_count(fn, 16)
|
||||
|
||||
def test_multiple_inplace_ops_fusion(self):
|
||||
def fn():
|
||||
x = torch.randn(64, 64, device=device)
|
||||
x += 1.0
|
||||
x *= 2.0
|
||||
return torch.nn.functional.relu(x)
|
||||
self._check_kernel_count(fn, 4)
|
||||
|
||||
def test_view_inplace_no_fusion_break(self):
|
||||
def fn():
|
||||
x = torch.randn(4, 64, device=device)
|
||||
view = x[1:3]
|
||||
view += 1.0
|
||||
return x.sum()
|
||||
self._check_kernel_count(fn, 8)
|
||||
|
||||
def test_batchnorm_running_stats_update(self):
|
||||
def fn():
|
||||
x = torch.randn(2, 8, 8, 8, device=device)
|
||||
bn = torch.nn.BatchNorm2d(8).to(device)
|
||||
bn.train()
|
||||
with torch.no_grad():
|
||||
return bn(x)
|
||||
self._check_kernel_count(fn, 10)
|
||||
|
||||
# this is a minimal extra/other_mnist/beautiful_mnist_torch.py to cover fusion for training with optimizer
|
||||
def test_mnist_training_fusion(self):
|
||||
def fn():
|
||||
model = torch.nn.Sequential(
|
||||
torch.nn.Conv2d(1, 8, 3, padding=1),
|
||||
torch.nn.ReLU(),
|
||||
torch.nn.MaxPool2d(2),
|
||||
torch.nn.Flatten(),
|
||||
torch.nn.Linear(8*14*14, 10)
|
||||
).to(device)
|
||||
optimizer = torch.optim.Adam(model.parameters(), 1e-3)
|
||||
x = torch.randn(32, 1, 28, 28, device=device)
|
||||
labels = torch.randint(0, 10, (32,), device=device)
|
||||
out = model(x)
|
||||
loss = torch.nn.functional.cross_entropy(out, labels)
|
||||
optimizer.zero_grad()
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
return loss
|
||||
self._check_kernel_count(fn, 33)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -113,16 +113,9 @@ int register_hook() {
|
||||
int temp_register_hook = register_hook();
|
||||
|
||||
at::Tensor wrap_tensor(py::object &py_obj, c10::ScalarType dtype, c10::DeviceIndex device_index) {
|
||||
// TODO: we have to get the dtype and the shape from the tinygrad Tensor
|
||||
std::vector<int64_t> sizes = py_obj.attr("shape").cast<std::vector<int64_t>>();
|
||||
|
||||
py::list views = py_obj.attr("uop").attr("st").attr("views");
|
||||
std::vector<int64_t> strides = views[views.size() - 1].attr("strides").cast<std::vector<int64_t>>();
|
||||
int64_t storage_offset = 0;
|
||||
for (auto& v: views) {
|
||||
storage_offset += v.attr("offset").cast<int64_t>(); // TODO: is this correct?
|
||||
}
|
||||
|
||||
std::vector<int64_t> strides = py_obj.attr("_strides").cast<std::vector<int64_t>>();
|
||||
int64_t storage_offset = py_obj.attr("_storage_offset").cast<int64_t>();
|
||||
return at::detail::make_tensor<at::TinyOpaqueTensorImpl<std::shared_ptr<c10::SafePyObject>>>(
|
||||
at::DispatchKeySet(at::DispatchKey::PrivateUse1),
|
||||
c10::scalarTypeToTypeMeta(dtype),
|
||||
|
||||
@@ -4,6 +4,8 @@ import token
|
||||
import tokenize
|
||||
import itertools
|
||||
from tabulate import tabulate
|
||||
from tinygrad.uop import Ops
|
||||
from tinygrad.helpers import ContextVar
|
||||
|
||||
TOKEN_WHITELIST = [token.OP, token.NAME, token.NUMBER, token.STRING]
|
||||
|
||||
@@ -79,11 +81,15 @@ if __name__ == "__main__":
|
||||
print(tabulate([headers] + sorted(table, key=lambda x: -x[1]), headers="firstrow", floatfmt=".1f")+"\n")
|
||||
groups = sorted([('/'.join(x[0].rsplit("/", 1)[0].split("/")[0:2]), x[1], x[2]) for x in table])
|
||||
dir_sizes = {}
|
||||
for dir_name, group in itertools.groupby(groups, key=lambda x:x[0]):
|
||||
for dir_name, _group in itertools.groupby(groups, key=lambda x:x[0]):
|
||||
group = list(_group)
|
||||
dir_sizes[dir_name] = sum([x[1] for x in group])
|
||||
print(f"{dir_name:30s} : {dir_sizes[dir_name]:6d}")
|
||||
print(f"\n core line count: {sum([v for k,v in dir_sizes.items() if k not in NONCORE_DIRS])}")
|
||||
print(f"{dir_name:30s} : {dir_sizes[dir_name]:6d} in {len(group):2d} files")
|
||||
print()
|
||||
print(f" ops: {len(Ops)}")
|
||||
print(f" flags: {len(ContextVar._cache)}")
|
||||
print(f" core lines: {sum([v for k,v in dir_sizes.items() if k not in NONCORE_DIRS])}")
|
||||
total_lines = sum([x[1] for x in table])
|
||||
print(f"total line count: {total_lines}")
|
||||
print(f"total lines: {total_lines}")
|
||||
max_line_count = int(os.getenv("MAX_LINE_COUNT", "-1"))
|
||||
assert max_line_count == -1 or total_lines <= max_line_count, f"OVER {max_line_count} LINES"
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
# benchmark speed of pyrender for all created UOps saved with TRACK_MATCH_STATS=2
|
||||
import functools, pickle
|
||||
from tinygrad.uop.ops import UOp, Ops
|
||||
from tinygrad.helpers import tqdm, temp, time_to_str, cpu_profile
|
||||
|
||||
BENCHMARK_OPS = {Ops.INDEX, Ops.BUFFERIZE}
|
||||
|
||||
@functools.cache
|
||||
def create_uop(a:int) -> UOp:
|
||||
op, dtype, src, arg, *rest = trace.uop_fields[a]
|
||||
return UOp(op, dtype, tuple(create_uop(s) for s in src), arg, *rest)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# load rewrite trace
|
||||
with open(temp("rewrites.pkl", append_user=True), "rb") as f:
|
||||
trace = pickle.load(f)
|
||||
|
||||
# benchmark
|
||||
result:list[tuple[str, int]] = []
|
||||
try:
|
||||
for steps in tqdm(trace.rewrites):
|
||||
for r in steps:
|
||||
for _,yn,_,__ in r.matches:
|
||||
y = create_uop(yn)
|
||||
if y.op in BENCHMARK_OPS:
|
||||
with cpu_profile("pyrender") as e:
|
||||
try: ren = y.render()
|
||||
except Exception: ren = "PYRENDER_ERR"
|
||||
result.append((ren, float(e.en-e.st)/1e6))
|
||||
finally:
|
||||
N = 10
|
||||
print(f"Slowst {N} renders from {len(result)} samples:")
|
||||
for ren,tm in sorted(result, key=lambda x:x[1], reverse=True)[:N]:
|
||||
print(f"{time_to_str(tm).strip():<10s} {ren}")
|
||||
+3
-2
@@ -1,13 +1,14 @@
|
||||
import unittest
|
||||
from tinygrad import Device
|
||||
from tinygrad.tensor import Tensor
|
||||
from tinygrad.helpers import getenv, CI
|
||||
from tinygrad.helpers import getenv, CI, OSX
|
||||
|
||||
def multidevice_test(fxn):
|
||||
exclude_devices = getenv("EXCLUDE_DEVICES", "").split(",")
|
||||
def ret(self):
|
||||
for device in Device._devices:
|
||||
if device in ["REMOTE", "DISK", "NPY", "FAKE", "DSP", "NULL"]: continue
|
||||
# broken on OSX USB AMD, why?
|
||||
if device in ["REMOTE", "DISK", "NPY", "FAKE", "DSP", "NULL"] or (OSX and device in ["AMD"]): continue
|
||||
if not CI: print(device)
|
||||
if device in exclude_devices:
|
||||
if not CI: print(f"WARNING: {device} test is excluded")
|
||||
|
||||
Vendored
+2
@@ -2,6 +2,7 @@ import gc
|
||||
from tinygrad import Tensor, UOp, Device, nn
|
||||
from tinygrad.engine.realize import method_cache, get_program
|
||||
from tinygrad.schedule.indexing import apply_movement_op
|
||||
from tinygrad.uop.divandmod import fold_divmod_general
|
||||
from test.test_tiny import TestTiny
|
||||
|
||||
def uops_allocated(): return sum([isinstance(x, UOp) for x in gc.get_objects()])
|
||||
@@ -69,6 +70,7 @@ if __name__ == "__main__":
|
||||
# these caches will keep uops alive
|
||||
method_cache.clear()
|
||||
apply_movement_op.cache_clear()
|
||||
fold_divmod_general.cache_clear()
|
||||
Tensor._device_seeds.clear()
|
||||
Tensor._device_rng_counters.clear()
|
||||
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
import random
|
||||
import z3
|
||||
from tinygrad.uop.ops import UOp, Ops
|
||||
from tinygrad.uop.validate import uops_to_z3
|
||||
from tinygrad.helpers import DEBUG, Context, colored
|
||||
|
||||
seed = random.randint(0, 100)
|
||||
print(f"Seed: {seed}")
|
||||
random.seed(seed)
|
||||
|
||||
def get_random_term(ranges, factors):
|
||||
# 10% chance of nesting
|
||||
if random.randint(0,9) == 0: return get_random_expr(ranges, factors)
|
||||
return random.choice(ranges)*random.choice(factors)*random.choice([1, 1, 1, -1])
|
||||
|
||||
def get_random_expr(ranges, factors):
|
||||
num_terms = random.randint(2,4)
|
||||
x = UOp.sum(*[get_random_term(ranges, factors) for _ in range(num_terms)])
|
||||
return x.alu(random.choice([Ops.IDIV, Ops.MOD]), x.ufix(random.choice(factors)*random.choice([1, 1, 1, -1])))
|
||||
|
||||
if __name__ == "__main__":
|
||||
skipped = 0
|
||||
for i in range(700):
|
||||
if i % 100 == 0:
|
||||
print(f"Running test {i}")
|
||||
upper_bounds = [*list(range(1, 4)), 16, 33, 53, 64, 256]
|
||||
variable_names = ["i", "j", "k"]
|
||||
variables = [UOp.variable(s, 1, random.choice(upper_bounds)) for s in variable_names]
|
||||
factors = variables+upper_bounds
|
||||
# add some products
|
||||
for _ in range(2): factors.append(random.choice(variables)*random.choice(variables))
|
||||
# add some adds
|
||||
for _ in range(2): factors.append(random.choice(variables)+random.choice(factors))
|
||||
num_ranges = 4
|
||||
ranges = [UOp.range(random.choice(factors), i) for i in range(num_ranges)]
|
||||
variable_names += [f"r{i}" for i in range(num_ranges)]
|
||||
expr = get_random_expr(ranges, factors)
|
||||
|
||||
with Context(CORRECT_DIVMOD_FOLDING=1):
|
||||
simplified_expr = expr.simplify()
|
||||
|
||||
if DEBUG>=1:
|
||||
print(expr.render(simplify=False), " --> ", simplified_expr.render(simplify=False))
|
||||
|
||||
solver = z3.Solver()
|
||||
solver.set(timeout=3000) # some expressions take very long verify, but its very unlikely they actually return sat
|
||||
z3_expr, z3_simplified_expr, *z3_vars = uops_to_z3(solver, expr, simplified_expr, *variables, *ranges)
|
||||
check = solver.check(z3_simplified_expr != z3_expr)
|
||||
if check == z3.unknown and DEBUG>=1:
|
||||
skipped += 1
|
||||
print("skipped z3 verification due to timeout")
|
||||
elif check == z3.sat:
|
||||
print(colored("simplify INCORRECT!", "red"))
|
||||
print(solver.model())
|
||||
var_vals = {s:solver.model()[z] for s,z in zip(variable_names, z3_vars)}
|
||||
print("reproduce with:")
|
||||
print("var_vals = ", var_vals)
|
||||
print("globals = var_vals|{'cdiv':cdiv,'cmod':cmod}")
|
||||
print("expr = ast.simplify()")
|
||||
print("assert eval(ast.render(pm=renderer_infer, simplify=False),globals) == eval(expr.render(pm=renderer_infer, simplify=False),globals)")
|
||||
print()
|
||||
|
||||
assert False
|
||||
|
||||
if DEBUG >= 2: print(f"validated {expr.render()}")
|
||||
print(f"Skipped {skipped} expressions due to timeout")
|
||||
+3
-1
@@ -36,7 +36,9 @@ def trunc_log(x):
|
||||
logging.info("\n".join(lines))
|
||||
|
||||
# user config
|
||||
SKIP_PROCESS_REPLAY = (k:="[skip_process_replay]") in os.getenv("COMMIT_MESSAGE", "") or k in os.getenv("PR_TITLE", "")
|
||||
# NOTE: process replay is slow so it's now disabled by default. add [pr] to enable it
|
||||
#SKIP_PROCESS_REPLAY = (k:="[skip_process_replay]") in os.getenv("COMMIT_MESSAGE", "") or k in os.getenv("PR_TITLE", "")
|
||||
SKIP_PROCESS_REPLAY = not ASSERT_DIFF and not ((k:="[p]") in os.getenv("COMMIT_MESSAGE", "") or k in os.getenv("PR_TITLE", ""))
|
||||
if REF == "master": SKIP_PROCESS_REPLAY = True
|
||||
class ProcessReplayWarning(Warning): pass
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@ class PM4Executor(AMDQueue):
|
||||
elif mem_data_sel == 3:
|
||||
if mem_event_type == CACHE_FLUSH_AND_INV_TS_EVENT: ptr.cast('Q')[0] = int(time.perf_counter() * 1e8)
|
||||
else: raise RuntimeError(f"Unknown {mem_data_sel=} {mem_event_type=}")
|
||||
elif mem_data_sel == 0: pass # no write
|
||||
else: raise RuntimeError(f"Unknown {mem_data_sel=}")
|
||||
|
||||
def _exec_copy_data(self, n):
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import unittest
|
||||
import pathlib
|
||||
from examples.whisper import init_whisper, load_file_waveform, transcribe_file, transcribe_waveform
|
||||
import examples.mlperf.metrics as metrics
|
||||
from tinygrad.helpers import CI, fetch, CPU_LLVM
|
||||
from tinygrad import Device, dtypes
|
||||
from tinygrad.device import is_dtype_supported
|
||||
@@ -14,7 +15,39 @@ TEST_FILE_2 = str(pathlib.Path(__file__).parent / "whisper/test2.wav")
|
||||
TRANSCRIPTION_2 = "a slightly longer audio file so that we can test batch transcriptions of varying length."
|
||||
# TODO this file will possibly not survive long. find another 1-2 minute sound file online to transcribe
|
||||
TEST_FILE_3_URL = 'https://homepage.ntu.edu.tw/~karchung/miniconversations/mc45.mp3'
|
||||
TRANSCRIPTION_3 = "Just lie back and relax. Is the level of pressure about right? Yes, it's fine, and I'd like conditioner please. Sure. I'm going to start the second lathering now. Would you like some Q-tips? How'd you like it cut? I'd like my bangs and the back trimmed, and I'd like the rest thinned out a bit and layered. Where would you like the part? On the left, right about here. Here, have a look. What do you think? It's fine. Here's a thousand anti-dollars. It's 30-ant extra for the rants. Here's your change and receipt. Thank you, and please come again. So how do you like it? It could have been worse, but you'll notice that I didn't ask her for her card. Hmm, yeah. Maybe you can try that place over there next time." # noqa: E501
|
||||
TRANSCRIPTION_3 = """Just lie back and relax.
|
||||
Is the level of pressure about right?
|
||||
Yes, it's fine. And I'd like conditioner, please.
|
||||
Sure. I'm going to start the second lathering now.
|
||||
Would you like some Q-tips?
|
||||
How'd you like it cut?
|
||||
I'd like my bangs and the back trimmed,
|
||||
and I'd like the rest thinned out a bit and layered.
|
||||
Where would you like the part?
|
||||
On the left, right about here.
|
||||
Here, have a look. What do you think?
|
||||
It's fine. Here's thousand NT dollars.
|
||||
It's 30 NT extra for the rinse. Here's your change and receipt.
|
||||
Thank you, and please come again!
|
||||
So, how do you like it?
|
||||
It could have been worse. But you'll notice that I didn't ask her for her card.
|
||||
Hmm, yeah.
|
||||
Mm, maybe you can try that place over there next time."""
|
||||
|
||||
TRANSCRIPTION_3_ALT = "Just lie back and relax. Is the level of pressure about right? Yes, it's fine. And I'd like conditioner please. Sure. I'm going to start the second lathering now. Would you like some Q-tips? How'd you like it cut? I'd like my bangs on the back trimmed, and I'd like the rest to stand out a bit and layered. Where would you like the part? On the left, right about here. Here. Have a look. What do you think? It's fine. Here's a thousand and eighty dollars. It's thirty and t extra for the rants. Here's your change and receipt. Thank you, and please come again. So how do you like it? It could have been worse, but you'll notice that I didn't ask her for her card. Hmm, yeah. Maybe you can try that place over there next time." #noqa: E501
|
||||
# NOTE: same as TRANSCRIPTION_3 but with minor changes that should only amount to ~0.079 WER difference (see test_wer_same)
|
||||
# 'and' --> 'on'
|
||||
# 'thinned' --> 'to stand'
|
||||
# 'nt' --> 'and eighty'
|
||||
# '30 nt' --> 'thirty and t'
|
||||
# 'rinse' --> 'rants'
|
||||
# 'mm' --> ''
|
||||
|
||||
def wer_helper(result: str, reference: str)->float:
|
||||
result = metrics.normalize_string(result)
|
||||
reference = metrics.normalize_string(reference)
|
||||
wer, _, _ = metrics.word_error_rate([result], [reference])
|
||||
return wer
|
||||
|
||||
@unittest.skipIf(Device.DEFAULT in ["CPU"], "slow")
|
||||
@unittest.skipUnless(is_dtype_supported(dtypes.float16), "need float16 support")
|
||||
@@ -30,6 +63,15 @@ class TestWhisper(unittest.TestCase):
|
||||
del cls.model
|
||||
del cls.enc
|
||||
|
||||
def assertWER(self, actual: str, expected: str, threshold: float):
|
||||
__tracebackhide__ = True # Hide traceback for py.test
|
||||
wer = wer_helper(actual, expected)
|
||||
if wer > threshold:
|
||||
err = f"WER={wer:.3f} > {threshold}"
|
||||
raise AssertionError(
|
||||
err
|
||||
)
|
||||
|
||||
def test_transcribe_file1(self):
|
||||
self.assertEqual(transcribe_file(self.model, self.enc, TEST_FILE_1), TRANSCRIPTION_1)
|
||||
|
||||
@@ -56,7 +98,7 @@ class TestWhisper(unittest.TestCase):
|
||||
def test_transcribe_long(self):
|
||||
waveform = [load_file_waveform(fetch(TEST_FILE_3_URL))]
|
||||
transcription = transcribe_waveform(self.model, self.enc, waveform)
|
||||
self.assertEqual(TRANSCRIPTION_3, transcription)
|
||||
self.assertWER(transcription, TRANSCRIPTION_3, 0.085)
|
||||
|
||||
@unittest.skipIf(CI or (Device.DEFAULT == "CPU" and CPU_LLVM), "too long for CI")
|
||||
def test_transcribe_long_no_batch(self):
|
||||
@@ -64,8 +106,24 @@ class TestWhisper(unittest.TestCase):
|
||||
|
||||
trancriptions = transcribe_waveform(self.model, self.enc, waveforms)
|
||||
self.assertEqual(2, len(trancriptions))
|
||||
self.assertEqual(TRANSCRIPTION_3, trancriptions[0])
|
||||
self.assertWER(trancriptions[0], TRANSCRIPTION_3, 0.085)
|
||||
self.assertEqual(TRANSCRIPTION_1, trancriptions[1])
|
||||
|
||||
def test_wer_same(self):
|
||||
reference = TRANSCRIPTION_3
|
||||
self.assertWER(TRANSCRIPTION_3_ALT, reference, 0.079)
|
||||
|
||||
def test_wer_different(self):
|
||||
reference = TRANSCRIPTION_3
|
||||
self.assertWER("[no speech]", reference, 1.0)
|
||||
|
||||
def test_wer_different_2(self):
|
||||
reference = TRANSCRIPTION_3
|
||||
self.assertWER("", reference, 1.0)
|
||||
|
||||
def test_wer_different_3(self):
|
||||
reference = TRANSCRIPTION_3
|
||||
self.assertWER(reference[:len(reference)//2], reference, 0.524)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
+22
-8
@@ -5,26 +5,40 @@ from tinygrad.helpers import CI, Context, getenv
|
||||
from tinygrad.engine.realize import run_schedule
|
||||
from tinygrad.engine.realize import CompiledRunner, ExecItem, get_program
|
||||
from tinygrad.uop.ops import Ops
|
||||
from tinygrad.renderer import Estimates
|
||||
from tinygrad.renderer.ptx import PTXRenderer
|
||||
|
||||
class TestArange(unittest.TestCase):
|
||||
def _get_flops(self, N):
|
||||
def _get_flops(self, tensor, desired):
|
||||
GlobalCounters.reset()
|
||||
tt = Tensor.arange(N)
|
||||
sched = tt.schedule()
|
||||
sched = tensor.schedule()
|
||||
self.assertEqual(len(sched), 1)
|
||||
p = get_program(sched[-1].ast)
|
||||
ExecItem(CompiledRunner(p), [tt.uop.buffer]).run()
|
||||
np.testing.assert_equal(tt.numpy(), np.arange(N))
|
||||
ExecItem(CompiledRunner(p), [tensor.uop.buffer]).run()
|
||||
np.testing.assert_equal(tensor.numpy(), desired)
|
||||
return p.estimates.ops
|
||||
|
||||
def test_complexity(self):
|
||||
self.assertEqual(self._get_flops(256), 0)
|
||||
self.assertEqual(self._get_flops(2560), 0)
|
||||
def test_arange_complexity(self):
|
||||
self.assertEqual(self._get_flops(Tensor.arange(256), np.arange(256)), 0)
|
||||
self.assertEqual(self._get_flops(Tensor.arange(2560), np.arange(2560)), 0)
|
||||
|
||||
def test_arange_cat(self):
|
||||
t = Tensor.arange(2, dtype=dtypes.int)+Tensor([3])
|
||||
self.assertEqual(t.cat(t).tolist(), [3, 4, 3, 4])
|
||||
|
||||
def test_eye_complexity(self):
|
||||
with Context(NOOPT=1):
|
||||
# NOTE: not every backend supports CMPEQ
|
||||
self.assertLessEqual(self._get_flops(Tensor.eye(2560).contiguous(), np.eye(2560)), 2*2560*2560)
|
||||
|
||||
@unittest.skipIf(isinstance(Device[Device.DEFAULT].renderer, PTXRenderer), "PTX indexing is weird")
|
||||
def test_tri_complexity(self):
|
||||
with Context(NOOPT=1):
|
||||
t = Tensor.ones(256, 256).contiguous().realize()
|
||||
sched = t.triu().schedule()
|
||||
p = get_program(sched[-1].ast)
|
||||
self.assertLessEqual(Estimates.from_uops(p.uops).ops, 4 * 256 * 256)
|
||||
|
||||
DSET, DDIM = 2048, 32
|
||||
|
||||
class TestIndexing(unittest.TestCase):
|
||||
|
||||
@@ -102,6 +102,11 @@ def backward_gemm_custom(gradient:UOp, kernel:UOp) -> tuple[UOp, UOp]:
|
||||
# **** tests ****
|
||||
|
||||
class TestCustomKernel(unittest.TestCase):
|
||||
def test_empty(self):
|
||||
a = Tensor.empty(1)
|
||||
a = Tensor.custom_kernel(a, fxn=lambda _: UOp.sink())[0]
|
||||
a.realize()
|
||||
|
||||
def test_simple(self):
|
||||
a = Tensor.ones(16, 16).contiguous()
|
||||
b = Tensor.ones(16, 16).contiguous()
|
||||
|
||||
+19
-1
@@ -14,6 +14,8 @@ from tinygrad.renderer.ptx import PTXRenderer
|
||||
from tinygrad.renderer.cstyle import CUDARenderer
|
||||
MOCKGPU = getenv("MOCKGPU")
|
||||
|
||||
from tinygrad.uop.ops import print_uops # noqa: F401 # pylint: disable=unused-import
|
||||
|
||||
class TestLinearizer(unittest.TestCase):
|
||||
def test_arg_dedup(self):
|
||||
# NOTE: this realize exists because Tensor.numpy calls .contiguous() internally
|
||||
@@ -38,6 +40,22 @@ class TestLinearizer(unittest.TestCase):
|
||||
np.testing.assert_equal(a.numpy(), ta)
|
||||
np.testing.assert_equal(b.numpy(), tb)
|
||||
|
||||
@unittest.skip("TODO: some backends insert more casts")
|
||||
def test_cast_there_and_back(self):
|
||||
tst = Tensor.ones(16, dtype=dtypes.int).contiguous().realize()
|
||||
out = tst.neg().cast(dtypes.char).cast(dtypes.int).cast(dtypes.char) * 2
|
||||
ast = helper_linearizer_opt(out)
|
||||
uops = get_program(ast, opts=[]).uops
|
||||
self.assertEqual(len([x for x in uops if x.op is Ops.CAST]), 1)
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_cast_back_and_there(self):
|
||||
tst = Tensor.ones(16, dtype=dtypes.int).contiguous().realize()
|
||||
out = tst.neg().cast(dtypes.char).cast(dtypes.int) * 2
|
||||
ast = helper_linearizer_opt(out)
|
||||
uops = get_program(ast, opts=[]).uops
|
||||
self.assertEqual(len([x for x in uops if x.op is Ops.CAST]), 0)
|
||||
|
||||
@unittest.skipIf(isinstance(Device[Device.DEFAULT].renderer, PTXRenderer), "broken on ptx")
|
||||
def test_late_bias_load(self):
|
||||
img = Tensor.empty(1, 3, 16, 16)
|
||||
@@ -491,7 +509,7 @@ def copyout_outputs(outbufs:list[Buffer]) -> list[np.ndarray]:
|
||||
return [np.frombuffer(x.as_buffer(), _to_np_dtype(x.dtype)) for x in outbufs]
|
||||
|
||||
def reset_bufs(bufs:list[Buffer]):
|
||||
for buf in bufs: buf.copyin(np.zeros((buf.size, ), dtype=_to_np_dtype(buf.dtype)).data) # Zero to check that all values are filled
|
||||
for buf in bufs: buf.copyin(np.zeros((buf.size*buf.dtype.itemsize,), dtype=np.uint8).data)
|
||||
|
||||
def _helper_linearizer_opt_ast(realized_ast:UOp, real_bufs:list[Buffer], opts=[],
|
||||
apply_tc=False, atol=1e-4, rtol=1e-4, color_sizes=[], wanna_output=[]):
|
||||
|
||||
@@ -765,6 +765,16 @@ class TestMultiTensor(unittest.TestCase):
|
||||
with self.assertRaises(RuntimeError):
|
||||
Tensor.rand_like(t, device=(d3, d4))
|
||||
|
||||
def test_full_like_on_shard(self, axis=None):
|
||||
t = Tensor.empty((16, 16)).shard(devices_2, axis=axis)
|
||||
t2 = Tensor.full_like(t, 1.0)
|
||||
self.assertEqual(t.shape, t2.shape)
|
||||
self.assertEqual(t.device, t2.device)
|
||||
self.assertEqual(t.dtype, t2.dtype)
|
||||
self.assertEqual(t.uop.axis, t2.uop.axis)
|
||||
t2.realize()
|
||||
def test_full_like_on_shard_axis(self): self.test_full_like_on_shard(0)
|
||||
|
||||
def test_dropout_on_shard(self):
|
||||
with Tensor.train():
|
||||
X = Tensor.ones(256).to(devices_2)
|
||||
|
||||
@@ -2699,6 +2699,9 @@ class TestOps(unittest.TestCase):
|
||||
a = Tensor(3.14)
|
||||
np.testing.assert_allclose(Tensor.stack(a, a).numpy(), Tensor([3.14, 3.14]).numpy())
|
||||
|
||||
def test_stack_max(self):
|
||||
helper_test_op(None, lambda x, y: torch.stack((x, y)).max(axis=0)[0], lambda x, y: Tensor.stack(x, y).max(axis=0), vals=[[1.], [2.]])
|
||||
|
||||
def test_repeat(self):
|
||||
x = Tensor.randn(4, 6, 3)
|
||||
base_repeats = [2, 4, 3]
|
||||
|
||||
+157
-1
@@ -1,5 +1,6 @@
|
||||
import unittest
|
||||
from tinygrad import Tensor, UOp
|
||||
import numpy as np
|
||||
from tinygrad import Tensor, UOp, nn
|
||||
from tinygrad.uop.ops import AxisType, Ops
|
||||
|
||||
class TestOuterworldReduce(unittest.TestCase):
|
||||
@@ -11,6 +12,81 @@ class TestOuterworldReduce(unittest.TestCase):
|
||||
t = Tensor(UOp(Ops.REDUCE, dtype=out.uop.dtype, src=(out.uop, a), arg=Ops.ADD))
|
||||
self.assertListEqual(t.tolist(), [5.,5.,5.,5.,5.])
|
||||
|
||||
# TODO: delete test_outerworld_range?
|
||||
class TestOuterRange(unittest.TestCase):
|
||||
def test_simple_range(self):
|
||||
a = Tensor.ones(10).contiguous()
|
||||
acc = Tensor.zeros().contiguous()
|
||||
Tensor.realize(a, acc)
|
||||
|
||||
# this is fold
|
||||
i = UOp.range(10, -100, AxisType.OUTER)
|
||||
acc_i = acc.uop.after(i)
|
||||
vi = UOp.variable("i", i.vmin, i.vmax).bind(i)
|
||||
out = Tensor(acc.uop.after(acc_i.store(acc_i + a[vi].uop).end(i)))
|
||||
out.realize()
|
||||
assert out.item() == 10.0
|
||||
|
||||
def test_inner_range(self):
|
||||
a = Tensor.ones(10, 10).contiguous()
|
||||
acc = Tensor.zeros(10).contiguous()
|
||||
Tensor.realize(a, acc)
|
||||
|
||||
# this is fold
|
||||
i = UOp.range(10, -100, AxisType.OUTER)
|
||||
acc_i = acc.uop.after(i)
|
||||
vi = UOp.variable("i", i.vmin, i.vmax).bind(i)
|
||||
out = Tensor(acc.uop.after(acc_i.store(acc_i + a[:, vi].uop).end(i)))
|
||||
out.realize()
|
||||
assert all(x == 10.0 for x in out.tolist())
|
||||
|
||||
def test_range_matmul(self):
|
||||
vec = Tensor.randn(1, 10).realize()
|
||||
mats = Tensor.randn(3, 10, 10).realize()
|
||||
|
||||
# 3 matmuls in "scan"
|
||||
ref = ((vec @ mats[0]) @ mats[1]) @ mats[2]
|
||||
ref.realize()
|
||||
|
||||
# 3 matmuls with outer world range
|
||||
i = UOp.range(3, -100, AxisType.OUTER)
|
||||
vec_i = Tensor(vec.uop.after(i))
|
||||
comp = vec_i.contiguous() @ mats[i]
|
||||
store = vec_i.uop.store(comp.uop).end(i)
|
||||
out = Tensor(vec.uop.after(store))
|
||||
out.realize()
|
||||
|
||||
# TODO: testing allclose
|
||||
assert Tensor.allclose(ref, out, atol=1e-6), f"{ref.numpy()=}, {out.numpy()=}"
|
||||
|
||||
class TestOuterScan(unittest.TestCase):
|
||||
def _test_scan(self):
|
||||
vec = Tensor.randn(1, 10).realize()
|
||||
mats = Tensor.randn(3, 10, 10).realize()
|
||||
|
||||
# 3 matmuls in "scan"
|
||||
vec1 = vec @ mats[0]
|
||||
vec2 = vec1 @ mats[1]
|
||||
vec3 = vec2 @ mats[2]
|
||||
ref = Tensor.stack(vec1, vec2, vec3)
|
||||
ref.realize()
|
||||
return vec, mats, ref
|
||||
|
||||
def test_uop_scan_matmul(self):
|
||||
vec, mats, ref = self._test_scan()
|
||||
|
||||
# 3 matmuls with SCAN
|
||||
i = UOp.range(3, -100, AxisType.OUTER)
|
||||
out = Tensor.empty(3, 1, 10)
|
||||
phi = Tensor(i.eq(0).where(vec.uop, out[(i-1).maximum(0)].uop))
|
||||
comp = phi @ mats[i]
|
||||
store = out[i].uop.store(comp.uop).end(i)
|
||||
out = Tensor(out.uop.after(store))
|
||||
out.realize()
|
||||
|
||||
# TODO: testing allclose
|
||||
assert Tensor.allclose(ref, out, atol=1e-6), f"{ref.numpy()=}, {out.numpy()=}"
|
||||
|
||||
class TestOuterworld(unittest.TestCase):
|
||||
def test_range_plus_1(self):
|
||||
t = Tensor.arange(100).reshape(10,10).realize()
|
||||
@@ -70,5 +146,85 @@ class TestOuterworld(unittest.TestCase):
|
||||
out = out.reshape(1, 3).expand(a, 3).contiguous().realize()
|
||||
self.assertListEqual([[0,4,8],[4,8,12],[8,12,16]], out.tolist())
|
||||
|
||||
class TestVmap(unittest.TestCase):
|
||||
def test_vmap_inner(self, axis_type=AxisType.LOOP, fuse=False, grad=False):
|
||||
x = Tensor.ones(1, 10).contiguous().requires_grad_()
|
||||
mats = Tensor.ones(3, 10, 10).contiguous().requires_grad_()
|
||||
|
||||
ref = x @ mats
|
||||
if fuse: ref = ref * 2
|
||||
|
||||
# vmap across axis 0
|
||||
a = UOp.range(3, -1, axis_type)
|
||||
out = x @ mats[a]
|
||||
out = out.reshape(1, 10).pad(((a,(3-a)-1), None))
|
||||
out = Tensor(out.uop.reduce(a, arg=Ops.ADD))
|
||||
if fuse: out = out * 2
|
||||
if grad:
|
||||
out.mean().backward()
|
||||
np.testing.assert_allclose(mats.grad.numpy(), (2./30) if fuse else (1./30))
|
||||
out.realize()
|
||||
|
||||
# TODO: testing allclose
|
||||
assert Tensor.allclose(ref, out, atol=1e-6), f"{ref.numpy()=}, {out.numpy()=}"
|
||||
def test_vmap_inner_fuse(self): self.test_vmap_inner(fuse=True)
|
||||
def test_vmap_outer(self): self.test_vmap_inner(AxisType.OUTER)
|
||||
def test_vmap_outer_fuse(self): self.test_vmap_inner(AxisType.OUTER, fuse=True)
|
||||
|
||||
def test_vmap_inner_grad(self): self.test_vmap_inner(grad=True)
|
||||
def test_vmap_inner_fuse_grad(self): self.test_vmap_inner(fuse=True, grad=True)
|
||||
def test_vmap_outer_grad(self): self.test_vmap_inner(AxisType.OUTER, grad=True)
|
||||
|
||||
def test_vmap_convs(self):
|
||||
layers = [
|
||||
nn.Conv2d(1, 8, 3), Tensor.relu,
|
||||
nn.Conv2d(8, 8, 3), Tensor.relu]
|
||||
img = Tensor.randn(4, 1, 16, 16).realize(*nn.state.get_parameters(layers))
|
||||
a = UOp.range(4, -1, AxisType.OUTER)
|
||||
out = img[a:a+1].sequential(layers)
|
||||
out = out.pad(((a,(4-a)-1), None, None, None))
|
||||
out = Tensor(out.uop.reduce(a, arg=Ops.ADD))
|
||||
out.realize()
|
||||
np.testing.assert_allclose(out.numpy(), img.sequential(layers).numpy(), atol=1e-6)
|
||||
|
||||
def test_vmap_gemm(self):
|
||||
layers = [
|
||||
nn.Linear(16, 16, bias=False), Tensor.relu,
|
||||
nn.Linear(16, 16, bias=False), Tensor.relu]
|
||||
img = Tensor.randn(4, 16).realize(*nn.state.get_parameters(layers))
|
||||
a = UOp.range(4, -1, AxisType.OUTER)
|
||||
out = img[a:a+1].sequential(layers)
|
||||
out = out.pad(((a,(4-a)-1), None))
|
||||
out = Tensor(out.uop.reduce(a, arg=Ops.ADD))
|
||||
out.realize()
|
||||
np.testing.assert_allclose(out.numpy(), img.sequential(layers).numpy(), atol=1e-6)
|
||||
|
||||
@unittest.skip("this is broken, we need to lower the outer reduce in the outer graph")
|
||||
def test_vmap_gemm_grad(self):
|
||||
layers = [
|
||||
nn.Linear(16, 16, bias=False), Tensor.relu,
|
||||
nn.Linear(16, 16, bias=False), Tensor.relu]
|
||||
layer_tensors = nn.state.get_parameters(layers)
|
||||
img = Tensor.randn(4, 16).realize(*layer_tensors)
|
||||
for l in layer_tensors: l.requires_grad_()
|
||||
a = UOp.range(4, -1, AxisType.OUTER)
|
||||
out = img[a:a+1].sequential(layers)
|
||||
out = out.pad(((a,(4-a)-1), None))
|
||||
out = Tensor(out.uop.reduce(a, arg=Ops.ADD))
|
||||
out.mean().backward()
|
||||
grads = [l.grad for l in layer_tensors]
|
||||
out.realize(*grads)
|
||||
out_grads = [x.numpy() for x in grads]
|
||||
|
||||
# compute reference grads
|
||||
for l in layer_tensors: l.grad = None
|
||||
img.sequential(layers).mean().backward()
|
||||
grads = [l.grad for l in layer_tensors]
|
||||
out.realize(*grads)
|
||||
ref_grads = [x.numpy() for x in grads]
|
||||
|
||||
# compare
|
||||
for o,r in zip(out_grads, ref_grads): np.testing.assert_allclose(o, r, atol=1e-6)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
+1
-1
@@ -20,7 +20,7 @@ class TestPickle(unittest.TestCase):
|
||||
self.assertEqual(pm2.rewrite(sink).key, tt.key)
|
||||
|
||||
def test_pickle_main_pattern_matcher(self):
|
||||
from tinygrad.codegen.late.devectorizer import sym
|
||||
from tinygrad.uop.symbolic import sym
|
||||
ssym = pickle.dumps(sym)
|
||||
dsym = pickle.loads(ssym)
|
||||
self.assertEqual(dsym.patterns[0][0].location, sym.patterns[0][0].location)
|
||||
|
||||
@@ -17,7 +17,7 @@ def helper_collect_profile(*devs):
|
||||
cpu_events.clear()
|
||||
|
||||
profile_list = []
|
||||
with Context(VIZ=1):
|
||||
with Context(VIZ=1, PROFILE=1):
|
||||
yield profile_list
|
||||
for dev in devs: dev.synchronize()
|
||||
for dev in devs: dev._at_profile_finalize()
|
||||
|
||||
+3
-3
@@ -35,9 +35,9 @@ class TestTiny(unittest.TestCase):
|
||||
out = Tensor.cat(Tensor.ones(8).contiguous(), Tensor.zeros(8).contiguous())
|
||||
self.assertListEqual(out.tolist(), [1]*8+[0]*8)
|
||||
|
||||
def test_sum(self):
|
||||
out = Tensor.ones(256).contiguous().sum()
|
||||
self.assertEqual(out.item(), 256)
|
||||
def test_sum(self, N=getenv("SUM_N", 256)):
|
||||
out = Tensor.ones(N).contiguous().sum()
|
||||
self.assertEqual(out.item(), N)
|
||||
|
||||
def test_gemm(self, N=getenv("GEMM_N", 64), out_dtype=dtypes.float):
|
||||
a = Tensor.ones(N,N).contiguous()
|
||||
|
||||
+1
-1
@@ -517,7 +517,7 @@ class TestUOpStr(unittest.TestCase):
|
||||
|
||||
class TestUPatHelpers(unittest.TestCase):
|
||||
def test_location(self):
|
||||
self.assertEqual(sym.patterns[-1][0].location[0].replace("\\", "/").split("/")[-1], "math.py")
|
||||
self.assertEqual(sym.patterns[-1][0].location[0].replace("\\", "/").split("/")[-1], "symbolic.py")
|
||||
self.assertEqual(shared_spec.patterns[0][0].location[0].replace("\\", "/").split("/")[-1], "spec.py")
|
||||
test_upat = UPat(Ops.CONST, dtypes.bool)
|
||||
self.assertEqual(test_upat.location[0].split("/")[-1], __file__.replace("\\", "/").split("/")[-1])
|
||||
|
||||
@@ -9,7 +9,7 @@ import numpy as np
|
||||
from extra.thunder.tiny.tk import WARP_THREADS
|
||||
from extra.thunder.tiny.tk.kernel import Kernel
|
||||
|
||||
@unittest.skipUnless(Device.DEFAULT in ["CUDA", "NV"], "only cuda")
|
||||
@unittest.skipIf(CI and Device.DEFAULT not in ["CUDA", "NV"], "only cuda")
|
||||
@unittest.skipIf(isinstance(Device[Device.DEFAULT].renderer, PTXRenderer), "no ptx")
|
||||
class TestTK(unittest.TestCase):
|
||||
@unittest.skipIf(CI, "no wmma in ci")
|
||||
|
||||
@@ -5,16 +5,16 @@ from tinygrad.runtime.support.c import Struct
|
||||
class TestAutogen(unittest.TestCase):
|
||||
def test_packed_struct_sizeof(self):
|
||||
layout = [('a', ctypes.c_char), ('b', ctypes.c_int, 5), ('c', ctypes.c_char)]
|
||||
class X(ctypes.Structure): _fields_, _layout_ = layout, 'gcc-sysv'
|
||||
class Y(ctypes.Structure): _fields_, _pack_, _layout_ = layout, 1, 'ms'
|
||||
class Z(Struct): _packed_, _fields_ = True, layout
|
||||
self.assertNotEqual(ctypes.sizeof(X), 4) # ctypes bug! gcc-13.3.0 says this should have size 4
|
||||
class Z(Struct): pass
|
||||
Z._packed_, Z._fields_ = True, layout
|
||||
self.assertEqual(ctypes.sizeof(Y), 6)
|
||||
self.assertEqual(ctypes.sizeof(Z), 3)
|
||||
layout = [('a', ctypes.c_int, 31), ('b', ctypes.c_int, 31), ('c', ctypes.c_int, 1), ('d', ctypes.c_int, 1)]
|
||||
class Foo(ctypes.Structure): _fields_, _layout_ = layout, 'gcc-sysv'
|
||||
class Bar(ctypes.Structure): _fields_, _pack_, _layout_ = layout, 1, 'ms'
|
||||
class Baz(Struct): _fields_, _packed_ = layout, True
|
||||
class Baz(Struct): pass
|
||||
Baz._packed_, Baz._fields_ = True, layout
|
||||
self.assertEqual(ctypes.sizeof(Foo), 12)
|
||||
self.assertEqual(ctypes.sizeof(Bar), 12)
|
||||
self.assertEqual(ctypes.sizeof(Baz), 8)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import unittest, time
|
||||
from tinygrad.helpers import Profiling
|
||||
from tinygrad.uop.ops import UOp
|
||||
from tinygrad.dtype import dtypes
|
||||
|
||||
@@ -38,6 +39,14 @@ class TestMicrobenchmarks(unittest.TestCase):
|
||||
a = UOp.const(dtypes.int, 2)
|
||||
for _ in range(N): (a+a).simplify()
|
||||
|
||||
class TestMicroprofile(unittest.TestCase):
|
||||
def test_uop_simplify_complex(self):
|
||||
x = UOp.variable("x", 0, 10)
|
||||
y = UOp.variable("y", 0, 10)
|
||||
expr = (x*2)+5+(x*4)+(y*2)+y
|
||||
with Profiling():
|
||||
for _ in range(1000): expr.simplify()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
|
||||
@@ -430,5 +430,27 @@ class TestImageSimplification(unittest.TestCase):
|
||||
load = get_load_image_uop((128, 768, 4), valid, (alu0, alu1))
|
||||
self.check(load, None, "((((idx1*24)+r3)+(r5*3))+-3)", "(((idx2*2)+r4)+-1)")
|
||||
|
||||
def test_simplify7(self):
|
||||
# DEBUG=2 ALLOWED_KERNEL_COUNT=123 ALLOWED_READ_IMAGE=1397 ALLOWED_GATED_READ_IMAGE=94 FLOAT16=1 CL=1 IMAGE=2 python examples/openpilot/compile3.py https://gitlab.com/commaai/openpilot-lfs.git/gitlab-lfs/objects/cf6376aa9a090f0da26c280ef69eabf9bbdd51d1faac9ed392919c3db69be916 # noqa: E501
|
||||
# kernel 143
|
||||
gidx0 = Special("gidx0", 32)
|
||||
lidx0 = Special("lidx0", 16)
|
||||
lidx1 = Special("lidx1", 8)
|
||||
r0 = Range(0, 7)
|
||||
|
||||
# buf.render()='UOp(Ops.DEFINE_GLOBAL, dtypes.imageh((32, 1024, 4)), arg=1, src=())'
|
||||
alu0 = ((gidx0*2+(lidx0*128+r0*64+lidx1*8+-183)%64*64+(lidx0*128+r0*64+lidx1*8+-183)//64%32*4096+1)//4%1024)
|
||||
alu1 = ((gidx0*2+(lidx0*128+r0*64+lidx1*8+-183)%64*64+(lidx0*128+r0*64+lidx1*8+-183)//64%32*4096+1)//4096)
|
||||
valid = ((lidx1<7)&((((lidx0*2+r0)<3)!=1)&((lidx0*2+r0)<35)))
|
||||
load = get_load_image_uop((32, 1024, 4), valid, (alu0, alu1))
|
||||
self.check(load, None, "(lidx1*128+gidx0//2+144)", "(lidx0*2+r0+-3)")
|
||||
|
||||
# TODO: this is the same idx as above, but simplifying idx too early makes it hard to drop the valid
|
||||
alu0 = ((gidx0*2+lidx1*512+(lidx0*8192+r0*4096)+-11711)//4%1024)
|
||||
alu1 = (lidx0*2+r0+-3)
|
||||
valid = ((lidx1<7)&((((lidx0*2+r0)<3)!=1)&((lidx0*2+r0)<35)))
|
||||
load = get_load_image_uop((32, 1024, 4), valid, (alu0, alu1))
|
||||
self.check(load, "(lidx1<7)", "((gidx0*2+lidx1*512+(lidx0*8192+r0*4096)+-11711)//4%1024)", "(lidx0*2+r0+-3)")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
@@ -159,3 +159,38 @@ class TestFuzzFailure(unittest.TestCase):
|
||||
num = expr.simplify().substitute({v1:v1_val, v2:v2_val, v3:v3_val}).ssimplify()
|
||||
rn = expr.substitute({v1:v1_val, v2:v2_val, v3:v3_val}).ssimplify()
|
||||
self.assertEqual(num, rn)
|
||||
|
||||
def test_fuzz_failure11(self):
|
||||
v1=Variable("v1", 0, 16)
|
||||
v2=Variable("v2", 0, 128)
|
||||
v3=Variable("v3", 0, 5)
|
||||
expr = UOp(Ops.MOD, dtypes.index, arg=None, src=(
|
||||
UOp(Ops.ADD, dtypes.index, arg=None, src=(
|
||||
UOp(Ops.MOD, dtypes.index, arg=None, src=(
|
||||
UOp(Ops.ADD, dtypes.index, arg=None, src=(
|
||||
UOp(Ops.MAX, dtypes.index, arg=None, src=(
|
||||
UOp(Ops.MUL, dtypes.index, arg=None, src=(
|
||||
x5:=UOp(Ops.DEFINE_VAR, dtypes.index, arg=('v2', 0, 128), src=()),
|
||||
UOp(Ops.CONST, dtypes.index, arg=0, src=()),)),
|
||||
UOp(Ops.CONST, dtypes.index, arg=8, src=()),)),
|
||||
UOp(Ops.MUL, dtypes.index, arg=None, src=(
|
||||
x5,
|
||||
UOp(Ops.CONST, dtypes.index, arg=-2, src=()),)),)),
|
||||
x10:=UOp(Ops.CONST, dtypes.index, arg=5, src=()),)),
|
||||
UOp(Ops.ADD, dtypes.index, arg=None, src=(
|
||||
UOp(Ops.ADD, dtypes.index, arg=None, src=(
|
||||
UOp(Ops.IDIV, dtypes.index, arg=None, src=(
|
||||
x14:=UOp(Ops.DEFINE_VAR, dtypes.index, arg=('v1', 0, 16), src=()),
|
||||
UOp(Ops.CONST, dtypes.index, arg=6, src=()),)),
|
||||
UOp(Ops.CONST, dtypes.index, arg=4, src=()),)),
|
||||
UOp(Ops.ADD, dtypes.index, arg=None, src=(
|
||||
x14,
|
||||
UOp(Ops.CONST, dtypes.index, arg=1, src=()),)),)),)),
|
||||
x10,))
|
||||
v1_val, v2_val, v3_val = UOp.const(dtypes.int, 0), UOp.const(dtypes.int, 7),UOp.const(dtypes.int, 0)
|
||||
num = expr.simplify().substitute({v1:v1_val, v2:v2_val, v3:v3_val}).ssimplify()
|
||||
rn = expr.substitute({v1:v1_val, v2:v2_val, v3:v3_val}).ssimplify()
|
||||
self.assertEqual(num, rn)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
@@ -3,19 +3,19 @@ from tinygrad import Tensor
|
||||
|
||||
class TestLoadStore(unittest.TestCase):
|
||||
def test_load_shape(self):
|
||||
t = Tensor(bytes(16)).load(1024).kernelize()
|
||||
t = Tensor(bytes(16)).fs_load(1024).kernelize()
|
||||
assert t.shape == (1024,), t.shape
|
||||
|
||||
def test_store_shape(self):
|
||||
t = Tensor.zeros(1024).store().kernelize()
|
||||
t = Tensor.zeros(1024).fs_store().kernelize()
|
||||
assert t.shape == (16,), t.shape
|
||||
|
||||
def test_load_large_shape(self):
|
||||
t = Tensor(bytes(16)).load(10_000_000).kernelize()
|
||||
t = Tensor(bytes(16)).fs_load(10_000_000).kernelize()
|
||||
assert t.shape == (10_000_000,), t.shape
|
||||
|
||||
def test_store_large_shape(self):
|
||||
t = Tensor.zeros(10_000_000).store().kernelize()
|
||||
t = Tensor.zeros(10_000_000).fs_store().kernelize()
|
||||
assert t.shape == (16,), t.shape
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -66,6 +66,7 @@ class TestProgressBar(unittest.TestCase):
|
||||
tqdm_output = tqdm.format_meter(n=total, total=total, elapsed=elapsed, ncols=ncols, prefix="Test")
|
||||
self._compare_bars(tinytqdm_output, tqdm_output)
|
||||
|
||||
@unittest.skip("this is flaky")
|
||||
@patch('sys.stderr', new_callable=StringIO)
|
||||
@patch('shutil.get_terminal_size')
|
||||
def test_unit_scale(self, mock_terminal_size, mock_stderr):
|
||||
@@ -127,6 +128,7 @@ class TestProgressBar(unittest.TestCase):
|
||||
self._compare_bars(tinytqdm_output, tqdm_output)
|
||||
if n > 5: break
|
||||
|
||||
@unittest.skip("this is flaky")
|
||||
@patch('sys.stderr', new_callable=StringIO)
|
||||
@patch('shutil.get_terminal_size')
|
||||
def test_set_description(self, mock_terminal_size, mock_stderr):
|
||||
|
||||
@@ -15,7 +15,7 @@ def check_uop_against_string(self, v:UOp, s:str):
|
||||
if isinstance(s_eval, int) and v.dtype==dtypes.index: s_eval = UOp.const(dtypes.index, s_eval)
|
||||
elif isinstance(s_eval, (bool, int, float)): s_eval = UOp.const(dtypes.from_py(s_eval), s_eval)
|
||||
s_eval = graph_rewrite(s_eval, commutative, name="cannonicalize eval")
|
||||
self.assertIs(s_eval, v, f"eval did not match simplified: {s_eval} != {v} for {s}")
|
||||
self.assertIs(s_eval, v, f"eval did not match simplified: {s_eval} != {v.render()} for {s}")
|
||||
|
||||
def Variable(name: str, min_val: ConstType, max_val: ConstType, dtype: DType=dtypes.index): return UOp.variable(name,min_val,max_val,dtype)
|
||||
def uconst(val): return UOp.const(dtypes.index, val)
|
||||
@@ -679,6 +679,10 @@ class TestSymbolic(unittest.TestCase):
|
||||
b = Variable("b", 0, 3)
|
||||
c = Variable("c", 0, 3)
|
||||
d = Variable("d", -3, 3)
|
||||
self.helper_test_variable((a<2), 0, 1, "(a<2)")
|
||||
self.helper_test_variable((a<=2), 0, 1, "((2<a)!=True)")
|
||||
self.helper_test_variable((a>1), 0, 1, "(1<a)")
|
||||
self.helper_test_variable((a>=1), 0, 1, "((a<1)!=True)")
|
||||
self.helper_test_variable((a<1).ne(True), 0, 1, "((a<1)!=True)")
|
||||
self.helper_test_variable((a+b<1).ne(True), 0, 1, "(((a+b)<1)!=True)")
|
||||
self.helper_test_variable((a*3+b*4<1).ne(True), 0, 1, "(((a+b)<1)!=True)")
|
||||
|
||||
@@ -6,6 +6,7 @@ from tinygrad.uop.ops import UOp, UPat, Ops, PatternMatcher, TrackedPatternMatch
|
||||
from tinygrad.uop.symbolic import sym
|
||||
from tinygrad.dtype import dtypes
|
||||
from tinygrad.helpers import PROFILE, colored, ansistrip, flatten, TracingKey, ProfileRangeEvent, ProfileEvent, Context, cpu_events, profile_marker
|
||||
from tinygrad.helpers import VIZ
|
||||
from tinygrad.device import Buffer
|
||||
|
||||
@track_rewrites(name=True)
|
||||
@@ -33,11 +34,14 @@ class BaseTestViz(unittest.TestCase):
|
||||
cpu_events.clear()
|
||||
self.tms = TRACK_MATCH_STATS.value
|
||||
self.profile = PROFILE.value
|
||||
self.viz = VIZ.value
|
||||
TRACK_MATCH_STATS.value = 2
|
||||
PROFILE.value = 1
|
||||
VIZ.value = 1
|
||||
def tearDown(self):
|
||||
TRACK_MATCH_STATS.value = self.tms
|
||||
PROFILE.value = self.profile
|
||||
VIZ.value = self.viz
|
||||
|
||||
class TestViz(BaseTestViz):
|
||||
def test_simple(self):
|
||||
|
||||
@@ -4,7 +4,7 @@ from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
from tinygrad.dtype import dtypes, ImageDType, DType, AddrSpace, Invalid, PtrDType
|
||||
from tinygrad.uop.ops import UOp, Ops, UPat, PatternMatcher, graph_rewrite, GroupOp, identity_element
|
||||
from tinygrad.uop.symbolic import uop_given_valid, parse_valid, sym, symbolic, invalid_gate
|
||||
from tinygrad.uop.symbolic import uop_given_valid, parse_valid, symbolic, invalid_gate
|
||||
from tinygrad.helpers import getenv, flatten, AMX, prod
|
||||
from tinygrad.renderer import Renderer
|
||||
|
||||
@@ -26,7 +26,6 @@ def simplify_valid_load(buf:UOp, start_idx:UOp, valid:UOp) -> UOp|None:
|
||||
# for X0 + X1 + ... >= 1, check if it's out of bound when Xi = 0 for all i
|
||||
if not is_upper_bound and c == 1 and all(u.op in GroupOp.Irreducible and u.vmin == 0 for u in X.split_uop(Ops.ADD)):
|
||||
testidx = functools.reduce(lambda nowidx,u: nowidx.substitute({u:u.const_like(0)}), X.split_uop(Ops.ADD), idx)
|
||||
testidx = testidx.simplify()
|
||||
if testidx.gep(0).vmax < 0 or testidx.gep(1).vmax < 0:
|
||||
drop_stmt.append(stmt)
|
||||
continue
|
||||
@@ -36,7 +35,7 @@ def simplify_valid_load(buf:UOp, start_idx:UOp, valid:UOp) -> UOp|None:
|
||||
test_value = c + 1 if is_upper_bound else c - 1
|
||||
for i,b in zip(idx.src, (buf.dtype.shape[1], buf.dtype.shape[0])):
|
||||
if i.is_increasing():
|
||||
rw = i.substitute({X:X.const_like(test_value)}).simplify()
|
||||
rw = i.substitute({X:X.const_like(test_value)})
|
||||
if rw.vmin >= b or rw.vmax < 0:
|
||||
drop_stmt.append(stmt)
|
||||
break
|
||||
@@ -314,7 +313,7 @@ pm_reduce = PatternMatcher([
|
||||
# tensor core built in accumulate
|
||||
(UPat(Ops.WMMA, name="wmma") + UPat.var("add"),
|
||||
lambda add, wmma: UOp(wmma.op, wmma.dtype, (wmma.src[0], wmma.src[1], wmma.src[2]+add), wmma.arg)),
|
||||
])+sym
|
||||
])
|
||||
|
||||
# add loads
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ class Scheduler:
|
||||
self.ast, self.ren = ast, ren
|
||||
self.dont_use_locals = self.ast.arg.dont_use_locals if self.ast.arg is not None else False
|
||||
self.applied_opts = list(self.ast.arg.applied_opts) if self.ast.arg is not None else []
|
||||
self.opt_range = itertools.count(start=max([x.arg[0] for x in self.rngs], default=0)+1)
|
||||
|
||||
@property
|
||||
def rngs(self):
|
||||
@@ -29,8 +30,6 @@ class Scheduler:
|
||||
def full_shape(self): return [ssimplify(x.src[0]) for x in self.rngs]
|
||||
@property
|
||||
def axis_types(self): return [x.arg[-1] for x in self.rngs]
|
||||
@property
|
||||
def maxarg(self): return max([x.arg[0] for x in self.rngs], default=0)
|
||||
|
||||
# strings like ['g0', 'g1', 'l0', 'l1', 'l2', 'l3', 'l4', 'l5', 'R0', 'r0', 'r1', 'r2', 'u0', 'u1', 'u2']
|
||||
def shape_str(self) -> list[str]:
|
||||
@@ -52,8 +51,10 @@ class Scheduler:
|
||||
def get_optimized_ast(self, name_override:str|None=None):
|
||||
if name_override is not None: name = name_override
|
||||
else:
|
||||
kernel_type = "r" if self.reduceop is not None else "E"
|
||||
name = kernel_type + colored('_', 'BLACK').join(['']+[colored(x.src[0].render(), color) for x,color in zip(self.rngs, self.colors())])
|
||||
k_type = "r" if self.reduceop is not None else "E"
|
||||
special_uops = sorted([x for x in self.ast.toposort() if x.op is Ops.SPECIAL], key=lambda x: x.arg)
|
||||
special_ops = [colored(str(x.vmax+1), "blue" if x.arg[0] == "g" else "cyan") for x in special_uops]
|
||||
name = k_type + colored('_', 'BLACK').join(['']+special_ops+[colored(x.src[0].render(), color) for x,color in zip(self.rngs, self.colors())])
|
||||
Scheduler.kernel_cnt[(function_name := to_function_name(name))] += 1
|
||||
num = f"n{Scheduler.kernel_cnt[function_name]-1}" if Scheduler.kernel_cnt[function_name] > 1 else ""
|
||||
name += colored(num, 'BLACK')
|
||||
@@ -93,7 +94,7 @@ class Scheduler:
|
||||
def shift_to(self, rng:UOp, amount:int, new_type:AxisType, top:bool=False, input_new_rng=None):
|
||||
if (old_sz:=rng.src[0].divides(amount)) is None:
|
||||
raise KernelOptError(f"{amount} can't divide {rng.src[0]} in {self.colored_shape()}")
|
||||
new_rng = UOp.range(amount, self.maxarg+1, new_type) if input_new_rng is None else input_new_rng
|
||||
new_rng = UOp.range(amount, next(self.opt_range), new_type) if input_new_rng is None else input_new_rng
|
||||
replaced_rng = rng.replace(src=(UOp.const(dtypes.int, old_sz),))
|
||||
sub_axis = (new_rng * old_sz + replaced_rng) if top else (replaced_rng * amount + new_rng)
|
||||
self.ast = self.ast.substitute({rng:sub_axis}, name=f"shift {rng.arg[:-1]} {amount} {str(new_type).split('.')[1].lower()}")
|
||||
@@ -229,9 +230,9 @@ class Scheduler:
|
||||
for tc in tensor_cores:
|
||||
if tc.dtype_in == in0.dtype.scalar() and tc.dtype_in == in1.dtype.scalar() and tc.dtype_out == reduceop.dtype.scalar():
|
||||
# tensor cores have three ranges. X, Y, and REDUCE
|
||||
in0_ranges = sorted([u for u in in0.ranges if u not in in1.ranges], key=lambda x: -x.arg[0])
|
||||
in1_ranges = sorted([u for u in in1.ranges if u not in in0.ranges], key=lambda x: -x.arg[0])
|
||||
red_ranges = sorted(reduceop.src[1:], key=lambda x: -x.arg[0])
|
||||
in0_ranges = sorted([u for u in in0.ranges if u not in in1.ranges], key=lambda x: x.arg[0], reverse=True)
|
||||
in1_ranges = sorted([u for u in in1.ranges if u not in in0.ranges], key=lambda x: x.arg[0], reverse=True)
|
||||
red_ranges = sorted(reduceop.src[1:], key=lambda x: x.arg[0], reverse=True)
|
||||
if DEBUG >= 3:
|
||||
print(f"TC({axis}): {[(x.arg[0],x.vmax+1) for x in in0_ranges]}",
|
||||
f"{[(x.arg[0],x.vmax+1) for x in in1_ranges]} {[(x.arg[0],x.vmax+1) for x in red_ranges]}")
|
||||
|
||||
@@ -142,7 +142,7 @@ pm_reduce_simplify = pm_reduce_unparented + PatternMatcher([
|
||||
# remove REDUCE on load, comes from indexing a tensor with another tensor
|
||||
def no_load(u:UOp) -> bool: return not any(x.op is Ops.INDEX for x in u.backward_slice_with_self)
|
||||
pm_load_collapse = PatternMatcher([
|
||||
(UPat(Ops.REDUCE, src=(UPat.var("u"), UPat()), name="red"), reduce_load_collapse),
|
||||
(UPat(Ops.REDUCE, arg=Ops.ADD, src=(UPat.var("u"), UPat()), name="red"), reduce_load_collapse),
|
||||
# we want to make sure we dont do math on a loaded index since that can cause overflow, this undoes the rule in pm_reduce_load_collapse
|
||||
((UPat.var("x", dtypes.index)+UPat.var("y"))<UPat.var("c"), lambda x,y,c: x < c-y if no_load(y) and no_load(c) and not no_load(x) else None),
|
||||
])
|
||||
|
||||
+5
-4
@@ -5,7 +5,7 @@ from typing import Any, Generic, TypeVar, Iterator, Sequence, cast, Generator
|
||||
import importlib, inspect, functools, pathlib, os, platform, contextlib, sys, re, atexit, pickle, decimal
|
||||
from tinygrad.helpers import CI, OSX, LRU, getenv, diskcache_get, diskcache_put, DEBUG, GlobalCounters, flat_mv, PROFILE, temp, colored, CPU_LLVM
|
||||
from tinygrad.helpers import Context, CCACHE, ALLOW_DEVICE_USAGE, MAX_BUFFER_SIZE, cpu_events, ProfileEvent, ProfilePointEvent, dedup
|
||||
from tinygrad.helpers import unwrap_class_type, suppress_finalizing, AMD_LLVM, select_first_inited
|
||||
from tinygrad.helpers import unwrap_class_type, suppress_finalizing, select_first_inited, VIZ
|
||||
from tinygrad.dtype import DType, ImageDType, PtrDType, dtypes, _to_np_dtype
|
||||
from tinygrad.renderer import Renderer
|
||||
|
||||
@@ -329,7 +329,7 @@ def is_dtype_supported(dtype:DType, device:str|None=None) -> bool:
|
||||
return device in {"AMD", "PYTHON", "NULL"}
|
||||
if dtype in dtypes.fp8s:
|
||||
if device in {"CUDA", "NV"}: return not CI and not getenv(f"{device}_PTX") and not getenv("NV_NAK")
|
||||
if device == "AMD": return not CI and not AMD_LLVM and getattr(Device["AMD"], "target") in {(9,4,2), (9,5,0)}
|
||||
if device == "AMD": return not CI and getattr(Device["AMD"], "target") in {(9,4,2), (9,5,0)}
|
||||
return device in {"PYTHON", "NULL"}
|
||||
if device == "WEBGPU": return dtype in [dtypes.bool, dtypes.char, dtypes.uchar, dtypes.short,
|
||||
dtypes.ushort, dtypes.float, dtypes.int32, dtypes.uint32, dtypes.half]
|
||||
@@ -355,8 +355,9 @@ if PROFILE:
|
||||
|
||||
with open(fn:=temp("profile.pkl", append_user=True), "wb") as f: pickle.dump(cpu_events+Compiled.profile_events+Buffer.profile_events, f)
|
||||
|
||||
from tinygrad.uop.ops import launch_viz
|
||||
launch_viz("PROFILE", fn)
|
||||
if VIZ:
|
||||
from tinygrad.uop.ops import launch_viz
|
||||
launch_viz("PROFILE", fn)
|
||||
|
||||
def enumerate_devices_str() -> Generator[str, None, None]:
|
||||
from tinygrad import Tensor, Device
|
||||
|
||||
+58
-25
@@ -1,5 +1,5 @@
|
||||
from typing import cast
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass, field, replace
|
||||
from collections import deque, defaultdict
|
||||
from tinygrad.uop.ops import UOp, Ops, buffers
|
||||
from tinygrad.device import Device, Buffer, MultiBuffer
|
||||
@@ -13,6 +13,7 @@ class ScheduleItem:
|
||||
bufs: tuple[Buffer, ...]
|
||||
metadata: tuple[Metadata, ...] = ()
|
||||
fixedvars: dict[str, int] = field(default_factory=dict)
|
||||
bound_ranges: tuple[UOp, ...] = ()
|
||||
|
||||
# **** schedule linearizer
|
||||
|
||||
@@ -22,10 +23,13 @@ def create_schedule_with_vars(sched_sink:UOp) -> tuple[list[ScheduleItem], dict[
|
||||
in_degree: dict[UOp, int] = {}
|
||||
var_vals: dict[str, int] = {}
|
||||
for u in sched_sink.toposort():
|
||||
if u.op is not Ops.AFTER: continue # anything that's not an ASSIGN doesn't write a kernel, so we can skip
|
||||
if u.op is Ops.RANGE:
|
||||
in_degree.setdefault(u, 0)
|
||||
continue
|
||||
if u.op is not Ops.AFTER or u.src[1].op is Ops.RANGE: continue
|
||||
k = u.src[1]
|
||||
in_degree.setdefault(k, 0)
|
||||
for s in k.src:
|
||||
for s in k.src[0].src if k.op is Ops.END else k.src:
|
||||
if s.op is Ops.AFTER:
|
||||
children[s.src[1]].append(k)
|
||||
in_degree[k] += 1
|
||||
@@ -39,16 +43,19 @@ def create_schedule_with_vars(sched_sink:UOp) -> tuple[list[ScheduleItem], dict[
|
||||
elif s.op is Ops.BUFFER:
|
||||
pass # a BUFFER is already realized, nothing to do here
|
||||
elif s.op is Ops.BIND:
|
||||
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
|
||||
# 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}")
|
||||
|
||||
# linearize KERNEL UOps into ScheduleItems in BFS order
|
||||
|
||||
def _heuristic(k: UOp):
|
||||
if k.arg.ast.op is Ops.COPY and not all_same([Device[cast(Buffer, s.buf_uop.buffer).device].group_id for s in k.src]): return 1000
|
||||
if k.op is Ops.KERNEL and k.arg.ast.op is Ops.COPY and not all_same([Device[cast(Buffer, s.buf_uop.buffer).device].group_id for s in k.src]):
|
||||
return 1000
|
||||
return 0
|
||||
|
||||
last_heuristic: int = 0
|
||||
@@ -57,27 +64,53 @@ def create_schedule_with_vars(sched_sink:UOp) -> tuple[list[ScheduleItem], dict[
|
||||
for k,v in in_degree.items():
|
||||
if v == 0: queues[_heuristic(k)].append(k)
|
||||
|
||||
schedule: list[ScheduleItem] = []
|
||||
schedule: list[ScheduleItem|UOp] = []
|
||||
while last_queue or any(queues.values()):
|
||||
if not last_queue: last_heuristic, last_queue = min((it for it in queues.items() if it[1]), key=lambda x: abs(x[0]-last_heuristic))
|
||||
k = last_queue.popleft()
|
||||
ast = k.arg.ast
|
||||
# create subbuffers if needed
|
||||
if ast.op is Ops.BUFFER_VIEW:
|
||||
base = k.src[1].buf_uop.buffer
|
||||
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)
|
||||
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']
|
||||
for i,bufs in enumerate(zip(*[x.bufs for x in cast(tuple[MultiBuffer, ...], ubufs)])):
|
||||
schedule.append(ScheduleItem(ast, bufs, k.arg.metadata, {dnums[0].expr:i} if len(dnums) else {}))
|
||||
k = rk = last_queue.popleft()
|
||||
if k.op is Ops.END: k = k.src[0]
|
||||
if k.op is Ops.RANGE: schedule.append(k)
|
||||
elif k.op is Ops.KERNEL:
|
||||
ast = k.arg.ast
|
||||
# create subbuffers if needed
|
||||
if ast.op is Ops.BUFFER_VIEW:
|
||||
base = k.src[1].buf_uop.buffer
|
||||
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 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']
|
||||
for i,bufs in enumerate(zip(*[x.bufs for x in cast(tuple[MultiBuffer, ...], ubufs)])):
|
||||
schedule.append(ScheduleItem(ast, bufs, k.arg.metadata, {dnums[0].expr:i} if len(dnums) else {}, bound_ranges=bound_ranges))
|
||||
else:
|
||||
# ONE -> ONE
|
||||
schedule.append(ScheduleItem(ast, cast(tuple[Buffer, ...], ubufs), k.arg.metadata, bound_ranges=bound_ranges))
|
||||
if rk.op is Ops.END: schedule.append(rk)
|
||||
else:
|
||||
# ONE -> ONE
|
||||
schedule.append(ScheduleItem(ast, cast(tuple[Buffer, ...], ubufs), k.arg.metadata))
|
||||
for x in children[k]:
|
||||
raise RuntimeError(f"can't schedule {k.op}")
|
||||
for x in children[rk]:
|
||||
in_degree[x] -= 1
|
||||
if in_degree[x] == 0: queues[_heuristic(x)].append(x)
|
||||
|
||||
return schedule, var_vals
|
||||
# expand the ranges in the schedule
|
||||
real_schedule: list[ScheduleItem] = []
|
||||
sched_ptr = 0
|
||||
in_ranges = {}
|
||||
range_ptrs = {}
|
||||
while sched_ptr < len(schedule):
|
||||
si = schedule[sched_ptr]
|
||||
if isinstance(si, UOp):
|
||||
if si.op is Ops.RANGE:
|
||||
in_ranges[si] = 0
|
||||
range_ptrs[si] = sched_ptr + 1
|
||||
elif si.op is Ops.END:
|
||||
if in_ranges[si.src[1]] < si.src[1].vmax:
|
||||
in_ranges[si.src[1]] += 1
|
||||
sched_ptr = range_ptrs[si.src[1]]
|
||||
continue
|
||||
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, var_vals
|
||||
|
||||
+11
-5
@@ -3,14 +3,15 @@ import math, dataclasses
|
||||
from tinygrad.uop.ops import UOp, PatternMatcher, UPat, Ops, all_metadata
|
||||
from tinygrad.helpers import argsort
|
||||
|
||||
def reduce_gradient(ctx:UOp, ret:UOp):
|
||||
def reduce_gradient(ctx:UOp, ret:UOp, op:Ops):
|
||||
def broadcast_to_input(x): return x.reshape(x.shape+(1,)*(len(ret.src[0].shape)-len(x.shape))).expand(ret.src[0].shape)
|
||||
if ret.arg[0] == Ops.ADD: return (broadcast_to_input(ctx),)
|
||||
if ret.arg[0] == Ops.MAX:
|
||||
if op == Ops.ADD: return (broadcast_to_input(ctx),)
|
||||
if op == Ops.MAX:
|
||||
assert ret.op is Ops.REDUCE_AXIS, "only works on REDUCE_AXIS"
|
||||
mask = ret.src[0].eq(broadcast_to_input(ret)).cast(ctx.dtype)
|
||||
count = mask.r(Ops.ADD, ret.arg[1])
|
||||
return ((mask/broadcast_to_input(count)) * broadcast_to_input(ctx),)
|
||||
if ret.arg[0] == Ops.MUL: return (broadcast_to_input(ctx * ret) / ret.src[0],)
|
||||
if op == Ops.MUL: return (broadcast_to_input(ctx * ret) / ret.src[0],)
|
||||
|
||||
# ctx is grad_output
|
||||
pm_gradient = PatternMatcher([
|
||||
@@ -28,7 +29,8 @@ pm_gradient = PatternMatcher([
|
||||
((x>y).where(ctx, (x.eq(y)).where(ctx * 0.5, 0)), (x<y).where(ctx, (x.eq(y)).where(ctx * 0.5, 0)))),
|
||||
(UPat(Ops.MUL, name="ret"), lambda ctx, ret: (ret.src[1]*ctx, ret.src[0]*ctx)),
|
||||
(UPat(Ops.WHERE, name="ret"), lambda ctx, ret: (None, ret.src[0].where(ctx, ctx.const_like(0)), ret.src[0].where(ctx.const_like(0), ctx))),
|
||||
(UPat(Ops.REDUCE_AXIS, name="ret"), reduce_gradient),
|
||||
(UPat(Ops.REDUCE_AXIS, name="ret"), lambda ctx, ret: reduce_gradient(ctx, ret, ret.arg[0])),
|
||||
(UPat(Ops.REDUCE, name="ret"), lambda ctx, ret: reduce_gradient(ctx, ret, ret.arg) + (None,)*(len(ret.src)-1)),
|
||||
(UPat(Ops.CONTIGUOUS), lambda ctx: (ctx,)),
|
||||
(UPat(Ops.CONTIGUOUS_BACKWARD), lambda ctx: (ctx.contiguous(),)),
|
||||
(UPat(Ops.RESHAPE, name="ret"), lambda ctx, ret: (ctx.reshape(ret.src[0].shape), None)),
|
||||
@@ -68,4 +70,8 @@ def compute_gradient(root:UOp, root_grad:UOp, targets:set[UOp]) -> dict[UOp, UOp
|
||||
# we add the backward metadata to everything new in the graph
|
||||
for bw_uop in v.toposort(lambda x: x not in (t0, *t0.src, grads[t0])):
|
||||
all_metadata[bw_uop] = all_metadata.get(bw_uop, ())+backward_metadata
|
||||
# end any ranges on grads with a reduce sum
|
||||
for k,v in grads.items():
|
||||
if len(v.ranges):
|
||||
grads[k] = v.reduce(*v.ranges, arg=Ops.ADD)
|
||||
return grads
|
||||
|
||||
+13
-5
@@ -147,8 +147,10 @@ def temp(x:str, append_user:bool=False) -> str:
|
||||
class Context(contextlib.ContextDecorator):
|
||||
def __init__(self, **kwargs): self.kwargs = kwargs
|
||||
def __enter__(self):
|
||||
self.old_context:dict[str, int] = {k:v.value for k,v in ContextVar._cache.items()}
|
||||
for k,v in self.kwargs.items(): ContextVar._cache[k].value = v
|
||||
self.old_context:dict[str, int] = {}
|
||||
for k,v in self.kwargs.items():
|
||||
self.old_context[k] = ContextVar._cache[k].value
|
||||
ContextVar._cache[k].value = v
|
||||
def __exit__(self, *args):
|
||||
for k,v in self.old_context.items(): ContextVar._cache[k].value = v
|
||||
|
||||
@@ -179,7 +181,9 @@ ALLOW_DEVICE_USAGE, MAX_BUFFER_SIZE = ContextVar("ALLOW_DEVICE_USAGE", 1), Conte
|
||||
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)))
|
||||
CPU_LLVM, CPU_LVP, AMD_LLVM = ContextVar("CPU_LLVM", 0), ContextVar("CPU_LVP", 0), ContextVar("AMD_LLVM", 0)
|
||||
VIZ = PROFILE = ContextVar("VIZ", 0)
|
||||
# VIZ implies PROFILE, but you can run PROFILE without VIZ
|
||||
VIZ = ContextVar("VIZ", 0)
|
||||
PROFILE = ContextVar("PROFILE", VIZ.value)
|
||||
SPEC = ContextVar("SPEC", 1)
|
||||
# TODO: disable by default due to speed
|
||||
IGNORE_OOB = ContextVar("IGNORE_OOB", 1)
|
||||
@@ -277,7 +281,7 @@ class ProfilePointEvent(ProfileEvent):
|
||||
|
||||
cpu_events:list[ProfileEvent] = []
|
||||
@contextlib.contextmanager
|
||||
def cpu_profile(name:str|TracingKey, device="CPU", is_copy=False, display=True) -> Generator[ProfileRangeEvent, None, None]:
|
||||
def cpu_profile(name:str|TracingKey, device="TINY", is_copy=False, display=True) -> Generator[ProfileRangeEvent, None, None]:
|
||||
res = ProfileRangeEvent(device, name, perf_counter_us(), is_copy=is_copy)
|
||||
try: yield res
|
||||
finally:
|
||||
@@ -380,7 +384,11 @@ def fetch(url:str, name:pathlib.Path|str|None=None, subdir:str|None=None, gunzip
|
||||
|
||||
# *** Exec helpers
|
||||
|
||||
def system(cmd, **kwargs): return subprocess.check_output(cmd.split(), **kwargs).decode().strip()
|
||||
def system(cmd:str, **kwargs) -> str:
|
||||
st = time.perf_counter()
|
||||
ret = subprocess.check_output(cmd.split(), **kwargs).decode().strip()
|
||||
if DEBUG >= 1: print(f"system: '{cmd}' returned {len(ret)} bytes in {(time.perf_counter() - st)*1e3:.2f} ms")
|
||||
return ret
|
||||
|
||||
def cpu_objdump(lib, objdump_tool='objdump'):
|
||||
with tempfile.NamedTemporaryFile(delete=True) as f:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import itertools
|
||||
from tinygrad.helpers import dedup, flatten, getenv, unwrap, FUSE_OPTIM
|
||||
from tinygrad.tensor import Tensor
|
||||
from tinygrad.dtype import dtypes, least_upper_dtype
|
||||
from tinygrad.dtype import dtypes, least_upper_dtype, to_dtype
|
||||
|
||||
class Optimizer:
|
||||
"""
|
||||
@@ -24,9 +24,9 @@ class Optimizer:
|
||||
if self.fused: self.pos_params = list(itertools.accumulate(self.params, lambda x,y: x+y.numel(), initial=0))
|
||||
|
||||
def _new_optim_param(self) -> list[Tensor]:
|
||||
param_dtype = getenv("OPTIM_DTYPE", "float32")
|
||||
param_dtype = to_dtype(getenv("OPTIM_DTYPE", "float32"))
|
||||
if self.fused: return [Tensor.zeros(self.pos_params[-1], dtype=param_dtype, device=self.device, requires_grad=False).contiguous()]
|
||||
return [Tensor.zeros(*t.shape, dtype=param_dtype, device=t.device, requires_grad=False).contiguous() for t in self.params]
|
||||
return [Tensor.zeros_like(t, dtype=param_dtype, requires_grad=False).contiguous() for t in self.params]
|
||||
|
||||
def zero_grad(self):
|
||||
"""
|
||||
|
||||
+11
-10
@@ -22,10 +22,10 @@ base_rewrite = PatternMatcher([
|
||||
(UPat(Ops.CAST, name="x"), lambda ctx,x:
|
||||
f"__builtin_convertvector({ctx[x.src[0]]}, {ctx.render_dtype(x.dtype)})" if x.dtype.count > 1 and not isinstance(x.dtype, PtrDType) else None),
|
||||
(UPat(Ops.CAST, name="x"), lambda ctx,x: f"({ctx.render_cast(x.dtype, ctx[x.src[0]])})"),
|
||||
(UPat(Ops.BITCAST, name="x"), lambda ctx,x: f"(*(({ctx.buffer_prefix}{ctx.render_dtype(x.dtype)}*)&{ctx[x.src[0]]}))"),
|
||||
(UPat(Ops.BITCAST, name="x"), lambda ctx,x:
|
||||
f"__builtin_bit_cast({ctx.render_dtype(x.dtype)}, ({ctx.render_dtype(x.src[0].dtype)})({ctx[x.src[0]]}))"),
|
||||
(UPat(Ops.DEFINE_LOCAL, name="x"), lambda ctx,x: f"{ctx.smem_align}{ctx.smem_prefix}{ctx.render_dtype(x.dtype.base)} {ctx[x]}[{x.dtype.size}];"),
|
||||
(UPat(Ops.BARRIER), lambda ctx: ctx.barrier),
|
||||
(UPat(Ops.PRECAST, name="x"), lambda ctx,x: ctx[x.src[0]]),
|
||||
(UPat(Ops.SPECIAL, name="x"), lambda ctx,x: f"{ctx.code_for_workitem[x.arg[0]](x.arg[-1])}; /* {(x.src[0]).render()} */"),
|
||||
# const
|
||||
(UPat(Ops.CONST, arg=math.inf, name="x"), lambda ctx, x: f"({ctx.render_cast(x.dtype, ctx.infinity)})"),
|
||||
@@ -60,9 +60,6 @@ base_rewrite = PatternMatcher([
|
||||
])
|
||||
|
||||
extra_pm = PatternMatcher([
|
||||
# insert a PRECAST before BITCAST to force it to be rendered. not needed on all backends?
|
||||
(UPat(Ops.BITCAST, name="x"), lambda x: UOp(Ops.BITCAST, x.dtype, (UOp(Ops.PRECAST, x.src[0].dtype, x.src),))
|
||||
if x.src[0].op not in {Ops.PRECAST, Ops.LOAD, Ops.CUSTOM} else None),
|
||||
# devectorize any bools
|
||||
(UPat((*GroupOp.ALU, Ops.CAST, Ops.BITCAST, Ops.INDEX), dtype=dtypes.bool, name="alu"), no_vectorized_alu),
|
||||
# CAST (from bool) can't be vectorized
|
||||
@@ -181,7 +178,7 @@ class CStyleLanguage(Renderer):
|
||||
elif u.op is Ops.RANGE: r[u] = f"{axis_letters[u.arg[-1]]}idx"+range_str(u)
|
||||
else:
|
||||
prefix = {Ops.WMMA: "wmma", Ops.DEFINE_LOCAL: "temp", Ops.CONST: "const",
|
||||
Ops.CAST: "cast", Ops.BITCAST: "cast", Ops.GEP: "gep", Ops.VECTORIZE: "cast", Ops.PRECAST: "precast",
|
||||
Ops.CAST: "cast", Ops.BITCAST: "cast", Ops.GEP: "gep", Ops.VECTORIZE: "cast",
|
||||
Ops.INDEX: "bidx", Ops.DEFINE_REG: "acc", Ops.LOAD: "val"}.get(u.op, "alu")
|
||||
r[u] = f"{prefix}{c[prefix]}"
|
||||
|
||||
@@ -278,7 +275,7 @@ class OpenCLRenderer(CStyleLanguage):
|
||||
dtypes.bfloat16: "ushort" }
|
||||
|
||||
string_rewrite = PatternMatcher([
|
||||
(UPat(Ops.BITCAST, name="x"), lambda ctx,x: f"as_{ctx.render_dtype(x.dtype)}({ctx[x.src[0]]})"),
|
||||
(UPat(Ops.BITCAST, name="x"), lambda ctx,x: f"as_{ctx.render_dtype(x.dtype)}(({ctx.render_dtype(x.src[0].dtype)})({ctx[x.src[0]]}))"),
|
||||
# load/store image (OpenCL)
|
||||
(UPat(Ops.LOAD, dtype=dtypes.float.vec(4), src=(UPat.var('buf').index(UPat.var('idx', dtypes.int.vec(2)), UPat.var("gate")), UPat.var("var"))),
|
||||
lambda ctx,buf,idx,var,gate: f"({ctx[gate]}?read_imagef({ctx[buf]}, smp, {ctx[idx]}):{ctx[var]})"),
|
||||
@@ -338,7 +335,7 @@ class MetalRenderer(CStyleLanguage):
|
||||
]) + extra_pm
|
||||
|
||||
string_rewrite = PatternMatcher([
|
||||
(UPat(Ops.BITCAST, name="x"), lambda ctx,x: f"as_type<{ctx.render_dtype(x.dtype)}>({ctx[x.src[0]]})"),
|
||||
(UPat(Ops.BITCAST, name="x"), lambda ctx,x: f"as_type<{ctx.render_dtype(x.dtype)}>(({ctx.render_dtype(x.src[0].dtype)})({ctx[x.src[0]]}))"),
|
||||
]) + base_rewrite
|
||||
|
||||
def render_kernel(self, function_name, kernel, bufs, uops, prefix=None):
|
||||
@@ -385,6 +382,10 @@ class CUDARenderer(CStyleLanguage):
|
||||
extra_matcher = create_non_native_float_pats(dtypes.fp8s, casting=False) + PatternMatcher([
|
||||
(UPat(Ops.CAST, dtypes.fp8s, UPat.var("x", dtypes.fp8s), name='y'), lambda x,y: x.cast(dtypes.float).cast(y.dtype) if x.dtype!=y.dtype else None),
|
||||
]) + extra_pm
|
||||
string_rewrite = PatternMatcher([
|
||||
(UPat(Ops.BITCAST, name="x"), lambda ctx,x: f"tg_bitcast<{ctx.render_dtype(x.dtype)}>(({ctx.render_dtype(x.src[0].dtype)})({ctx[x.src[0]]}))"),
|
||||
]) + base_rewrite
|
||||
|
||||
def render_vector_prefix(self, dt:DType) -> str:
|
||||
vec, scal = self.render_dtype(dt), self.render_dtype(dt.scalar()),
|
||||
elems, header = ', '.join(_nms[:dt.count]), ', '.join([f"{scal} {x}" for x in _nms[:dt.count]])
|
||||
@@ -392,8 +393,8 @@ class CUDARenderer(CStyleLanguage):
|
||||
|
||||
def render_kernel(self, function_name, kernel, bufs, uops, prefix=None):
|
||||
# TODO: why is dtypes.bfloat16.name == "__bf16"? would be easier not override dtypes.name
|
||||
prefix = ["#define INFINITY (__int_as_float(0x7f800000))","#define NAN (__int_as_float(0x7fffffff))"]
|
||||
|
||||
prefix = ["#define INFINITY (__int_as_float(0x7f800000))", "#define NAN (__int_as_float(0x7fffffff))",
|
||||
"template <class T, class F> __device__ __forceinline__ T tg_bitcast(F v) { union U { F f; T t; }; U u; u.f = v; return u.t; }"]
|
||||
used_dtypes = uops_to_dtypes(uops)
|
||||
if any(dt.scalar() in dtypes.fp8s for dt in used_dtypes): prefix.append("#include <cuda_fp8.h>")
|
||||
if any(dt.scalar() == dtypes.half for dt in used_dtypes): prefix.append("#include <cuda_fp16.h>")
|
||||
|
||||
+33
-21
@@ -2,21 +2,22 @@ from typing import cast
|
||||
import math, struct, sys
|
||||
from tinygrad.codegen.opt import tc
|
||||
from tinygrad.renderer import Renderer
|
||||
from tinygrad.renderer.cstyle import AMDRenderer
|
||||
from tinygrad.renderer.cstyle import AMDRenderer, create_non_native_float_pats
|
||||
from tinygrad.uop.decompositions import xexp2, xlog2
|
||||
from tinygrad.uop.ops import UOp, PatternMatcher, UPat, Ops, GroupOp, range_str
|
||||
from tinygrad.dtype import dtypes, DType, PtrDType, truncate
|
||||
from tinygrad.dtype import dtypes, float_to_fp8, DType, PtrDType, truncate
|
||||
from tinygrad.helpers import prod, AMX
|
||||
|
||||
def ldt(dt:DType):
|
||||
if dt.vcount > 1: return f"<{dt.vcount} x {ldt(dt.scalar())}>"
|
||||
if isinstance(dt, PtrDType): return ldt(dt.base) + "*"
|
||||
return {dtypes.void: "void", dtypes.bool: "i1", dtypes.int8: "i8", dtypes.int16: "i16", dtypes.int32: "i32", dtypes.int64: "i64",
|
||||
dtypes.uint8: "i8", dtypes.uint16: "i16", dtypes.uint32: "i32", dtypes.uint64: "i64",
|
||||
dtypes.uint8: "i8", dtypes.uint16: "i16", dtypes.uint32: "i32", dtypes.uint64: "i64", dtypes.fp8e4m3: "i8", dtypes.fp8e5m2: "i8",
|
||||
dtypes.float16: "half", dtypes.bfloat16: "bfloat", dtypes.float32: "float", dtypes.float64: "double"}[dt]
|
||||
|
||||
def lconst(x, dtype:DType):
|
||||
if dtype in dtypes.floats:
|
||||
if dtype in dtypes.fp8s: return float_to_fp8(x, dtype)
|
||||
if math.isinf(x) or math.isnan(x): return "0x%02X%02X%02X%02X%02X%02X%02X%02X" % tuple(struct.pack("d",x)[::-1])
|
||||
return truncate[dtype](x)
|
||||
return int(x)
|
||||
@@ -47,13 +48,14 @@ def render_wmma_amx(ctx, wmma: UOp) -> str:
|
||||
f' {ctx[wmma]} = load {ldt(wmma.dtype)}, ptr {ctx[wmma]}_amx2, align {wmma.dtype.itemsize}'])
|
||||
|
||||
def render_wmma_amd(ctx, wmma: UOp, cdna=False) -> str:
|
||||
dt_map = {dtypes.half: "f16", dtypes.float: "f32", dtypes.ushort: "bf16.1k" if cdna else "bf16", dtypes.bfloat16: "bf16.1k" if cdna else "bf16"}
|
||||
dt_map = {dtypes.half: "f16", dtypes.float: "f32", dtypes.ushort: "bf16.1k" if cdna else "bf16", dtypes.bfloat16: "bf16.1k" if cdna else "bf16",
|
||||
dtypes.fp8e4m3: ".fp8.fp8", dtypes.fp8e5m2: ".bf8.bf8"}
|
||||
# https://github.com/llvm/llvm-project/blob/main/clang/test/CodeGenOpenCL/builtins-amdgcn-mfma.cl
|
||||
N,M,K = wmma.arg[1]
|
||||
if cdna:
|
||||
if K == 32: dt_map.update({dtypes.half: ".f16", dtypes.bfloat16: ".bf16"})
|
||||
return f" {ctx[wmma]} = call {ldt(wmma.dtype)} @llvm.amdgcn.mfma.{dt_map[wmma.src[-1].dtype.scalar()]}" + \
|
||||
f".{N}x{M}x{K}{dt_map[wmma.src[0].dtype.scalar()]}(" + ", ".join([f"{ldt(w.dtype)} {ctx[w]}" for w in wmma.src]) + ", i32 0, i32 0, i32 0)"
|
||||
f".{N}x{M}x{K}{dt_map[wmma.arg[2]]}(" + ", ".join([f"{ldt(w.dtype)} {ctx[w]}" for w in wmma.src]) + ", i32 0, i32 0, i32 0)"
|
||||
# https://github.com/llvm/llvm-project/blob/main/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.wmma_32.ll
|
||||
# example: %wmma0 = call <8 x float> @llvm.amdgcn.wmma.f32.16x16x16.f16(<16 x half> %v99,<16 x half> %v100,<8 x float> %v101)
|
||||
return f" {ctx[wmma]} = call {ldt(wmma.dtype)} @llvm.amdgcn.wmma.{dt_map[wmma.src[-1].dtype.scalar()]}.16x16x16." + \
|
||||
@@ -136,27 +138,16 @@ class LLVMRenderer(Renderer):
|
||||
has_local = False
|
||||
global_max: tuple[int, ...] | None = None
|
||||
string_rewrite = base_rewrite + PatternMatcher([(UPat(Ops.WMMA, name="wmma"), render_wmma_amx)])
|
||||
code_for_op = {Ops.FDIV: lambda: None}
|
||||
code_for_op = {Ops.FDIV: lambda: None, Ops.CMPLT: lambda: None}
|
||||
if AMX: tensor_cores = tc.amx
|
||||
|
||||
extra_matcher = PatternMatcher([
|
||||
# rewrite MAX to CMPLT + WHERE
|
||||
(UPat(Ops.MAX, name="m"), lambda m: (m.src[0] < m.src[1]).where(m.src[1], m.src[0])),
|
||||
# copied from cstyle.py, upcast to float32 all the ops that don't support bfloat16
|
||||
(UPat((Ops.SQRT, Ops.EXP2, Ops.LOG2, Ops.SIN), dtype=dtypes.bfloat16, name="x"),
|
||||
lambda x: (UOp(x.op, dtypes.float, tuple(vv.cast(dtypes.float) for vv in x.src), x.arg).cast(dtypes.bfloat16))),
|
||||
# copied from cstyle.py, add float intermediate casting
|
||||
(UPat(Ops.CAST, name="x", src=UPat.var("y", dtypes.bfloat16)),lambda x,y: y.cast(dtypes.float).cast(x.dtype) if x.dtype!=dtypes.float else None),
|
||||
(UPat(Ops.CAST, dtypes.bfloat16, UPat.var("x")),lambda x: x.cast(dtypes.float).cast(dtypes.bfloat16) if x.dtype!=dtypes.float else None),
|
||||
])
|
||||
|
||||
extra_matcher = create_non_native_float_pats((dtypes.bfloat16,))
|
||||
def render(self, uops: list[UOp]) -> str: return "\n".join((k:=self._render_kernel(uops))[0] + (k[1], self._render_footer(uops)))
|
||||
def _render_footer(self, uops: list[UOp]) -> str: return 'attributes #0 = { alwaysinline nounwind "no-builtins" "no-trapping-math"="true" }'
|
||||
def _render_fn(self, name:str, args:list[tuple[str,DType]], kernel:list[str], prefix:list[str]|None=None) -> str:
|
||||
# NOTE: CPUAllocator promises 0x20 alignment
|
||||
sargs = ", ".join([f"{ldt(dt)}{' noalias align 32' if isinstance(dt, PtrDType) else ''} {name}" for name,dt in args])
|
||||
sprefix = "".join([f" {x}" for x in (prefix or []) + [self.abi] if x is not None])
|
||||
return "\n".join([f"define{sprefix} void @{name}({sargs}) #0", "{"] + kernel + [" ret void\n}"])
|
||||
return "\n".join((prefix or []) + [f"define{' ' + self.abi if self.abi else ''} void @{name}({sargs}) #0", "{"] + kernel + [" ret void\n}"])
|
||||
def _render_kernel(self, uops: list[UOp], prefix:list[str]|None=None) -> tuple[tuple[str, ...], str]:
|
||||
r: dict[UOp, str] = {}
|
||||
args: list[tuple[str, DType]] = []
|
||||
@@ -226,8 +217,13 @@ class AMDLLVMRenderer(LLVMRenderer):
|
||||
(UPat(tuple(llvm_intrinsics), name="x"),
|
||||
lambda ctx, x: f" {ctx[x]} = call {ldt(x.dtype)} @llvm.{llvm_intrinsics[x.op]}.{ldt(x.dtype.scalar())}({ldt(x.src[0].dtype)} {ctx[x.src[0]]})"),
|
||||
(UPat(Ops.BARRIER), lambda ctx: barrier),
|
||||
(UPat(Ops.CAST, dtypes.fp8s, (UPat.var("y", dtypes.float),), name="x",), lambda ctx,x,y:
|
||||
f" {ctx[x]} = call i8 @f32_to_fp8({ldt(x.src[0].dtype)} {ctx[x.src[0]]}, i1 {'1' if x.dtype == dtypes.fp8e5m2 else '0'})"),
|
||||
(UPat(Ops.CAST, dtypes.float, (UPat.var("y", dtypes.fp8s),), name="x",), lambda ctx,x,y:
|
||||
f" {ctx[x.src[0]]}_i32 = zext i8 {ctx[x.src[0]]} to i32\n"
|
||||
f" {ctx[x]} = call float @llvm.amdgcn.cvt.f32.{'bf8' if y.dtype == dtypes.fp8e5m2 else 'fp8'}(i32 {ctx[x.src[0]]}_i32, i32 0)"),
|
||||
]) + base_rewrite
|
||||
extra_matcher = LLVMRenderer.extra_matcher + PatternMatcher([
|
||||
extra_matcher = LLVMRenderer.extra_matcher + create_non_native_float_pats(dtypes.fp8s) + PatternMatcher([
|
||||
(UPat(Ops.CAST, name="x", dtype=dtypes.half.vec(16), src=UPat.var("y", dtypes.half.vec(8))),
|
||||
lambda x, y: UOp(Ops.VECTORIZE, dtypes.half.vec(16), tuple(y.gep(i // 2) if i % 2 == 0 else UOp.const(dtypes.half, 0.0) for i in range(16)))),
|
||||
(UPat(Ops.CAST, name="x", dtype=dtypes.half.vec(8), src=UPat.var("y", dtypes.half.vec(16))),
|
||||
@@ -236,6 +232,19 @@ class AMDLLVMRenderer(LLVMRenderer):
|
||||
(UPat(Ops.LOG2, dtype=dtypes.double, src=(UPat.var("d"),)), xlog2),
|
||||
(UPat(Ops.EXP2, dtype=dtypes.double, src=(UPat.var("d"),)), xexp2),
|
||||
])
|
||||
def render(self, uops: list[UOp]) -> str:
|
||||
prefix = ["""define i8 @f32_to_fp8(float %val, i1 %is_bf8) {
|
||||
entry: %ival = bitcast float %val to i32\n %exp = and i32 %ival, 2139095040\n %is_special = icmp eq i32 %exp, 2139095040
|
||||
br i1 %is_special, label %select_clip, label %clip
|
||||
clip: br i1 %is_bf8, label %bf8_clip, label %fp8_clip
|
||||
bf8_clip: %clamped_bf8 = call float @llvm.amdgcn.fmed3.f32(float %val, float 57344.0, float -57344.0)\n br label %select_clip
|
||||
fp8_clip: %clamped_fp8 = call float @llvm.amdgcn.fmed3.f32(float %val, float 448.0, float -448.0) \n br label %select_clip
|
||||
select_clip: %phi_val = phi float [%val, %entry], [%clamped_bf8, %bf8_clip], [%clamped_fp8, %fp8_clip]\n br i1 %is_bf8, label %do_bf8, label %do_fp8
|
||||
do_bf8: %packed_bf8 = call i32 @llvm.amdgcn.cvt.pk.bf8.f32(float %phi_val, float %phi_val, i32 0, i1 false)\n br label %exit
|
||||
do_fp8: %packed_fp8 = call i32 @llvm.amdgcn.cvt.pk.fp8.f32(float %phi_val, float %phi_val, i32 0, i1 false)\n br label %exit
|
||||
exit: %packed = phi i32 [%packed_bf8, %do_bf8], [%packed_fp8, %do_fp8]\n %trunc = trunc i32 %packed to i8\n ret i8 %trunc
|
||||
}""".replace(": ", ":\n ")] if any(u.dtype in dtypes.fp8s for u in uops) else []
|
||||
return "\n".join((k:=self._render_kernel(uops, prefix))[0] + (k[1], self._render_footer(uops)))
|
||||
def _render_footer(self, uops: list[UOp]) -> str:
|
||||
# TODO: this is copied from cstyle
|
||||
local_dims = [u.src[0] for u in uops if u.op is Ops.SPECIAL and u.arg[0] == "l"]
|
||||
@@ -252,7 +261,10 @@ class AMDLLVMRenderer(LLVMRenderer):
|
||||
self.extra_matcher += PatternMatcher([
|
||||
(UPat(Ops.WMMA, name="x", dtype=dtypes.float.vec(4)),
|
||||
lambda x: UOp(Ops.WMMA, dtypes.float.vec(4), (x.src[0].bitcast(dtypes.uint16.vec(4)), x.src[1].bitcast(dtypes.uint16.vec(4)),
|
||||
x.src[2]), (*x.arg,)) if x.src[0].dtype == dtypes.bfloat16.vec(4) else None)
|
||||
x.src[2]), (*x.arg,)) if x.src[0].dtype == dtypes.bfloat16.vec(4) else None),
|
||||
(UPat(Ops.WMMA, name="x", dtype=dtypes.float.vec(4)),
|
||||
lambda x: UOp(Ops.WMMA, dtypes.float.vec(4), (x.src[0].bitcast(dtypes.uint64), x.src[1].bitcast(dtypes.uint64),
|
||||
x.src[2]), (*x.arg,)) if x.src[0].dtype in (dtypes.fp8e4m3.vec(8), dtypes.fp8e5m2.vec(8)) else None),
|
||||
])
|
||||
if self.arch.split(":")[0] == "gfx1100":
|
||||
self.extra_matcher += PatternMatcher([
|
||||
|
||||
@@ -5,7 +5,7 @@ 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
|
||||
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))
|
||||
@@ -157,8 +157,7 @@ class NIRRenderer(Renderer):
|
||||
def __init__(self): mesa.glsl_type_singleton_init_or_ref()
|
||||
|
||||
def __del__(self):
|
||||
try: mesa.glsl_type_singleton_decref()
|
||||
except FileNotFoundError: pass
|
||||
with contextlib.suppress(AttributeError):mesa.glsl_type_singleton_decref()
|
||||
|
||||
@property
|
||||
def nir_options(self): raise NotImplementedError("needs nir_options")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import glob, importlib, pathlib, subprocess, tarfile
|
||||
from tinygrad.helpers import fetch, flatten, system
|
||||
from tinygrad.helpers import fetch, flatten, system, getenv
|
||||
|
||||
root = (here:=pathlib.Path(__file__).parent).parents[2]
|
||||
nv_src = {"nv_570": "https://github.com/NVIDIA/open-gpu-kernel-modules/archive/81fe4fb417c8ac3b9bdcc1d56827d116743892a5.tar.gz",
|
||||
@@ -7,7 +7,7 @@ nv_src = {"nv_570": "https://github.com/NVIDIA/open-gpu-kernel-modules/archive/8
|
||||
macossdk = "/var/db/xcode_select_link/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
|
||||
|
||||
def load(name, dll, files, **kwargs):
|
||||
if not (f:=(root/(path:=kwargs.pop("path", __name__)).replace('.','/')/f"{name}.py")).exists():
|
||||
if not (f:=(root/(path:=kwargs.pop("path", __name__)).replace('.','/')/f"{name}.py")).exists() or getenv('REGEN'):
|
||||
files, kwargs['args'] = files() if callable(files) else files, args() if callable(args:=kwargs.get('args', [])) else args
|
||||
if (tarball:=kwargs.pop('tarball', None)):
|
||||
# dangerous for arbitrary urls!
|
||||
@@ -123,8 +123,8 @@ python3 src/compiler/builtin_types_h.py gen/builtin_types.h""", cwd=path, shell=
|
||||
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'))"],
|
||||
lambda: [system("llvm-config-20 --includedir")+"/clang-c/Index.h"], args=lambda: system("llvm-config-20 --cflags").split(),
|
||||
types={"CXString":"ci._CXString","CXType":"ci.Type","CXCursor":"ci.Cursor"}, prolog=["import clang.cindex as ci"])
|
||||
lambda: [f"{system('llvm-config-20 --includedir')}/clang-c/{s}.h" for s in ["Index", "CXString", "CXSourceLocation", "CXFile"]],
|
||||
args=lambda: system("llvm-config-20 --cflags").split())
|
||||
case "metal":
|
||||
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"]],
|
||||
|
||||
@@ -476,7 +476,7 @@ PP_GRTAVFS_FW_SEP_FUSE_FREQUENCY_TO_COUNT_SCALER_4 = PP_GRTAVFS_FW_SEP_FUSE_e.de
|
||||
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_char
|
||||
int8_t = ctypes.c_byte
|
||||
SviTelemetryScale_t._fields_ = [
|
||||
('Offset', int8_t),
|
||||
('Padding', uint8_t),
|
||||
|
||||
@@ -29,12 +29,10 @@ AMD_COMGR_LANGUAGE_LLVM_IR = amd_comgr_language_s.define('AMD_COMGR_LANGUAGE_LLV
|
||||
AMD_COMGR_LANGUAGE_LAST = amd_comgr_language_s.define('AMD_COMGR_LANGUAGE_LAST', 5)
|
||||
|
||||
amd_comgr_language_t = amd_comgr_language_s
|
||||
# amd_comgr_status_t amd_comgr_status_string(amd_comgr_status_t status, const char **status_string)
|
||||
try: (amd_comgr_status_string:=dll.amd_comgr_status_string).restype, amd_comgr_status_string.argtypes = amd_comgr_status_t, [amd_comgr_status_t, ctypes.POINTER(ctypes.POINTER(ctypes.c_char))]
|
||||
except AttributeError: pass
|
||||
|
||||
size_t = ctypes.c_uint64
|
||||
# void amd_comgr_get_version(size_t *major, size_t *minor)
|
||||
try: (amd_comgr_get_version:=dll.amd_comgr_get_version).restype, amd_comgr_get_version.argtypes = None, [ctypes.POINTER(size_t), ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -93,167 +91,126 @@ amd_comgr_symbolizer_info_s._fields_ = [
|
||||
('handle', uint64_t),
|
||||
]
|
||||
amd_comgr_symbolizer_info_t = amd_comgr_symbolizer_info_s
|
||||
# amd_comgr_status_t amd_comgr_get_isa_count(size_t *count)
|
||||
try: (amd_comgr_get_isa_count:=dll.amd_comgr_get_isa_count).restype, amd_comgr_get_isa_count.argtypes = amd_comgr_status_t, [ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_isa_name(size_t index, const char **isa_name)
|
||||
try: (amd_comgr_get_isa_name:=dll.amd_comgr_get_isa_name).restype, amd_comgr_get_isa_name.argtypes = amd_comgr_status_t, [size_t, ctypes.POINTER(ctypes.POINTER(ctypes.c_char))]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_isa_metadata(const char *isa_name, amd_comgr_metadata_node_t *metadata)
|
||||
try: (amd_comgr_get_isa_metadata:=dll.amd_comgr_get_isa_metadata).restype, amd_comgr_get_isa_metadata.argtypes = amd_comgr_status_t, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(amd_comgr_metadata_node_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_create_data(amd_comgr_data_kind_t kind, amd_comgr_data_t *data)
|
||||
try: (amd_comgr_create_data:=dll.amd_comgr_create_data).restype, amd_comgr_create_data.argtypes = amd_comgr_status_t, [amd_comgr_data_kind_t, ctypes.POINTER(amd_comgr_data_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_release_data(amd_comgr_data_t data)
|
||||
try: (amd_comgr_release_data:=dll.amd_comgr_release_data).restype, amd_comgr_release_data.argtypes = amd_comgr_status_t, [amd_comgr_data_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_data_kind(amd_comgr_data_t data, amd_comgr_data_kind_t *kind)
|
||||
try: (amd_comgr_get_data_kind:=dll.amd_comgr_get_data_kind).restype, amd_comgr_get_data_kind.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(amd_comgr_data_kind_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_set_data(amd_comgr_data_t data, size_t size, const char *bytes)
|
||||
try: (amd_comgr_set_data:=dll.amd_comgr_set_data).restype, amd_comgr_set_data.argtypes = amd_comgr_status_t, [amd_comgr_data_t, size_t, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_set_data_from_file_slice(amd_comgr_data_t data, int file_descriptor, uint64_t offset, uint64_t size)
|
||||
try: (amd_comgr_set_data_from_file_slice:=dll.amd_comgr_set_data_from_file_slice).restype, amd_comgr_set_data_from_file_slice.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.c_int32, uint64_t, uint64_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_set_data_name(amd_comgr_data_t data, const char *name)
|
||||
try: (amd_comgr_set_data_name:=dll.amd_comgr_set_data_name).restype, amd_comgr_set_data_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_data(amd_comgr_data_t data, size_t *size, char *bytes)
|
||||
try: (amd_comgr_get_data:=dll.amd_comgr_get_data).restype, amd_comgr_get_data.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_data_name(amd_comgr_data_t data, size_t *size, char *name)
|
||||
try: (amd_comgr_get_data_name:=dll.amd_comgr_get_data_name).restype, amd_comgr_get_data_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_data_isa_name(amd_comgr_data_t data, size_t *size, char *isa_name)
|
||||
try: (amd_comgr_get_data_isa_name:=dll.amd_comgr_get_data_isa_name).restype, amd_comgr_get_data_isa_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_create_symbolizer_info(amd_comgr_data_t code_object, void (*print_symbol_callback)(const char *, void *), amd_comgr_symbolizer_info_t *symbolizer_info)
|
||||
try: (amd_comgr_create_symbolizer_info:=dll.amd_comgr_create_symbolizer_info).restype, amd_comgr_create_symbolizer_info.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_char), ctypes.c_void_p), ctypes.POINTER(amd_comgr_symbolizer_info_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_destroy_symbolizer_info(amd_comgr_symbolizer_info_t symbolizer_info)
|
||||
try: (amd_comgr_destroy_symbolizer_info:=dll.amd_comgr_destroy_symbolizer_info).restype, amd_comgr_destroy_symbolizer_info.argtypes = amd_comgr_status_t, [amd_comgr_symbolizer_info_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_symbolize(amd_comgr_symbolizer_info_t symbolizer_info, uint64_t address, bool is_code, void *user_data)
|
||||
try: (amd_comgr_symbolize:=dll.amd_comgr_symbolize).restype, amd_comgr_symbolize.argtypes = amd_comgr_status_t, [amd_comgr_symbolizer_info_t, uint64_t, ctypes.c_bool, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_data_metadata(amd_comgr_data_t data, amd_comgr_metadata_node_t *metadata)
|
||||
try: (amd_comgr_get_data_metadata:=dll.amd_comgr_get_data_metadata).restype, amd_comgr_get_data_metadata.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(amd_comgr_metadata_node_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_destroy_metadata(amd_comgr_metadata_node_t metadata)
|
||||
try: (amd_comgr_destroy_metadata:=dll.amd_comgr_destroy_metadata).restype, amd_comgr_destroy_metadata.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_create_data_set(amd_comgr_data_set_t *data_set)
|
||||
try: (amd_comgr_create_data_set:=dll.amd_comgr_create_data_set).restype, amd_comgr_create_data_set.argtypes = amd_comgr_status_t, [ctypes.POINTER(amd_comgr_data_set_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_destroy_data_set(amd_comgr_data_set_t data_set)
|
||||
try: (amd_comgr_destroy_data_set:=dll.amd_comgr_destroy_data_set).restype, amd_comgr_destroy_data_set.argtypes = amd_comgr_status_t, [amd_comgr_data_set_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_data_set_add(amd_comgr_data_set_t data_set, amd_comgr_data_t data)
|
||||
try: (amd_comgr_data_set_add:=dll.amd_comgr_data_set_add).restype, amd_comgr_data_set_add.argtypes = amd_comgr_status_t, [amd_comgr_data_set_t, amd_comgr_data_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_data_set_remove(amd_comgr_data_set_t data_set, amd_comgr_data_kind_t data_kind)
|
||||
try: (amd_comgr_data_set_remove:=dll.amd_comgr_data_set_remove).restype, amd_comgr_data_set_remove.argtypes = amd_comgr_status_t, [amd_comgr_data_set_t, amd_comgr_data_kind_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_data_count(amd_comgr_data_set_t data_set, amd_comgr_data_kind_t data_kind, size_t *count)
|
||||
try: (amd_comgr_action_data_count:=dll.amd_comgr_action_data_count).restype, amd_comgr_action_data_count.argtypes = amd_comgr_status_t, [amd_comgr_data_set_t, amd_comgr_data_kind_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_data_get_data(amd_comgr_data_set_t data_set, amd_comgr_data_kind_t data_kind, size_t index, amd_comgr_data_t *data)
|
||||
try: (amd_comgr_action_data_get_data:=dll.amd_comgr_action_data_get_data).restype, amd_comgr_action_data_get_data.argtypes = amd_comgr_status_t, [amd_comgr_data_set_t, amd_comgr_data_kind_t, size_t, ctypes.POINTER(amd_comgr_data_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_create_action_info(amd_comgr_action_info_t *action_info)
|
||||
try: (amd_comgr_create_action_info:=dll.amd_comgr_create_action_info).restype, amd_comgr_create_action_info.argtypes = amd_comgr_status_t, [ctypes.POINTER(amd_comgr_action_info_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_destroy_action_info(amd_comgr_action_info_t action_info)
|
||||
try: (amd_comgr_destroy_action_info:=dll.amd_comgr_destroy_action_info).restype, amd_comgr_destroy_action_info.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_isa_name(amd_comgr_action_info_t action_info, const char *isa_name)
|
||||
try: (amd_comgr_action_info_set_isa_name:=dll.amd_comgr_action_info_set_isa_name).restype, amd_comgr_action_info_set_isa_name.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_isa_name(amd_comgr_action_info_t action_info, size_t *size, char *isa_name)
|
||||
try: (amd_comgr_action_info_get_isa_name:=dll.amd_comgr_action_info_get_isa_name).restype, amd_comgr_action_info_get_isa_name.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_language(amd_comgr_action_info_t action_info, amd_comgr_language_t language)
|
||||
try: (amd_comgr_action_info_set_language:=dll.amd_comgr_action_info_set_language).restype, amd_comgr_action_info_set_language.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, amd_comgr_language_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_language(amd_comgr_action_info_t action_info, amd_comgr_language_t *language)
|
||||
try: (amd_comgr_action_info_get_language:=dll.amd_comgr_action_info_get_language).restype, amd_comgr_action_info_get_language.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(amd_comgr_language_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# __attribute__((deprecated("Will be removed in Comgr v3.0 (Rocm v6.0). Use amd_comgr_action_info_set_option_list() instead"))) amd_comgr_status_t amd_comgr_action_info_set_options(amd_comgr_action_info_t action_info, const char *options)
|
||||
try: (amd_comgr_action_info_set_options:=dll.amd_comgr_action_info_set_options).restype, amd_comgr_action_info_set_options.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# __attribute__((deprecated("Will be removed in Comgr v3.0 (Rocm v6.0). Use amd_comgr_action_info_get_option_list_count() and amd_comgr_action_info_get_option_list_item() instead"))) amd_comgr_status_t amd_comgr_action_info_get_options(amd_comgr_action_info_t action_info, size_t *size, char *options)
|
||||
try: (amd_comgr_action_info_get_options:=dll.amd_comgr_action_info_get_options).restype, amd_comgr_action_info_get_options.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_option_list(amd_comgr_action_info_t action_info, const char *options[], size_t count)
|
||||
try: (amd_comgr_action_info_set_option_list:=dll.amd_comgr_action_info_set_option_list).restype, amd_comgr_action_info_set_option_list.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, (ctypes.POINTER(ctypes.c_char) * 0), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_option_list_count(amd_comgr_action_info_t action_info, size_t *count)
|
||||
try: (amd_comgr_action_info_get_option_list_count:=dll.amd_comgr_action_info_get_option_list_count).restype, amd_comgr_action_info_get_option_list_count.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_option_list_item(amd_comgr_action_info_t action_info, size_t index, size_t *size, char *option)
|
||||
try: (amd_comgr_action_info_get_option_list_item:=dll.amd_comgr_action_info_get_option_list_item).restype, amd_comgr_action_info_get_option_list_item.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, size_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_bundle_entry_ids(amd_comgr_action_info_t action_info, const char *bundle_entry_ids[], size_t count)
|
||||
try: (amd_comgr_action_info_set_bundle_entry_ids:=dll.amd_comgr_action_info_set_bundle_entry_ids).restype, amd_comgr_action_info_set_bundle_entry_ids.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, (ctypes.POINTER(ctypes.c_char) * 0), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_bundle_entry_id_count(amd_comgr_action_info_t action_info, size_t *count)
|
||||
try: (amd_comgr_action_info_get_bundle_entry_id_count:=dll.amd_comgr_action_info_get_bundle_entry_id_count).restype, amd_comgr_action_info_get_bundle_entry_id_count.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_bundle_entry_id(amd_comgr_action_info_t action_info, size_t index, size_t *size, char *bundle_entry_id)
|
||||
try: (amd_comgr_action_info_get_bundle_entry_id:=dll.amd_comgr_action_info_get_bundle_entry_id).restype, amd_comgr_action_info_get_bundle_entry_id.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, size_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_working_directory_path(amd_comgr_action_info_t action_info, const char *path)
|
||||
try: (amd_comgr_action_info_set_working_directory_path:=dll.amd_comgr_action_info_set_working_directory_path).restype, amd_comgr_action_info_set_working_directory_path.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_working_directory_path(amd_comgr_action_info_t action_info, size_t *size, char *path)
|
||||
try: (amd_comgr_action_info_get_working_directory_path:=dll.amd_comgr_action_info_get_working_directory_path).restype, amd_comgr_action_info_get_working_directory_path.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_logging(amd_comgr_action_info_t action_info, bool logging)
|
||||
try: (amd_comgr_action_info_set_logging:=dll.amd_comgr_action_info_set_logging).restype, amd_comgr_action_info_set_logging.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.c_bool]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_logging(amd_comgr_action_info_t action_info, bool *logging)
|
||||
try: (amd_comgr_action_info_get_logging:=dll.amd_comgr_action_info_get_logging).restype, amd_comgr_action_info_get_logging.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(ctypes.c_bool)]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -280,7 +237,6 @@ AMD_COMGR_ACTION_UNBUNDLE = amd_comgr_action_kind_s.define('AMD_COMGR_ACTION_UNB
|
||||
AMD_COMGR_ACTION_LAST = amd_comgr_action_kind_s.define('AMD_COMGR_ACTION_LAST', 18)
|
||||
|
||||
amd_comgr_action_kind_t = amd_comgr_action_kind_s
|
||||
# amd_comgr_status_t amd_comgr_do_action(amd_comgr_action_kind_t kind, amd_comgr_action_info_t info, amd_comgr_data_set_t input, amd_comgr_data_set_t result)
|
||||
try: (amd_comgr_do_action:=dll.amd_comgr_do_action).restype, amd_comgr_do_action.argtypes = amd_comgr_status_t, [amd_comgr_action_kind_t, amd_comgr_action_info_t, amd_comgr_data_set_t, amd_comgr_data_set_t]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -292,39 +248,30 @@ AMD_COMGR_METADATA_KIND_LIST = amd_comgr_metadata_kind_s.define('AMD_COMGR_METAD
|
||||
AMD_COMGR_METADATA_KIND_LAST = amd_comgr_metadata_kind_s.define('AMD_COMGR_METADATA_KIND_LAST', 3)
|
||||
|
||||
amd_comgr_metadata_kind_t = amd_comgr_metadata_kind_s
|
||||
# amd_comgr_status_t amd_comgr_get_metadata_kind(amd_comgr_metadata_node_t metadata, amd_comgr_metadata_kind_t *kind)
|
||||
try: (amd_comgr_get_metadata_kind:=dll.amd_comgr_get_metadata_kind).restype, amd_comgr_get_metadata_kind.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.POINTER(amd_comgr_metadata_kind_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_metadata_string(amd_comgr_metadata_node_t metadata, size_t *size, char *string)
|
||||
try: (amd_comgr_get_metadata_string:=dll.amd_comgr_get_metadata_string).restype, amd_comgr_get_metadata_string.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_metadata_map_size(amd_comgr_metadata_node_t metadata, size_t *size)
|
||||
try: (amd_comgr_get_metadata_map_size:=dll.amd_comgr_get_metadata_map_size).restype, amd_comgr_get_metadata_map_size.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_iterate_map_metadata(amd_comgr_metadata_node_t metadata, amd_comgr_status_t (*callback)(amd_comgr_metadata_node_t, amd_comgr_metadata_node_t, void *), void *user_data)
|
||||
try: (amd_comgr_iterate_map_metadata:=dll.amd_comgr_iterate_map_metadata).restype, amd_comgr_iterate_map_metadata.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.CFUNCTYPE(amd_comgr_status_t, amd_comgr_metadata_node_t, amd_comgr_metadata_node_t, ctypes.c_void_p), ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_metadata_lookup(amd_comgr_metadata_node_t metadata, const char *key, amd_comgr_metadata_node_t *value)
|
||||
try: (amd_comgr_metadata_lookup:=dll.amd_comgr_metadata_lookup).restype, amd_comgr_metadata_lookup.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.POINTER(ctypes.c_char), ctypes.POINTER(amd_comgr_metadata_node_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_metadata_list_size(amd_comgr_metadata_node_t metadata, size_t *size)
|
||||
try: (amd_comgr_get_metadata_list_size:=dll.amd_comgr_get_metadata_list_size).restype, amd_comgr_get_metadata_list_size.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_index_list_metadata(amd_comgr_metadata_node_t metadata, size_t index, amd_comgr_metadata_node_t *value)
|
||||
try: (amd_comgr_index_list_metadata:=dll.amd_comgr_index_list_metadata).restype, amd_comgr_index_list_metadata.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, size_t, ctypes.POINTER(amd_comgr_metadata_node_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_iterate_symbols(amd_comgr_data_t data, amd_comgr_status_t (*callback)(amd_comgr_symbol_t, void *), void *user_data)
|
||||
try: (amd_comgr_iterate_symbols:=dll.amd_comgr_iterate_symbols).restype, amd_comgr_iterate_symbols.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.CFUNCTYPE(amd_comgr_status_t, amd_comgr_symbol_t, ctypes.c_void_p), ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_symbol_lookup(amd_comgr_data_t data, const char *name, amd_comgr_symbol_t *symbol)
|
||||
try: (amd_comgr_symbol_lookup:=dll.amd_comgr_symbol_lookup).restype, amd_comgr_symbol_lookup.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(ctypes.c_char), ctypes.POINTER(amd_comgr_symbol_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -349,39 +296,30 @@ AMD_COMGR_SYMBOL_INFO_VALUE = amd_comgr_symbol_info_s.define('AMD_COMGR_SYMBOL_I
|
||||
AMD_COMGR_SYMBOL_INFO_LAST = amd_comgr_symbol_info_s.define('AMD_COMGR_SYMBOL_INFO_LAST', 5)
|
||||
|
||||
amd_comgr_symbol_info_t = amd_comgr_symbol_info_s
|
||||
# amd_comgr_status_t amd_comgr_symbol_get_info(amd_comgr_symbol_t symbol, amd_comgr_symbol_info_t attribute, void *value)
|
||||
try: (amd_comgr_symbol_get_info:=dll.amd_comgr_symbol_get_info).restype, amd_comgr_symbol_get_info.argtypes = amd_comgr_status_t, [amd_comgr_symbol_t, amd_comgr_symbol_info_t, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_create_disassembly_info(const char *isa_name, uint64_t (*read_memory_callback)(uint64_t, char *, uint64_t, void *), void (*print_instruction_callback)(const char *, void *), void (*print_address_annotation_callback)(uint64_t, void *), amd_comgr_disassembly_info_t *disassembly_info)
|
||||
try: (amd_comgr_create_disassembly_info:=dll.amd_comgr_create_disassembly_info).restype, amd_comgr_create_disassembly_info.argtypes = amd_comgr_status_t, [ctypes.POINTER(ctypes.c_char), ctypes.CFUNCTYPE(uint64_t, uint64_t, ctypes.POINTER(ctypes.c_char), uint64_t, ctypes.c_void_p), ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_char), ctypes.c_void_p), ctypes.CFUNCTYPE(None, uint64_t, ctypes.c_void_p), ctypes.POINTER(amd_comgr_disassembly_info_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_destroy_disassembly_info(amd_comgr_disassembly_info_t disassembly_info)
|
||||
try: (amd_comgr_destroy_disassembly_info:=dll.amd_comgr_destroy_disassembly_info).restype, amd_comgr_destroy_disassembly_info.argtypes = amd_comgr_status_t, [amd_comgr_disassembly_info_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_disassemble_instruction(amd_comgr_disassembly_info_t disassembly_info, uint64_t address, void *user_data, uint64_t *size)
|
||||
try: (amd_comgr_disassemble_instruction:=dll.amd_comgr_disassemble_instruction).restype, amd_comgr_disassemble_instruction.argtypes = amd_comgr_status_t, [amd_comgr_disassembly_info_t, uint64_t, ctypes.c_void_p, ctypes.POINTER(uint64_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_demangle_symbol_name(amd_comgr_data_t mangled_symbol_name, amd_comgr_data_t *demangled_symbol_name)
|
||||
try: (amd_comgr_demangle_symbol_name:=dll.amd_comgr_demangle_symbol_name).restype, amd_comgr_demangle_symbol_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(amd_comgr_data_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_populate_mangled_names(amd_comgr_data_t data, size_t *count)
|
||||
try: (amd_comgr_populate_mangled_names:=dll.amd_comgr_populate_mangled_names).restype, amd_comgr_populate_mangled_names.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_mangled_name(amd_comgr_data_t data, size_t index, size_t *size, char *mangled_name)
|
||||
try: (amd_comgr_get_mangled_name:=dll.amd_comgr_get_mangled_name).restype, amd_comgr_get_mangled_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, size_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_populate_name_expression_map(amd_comgr_data_t data, size_t *count)
|
||||
try: (amd_comgr_populate_name_expression_map:=dll.amd_comgr_populate_name_expression_map).restype, amd_comgr_populate_name_expression_map.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_map_name_expression_to_symbol_name(amd_comgr_data_t data, size_t *size, char *name_expression, char *symbol_name)
|
||||
try: (amd_comgr_map_name_expression_to_symbol_name:=dll.amd_comgr_map_name_expression_to_symbol_name).restype, amd_comgr_map_name_expression_to_symbol_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -392,11 +330,9 @@ code_object_info_s._fields_ = [
|
||||
('offset', uint64_t),
|
||||
]
|
||||
amd_comgr_code_object_info_t = code_object_info_s
|
||||
# amd_comgr_status_t amd_comgr_lookup_code_object(amd_comgr_data_t data, amd_comgr_code_object_info_t *info_list, size_t info_list_size)
|
||||
try: (amd_comgr_lookup_code_object:=dll.amd_comgr_lookup_code_object).restype, amd_comgr_lookup_code_object.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(amd_comgr_code_object_info_t), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_map_elf_virtual_address_to_code_object_offset(amd_comgr_data_t data, uint64_t elf_virtual_address, uint64_t *code_object_offset, uint64_t *slice_size, bool *nobits)
|
||||
try: (amd_comgr_map_elf_virtual_address_to_code_object_offset:=dll.amd_comgr_map_elf_virtual_address_to_code_object_offset).restype, amd_comgr_map_elf_virtual_address_to_code_object_offset.argtypes = amd_comgr_status_t, [amd_comgr_data_t, uint64_t, ctypes.POINTER(uint64_t), ctypes.POINTER(uint64_t), ctypes.POINTER(ctypes.c_bool)]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
@@ -28,12 +28,10 @@ AMD_COMGR_LANGUAGE_LLVM_IR = amd_comgr_language_s.define('AMD_COMGR_LANGUAGE_LLV
|
||||
AMD_COMGR_LANGUAGE_LAST = amd_comgr_language_s.define('AMD_COMGR_LANGUAGE_LAST', 4)
|
||||
|
||||
amd_comgr_language_t = amd_comgr_language_s
|
||||
# amd_comgr_status_t amd_comgr_status_string(amd_comgr_status_t status, const char **status_string)
|
||||
try: (amd_comgr_status_string:=dll.amd_comgr_status_string).restype, amd_comgr_status_string.argtypes = amd_comgr_status_t, [amd_comgr_status_t, ctypes.POINTER(ctypes.POINTER(ctypes.c_char))]
|
||||
except AttributeError: pass
|
||||
|
||||
size_t = ctypes.c_uint64
|
||||
# void amd_comgr_get_version(size_t *major, size_t *minor)
|
||||
try: (amd_comgr_get_version:=dll.amd_comgr_get_version).restype, amd_comgr_get_version.argtypes = None, [ctypes.POINTER(size_t), ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -93,163 +91,123 @@ amd_comgr_symbolizer_info_s._fields_ = [
|
||||
('handle', uint64_t),
|
||||
]
|
||||
amd_comgr_symbolizer_info_t = amd_comgr_symbolizer_info_s
|
||||
# amd_comgr_status_t amd_comgr_get_isa_count(size_t *count)
|
||||
try: (amd_comgr_get_isa_count:=dll.amd_comgr_get_isa_count).restype, amd_comgr_get_isa_count.argtypes = amd_comgr_status_t, [ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_isa_name(size_t index, const char **isa_name)
|
||||
try: (amd_comgr_get_isa_name:=dll.amd_comgr_get_isa_name).restype, amd_comgr_get_isa_name.argtypes = amd_comgr_status_t, [size_t, ctypes.POINTER(ctypes.POINTER(ctypes.c_char))]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_isa_metadata(const char *isa_name, amd_comgr_metadata_node_t *metadata)
|
||||
try: (amd_comgr_get_isa_metadata:=dll.amd_comgr_get_isa_metadata).restype, amd_comgr_get_isa_metadata.argtypes = amd_comgr_status_t, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(amd_comgr_metadata_node_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_create_data(amd_comgr_data_kind_t kind, amd_comgr_data_t *data)
|
||||
try: (amd_comgr_create_data:=dll.amd_comgr_create_data).restype, amd_comgr_create_data.argtypes = amd_comgr_status_t, [amd_comgr_data_kind_t, ctypes.POINTER(amd_comgr_data_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_release_data(amd_comgr_data_t data)
|
||||
try: (amd_comgr_release_data:=dll.amd_comgr_release_data).restype, amd_comgr_release_data.argtypes = amd_comgr_status_t, [amd_comgr_data_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_data_kind(amd_comgr_data_t data, amd_comgr_data_kind_t *kind)
|
||||
try: (amd_comgr_get_data_kind:=dll.amd_comgr_get_data_kind).restype, amd_comgr_get_data_kind.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(amd_comgr_data_kind_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_set_data(amd_comgr_data_t data, size_t size, const char *bytes)
|
||||
try: (amd_comgr_set_data:=dll.amd_comgr_set_data).restype, amd_comgr_set_data.argtypes = amd_comgr_status_t, [amd_comgr_data_t, size_t, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_set_data_from_file_slice(amd_comgr_data_t data, int file_descriptor, uint64_t offset, uint64_t size)
|
||||
try: (amd_comgr_set_data_from_file_slice:=dll.amd_comgr_set_data_from_file_slice).restype, amd_comgr_set_data_from_file_slice.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.c_int32, uint64_t, uint64_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_set_data_name(amd_comgr_data_t data, const char *name)
|
||||
try: (amd_comgr_set_data_name:=dll.amd_comgr_set_data_name).restype, amd_comgr_set_data_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_data(amd_comgr_data_t data, size_t *size, char *bytes)
|
||||
try: (amd_comgr_get_data:=dll.amd_comgr_get_data).restype, amd_comgr_get_data.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_data_name(amd_comgr_data_t data, size_t *size, char *name)
|
||||
try: (amd_comgr_get_data_name:=dll.amd_comgr_get_data_name).restype, amd_comgr_get_data_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_data_isa_name(amd_comgr_data_t data, size_t *size, char *isa_name)
|
||||
try: (amd_comgr_get_data_isa_name:=dll.amd_comgr_get_data_isa_name).restype, amd_comgr_get_data_isa_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_create_symbolizer_info(amd_comgr_data_t code_object, void (*print_symbol_callback)(const char *, void *), amd_comgr_symbolizer_info_t *symbolizer_info)
|
||||
try: (amd_comgr_create_symbolizer_info:=dll.amd_comgr_create_symbolizer_info).restype, amd_comgr_create_symbolizer_info.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_char), ctypes.c_void_p), ctypes.POINTER(amd_comgr_symbolizer_info_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_destroy_symbolizer_info(amd_comgr_symbolizer_info_t symbolizer_info)
|
||||
try: (amd_comgr_destroy_symbolizer_info:=dll.amd_comgr_destroy_symbolizer_info).restype, amd_comgr_destroy_symbolizer_info.argtypes = amd_comgr_status_t, [amd_comgr_symbolizer_info_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_symbolize(amd_comgr_symbolizer_info_t symbolizer_info, uint64_t address, bool is_code, void *user_data)
|
||||
try: (amd_comgr_symbolize:=dll.amd_comgr_symbolize).restype, amd_comgr_symbolize.argtypes = amd_comgr_status_t, [amd_comgr_symbolizer_info_t, uint64_t, ctypes.c_bool, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_data_metadata(amd_comgr_data_t data, amd_comgr_metadata_node_t *metadata)
|
||||
try: (amd_comgr_get_data_metadata:=dll.amd_comgr_get_data_metadata).restype, amd_comgr_get_data_metadata.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(amd_comgr_metadata_node_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_destroy_metadata(amd_comgr_metadata_node_t metadata)
|
||||
try: (amd_comgr_destroy_metadata:=dll.amd_comgr_destroy_metadata).restype, amd_comgr_destroy_metadata.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_create_data_set(amd_comgr_data_set_t *data_set)
|
||||
try: (amd_comgr_create_data_set:=dll.amd_comgr_create_data_set).restype, amd_comgr_create_data_set.argtypes = amd_comgr_status_t, [ctypes.POINTER(amd_comgr_data_set_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_destroy_data_set(amd_comgr_data_set_t data_set)
|
||||
try: (amd_comgr_destroy_data_set:=dll.amd_comgr_destroy_data_set).restype, amd_comgr_destroy_data_set.argtypes = amd_comgr_status_t, [amd_comgr_data_set_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_data_set_add(amd_comgr_data_set_t data_set, amd_comgr_data_t data)
|
||||
try: (amd_comgr_data_set_add:=dll.amd_comgr_data_set_add).restype, amd_comgr_data_set_add.argtypes = amd_comgr_status_t, [amd_comgr_data_set_t, amd_comgr_data_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_data_set_remove(amd_comgr_data_set_t data_set, amd_comgr_data_kind_t data_kind)
|
||||
try: (amd_comgr_data_set_remove:=dll.amd_comgr_data_set_remove).restype, amd_comgr_data_set_remove.argtypes = amd_comgr_status_t, [amd_comgr_data_set_t, amd_comgr_data_kind_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_data_count(amd_comgr_data_set_t data_set, amd_comgr_data_kind_t data_kind, size_t *count)
|
||||
try: (amd_comgr_action_data_count:=dll.amd_comgr_action_data_count).restype, amd_comgr_action_data_count.argtypes = amd_comgr_status_t, [amd_comgr_data_set_t, amd_comgr_data_kind_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_data_get_data(amd_comgr_data_set_t data_set, amd_comgr_data_kind_t data_kind, size_t index, amd_comgr_data_t *data)
|
||||
try: (amd_comgr_action_data_get_data:=dll.amd_comgr_action_data_get_data).restype, amd_comgr_action_data_get_data.argtypes = amd_comgr_status_t, [amd_comgr_data_set_t, amd_comgr_data_kind_t, size_t, ctypes.POINTER(amd_comgr_data_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_create_action_info(amd_comgr_action_info_t *action_info)
|
||||
try: (amd_comgr_create_action_info:=dll.amd_comgr_create_action_info).restype, amd_comgr_create_action_info.argtypes = amd_comgr_status_t, [ctypes.POINTER(amd_comgr_action_info_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_destroy_action_info(amd_comgr_action_info_t action_info)
|
||||
try: (amd_comgr_destroy_action_info:=dll.amd_comgr_destroy_action_info).restype, amd_comgr_destroy_action_info.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_isa_name(amd_comgr_action_info_t action_info, const char *isa_name)
|
||||
try: (amd_comgr_action_info_set_isa_name:=dll.amd_comgr_action_info_set_isa_name).restype, amd_comgr_action_info_set_isa_name.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_isa_name(amd_comgr_action_info_t action_info, size_t *size, char *isa_name)
|
||||
try: (amd_comgr_action_info_get_isa_name:=dll.amd_comgr_action_info_get_isa_name).restype, amd_comgr_action_info_get_isa_name.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_language(amd_comgr_action_info_t action_info, amd_comgr_language_t language)
|
||||
try: (amd_comgr_action_info_set_language:=dll.amd_comgr_action_info_set_language).restype, amd_comgr_action_info_set_language.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, amd_comgr_language_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_language(amd_comgr_action_info_t action_info, amd_comgr_language_t *language)
|
||||
try: (amd_comgr_action_info_get_language:=dll.amd_comgr_action_info_get_language).restype, amd_comgr_action_info_get_language.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(amd_comgr_language_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_option_list(amd_comgr_action_info_t action_info, const char *options[], size_t count)
|
||||
try: (amd_comgr_action_info_set_option_list:=dll.amd_comgr_action_info_set_option_list).restype, amd_comgr_action_info_set_option_list.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, (ctypes.POINTER(ctypes.c_char) * 0), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_option_list_count(amd_comgr_action_info_t action_info, size_t *count)
|
||||
try: (amd_comgr_action_info_get_option_list_count:=dll.amd_comgr_action_info_get_option_list_count).restype, amd_comgr_action_info_get_option_list_count.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_option_list_item(amd_comgr_action_info_t action_info, size_t index, size_t *size, char *option)
|
||||
try: (amd_comgr_action_info_get_option_list_item:=dll.amd_comgr_action_info_get_option_list_item).restype, amd_comgr_action_info_get_option_list_item.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, size_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_bundle_entry_ids(amd_comgr_action_info_t action_info, const char *bundle_entry_ids[], size_t count)
|
||||
try: (amd_comgr_action_info_set_bundle_entry_ids:=dll.amd_comgr_action_info_set_bundle_entry_ids).restype, amd_comgr_action_info_set_bundle_entry_ids.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, (ctypes.POINTER(ctypes.c_char) * 0), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_bundle_entry_id_count(amd_comgr_action_info_t action_info, size_t *count)
|
||||
try: (amd_comgr_action_info_get_bundle_entry_id_count:=dll.amd_comgr_action_info_get_bundle_entry_id_count).restype, amd_comgr_action_info_get_bundle_entry_id_count.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_bundle_entry_id(amd_comgr_action_info_t action_info, size_t index, size_t *size, char *bundle_entry_id)
|
||||
try: (amd_comgr_action_info_get_bundle_entry_id:=dll.amd_comgr_action_info_get_bundle_entry_id).restype, amd_comgr_action_info_get_bundle_entry_id.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, size_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_device_lib_linking(amd_comgr_action_info_t action_info, bool should_link_device_libs)
|
||||
try: (amd_comgr_action_info_set_device_lib_linking:=dll.amd_comgr_action_info_set_device_lib_linking).restype, amd_comgr_action_info_set_device_lib_linking.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.c_bool]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_working_directory_path(amd_comgr_action_info_t action_info, const char *path)
|
||||
try: (amd_comgr_action_info_set_working_directory_path:=dll.amd_comgr_action_info_set_working_directory_path).restype, amd_comgr_action_info_set_working_directory_path.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_working_directory_path(amd_comgr_action_info_t action_info, size_t *size, char *path)
|
||||
try: (amd_comgr_action_info_get_working_directory_path:=dll.amd_comgr_action_info_get_working_directory_path).restype, amd_comgr_action_info_get_working_directory_path.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_set_logging(amd_comgr_action_info_t action_info, bool logging)
|
||||
try: (amd_comgr_action_info_set_logging:=dll.amd_comgr_action_info_set_logging).restype, amd_comgr_action_info_set_logging.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.c_bool]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_action_info_get_logging(amd_comgr_action_info_t action_info, bool *logging)
|
||||
try: (amd_comgr_action_info_get_logging:=dll.amd_comgr_action_info_get_logging).restype, amd_comgr_action_info_get_logging.argtypes = amd_comgr_status_t, [amd_comgr_action_info_t, ctypes.POINTER(ctypes.c_bool)]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -274,7 +232,6 @@ AMD_COMGR_ACTION_TRANSLATE_SPIRV_TO_BC = amd_comgr_action_kind_s.define('AMD_COM
|
||||
AMD_COMGR_ACTION_LAST = amd_comgr_action_kind_s.define('AMD_COMGR_ACTION_LAST', 19)
|
||||
|
||||
amd_comgr_action_kind_t = amd_comgr_action_kind_s
|
||||
# amd_comgr_status_t amd_comgr_do_action(amd_comgr_action_kind_t kind, amd_comgr_action_info_t info, amd_comgr_data_set_t input, amd_comgr_data_set_t result)
|
||||
try: (amd_comgr_do_action:=dll.amd_comgr_do_action).restype, amd_comgr_do_action.argtypes = amd_comgr_status_t, [amd_comgr_action_kind_t, amd_comgr_action_info_t, amd_comgr_data_set_t, amd_comgr_data_set_t]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -286,39 +243,30 @@ AMD_COMGR_METADATA_KIND_LIST = amd_comgr_metadata_kind_s.define('AMD_COMGR_METAD
|
||||
AMD_COMGR_METADATA_KIND_LAST = amd_comgr_metadata_kind_s.define('AMD_COMGR_METADATA_KIND_LAST', 3)
|
||||
|
||||
amd_comgr_metadata_kind_t = amd_comgr_metadata_kind_s
|
||||
# amd_comgr_status_t amd_comgr_get_metadata_kind(amd_comgr_metadata_node_t metadata, amd_comgr_metadata_kind_t *kind)
|
||||
try: (amd_comgr_get_metadata_kind:=dll.amd_comgr_get_metadata_kind).restype, amd_comgr_get_metadata_kind.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.POINTER(amd_comgr_metadata_kind_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_metadata_string(amd_comgr_metadata_node_t metadata, size_t *size, char *string)
|
||||
try: (amd_comgr_get_metadata_string:=dll.amd_comgr_get_metadata_string).restype, amd_comgr_get_metadata_string.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_metadata_map_size(amd_comgr_metadata_node_t metadata, size_t *size)
|
||||
try: (amd_comgr_get_metadata_map_size:=dll.amd_comgr_get_metadata_map_size).restype, amd_comgr_get_metadata_map_size.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_iterate_map_metadata(amd_comgr_metadata_node_t metadata, amd_comgr_status_t (*callback)(amd_comgr_metadata_node_t, amd_comgr_metadata_node_t, void *), void *user_data)
|
||||
try: (amd_comgr_iterate_map_metadata:=dll.amd_comgr_iterate_map_metadata).restype, amd_comgr_iterate_map_metadata.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.CFUNCTYPE(amd_comgr_status_t, amd_comgr_metadata_node_t, amd_comgr_metadata_node_t, ctypes.c_void_p), ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_metadata_lookup(amd_comgr_metadata_node_t metadata, const char *key, amd_comgr_metadata_node_t *value)
|
||||
try: (amd_comgr_metadata_lookup:=dll.amd_comgr_metadata_lookup).restype, amd_comgr_metadata_lookup.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.POINTER(ctypes.c_char), ctypes.POINTER(amd_comgr_metadata_node_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_metadata_list_size(amd_comgr_metadata_node_t metadata, size_t *size)
|
||||
try: (amd_comgr_get_metadata_list_size:=dll.amd_comgr_get_metadata_list_size).restype, amd_comgr_get_metadata_list_size.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_index_list_metadata(amd_comgr_metadata_node_t metadata, size_t index, amd_comgr_metadata_node_t *value)
|
||||
try: (amd_comgr_index_list_metadata:=dll.amd_comgr_index_list_metadata).restype, amd_comgr_index_list_metadata.argtypes = amd_comgr_status_t, [amd_comgr_metadata_node_t, size_t, ctypes.POINTER(amd_comgr_metadata_node_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_iterate_symbols(amd_comgr_data_t data, amd_comgr_status_t (*callback)(amd_comgr_symbol_t, void *), void *user_data)
|
||||
try: (amd_comgr_iterate_symbols:=dll.amd_comgr_iterate_symbols).restype, amd_comgr_iterate_symbols.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.CFUNCTYPE(amd_comgr_status_t, amd_comgr_symbol_t, ctypes.c_void_p), ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_symbol_lookup(amd_comgr_data_t data, const char *name, amd_comgr_symbol_t *symbol)
|
||||
try: (amd_comgr_symbol_lookup:=dll.amd_comgr_symbol_lookup).restype, amd_comgr_symbol_lookup.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(ctypes.c_char), ctypes.POINTER(amd_comgr_symbol_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -343,39 +291,30 @@ AMD_COMGR_SYMBOL_INFO_VALUE = amd_comgr_symbol_info_s.define('AMD_COMGR_SYMBOL_I
|
||||
AMD_COMGR_SYMBOL_INFO_LAST = amd_comgr_symbol_info_s.define('AMD_COMGR_SYMBOL_INFO_LAST', 5)
|
||||
|
||||
amd_comgr_symbol_info_t = amd_comgr_symbol_info_s
|
||||
# amd_comgr_status_t amd_comgr_symbol_get_info(amd_comgr_symbol_t symbol, amd_comgr_symbol_info_t attribute, void *value)
|
||||
try: (amd_comgr_symbol_get_info:=dll.amd_comgr_symbol_get_info).restype, amd_comgr_symbol_get_info.argtypes = amd_comgr_status_t, [amd_comgr_symbol_t, amd_comgr_symbol_info_t, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_create_disassembly_info(const char *isa_name, uint64_t (*read_memory_callback)(uint64_t, char *, uint64_t, void *), void (*print_instruction_callback)(const char *, void *), void (*print_address_annotation_callback)(uint64_t, void *), amd_comgr_disassembly_info_t *disassembly_info)
|
||||
try: (amd_comgr_create_disassembly_info:=dll.amd_comgr_create_disassembly_info).restype, amd_comgr_create_disassembly_info.argtypes = amd_comgr_status_t, [ctypes.POINTER(ctypes.c_char), ctypes.CFUNCTYPE(uint64_t, uint64_t, ctypes.POINTER(ctypes.c_char), uint64_t, ctypes.c_void_p), ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_char), ctypes.c_void_p), ctypes.CFUNCTYPE(None, uint64_t, ctypes.c_void_p), ctypes.POINTER(amd_comgr_disassembly_info_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_destroy_disassembly_info(amd_comgr_disassembly_info_t disassembly_info)
|
||||
try: (amd_comgr_destroy_disassembly_info:=dll.amd_comgr_destroy_disassembly_info).restype, amd_comgr_destroy_disassembly_info.argtypes = amd_comgr_status_t, [amd_comgr_disassembly_info_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_disassemble_instruction(amd_comgr_disassembly_info_t disassembly_info, uint64_t address, void *user_data, uint64_t *size)
|
||||
try: (amd_comgr_disassemble_instruction:=dll.amd_comgr_disassemble_instruction).restype, amd_comgr_disassemble_instruction.argtypes = amd_comgr_status_t, [amd_comgr_disassembly_info_t, uint64_t, ctypes.c_void_p, ctypes.POINTER(uint64_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_demangle_symbol_name(amd_comgr_data_t mangled_symbol_name, amd_comgr_data_t *demangled_symbol_name)
|
||||
try: (amd_comgr_demangle_symbol_name:=dll.amd_comgr_demangle_symbol_name).restype, amd_comgr_demangle_symbol_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(amd_comgr_data_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_populate_mangled_names(amd_comgr_data_t data, size_t *count)
|
||||
try: (amd_comgr_populate_mangled_names:=dll.amd_comgr_populate_mangled_names).restype, amd_comgr_populate_mangled_names.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_get_mangled_name(amd_comgr_data_t data, size_t index, size_t *size, char *mangled_name)
|
||||
try: (amd_comgr_get_mangled_name:=dll.amd_comgr_get_mangled_name).restype, amd_comgr_get_mangled_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, size_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_populate_name_expression_map(amd_comgr_data_t data, size_t *count)
|
||||
try: (amd_comgr_populate_name_expression_map:=dll.amd_comgr_populate_name_expression_map).restype, amd_comgr_populate_name_expression_map.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_map_name_expression_to_symbol_name(amd_comgr_data_t data, size_t *size, char *name_expression, char *symbol_name)
|
||||
try: (amd_comgr_map_name_expression_to_symbol_name:=dll.amd_comgr_map_name_expression_to_symbol_name).restype, amd_comgr_map_name_expression_to_symbol_name.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(size_t), ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -386,11 +325,9 @@ code_object_info_s._fields_ = [
|
||||
('offset', uint64_t),
|
||||
]
|
||||
amd_comgr_code_object_info_t = code_object_info_s
|
||||
# amd_comgr_status_t amd_comgr_lookup_code_object(amd_comgr_data_t data, amd_comgr_code_object_info_t *info_list, size_t info_list_size)
|
||||
try: (amd_comgr_lookup_code_object:=dll.amd_comgr_lookup_code_object).restype, amd_comgr_lookup_code_object.argtypes = amd_comgr_status_t, [amd_comgr_data_t, ctypes.POINTER(amd_comgr_code_object_info_t), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# amd_comgr_status_t amd_comgr_map_elf_virtual_address_to_code_object_offset(amd_comgr_data_t data, uint64_t elf_virtual_address, uint64_t *code_object_offset, uint64_t *slice_size, bool *nobits)
|
||||
try: (amd_comgr_map_elf_virtual_address_to_code_object_offset:=dll.amd_comgr_map_elf_virtual_address_to_code_object_offset).restype, amd_comgr_map_elf_virtual_address_to_code_object_offset.argtypes = amd_comgr_status_t, [amd_comgr_data_t, uint64_t, ctypes.POINTER(uint64_t), ctypes.POINTER(uint64_t), ctypes.POINTER(ctypes.c_bool)]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -794,7 +794,6 @@ struct_ibv_async_event._fields_ = [
|
||||
('element', struct_ibv_async_event_element),
|
||||
('event_type', enum_ibv_event_type),
|
||||
]
|
||||
# const char *ibv_wc_status_str(enum ibv_wc_status status)
|
||||
try: (ibv_wc_status_str:=dll.ibv_wc_status_str).restype, ibv_wc_status_str.argtypes = ctypes.POINTER(ctypes.c_char), [enum_ibv_wc_status]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -916,19 +915,15 @@ IBV_RATE_600_GBPS = enum_ibv_rate.define('IBV_RATE_600_GBPS', 22)
|
||||
IBV_RATE_800_GBPS = enum_ibv_rate.define('IBV_RATE_800_GBPS', 23)
|
||||
IBV_RATE_1200_GBPS = enum_ibv_rate.define('IBV_RATE_1200_GBPS', 24)
|
||||
|
||||
# __attribute__((const)) int ibv_rate_to_mult(enum ibv_rate rate)
|
||||
try: (ibv_rate_to_mult:=dll.ibv_rate_to_mult).restype, ibv_rate_to_mult.argtypes = ctypes.c_int32, [enum_ibv_rate]
|
||||
except AttributeError: pass
|
||||
|
||||
# __attribute__((const)) enum ibv_rate mult_to_ibv_rate(int mult)
|
||||
try: (mult_to_ibv_rate:=dll.mult_to_ibv_rate).restype, mult_to_ibv_rate.argtypes = enum_ibv_rate, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# __attribute__((const)) int ibv_rate_to_mbps(enum ibv_rate rate)
|
||||
try: (ibv_rate_to_mbps:=dll.ibv_rate_to_mbps).restype, ibv_rate_to_mbps.argtypes = ctypes.c_int32, [enum_ibv_rate]
|
||||
except AttributeError: pass
|
||||
|
||||
# __attribute__((const)) enum ibv_rate mbps_to_ibv_rate(int mbps)
|
||||
try: (mbps_to_ibv_rate:=dll.mbps_to_ibv_rate).restype, mbps_to_ibv_rate.argtypes = enum_ibv_rate, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -1200,7 +1195,6 @@ struct_ibv_qp_rate_limit_attr._fields_ = [
|
||||
('typical_pkt_sz', uint16_t),
|
||||
('comp_mask', uint32_t),
|
||||
]
|
||||
# const char *ibv_wr_opcode_str(enum ibv_wr_opcode opcode)
|
||||
try: (ibv_wr_opcode_str:=dll.ibv_wr_opcode_str).restype, ibv_wr_opcode_str.argtypes = ctypes.POINTER(ctypes.c_char), [enum_ibv_wr_opcode]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -1284,7 +1278,6 @@ struct_ibv_qp_ex._fields_ = [
|
||||
('wr_atomic_write', ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_ibv_qp_ex), uint32_t, uint64_t, ctypes.c_void_p)),
|
||||
('wr_flush', ctypes.CFUNCTYPE(None, ctypes.POINTER(struct_ibv_qp_ex), uint32_t, uint64_t, size_t, uint8_t, uint8_t)),
|
||||
]
|
||||
# struct ibv_qp_ex *ibv_qp_to_qp_ex(struct ibv_qp *qp)
|
||||
try: (ibv_qp_to_qp_ex:=dll.ibv_qp_to_qp_ex).restype, ibv_qp_to_qp_ex.argtypes = ctypes.POINTER(struct_ibv_qp_ex), [ctypes.POINTER(struct_ibv_qp)]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -1739,120 +1732,91 @@ struct_verbs_context._fields_ = [
|
||||
('sz', size_t),
|
||||
('context', struct_ibv_context),
|
||||
]
|
||||
# struct ibv_device **ibv_get_device_list(int *num_devices)
|
||||
try: (ibv_get_device_list:=dll.ibv_get_device_list).restype, ibv_get_device_list.argtypes = ctypes.POINTER(ctypes.POINTER(struct_ibv_device)), [ctypes.POINTER(ctypes.c_int32)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void ibv_free_device_list(struct ibv_device **list)
|
||||
try: (ibv_free_device_list:=dll.ibv_free_device_list).restype, ibv_free_device_list.argtypes = None, [ctypes.POINTER(ctypes.POINTER(struct_ibv_device))]
|
||||
except AttributeError: pass
|
||||
|
||||
# const char *ibv_get_device_name(struct ibv_device *device)
|
||||
try: (ibv_get_device_name:=dll.ibv_get_device_name).restype, ibv_get_device_name.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(struct_ibv_device)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_get_device_index(struct ibv_device *device)
|
||||
try: (ibv_get_device_index:=dll.ibv_get_device_index).restype, ibv_get_device_index.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_device)]
|
||||
except AttributeError: pass
|
||||
|
||||
# __be64 ibv_get_device_guid(struct ibv_device *device)
|
||||
try: (ibv_get_device_guid:=dll.ibv_get_device_guid).restype, ibv_get_device_guid.argtypes = ctypes.c_uint64, [ctypes.POINTER(struct_ibv_device)]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_context *ibv_open_device(struct ibv_device *device)
|
||||
try: (ibv_open_device:=dll.ibv_open_device).restype, ibv_open_device.argtypes = ctypes.POINTER(struct_ibv_context), [ctypes.POINTER(struct_ibv_device)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_close_device(struct ibv_context *context)
|
||||
try: (ibv_close_device:=dll.ibv_close_device).restype, ibv_close_device.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_context *ibv_import_device(int cmd_fd)
|
||||
try: (ibv_import_device:=dll.ibv_import_device).restype, ibv_import_device.argtypes = ctypes.POINTER(struct_ibv_context), [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_pd *ibv_import_pd(struct ibv_context *context, uint32_t pd_handle)
|
||||
try: (ibv_import_pd:=dll.ibv_import_pd).restype, ibv_import_pd.argtypes = ctypes.POINTER(struct_ibv_pd), [ctypes.POINTER(struct_ibv_context), uint32_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# void ibv_unimport_pd(struct ibv_pd *pd)
|
||||
try: (ibv_unimport_pd:=dll.ibv_unimport_pd).restype, ibv_unimport_pd.argtypes = None, [ctypes.POINTER(struct_ibv_pd)]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_mr *ibv_import_mr(struct ibv_pd *pd, uint32_t mr_handle)
|
||||
try: (ibv_import_mr:=dll.ibv_import_mr).restype, ibv_import_mr.argtypes = ctypes.POINTER(struct_ibv_mr), [ctypes.POINTER(struct_ibv_pd), uint32_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# void ibv_unimport_mr(struct ibv_mr *mr)
|
||||
try: (ibv_unimport_mr:=dll.ibv_unimport_mr).restype, ibv_unimport_mr.argtypes = None, [ctypes.POINTER(struct_ibv_mr)]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_dm *ibv_import_dm(struct ibv_context *context, uint32_t dm_handle)
|
||||
try: (ibv_import_dm:=dll.ibv_import_dm).restype, ibv_import_dm.argtypes = ctypes.POINTER(struct_ibv_dm), [ctypes.POINTER(struct_ibv_context), uint32_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# void ibv_unimport_dm(struct ibv_dm *dm)
|
||||
try: (ibv_unimport_dm:=dll.ibv_unimport_dm).restype, ibv_unimport_dm.argtypes = None, [ctypes.POINTER(struct_ibv_dm)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_get_async_event(struct ibv_context *context, struct ibv_async_event *event)
|
||||
try: (ibv_get_async_event:=dll.ibv_get_async_event).restype, ibv_get_async_event.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_context), ctypes.POINTER(struct_ibv_async_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void ibv_ack_async_event(struct ibv_async_event *event)
|
||||
try: (ibv_ack_async_event:=dll.ibv_ack_async_event).restype, ibv_ack_async_event.argtypes = None, [ctypes.POINTER(struct_ibv_async_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_query_device(struct ibv_context *context, struct ibv_device_attr *device_attr)
|
||||
try: (ibv_query_device:=dll.ibv_query_device).restype, ibv_query_device.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_context), ctypes.POINTER(struct_ibv_device_attr)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_query_port(struct ibv_context *context, uint8_t port_num, struct _compat_ibv_port_attr *port_attr)
|
||||
try: (ibv_query_port:=dll.ibv_query_port).restype, ibv_query_port.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_context), uint8_t, ctypes.POINTER(struct__compat_ibv_port_attr)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_query_gid(struct ibv_context *context, uint8_t port_num, int index, union ibv_gid *gid)
|
||||
try: (ibv_query_gid:=dll.ibv_query_gid).restype, ibv_query_gid.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_context), uint8_t, ctypes.c_int32, ctypes.POINTER(union_ibv_gid)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int _ibv_query_gid_ex(struct ibv_context *context, uint32_t port_num, uint32_t gid_index, struct ibv_gid_entry *entry, uint32_t flags, size_t entry_size)
|
||||
try: (_ibv_query_gid_ex:=dll._ibv_query_gid_ex).restype, _ibv_query_gid_ex.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_context), uint32_t, uint32_t, ctypes.POINTER(struct_ibv_gid_entry), uint32_t, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
ssize_t = ctypes.c_int64
|
||||
# ssize_t _ibv_query_gid_table(struct ibv_context *context, struct ibv_gid_entry *entries, size_t max_entries, uint32_t flags, size_t entry_size)
|
||||
try: (_ibv_query_gid_table:=dll._ibv_query_gid_table).restype, _ibv_query_gid_table.argtypes = ssize_t, [ctypes.POINTER(struct_ibv_context), ctypes.POINTER(struct_ibv_gid_entry), size_t, uint32_t, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_query_pkey(struct ibv_context *context, uint8_t port_num, int index, __be16 *pkey)
|
||||
try: (ibv_query_pkey:=dll.ibv_query_pkey).restype, ibv_query_pkey.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_context), uint8_t, ctypes.c_int32, ctypes.POINTER(ctypes.c_uint16)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_get_pkey_index(struct ibv_context *context, uint8_t port_num, __be16 pkey)
|
||||
try: (ibv_get_pkey_index:=dll.ibv_get_pkey_index).restype, ibv_get_pkey_index.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_context), uint8_t, ctypes.c_uint16]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_pd *ibv_alloc_pd(struct ibv_context *context)
|
||||
try: (ibv_alloc_pd:=dll.ibv_alloc_pd).restype, ibv_alloc_pd.argtypes = ctypes.POINTER(struct_ibv_pd), [ctypes.POINTER(struct_ibv_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_dealloc_pd(struct ibv_pd *pd)
|
||||
try: (ibv_dealloc_pd:=dll.ibv_dealloc_pd).restype, ibv_dealloc_pd.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_pd)]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_mr *ibv_reg_mr_iova2(struct ibv_pd *pd, void *addr, size_t length, uint64_t iova, unsigned int access)
|
||||
try: (ibv_reg_mr_iova2:=dll.ibv_reg_mr_iova2).restype, ibv_reg_mr_iova2.argtypes = ctypes.POINTER(struct_ibv_mr), [ctypes.POINTER(struct_ibv_pd), ctypes.c_void_p, size_t, uint64_t, ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_mr *ibv_reg_mr(struct ibv_pd *pd, void *addr, size_t length, int access)
|
||||
try: (ibv_reg_mr:=dll.ibv_reg_mr).restype, ibv_reg_mr.argtypes = ctypes.POINTER(struct_ibv_mr), [ctypes.POINTER(struct_ibv_pd), ctypes.c_void_p, size_t, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_mr *ibv_reg_mr_iova(struct ibv_pd *pd, void *addr, size_t length, uint64_t iova, int access)
|
||||
try: (ibv_reg_mr_iova:=dll.ibv_reg_mr_iova).restype, ibv_reg_mr_iova.argtypes = ctypes.POINTER(struct_ibv_mr), [ctypes.POINTER(struct_ibv_pd), ctypes.c_void_p, size_t, uint64_t, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_mr *ibv_reg_dmabuf_mr(struct ibv_pd *pd, uint64_t offset, size_t length, uint64_t iova, int fd, int access)
|
||||
try: (ibv_reg_dmabuf_mr:=dll.ibv_reg_dmabuf_mr).restype, ibv_reg_dmabuf_mr.argtypes = ctypes.POINTER(struct_ibv_mr), [ctypes.POINTER(struct_ibv_pd), uint64_t, size_t, uint64_t, ctypes.c_int32, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -1863,131 +1827,99 @@ IBV_REREG_MR_ERR_DO_FORK_OLD = enum_ibv_rereg_mr_err_code.define('IBV_REREG_MR_E
|
||||
IBV_REREG_MR_ERR_CMD = enum_ibv_rereg_mr_err_code.define('IBV_REREG_MR_ERR_CMD', -4)
|
||||
IBV_REREG_MR_ERR_CMD_AND_DO_FORK_NEW = enum_ibv_rereg_mr_err_code.define('IBV_REREG_MR_ERR_CMD_AND_DO_FORK_NEW', -5)
|
||||
|
||||
# int ibv_rereg_mr(struct ibv_mr *mr, int flags, struct ibv_pd *pd, void *addr, size_t length, int access)
|
||||
try: (ibv_rereg_mr:=dll.ibv_rereg_mr).restype, ibv_rereg_mr.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_mr), ctypes.c_int32, ctypes.POINTER(struct_ibv_pd), ctypes.c_void_p, size_t, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_dereg_mr(struct ibv_mr *mr)
|
||||
try: (ibv_dereg_mr:=dll.ibv_dereg_mr).restype, ibv_dereg_mr.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_mr)]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_comp_channel *ibv_create_comp_channel(struct ibv_context *context)
|
||||
try: (ibv_create_comp_channel:=dll.ibv_create_comp_channel).restype, ibv_create_comp_channel.argtypes = ctypes.POINTER(struct_ibv_comp_channel), [ctypes.POINTER(struct_ibv_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_destroy_comp_channel(struct ibv_comp_channel *channel)
|
||||
try: (ibv_destroy_comp_channel:=dll.ibv_destroy_comp_channel).restype, ibv_destroy_comp_channel.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_comp_channel)]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_cq *ibv_create_cq(struct ibv_context *context, int cqe, void *cq_context, struct ibv_comp_channel *channel, int comp_vector)
|
||||
try: (ibv_create_cq:=dll.ibv_create_cq).restype, ibv_create_cq.argtypes = ctypes.POINTER(struct_ibv_cq), [ctypes.POINTER(struct_ibv_context), ctypes.c_int32, ctypes.c_void_p, ctypes.POINTER(struct_ibv_comp_channel), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_resize_cq(struct ibv_cq *cq, int cqe)
|
||||
try: (ibv_resize_cq:=dll.ibv_resize_cq).restype, ibv_resize_cq.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_cq), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_destroy_cq(struct ibv_cq *cq)
|
||||
try: (ibv_destroy_cq:=dll.ibv_destroy_cq).restype, ibv_destroy_cq.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_cq)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_get_cq_event(struct ibv_comp_channel *channel, struct ibv_cq **cq, void **cq_context)
|
||||
try: (ibv_get_cq_event:=dll.ibv_get_cq_event).restype, ibv_get_cq_event.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_comp_channel), ctypes.POINTER(ctypes.POINTER(struct_ibv_cq)), ctypes.POINTER(ctypes.c_void_p)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents)
|
||||
try: (ibv_ack_cq_events:=dll.ibv_ack_cq_events).restype, ibv_ack_cq_events.argtypes = None, [ctypes.POINTER(struct_ibv_cq), ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_srq *ibv_create_srq(struct ibv_pd *pd, struct ibv_srq_init_attr *srq_init_attr)
|
||||
try: (ibv_create_srq:=dll.ibv_create_srq).restype, ibv_create_srq.argtypes = ctypes.POINTER(struct_ibv_srq), [ctypes.POINTER(struct_ibv_pd), ctypes.POINTER(struct_ibv_srq_init_attr)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_modify_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr, int srq_attr_mask)
|
||||
try: (ibv_modify_srq:=dll.ibv_modify_srq).restype, ibv_modify_srq.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_srq), ctypes.POINTER(struct_ibv_srq_attr), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr)
|
||||
try: (ibv_query_srq:=dll.ibv_query_srq).restype, ibv_query_srq.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_srq), ctypes.POINTER(struct_ibv_srq_attr)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_destroy_srq(struct ibv_srq *srq)
|
||||
try: (ibv_destroy_srq:=dll.ibv_destroy_srq).restype, ibv_destroy_srq.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_srq)]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_qp *ibv_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr)
|
||||
try: (ibv_create_qp:=dll.ibv_create_qp).restype, ibv_create_qp.argtypes = ctypes.POINTER(struct_ibv_qp), [ctypes.POINTER(struct_ibv_pd), ctypes.POINTER(struct_ibv_qp_init_attr)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask)
|
||||
try: (ibv_modify_qp:=dll.ibv_modify_qp).restype, ibv_modify_qp.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_qp), ctypes.POINTER(struct_ibv_qp_attr), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_query_qp_data_in_order(struct ibv_qp *qp, enum ibv_wr_opcode op, uint32_t flags)
|
||||
try: (ibv_query_qp_data_in_order:=dll.ibv_query_qp_data_in_order).restype, ibv_query_qp_data_in_order.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_qp), enum_ibv_wr_opcode, uint32_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask, struct ibv_qp_init_attr *init_attr)
|
||||
try: (ibv_query_qp:=dll.ibv_query_qp).restype, ibv_query_qp.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_qp), ctypes.POINTER(struct_ibv_qp_attr), ctypes.c_int32, ctypes.POINTER(struct_ibv_qp_init_attr)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_destroy_qp(struct ibv_qp *qp)
|
||||
try: (ibv_destroy_qp:=dll.ibv_destroy_qp).restype, ibv_destroy_qp.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_qp)]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_ah *ibv_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr)
|
||||
try: (ibv_create_ah:=dll.ibv_create_ah).restype, ibv_create_ah.argtypes = ctypes.POINTER(struct_ibv_ah), [ctypes.POINTER(struct_ibv_pd), ctypes.POINTER(struct_ibv_ah_attr)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_init_ah_from_wc(struct ibv_context *context, uint8_t port_num, struct ibv_wc *wc, struct ibv_grh *grh, struct ibv_ah_attr *ah_attr)
|
||||
try: (ibv_init_ah_from_wc:=dll.ibv_init_ah_from_wc).restype, ibv_init_ah_from_wc.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_context), uint8_t, ctypes.POINTER(struct_ibv_wc), ctypes.POINTER(struct_ibv_grh), ctypes.POINTER(struct_ibv_ah_attr)]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct ibv_ah *ibv_create_ah_from_wc(struct ibv_pd *pd, struct ibv_wc *wc, struct ibv_grh *grh, uint8_t port_num)
|
||||
try: (ibv_create_ah_from_wc:=dll.ibv_create_ah_from_wc).restype, ibv_create_ah_from_wc.argtypes = ctypes.POINTER(struct_ibv_ah), [ctypes.POINTER(struct_ibv_pd), ctypes.POINTER(struct_ibv_wc), ctypes.POINTER(struct_ibv_grh), uint8_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_destroy_ah(struct ibv_ah *ah)
|
||||
try: (ibv_destroy_ah:=dll.ibv_destroy_ah).restype, ibv_destroy_ah.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_ah)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_attach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid)
|
||||
try: (ibv_attach_mcast:=dll.ibv_attach_mcast).restype, ibv_attach_mcast.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_qp), ctypes.POINTER(union_ibv_gid), uint16_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_detach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid)
|
||||
try: (ibv_detach_mcast:=dll.ibv_detach_mcast).restype, ibv_detach_mcast.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_qp), ctypes.POINTER(union_ibv_gid), uint16_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_fork_init(void)
|
||||
try: (ibv_fork_init:=dll.ibv_fork_init).restype, ibv_fork_init.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# enum ibv_fork_status ibv_is_fork_initialized(void)
|
||||
try: (ibv_is_fork_initialized:=dll.ibv_is_fork_initialized).restype, ibv_is_fork_initialized.argtypes = enum_ibv_fork_status, []
|
||||
except AttributeError: pass
|
||||
|
||||
# const char *ibv_node_type_str(enum ibv_node_type node_type)
|
||||
try: (ibv_node_type_str:=dll.ibv_node_type_str).restype, ibv_node_type_str.argtypes = ctypes.POINTER(ctypes.c_char), [enum_ibv_node_type]
|
||||
except AttributeError: pass
|
||||
|
||||
# const char *ibv_port_state_str(enum ibv_port_state port_state)
|
||||
try: (ibv_port_state_str:=dll.ibv_port_state_str).restype, ibv_port_state_str.argtypes = ctypes.POINTER(ctypes.c_char), [enum_ibv_port_state]
|
||||
except AttributeError: pass
|
||||
|
||||
# const char *ibv_event_type_str(enum ibv_event_type event)
|
||||
try: (ibv_event_type_str:=dll.ibv_event_type_str).restype, ibv_event_type_str.argtypes = ctypes.POINTER(ctypes.c_char), [enum_ibv_event_type]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_resolve_eth_l2_from_gid(struct ibv_context *context, struct ibv_ah_attr *attr, uint8_t eth_mac[6], uint16_t *vid)
|
||||
try: (ibv_resolve_eth_l2_from_gid:=dll.ibv_resolve_eth_l2_from_gid).restype, ibv_resolve_eth_l2_from_gid.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_context), ctypes.POINTER(struct_ibv_ah_attr), (uint8_t * 6), ctypes.POINTER(uint16_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_set_ece(struct ibv_qp *qp, struct ibv_ece *ece)
|
||||
try: (ibv_set_ece:=dll.ibv_set_ece).restype, ibv_set_ece.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_qp), ctypes.POINTER(struct_ibv_ece)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int ibv_query_ece(struct ibv_qp *qp, struct ibv_ece *ece)
|
||||
try: (ibv_query_ece:=dll.ibv_query_ece).restype, ibv_query_ece.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_ibv_qp), ctypes.POINTER(struct_ibv_ece)]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
@@ -13,115 +13,87 @@ off_t = ctypes.c_int64
|
||||
mode_t = ctypes.c_uint32
|
||||
size_t = ctypes.c_uint64
|
||||
__off_t = ctypes.c_int64
|
||||
# extern void *mmap(void *__addr, size_t __len, int __prot, int __flags, int __fd, __off_t __offset) __attribute__((nothrow))
|
||||
try: (mmap:=dll.mmap).restype, mmap.argtypes = ctypes.c_void_p, [ctypes.c_void_p, size_t, ctypes.c_int32, ctypes.c_int32, ctypes.c_int32, ctypes.c_int64]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int munmap(void *__addr, size_t __len) __attribute__((nothrow))
|
||||
try: (munmap:=dll.munmap).restype, munmap.argtypes = ctypes.c_int32, [ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int mprotect(void *__addr, size_t __len, int __prot) __attribute__((nothrow))
|
||||
try: (mprotect:=dll.mprotect).restype, mprotect.argtypes = ctypes.c_int32, [ctypes.c_void_p, size_t, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int msync(void *__addr, size_t __len, int __flags)
|
||||
try: (msync:=dll.msync).restype, msync.argtypes = ctypes.c_int32, [ctypes.c_void_p, size_t, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int madvise(void *__addr, size_t __len, int __advice) __attribute__((nothrow))
|
||||
try: (madvise:=dll.madvise).restype, madvise.argtypes = ctypes.c_int32, [ctypes.c_void_p, size_t, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int posix_madvise(void *__addr, size_t __len, int __advice) __attribute__((nothrow))
|
||||
try: (posix_madvise:=dll.posix_madvise).restype, posix_madvise.argtypes = ctypes.c_int32, [ctypes.c_void_p, size_t, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int mlock(const void *__addr, size_t __len) __attribute__((nothrow))
|
||||
try: (mlock:=dll.mlock).restype, mlock.argtypes = ctypes.c_int32, [ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int munlock(const void *__addr, size_t __len) __attribute__((nothrow))
|
||||
try: (munlock:=dll.munlock).restype, munlock.argtypes = ctypes.c_int32, [ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int mlockall(int __flags) __attribute__((nothrow))
|
||||
try: (mlockall:=dll.mlockall).restype, mlockall.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int munlockall(void) __attribute__((nothrow))
|
||||
try: (munlockall:=dll.munlockall).restype, munlockall.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int mincore(void *__start, size_t __len, unsigned char *__vec) __attribute__((nothrow))
|
||||
try: (mincore:=dll.mincore).restype, mincore.argtypes = ctypes.c_int32, [ctypes.c_void_p, size_t, ctypes.POINTER(ctypes.c_ubyte)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int shm_open(const char *__name, int __oflag, mode_t __mode)
|
||||
try: (shm_open:=dll.shm_open).restype, shm_open.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.c_int32, mode_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int shm_unlink(const char *__name)
|
||||
try: (shm_unlink:=dll.shm_unlink).restype, shm_unlink.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *memcpy(void *restrict __dest, const void *restrict __src, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (memcpy:=dll.memcpy).restype, memcpy.argtypes = ctypes.c_void_p, [ctypes.c_void_p, ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *memmove(void *__dest, const void *__src, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (memmove:=dll.memmove).restype, memmove.argtypes = ctypes.c_void_p, [ctypes.c_void_p, ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *memccpy(void *restrict __dest, const void *restrict __src, int __c, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (memccpy:=dll.memccpy).restype, memccpy.argtypes = ctypes.c_void_p, [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int32, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *memset(void *__s, int __c, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (memset:=dll.memset).restype, memset.argtypes = ctypes.c_void_p, [ctypes.c_void_p, ctypes.c_int32, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int memcmp(const void *__s1, const void *__s2, size_t __n) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 2)))
|
||||
try: (memcmp:=dll.memcmp).restype, memcmp.argtypes = ctypes.c_int32, [ctypes.c_void_p, ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int __memcmpeq(const void *__s1, const void *__s2, size_t __n) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 2)))
|
||||
try: (__memcmpeq:=dll.__memcmpeq).restype, __memcmpeq.argtypes = ctypes.c_int32, [ctypes.c_void_p, ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *memchr(const void *__s, int __c, size_t __n) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1)))
|
||||
try: (memchr:=dll.memchr).restype, memchr.argtypes = ctypes.c_void_p, [ctypes.c_void_p, ctypes.c_int32, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strcpy(char *restrict __dest, const char *restrict __src) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (strcpy:=dll.strcpy).restype, strcpy.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strncpy(char *restrict __dest, const char *restrict __src, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (strncpy:=dll.strncpy).restype, strncpy.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strcat(char *restrict __dest, const char *restrict __src) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (strcat:=dll.strcat).restype, strcat.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strncat(char *restrict __dest, const char *restrict __src, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (strncat:=dll.strncat).restype, strncat.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int strcmp(const char *__s1, const char *__s2) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 2)))
|
||||
try: (strcmp:=dll.strcmp).restype, strcmp.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int strncmp(const char *__s1, const char *__s2, size_t __n) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 2)))
|
||||
try: (strncmp:=dll.strncmp).restype, strncmp.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int strcoll(const char *__s1, const char *__s2) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 2)))
|
||||
try: (strcoll:=dll.strcoll).restype, strcoll.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern unsigned long strxfrm(char *restrict __dest, const char *restrict __src, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(2)))
|
||||
try: (strxfrm:=dll.strxfrm).restype, strxfrm.argtypes = ctypes.c_uint64, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -135,131 +107,99 @@ struct___locale_struct._fields_ = [
|
||||
('__names', (ctypes.POINTER(ctypes.c_char) * 13)),
|
||||
]
|
||||
locale_t = ctypes.POINTER(struct___locale_struct)
|
||||
# extern int strcoll_l(const char *__s1, const char *__s2, locale_t __l) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 2, 3)))
|
||||
try: (strcoll_l:=dll.strcoll_l).restype, strcoll_l.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), locale_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern size_t strxfrm_l(char *__dest, const char *__src, size_t __n, locale_t __l) __attribute__((nothrow)) __attribute__((nonnull(2, 4)))
|
||||
try: (strxfrm_l:=dll.strxfrm_l).restype, strxfrm_l.argtypes = size_t, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), size_t, locale_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strdup(const char *__s) __attribute__((nothrow)) __attribute__((malloc)) __attribute__((nonnull(1)))
|
||||
try: (strdup:=dll.strdup).restype, strdup.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strndup(const char *__string, size_t __n) __attribute__((nothrow)) __attribute__((malloc)) __attribute__((nonnull(1)))
|
||||
try: (strndup:=dll.strndup).restype, strndup.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strchr(const char *__s, int __c) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1)))
|
||||
try: (strchr:=dll.strchr).restype, strchr.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strrchr(const char *__s, int __c) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1)))
|
||||
try: (strrchr:=dll.strrchr).restype, strrchr.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strchrnul(const char *__s, int __c) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1)))
|
||||
try: (strchrnul:=dll.strchrnul).restype, strchrnul.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern unsigned long strcspn(const char *__s, const char *__reject) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 2)))
|
||||
try: (strcspn:=dll.strcspn).restype, strcspn.argtypes = ctypes.c_uint64, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern unsigned long strspn(const char *__s, const char *__accept) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 2)))
|
||||
try: (strspn:=dll.strspn).restype, strspn.argtypes = ctypes.c_uint64, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strpbrk(const char *__s, const char *__accept) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 2)))
|
||||
try: (strpbrk:=dll.strpbrk).restype, strpbrk.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strstr(const char *__haystack, const char *__needle) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 2)))
|
||||
try: (strstr:=dll.strstr).restype, strstr.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strtok(char *restrict __s, const char *restrict __delim) __attribute__((nothrow)) __attribute__((nonnull(2)))
|
||||
try: (strtok:=dll.strtok).restype, strtok.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *__strtok_r(char *restrict __s, const char *restrict __delim, char **restrict __save_ptr) __attribute__((nothrow)) __attribute__((nonnull(2, 3)))
|
||||
try: (__strtok_r:=dll.__strtok_r).restype, __strtok_r.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.POINTER(ctypes.c_char))]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strtok_r(char *restrict __s, const char *restrict __delim, char **restrict __save_ptr) __attribute__((nothrow)) __attribute__((nonnull(2, 3)))
|
||||
try: (strtok_r:=dll.strtok_r).restype, strtok_r.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.POINTER(ctypes.c_char))]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strcasestr(const char *__haystack, const char *__needle) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 2)))
|
||||
try: (strcasestr:=dll.strcasestr).restype, strcasestr.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *memmem(const void *__haystack, size_t __haystacklen, const void *__needle, size_t __needlelen) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1, 3)))
|
||||
try: (memmem:=dll.memmem).restype, memmem.argtypes = ctypes.c_void_p, [ctypes.c_void_p, size_t, ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *__mempcpy(void *restrict __dest, const void *restrict __src, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (__mempcpy:=dll.__mempcpy).restype, __mempcpy.argtypes = ctypes.c_void_p, [ctypes.c_void_p, ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *mempcpy(void *restrict __dest, const void *restrict __src, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (mempcpy:=dll.mempcpy).restype, mempcpy.argtypes = ctypes.c_void_p, [ctypes.c_void_p, ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern unsigned long strlen(const char *__s) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1)))
|
||||
try: (strlen:=dll.strlen).restype, strlen.argtypes = ctypes.c_uint64, [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern size_t strnlen(const char *__string, size_t __maxlen) __attribute__((nothrow)) __attribute__((pure)) __attribute__((nonnull(1)))
|
||||
try: (strnlen:=dll.strnlen).restype, strnlen.argtypes = size_t, [ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strerror(int __errnum) __attribute__((nothrow))
|
||||
try: (strerror:=dll.strerror).restype, strerror.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int strerror_r(int __errnum, char *__buf, size_t __buflen) asm("__xpg_strerror_r") __attribute__((nothrow)) __attribute__((nonnull(2)))
|
||||
try: (strerror_r:=dll.strerror_r).restype, strerror_r.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strerror_l(int __errnum, locale_t __l) __attribute__((nothrow))
|
||||
try: (strerror_l:=dll.strerror_l).restype, strerror_l.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.c_int32, locale_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void explicit_bzero(void *__s, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (explicit_bzero:=dll.explicit_bzero).restype, explicit_bzero.argtypes = None, [ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strsep(char **restrict __stringp, const char *restrict __delim) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (strsep:=dll.strsep).restype, strsep.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.POINTER(ctypes.c_char)), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *strsignal(int __sig) __attribute__((nothrow))
|
||||
try: (strsignal:=dll.strsignal).restype, strsignal.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *__stpcpy(char *restrict __dest, const char *restrict __src) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (__stpcpy:=dll.__stpcpy).restype, __stpcpy.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *stpcpy(char *restrict __dest, const char *restrict __src) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (stpcpy:=dll.stpcpy).restype, stpcpy.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *__stpncpy(char *restrict __dest, const char *restrict __src, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (__stpncpy:=dll.__stpncpy).restype, __stpncpy.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *stpncpy(char *restrict __dest, const char *restrict __src, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (stpncpy:=dll.stpncpy).restype, stpncpy.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern size_t strlcpy(char *restrict __dest, const char *restrict __src, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (strlcpy:=dll.strlcpy).restype, strlcpy.argtypes = size_t, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern size_t strlcat(char *restrict __dest, const char *restrict __src, size_t __n) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (strlcat:=dll.strlcat).restype, strlcat.argtypes = size_t, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -640,437 +580,330 @@ useconds_t = ctypes.c_uint32
|
||||
pid_t = ctypes.c_int32
|
||||
intptr_t = ctypes.c_int64
|
||||
socklen_t = ctypes.c_uint32
|
||||
# extern int access(const char *__name, int __type) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (access:=dll.access).restype, access.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int faccessat(int __fd, const char *__file, int __type, int __flag) __attribute__((nothrow)) __attribute__((nonnull(2)))
|
||||
try: (faccessat:=dll.faccessat).restype, faccessat.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.POINTER(ctypes.c_char), ctypes.c_int32, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __off_t lseek(int __fd, __off_t __offset, int __whence) __attribute__((nothrow))
|
||||
try: (lseek:=dll.lseek).restype, lseek.argtypes = ctypes.c_int64, [ctypes.c_int32, ctypes.c_int64, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int close(int __fd)
|
||||
try: (close:=dll.close).restype, close.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void closefrom(int __lowfd) __attribute__((nothrow))
|
||||
try: (closefrom:=dll.closefrom).restype, closefrom.argtypes = None, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern ssize_t read(int __fd, void *__buf, size_t __nbytes)
|
||||
try: (read:=dll.read).restype, read.argtypes = ssize_t, [ctypes.c_int32, ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern ssize_t write(int __fd, const void *__buf, size_t __n)
|
||||
try: (write:=dll.write).restype, write.argtypes = ssize_t, [ctypes.c_int32, ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern ssize_t pread(int __fd, void *__buf, size_t __nbytes, __off_t __offset)
|
||||
try: (pread:=dll.pread).restype, pread.argtypes = ssize_t, [ctypes.c_int32, ctypes.c_void_p, size_t, ctypes.c_int64]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern ssize_t pwrite(int __fd, const void *__buf, size_t __n, __off_t __offset)
|
||||
try: (pwrite:=dll.pwrite).restype, pwrite.argtypes = ssize_t, [ctypes.c_int32, ctypes.c_void_p, size_t, ctypes.c_int64]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int pipe(int __pipedes[2]) __attribute__((nothrow))
|
||||
try: (pipe:=dll.pipe).restype, pipe.argtypes = ctypes.c_int32, [(ctypes.c_int32 * 2)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern unsigned int alarm(unsigned int __seconds) __attribute__((nothrow))
|
||||
try: (alarm:=dll.alarm).restype, alarm.argtypes = ctypes.c_uint32, [ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern unsigned int sleep(unsigned int __seconds)
|
||||
try: (sleep:=dll.sleep).restype, sleep.argtypes = ctypes.c_uint32, [ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
__useconds_t = ctypes.c_uint32
|
||||
# extern __useconds_t ualarm(__useconds_t __value, __useconds_t __interval) __attribute__((nothrow))
|
||||
try: (ualarm:=dll.ualarm).restype, ualarm.argtypes = ctypes.c_uint32, [ctypes.c_uint32, ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int usleep(__useconds_t __useconds)
|
||||
try: (usleep:=dll.usleep).restype, usleep.argtypes = ctypes.c_int32, [ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int pause(void)
|
||||
try: (pause:=dll.pause).restype, pause.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
__uid_t = ctypes.c_uint32
|
||||
__gid_t = ctypes.c_uint32
|
||||
# extern int chown(const char *__file, __uid_t __owner, __gid_t __group) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (chown:=dll.chown).restype, chown.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.c_uint32, ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int fchown(int __fd, __uid_t __owner, __gid_t __group) __attribute__((nothrow))
|
||||
try: (fchown:=dll.fchown).restype, fchown.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.c_uint32, ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int lchown(const char *__file, __uid_t __owner, __gid_t __group) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (lchown:=dll.lchown).restype, lchown.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.c_uint32, ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int fchownat(int __fd, const char *__file, __uid_t __owner, __gid_t __group, int __flag) __attribute__((nothrow)) __attribute__((nonnull(2)))
|
||||
try: (fchownat:=dll.fchownat).restype, fchownat.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.POINTER(ctypes.c_char), ctypes.c_uint32, ctypes.c_uint32, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int chdir(const char *__path) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (chdir:=dll.chdir).restype, chdir.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int fchdir(int __fd) __attribute__((nothrow))
|
||||
try: (fchdir:=dll.fchdir).restype, fchdir.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *getcwd(char *__buf, size_t __size) __attribute__((nothrow))
|
||||
try: (getcwd:=dll.getcwd).restype, getcwd.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *getwd(char *__buf) __attribute__((nothrow)) __attribute__((nonnull(1))) __attribute__((deprecated("")))
|
||||
try: (getwd:=dll.getwd).restype, getwd.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int dup(int __fd) __attribute__((nothrow))
|
||||
try: (dup:=dll.dup).restype, dup.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int dup2(int __fd, int __fd2) __attribute__((nothrow))
|
||||
try: (dup2:=dll.dup2).restype, dup2.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
try: __environ = ctypes.POINTER(ctypes.POINTER(ctypes.c_char)).in_dll(dll, '__environ')
|
||||
except (ValueError,AttributeError): pass
|
||||
# extern int execve(const char *__path, char *const __argv[], char *const __envp[]) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (execve:=dll.execve).restype, execve.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), (ctypes.POINTER(ctypes.c_char) * 0), (ctypes.POINTER(ctypes.c_char) * 0)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int fexecve(int __fd, char *const __argv[], char *const __envp[]) __attribute__((nothrow)) __attribute__((nonnull(2)))
|
||||
try: (fexecve:=dll.fexecve).restype, fexecve.argtypes = ctypes.c_int32, [ctypes.c_int32, (ctypes.POINTER(ctypes.c_char) * 0), (ctypes.POINTER(ctypes.c_char) * 0)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int execv(const char *__path, char *const __argv[]) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (execv:=dll.execv).restype, execv.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), (ctypes.POINTER(ctypes.c_char) * 0)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int execle(const char *__path, const char *__arg, ...) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (execle:=dll.execle).restype, execle.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int execl(const char *__path, const char *__arg, ...) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (execl:=dll.execl).restype, execl.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int execvp(const char *__file, char *const __argv[]) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (execvp:=dll.execvp).restype, execvp.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), (ctypes.POINTER(ctypes.c_char) * 0)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int execlp(const char *__file, const char *__arg, ...) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (execlp:=dll.execlp).restype, execlp.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int nice(int __inc) __attribute__((nothrow))
|
||||
try: (nice:=dll.nice).restype, nice.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void _exit(int __status)
|
||||
try: (_exit:=dll._exit).restype, _exit.argtypes = None, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern long pathconf(const char *__path, int __name) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (pathconf:=dll.pathconf).restype, pathconf.argtypes = ctypes.c_int64, [ctypes.POINTER(ctypes.c_char), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern long fpathconf(int __fd, int __name) __attribute__((nothrow))
|
||||
try: (fpathconf:=dll.fpathconf).restype, fpathconf.argtypes = ctypes.c_int64, [ctypes.c_int32, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern long sysconf(int __name) __attribute__((nothrow))
|
||||
try: (sysconf:=dll.sysconf).restype, sysconf.argtypes = ctypes.c_int64, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern size_t confstr(int __name, char *__buf, size_t __len) __attribute__((nothrow))
|
||||
try: (confstr:=dll.confstr).restype, confstr.argtypes = size_t, [ctypes.c_int32, ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
__pid_t = ctypes.c_int32
|
||||
# extern __pid_t getpid(void) __attribute__((nothrow))
|
||||
try: (getpid:=dll.getpid).restype, getpid.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __pid_t getppid(void) __attribute__((nothrow))
|
||||
try: (getppid:=dll.getppid).restype, getppid.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __pid_t getpgrp(void) __attribute__((nothrow))
|
||||
try: (getpgrp:=dll.getpgrp).restype, getpgrp.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __pid_t __getpgid(__pid_t __pid) __attribute__((nothrow))
|
||||
try: (__getpgid:=dll.__getpgid).restype, __getpgid.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __pid_t getpgid(__pid_t __pid) __attribute__((nothrow))
|
||||
try: (getpgid:=dll.getpgid).restype, getpgid.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int setpgid(__pid_t __pid, __pid_t __pgid) __attribute__((nothrow))
|
||||
try: (setpgid:=dll.setpgid).restype, setpgid.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int setpgrp(void) __attribute__((nothrow))
|
||||
try: (setpgrp:=dll.setpgrp).restype, setpgrp.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __pid_t setsid(void) __attribute__((nothrow))
|
||||
try: (setsid:=dll.setsid).restype, setsid.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __pid_t getsid(__pid_t __pid) __attribute__((nothrow))
|
||||
try: (getsid:=dll.getsid).restype, getsid.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __uid_t getuid(void) __attribute__((nothrow))
|
||||
try: (getuid:=dll.getuid).restype, getuid.argtypes = ctypes.c_uint32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __uid_t geteuid(void) __attribute__((nothrow))
|
||||
try: (geteuid:=dll.geteuid).restype, geteuid.argtypes = ctypes.c_uint32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __gid_t getgid(void) __attribute__((nothrow))
|
||||
try: (getgid:=dll.getgid).restype, getgid.argtypes = ctypes.c_uint32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __gid_t getegid(void) __attribute__((nothrow))
|
||||
try: (getegid:=dll.getegid).restype, getegid.argtypes = ctypes.c_uint32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int getgroups(int __size, __gid_t __list[]) __attribute__((nothrow))
|
||||
try: (getgroups:=dll.getgroups).restype, getgroups.argtypes = ctypes.c_int32, [ctypes.c_int32, (ctypes.c_uint32 * 0)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int setuid(__uid_t __uid) __attribute__((nothrow))
|
||||
try: (setuid:=dll.setuid).restype, setuid.argtypes = ctypes.c_int32, [ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int setreuid(__uid_t __ruid, __uid_t __euid) __attribute__((nothrow))
|
||||
try: (setreuid:=dll.setreuid).restype, setreuid.argtypes = ctypes.c_int32, [ctypes.c_uint32, ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int seteuid(__uid_t __uid) __attribute__((nothrow))
|
||||
try: (seteuid:=dll.seteuid).restype, seteuid.argtypes = ctypes.c_int32, [ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int setgid(__gid_t __gid) __attribute__((nothrow))
|
||||
try: (setgid:=dll.setgid).restype, setgid.argtypes = ctypes.c_int32, [ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int setregid(__gid_t __rgid, __gid_t __egid) __attribute__((nothrow))
|
||||
try: (setregid:=dll.setregid).restype, setregid.argtypes = ctypes.c_int32, [ctypes.c_uint32, ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int setegid(__gid_t __gid) __attribute__((nothrow))
|
||||
try: (setegid:=dll.setegid).restype, setegid.argtypes = ctypes.c_int32, [ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __pid_t fork(void) __attribute__((nothrow))
|
||||
try: (fork:=dll.fork).restype, fork.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int vfork(void) __attribute__((nothrow))
|
||||
try: (vfork:=dll.vfork).restype, vfork.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *ttyname(int __fd) __attribute__((nothrow))
|
||||
try: (ttyname:=dll.ttyname).restype, ttyname.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int ttyname_r(int __fd, char *__buf, size_t __buflen) __attribute__((nothrow)) __attribute__((nonnull(2)))
|
||||
try: (ttyname_r:=dll.ttyname_r).restype, ttyname_r.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int isatty(int __fd) __attribute__((nothrow))
|
||||
try: (isatty:=dll.isatty).restype, isatty.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int ttyslot(void) __attribute__((nothrow))
|
||||
try: (ttyslot:=dll.ttyslot).restype, ttyslot.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int link(const char *__from, const char *__to) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (link:=dll.link).restype, link.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int linkat(int __fromfd, const char *__from, int __tofd, const char *__to, int __flags) __attribute__((nothrow)) __attribute__((nonnull(2, 4)))
|
||||
try: (linkat:=dll.linkat).restype, linkat.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.POINTER(ctypes.c_char), ctypes.c_int32, ctypes.POINTER(ctypes.c_char), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int symlink(const char *__from, const char *__to) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (symlink:=dll.symlink).restype, symlink.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern ssize_t readlink(const char *restrict __path, char *restrict __buf, size_t __len) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (readlink:=dll.readlink).restype, readlink.argtypes = ssize_t, [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int symlinkat(const char *__from, int __tofd, const char *__to) __attribute__((nothrow)) __attribute__((nonnull(1, 3)))
|
||||
try: (symlinkat:=dll.symlinkat).restype, symlinkat.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.c_int32, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern ssize_t readlinkat(int __fd, const char *restrict __path, char *restrict __buf, size_t __len) __attribute__((nothrow)) __attribute__((nonnull(2, 3)))
|
||||
try: (readlinkat:=dll.readlinkat).restype, readlinkat.argtypes = ssize_t, [ctypes.c_int32, ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int unlink(const char *__name) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (unlink:=dll.unlink).restype, unlink.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int unlinkat(int __fd, const char *__name, int __flag) __attribute__((nothrow)) __attribute__((nonnull(2)))
|
||||
try: (unlinkat:=dll.unlinkat).restype, unlinkat.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.POINTER(ctypes.c_char), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int rmdir(const char *__path) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (rmdir:=dll.rmdir).restype, rmdir.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern __pid_t tcgetpgrp(int __fd) __attribute__((nothrow))
|
||||
try: (tcgetpgrp:=dll.tcgetpgrp).restype, tcgetpgrp.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int tcsetpgrp(int __fd, __pid_t __pgrp_id) __attribute__((nothrow))
|
||||
try: (tcsetpgrp:=dll.tcsetpgrp).restype, tcsetpgrp.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *getlogin(void)
|
||||
try: (getlogin:=dll.getlogin).restype, getlogin.argtypes = ctypes.POINTER(ctypes.c_char), []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int getlogin_r(char *__name, size_t __name_len) __attribute__((nonnull(1)))
|
||||
try: (getlogin_r:=dll.getlogin_r).restype, getlogin_r.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int setlogin(const char *__name) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (setlogin:=dll.setlogin).restype, setlogin.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int gethostname(char *__name, size_t __len) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (gethostname:=dll.gethostname).restype, gethostname.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int sethostname(const char *__name, size_t __len) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (sethostname:=dll.sethostname).restype, sethostname.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int sethostid(long __id) __attribute__((nothrow))
|
||||
try: (sethostid:=dll.sethostid).restype, sethostid.argtypes = ctypes.c_int32, [ctypes.c_int64]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int getdomainname(char *__name, size_t __len) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (getdomainname:=dll.getdomainname).restype, getdomainname.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int setdomainname(const char *__name, size_t __len) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (setdomainname:=dll.setdomainname).restype, setdomainname.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int vhangup(void) __attribute__((nothrow))
|
||||
try: (vhangup:=dll.vhangup).restype, vhangup.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int revoke(const char *__file) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (revoke:=dll.revoke).restype, revoke.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int profil(unsigned short *__sample_buffer, size_t __size, size_t __offset, unsigned int __scale) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (profil:=dll.profil).restype, profil.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_uint16), size_t, size_t, ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int acct(const char *__name) __attribute__((nothrow))
|
||||
try: (acct:=dll.acct).restype, acct.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *getusershell(void) __attribute__((nothrow))
|
||||
try: (getusershell:=dll.getusershell).restype, getusershell.argtypes = ctypes.POINTER(ctypes.c_char), []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void endusershell(void) __attribute__((nothrow))
|
||||
try: (endusershell:=dll.endusershell).restype, endusershell.argtypes = None, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void setusershell(void) __attribute__((nothrow))
|
||||
try: (setusershell:=dll.setusershell).restype, setusershell.argtypes = None, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int daemon(int __nochdir, int __noclose) __attribute__((nothrow))
|
||||
try: (daemon:=dll.daemon).restype, daemon.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int chroot(const char *__path) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (chroot:=dll.chroot).restype, chroot.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *getpass(const char *__prompt) __attribute__((nonnull(1)))
|
||||
try: (getpass:=dll.getpass).restype, getpass.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int fsync(int __fd)
|
||||
try: (fsync:=dll.fsync).restype, fsync.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern long gethostid(void)
|
||||
try: (gethostid:=dll.gethostid).restype, gethostid.argtypes = ctypes.c_int64, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void sync(void) __attribute__((nothrow))
|
||||
try: (sync:=dll.sync).restype, sync.argtypes = None, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int getpagesize(void) __attribute__((nothrow)) __attribute__((const))
|
||||
try: (getpagesize:=dll.getpagesize).restype, getpagesize.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int getdtablesize(void) __attribute__((nothrow))
|
||||
try: (getdtablesize:=dll.getdtablesize).restype, getdtablesize.argtypes = ctypes.c_int32, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int truncate(const char *__file, __off_t __length) __attribute__((nothrow)) __attribute__((nonnull(1)))
|
||||
try: (truncate:=dll.truncate).restype, truncate.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char), ctypes.c_int64]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int ftruncate(int __fd, __off_t __length) __attribute__((nothrow))
|
||||
try: (ftruncate:=dll.ftruncate).restype, ftruncate.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.c_int64]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int brk(void *__addr) __attribute__((nothrow))
|
||||
try: (brk:=dll.brk).restype, brk.argtypes = ctypes.c_int32, [ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *sbrk(intptr_t __delta) __attribute__((nothrow))
|
||||
try: (sbrk:=dll.sbrk).restype, sbrk.argtypes = ctypes.c_void_p, [intptr_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern long syscall(long __sysno, ...) __attribute__((nothrow))
|
||||
try: (syscall:=dll.syscall).restype, syscall.argtypes = ctypes.c_int64, [ctypes.c_int64]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int lockf(int __fd, int __cmd, __off_t __len)
|
||||
try: (lockf:=dll.lockf).restype, lockf.argtypes = ctypes.c_int32, [ctypes.c_int32, ctypes.c_int32, ctypes.c_int64]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern int fdatasync(int __fildes)
|
||||
try: (fdatasync:=dll.fdatasync).restype, fdatasync.argtypes = ctypes.c_int32, [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern char *crypt(const char *__key, const char *__salt) __attribute__((nothrow)) __attribute__((nonnull(1, 2)))
|
||||
try: (crypt:=dll.crypt).restype, crypt.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int getentropy(void *__buffer, size_t __length)
|
||||
try: (getentropy:=dll.getentropy).restype, getentropy.argtypes = ctypes.c_int32, [ctypes.c_void_p, size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -388,334 +388,252 @@ struct_libusb_init_option._fields_ = [
|
||||
('option', enum_libusb_option),
|
||||
('value', struct_libusb_init_option_value),
|
||||
]
|
||||
# int libusb_init(libusb_context **ctx)
|
||||
try: (libusb_init:=dll.libusb_init).restype, libusb_init.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.POINTER(libusb_context))]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_init_context(libusb_context **ctx, const struct libusb_init_option options[], int num_options)
|
||||
try: (libusb_init_context:=dll.libusb_init_context).restype, libusb_init_context.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.POINTER(libusb_context)), (struct_libusb_init_option * 0), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_exit(libusb_context *ctx)
|
||||
try: (libusb_exit:=dll.libusb_exit).restype, libusb_exit.argtypes = None, [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_set_debug(libusb_context *ctx, int level)
|
||||
try: (libusb_set_debug:=dll.libusb_set_debug).restype, libusb_set_debug.argtypes = None, [ctypes.POINTER(libusb_context), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb, int mode)
|
||||
try: (libusb_set_log_cb:=dll.libusb_set_log_cb).restype, libusb_set_log_cb.argtypes = None, [ctypes.POINTER(libusb_context), libusb_log_cb, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# const struct libusb_version *libusb_get_version(void)
|
||||
try: (libusb_get_version:=dll.libusb_get_version).restype, libusb_get_version.argtypes = ctypes.POINTER(struct_libusb_version), []
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_has_capability(uint32_t capability)
|
||||
try: (libusb_has_capability:=dll.libusb_has_capability).restype, libusb_has_capability.argtypes = ctypes.c_int32, [uint32_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# const char *libusb_error_name(int errcode)
|
||||
try: (libusb_error_name:=dll.libusb_error_name).restype, libusb_error_name.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_setlocale(const char *locale)
|
||||
try: (libusb_setlocale:=dll.libusb_setlocale).restype, libusb_setlocale.argtypes = ctypes.c_int32, [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# const char *libusb_strerror(int errcode)
|
||||
try: (libusb_strerror:=dll.libusb_strerror).restype, libusb_strerror.argtypes = ctypes.POINTER(ctypes.c_char), [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
ssize_t = ctypes.c_int64
|
||||
# ssize_t libusb_get_device_list(libusb_context *ctx, libusb_device ***list)
|
||||
try: (libusb_get_device_list:=dll.libusb_get_device_list).restype, libusb_get_device_list.argtypes = ssize_t, [ctypes.POINTER(libusb_context), ctypes.POINTER(ctypes.POINTER(ctypes.POINTER(libusb_device)))]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_free_device_list(libusb_device **list, int unref_devices)
|
||||
try: (libusb_free_device_list:=dll.libusb_free_device_list).restype, libusb_free_device_list.argtypes = None, [ctypes.POINTER(ctypes.POINTER(libusb_device)), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# libusb_device *libusb_ref_device(libusb_device *dev)
|
||||
try: (libusb_ref_device:=dll.libusb_ref_device).restype, libusb_ref_device.argtypes = ctypes.POINTER(libusb_device), [ctypes.POINTER(libusb_device)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_unref_device(libusb_device *dev)
|
||||
try: (libusb_unref_device:=dll.libusb_unref_device).restype, libusb_unref_device.argtypes = None, [ctypes.POINTER(libusb_device)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_configuration(libusb_device_handle *dev, int *config)
|
||||
try: (libusb_get_configuration:=dll.libusb_get_configuration).restype, libusb_get_configuration.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.POINTER(ctypes.c_int32)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_device_descriptor(libusb_device *dev, struct libusb_device_descriptor *desc)
|
||||
try: (libusb_get_device_descriptor:=dll.libusb_get_device_descriptor).restype, libusb_get_device_descriptor.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device), ctypes.POINTER(struct_libusb_device_descriptor)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_active_config_descriptor(libusb_device *dev, struct libusb_config_descriptor **config)
|
||||
try: (libusb_get_active_config_descriptor:=dll.libusb_get_active_config_descriptor).restype, libusb_get_active_config_descriptor.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device), ctypes.POINTER(ctypes.POINTER(struct_libusb_config_descriptor))]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, struct libusb_config_descriptor **config)
|
||||
try: (libusb_get_config_descriptor:=dll.libusb_get_config_descriptor).restype, libusb_get_config_descriptor.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device), uint8_t, ctypes.POINTER(ctypes.POINTER(struct_libusb_config_descriptor))]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_config_descriptor_by_value(libusb_device *dev, uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
|
||||
try: (libusb_get_config_descriptor_by_value:=dll.libusb_get_config_descriptor_by_value).restype, libusb_get_config_descriptor_by_value.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device), uint8_t, ctypes.POINTER(ctypes.POINTER(struct_libusb_config_descriptor))]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_free_config_descriptor(struct libusb_config_descriptor *config)
|
||||
try: (libusb_free_config_descriptor:=dll.libusb_free_config_descriptor).restype, libusb_free_config_descriptor.argtypes = None, [ctypes.POINTER(struct_libusb_config_descriptor)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_ss_endpoint_companion_descriptor(libusb_context *ctx, const struct libusb_endpoint_descriptor *endpoint, struct libusb_ss_endpoint_companion_descriptor **ep_comp)
|
||||
try: (libusb_get_ss_endpoint_companion_descriptor:=dll.libusb_get_ss_endpoint_companion_descriptor).restype, libusb_get_ss_endpoint_companion_descriptor.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(struct_libusb_endpoint_descriptor), ctypes.POINTER(ctypes.POINTER(struct_libusb_ss_endpoint_companion_descriptor))]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_free_ss_endpoint_companion_descriptor(struct libusb_ss_endpoint_companion_descriptor *ep_comp)
|
||||
try: (libusb_free_ss_endpoint_companion_descriptor:=dll.libusb_free_ss_endpoint_companion_descriptor).restype, libusb_free_ss_endpoint_companion_descriptor.argtypes = None, [ctypes.POINTER(struct_libusb_ss_endpoint_companion_descriptor)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_bos_descriptor(libusb_device_handle *dev_handle, struct libusb_bos_descriptor **bos)
|
||||
try: (libusb_get_bos_descriptor:=dll.libusb_get_bos_descriptor).restype, libusb_get_bos_descriptor.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.POINTER(ctypes.POINTER(struct_libusb_bos_descriptor))]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
|
||||
try: (libusb_free_bos_descriptor:=dll.libusb_free_bos_descriptor).restype, libusb_free_bos_descriptor.argtypes = None, [ctypes.POINTER(struct_libusb_bos_descriptor)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_usb_2_0_extension_descriptor(libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)
|
||||
try: (libusb_get_usb_2_0_extension_descriptor:=dll.libusb_get_usb_2_0_extension_descriptor).restype, libusb_get_usb_2_0_extension_descriptor.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(struct_libusb_bos_dev_capability_descriptor), ctypes.POINTER(ctypes.POINTER(struct_libusb_usb_2_0_extension_descriptor))]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_free_usb_2_0_extension_descriptor(struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
|
||||
try: (libusb_free_usb_2_0_extension_descriptor:=dll.libusb_free_usb_2_0_extension_descriptor).restype, libusb_free_usb_2_0_extension_descriptor.argtypes = None, [ctypes.POINTER(struct_libusb_usb_2_0_extension_descriptor)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_ss_usb_device_capability_descriptor(libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap)
|
||||
try: (libusb_get_ss_usb_device_capability_descriptor:=dll.libusb_get_ss_usb_device_capability_descriptor).restype, libusb_get_ss_usb_device_capability_descriptor.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(struct_libusb_bos_dev_capability_descriptor), ctypes.POINTER(ctypes.POINTER(struct_libusb_ss_usb_device_capability_descriptor))]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_free_ss_usb_device_capability_descriptor(struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap)
|
||||
try: (libusb_free_ss_usb_device_capability_descriptor:=dll.libusb_free_ss_usb_device_capability_descriptor).restype, libusb_free_ss_usb_device_capability_descriptor.argtypes = None, [ctypes.POINTER(struct_libusb_ss_usb_device_capability_descriptor)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_container_id_descriptor(libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_container_id_descriptor **container_id)
|
||||
try: (libusb_get_container_id_descriptor:=dll.libusb_get_container_id_descriptor).restype, libusb_get_container_id_descriptor.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(struct_libusb_bos_dev_capability_descriptor), ctypes.POINTER(ctypes.POINTER(struct_libusb_container_id_descriptor))]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_free_container_id_descriptor(struct libusb_container_id_descriptor *container_id)
|
||||
try: (libusb_free_container_id_descriptor:=dll.libusb_free_container_id_descriptor).restype, libusb_free_container_id_descriptor.argtypes = None, [ctypes.POINTER(struct_libusb_container_id_descriptor)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_platform_descriptor(libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_platform_descriptor **platform_descriptor)
|
||||
try: (libusb_get_platform_descriptor:=dll.libusb_get_platform_descriptor).restype, libusb_get_platform_descriptor.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(struct_libusb_bos_dev_capability_descriptor), ctypes.POINTER(ctypes.POINTER(struct_libusb_platform_descriptor))]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_free_platform_descriptor(struct libusb_platform_descriptor *platform_descriptor)
|
||||
try: (libusb_free_platform_descriptor:=dll.libusb_free_platform_descriptor).restype, libusb_free_platform_descriptor.argtypes = None, [ctypes.POINTER(struct_libusb_platform_descriptor)]
|
||||
except AttributeError: pass
|
||||
|
||||
# uint8_t libusb_get_bus_number(libusb_device *dev)
|
||||
try: (libusb_get_bus_number:=dll.libusb_get_bus_number).restype, libusb_get_bus_number.argtypes = uint8_t, [ctypes.POINTER(libusb_device)]
|
||||
except AttributeError: pass
|
||||
|
||||
# uint8_t libusb_get_port_number(libusb_device *dev)
|
||||
try: (libusb_get_port_number:=dll.libusb_get_port_number).restype, libusb_get_port_number.argtypes = uint8_t, [ctypes.POINTER(libusb_device)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_port_numbers(libusb_device *dev, uint8_t *port_numbers, int port_numbers_len)
|
||||
try: (libusb_get_port_numbers:=dll.libusb_get_port_numbers).restype, libusb_get_port_numbers.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device), ctypes.POINTER(uint8_t), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# __attribute__((deprecated(""))) int libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t *path, uint8_t path_length)
|
||||
try: (libusb_get_port_path:=dll.libusb_get_port_path).restype, libusb_get_port_path.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(libusb_device), ctypes.POINTER(uint8_t), uint8_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# libusb_device *libusb_get_parent(libusb_device *dev)
|
||||
try: (libusb_get_parent:=dll.libusb_get_parent).restype, libusb_get_parent.argtypes = ctypes.POINTER(libusb_device), [ctypes.POINTER(libusb_device)]
|
||||
except AttributeError: pass
|
||||
|
||||
# uint8_t libusb_get_device_address(libusb_device *dev)
|
||||
try: (libusb_get_device_address:=dll.libusb_get_device_address).restype, libusb_get_device_address.argtypes = uint8_t, [ctypes.POINTER(libusb_device)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_device_speed(libusb_device *dev)
|
||||
try: (libusb_get_device_speed:=dll.libusb_get_device_speed).restype, libusb_get_device_speed.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint)
|
||||
try: (libusb_get_max_packet_size:=dll.libusb_get_max_packet_size).restype, libusb_get_max_packet_size.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device), ctypes.c_ubyte]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_max_iso_packet_size(libusb_device *dev, unsigned char endpoint)
|
||||
try: (libusb_get_max_iso_packet_size:=dll.libusb_get_max_iso_packet_size).restype, libusb_get_max_iso_packet_size.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device), ctypes.c_ubyte]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_max_alt_packet_size(libusb_device *dev, int interface_number, int alternate_setting, unsigned char endpoint)
|
||||
try: (libusb_get_max_alt_packet_size:=dll.libusb_get_max_alt_packet_size).restype, libusb_get_max_alt_packet_size.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device), ctypes.c_int32, ctypes.c_int32, ctypes.c_ubyte]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_interface_association_descriptors(libusb_device *dev, uint8_t config_index, struct libusb_interface_association_descriptor_array **iad_array)
|
||||
try: (libusb_get_interface_association_descriptors:=dll.libusb_get_interface_association_descriptors).restype, libusb_get_interface_association_descriptors.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device), uint8_t, ctypes.POINTER(ctypes.POINTER(struct_libusb_interface_association_descriptor_array))]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_active_interface_association_descriptors(libusb_device *dev, struct libusb_interface_association_descriptor_array **iad_array)
|
||||
try: (libusb_get_active_interface_association_descriptors:=dll.libusb_get_active_interface_association_descriptors).restype, libusb_get_active_interface_association_descriptors.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device), ctypes.POINTER(ctypes.POINTER(struct_libusb_interface_association_descriptor_array))]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_free_interface_association_descriptors(struct libusb_interface_association_descriptor_array *iad_array)
|
||||
try: (libusb_free_interface_association_descriptors:=dll.libusb_free_interface_association_descriptors).restype, libusb_free_interface_association_descriptors.argtypes = None, [ctypes.POINTER(struct_libusb_interface_association_descriptor_array)]
|
||||
except AttributeError: pass
|
||||
|
||||
intptr_t = ctypes.c_int64
|
||||
# int libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev, libusb_device_handle **dev_handle)
|
||||
try: (libusb_wrap_sys_device:=dll.libusb_wrap_sys_device).restype, libusb_wrap_sys_device.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), intptr_t, ctypes.POINTER(ctypes.POINTER(libusb_device_handle))]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_open(libusb_device *dev, libusb_device_handle **dev_handle)
|
||||
try: (libusb_open:=dll.libusb_open).restype, libusb_open.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device), ctypes.POINTER(ctypes.POINTER(libusb_device_handle))]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_close(libusb_device_handle *dev_handle)
|
||||
try: (libusb_close:=dll.libusb_close).restype, libusb_close.argtypes = None, [ctypes.POINTER(libusb_device_handle)]
|
||||
except AttributeError: pass
|
||||
|
||||
# libusb_device *libusb_get_device(libusb_device_handle *dev_handle)
|
||||
try: (libusb_get_device:=dll.libusb_get_device).restype, libusb_get_device.argtypes = ctypes.POINTER(libusb_device), [ctypes.POINTER(libusb_device_handle)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_set_configuration(libusb_device_handle *dev_handle, int configuration)
|
||||
try: (libusb_set_configuration:=dll.libusb_set_configuration).restype, libusb_set_configuration.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_claim_interface(libusb_device_handle *dev_handle, int interface_number)
|
||||
try: (libusb_claim_interface:=dll.libusb_claim_interface).restype, libusb_claim_interface.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_release_interface(libusb_device_handle *dev_handle, int interface_number)
|
||||
try: (libusb_release_interface:=dll.libusb_release_interface).restype, libusb_release_interface.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# libusb_device_handle *libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id, uint16_t product_id)
|
||||
try: (libusb_open_device_with_vid_pid:=dll.libusb_open_device_with_vid_pid).restype, libusb_open_device_with_vid_pid.argtypes = ctypes.POINTER(libusb_device_handle), [ctypes.POINTER(libusb_context), uint16_t, uint16_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_set_interface_alt_setting(libusb_device_handle *dev_handle, int interface_number, int alternate_setting)
|
||||
try: (libusb_set_interface_alt_setting:=dll.libusb_set_interface_alt_setting).restype, libusb_set_interface_alt_setting.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.c_int32, ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_clear_halt(libusb_device_handle *dev_handle, unsigned char endpoint)
|
||||
try: (libusb_clear_halt:=dll.libusb_clear_halt).restype, libusb_clear_halt.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.c_ubyte]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_reset_device(libusb_device_handle *dev_handle)
|
||||
try: (libusb_reset_device:=dll.libusb_reset_device).restype, libusb_reset_device.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_alloc_streams(libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints, int num_endpoints)
|
||||
try: (libusb_alloc_streams:=dll.libusb_alloc_streams).restype, libusb_alloc_streams.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), uint32_t, ctypes.POINTER(ctypes.c_ubyte), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_free_streams(libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints)
|
||||
try: (libusb_free_streams:=dll.libusb_free_streams).restype, libusb_free_streams.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.POINTER(ctypes.c_ubyte), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
size_t = ctypes.c_uint64
|
||||
# unsigned char *libusb_dev_mem_alloc(libusb_device_handle *dev_handle, size_t length)
|
||||
try: (libusb_dev_mem_alloc:=dll.libusb_dev_mem_alloc).restype, libusb_dev_mem_alloc.argtypes = ctypes.POINTER(ctypes.c_ubyte), [ctypes.POINTER(libusb_device_handle), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_dev_mem_free(libusb_device_handle *dev_handle, unsigned char *buffer, size_t length)
|
||||
try: (libusb_dev_mem_free:=dll.libusb_dev_mem_free).restype, libusb_dev_mem_free.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.POINTER(ctypes.c_ubyte), size_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_kernel_driver_active(libusb_device_handle *dev_handle, int interface_number)
|
||||
try: (libusb_kernel_driver_active:=dll.libusb_kernel_driver_active).restype, libusb_kernel_driver_active.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_detach_kernel_driver(libusb_device_handle *dev_handle, int interface_number)
|
||||
try: (libusb_detach_kernel_driver:=dll.libusb_detach_kernel_driver).restype, libusb_detach_kernel_driver.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_attach_kernel_driver(libusb_device_handle *dev_handle, int interface_number)
|
||||
try: (libusb_attach_kernel_driver:=dll.libusb_attach_kernel_driver).restype, libusb_attach_kernel_driver.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_set_auto_detach_kernel_driver(libusb_device_handle *dev_handle, int enable)
|
||||
try: (libusb_set_auto_detach_kernel_driver:=dll.libusb_set_auto_detach_kernel_driver).restype, libusb_set_auto_detach_kernel_driver.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# struct libusb_transfer *libusb_alloc_transfer(int iso_packets)
|
||||
try: (libusb_alloc_transfer:=dll.libusb_alloc_transfer).restype, libusb_alloc_transfer.argtypes = ctypes.POINTER(struct_libusb_transfer), [ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_submit_transfer(struct libusb_transfer *transfer)
|
||||
try: (libusb_submit_transfer:=dll.libusb_submit_transfer).restype, libusb_submit_transfer.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_libusb_transfer)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_cancel_transfer(struct libusb_transfer *transfer)
|
||||
try: (libusb_cancel_transfer:=dll.libusb_cancel_transfer).restype, libusb_cancel_transfer.argtypes = ctypes.c_int32, [ctypes.POINTER(struct_libusb_transfer)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_free_transfer(struct libusb_transfer *transfer)
|
||||
try: (libusb_free_transfer:=dll.libusb_free_transfer).restype, libusb_free_transfer.argtypes = None, [ctypes.POINTER(struct_libusb_transfer)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_transfer_set_stream_id(struct libusb_transfer *transfer, uint32_t stream_id)
|
||||
try: (libusb_transfer_set_stream_id:=dll.libusb_transfer_set_stream_id).restype, libusb_transfer_set_stream_id.argtypes = None, [ctypes.POINTER(struct_libusb_transfer), uint32_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# uint32_t libusb_transfer_get_stream_id(struct libusb_transfer *transfer)
|
||||
try: (libusb_transfer_get_stream_id:=dll.libusb_transfer_get_stream_id).restype, libusb_transfer_get_stream_id.argtypes = uint32_t, [ctypes.POINTER(struct_libusb_transfer)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_control_transfer(libusb_device_handle *dev_handle, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength, unsigned int timeout)
|
||||
try: (libusb_control_transfer:=dll.libusb_control_transfer).restype, libusb_control_transfer.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), uint8_t, uint8_t, uint16_t, uint16_t, ctypes.POINTER(ctypes.c_ubyte), uint16_t, ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_bulk_transfer(libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *actual_length, unsigned int timeout)
|
||||
try: (libusb_bulk_transfer:=dll.libusb_bulk_transfer).restype, libusb_bulk_transfer.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.c_ubyte, ctypes.POINTER(ctypes.c_ubyte), ctypes.c_int32, ctypes.POINTER(ctypes.c_int32), ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_interrupt_transfer(libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *actual_length, unsigned int timeout)
|
||||
try: (libusb_interrupt_transfer:=dll.libusb_interrupt_transfer).restype, libusb_interrupt_transfer.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), ctypes.c_ubyte, ctypes.POINTER(ctypes.c_ubyte), ctypes.c_int32, ctypes.POINTER(ctypes.c_int32), ctypes.c_uint32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle, uint8_t desc_index, unsigned char *data, int length)
|
||||
try: (libusb_get_string_descriptor_ascii:=dll.libusb_get_string_descriptor_ascii).restype, libusb_get_string_descriptor_ascii.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_device_handle), uint8_t, ctypes.POINTER(ctypes.c_ubyte), ctypes.c_int32]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_try_lock_events(libusb_context *ctx)
|
||||
try: (libusb_try_lock_events:=dll.libusb_try_lock_events).restype, libusb_try_lock_events.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_lock_events(libusb_context *ctx)
|
||||
try: (libusb_lock_events:=dll.libusb_lock_events).restype, libusb_lock_events.argtypes = None, [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_unlock_events(libusb_context *ctx)
|
||||
try: (libusb_unlock_events:=dll.libusb_unlock_events).restype, libusb_unlock_events.argtypes = None, [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_event_handling_ok(libusb_context *ctx)
|
||||
try: (libusb_event_handling_ok:=dll.libusb_event_handling_ok).restype, libusb_event_handling_ok.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_event_handler_active(libusb_context *ctx)
|
||||
try: (libusb_event_handler_active:=dll.libusb_event_handler_active).restype, libusb_event_handler_active.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_interrupt_event_handler(libusb_context *ctx)
|
||||
try: (libusb_interrupt_event_handler:=dll.libusb_interrupt_event_handler).restype, libusb_interrupt_event_handler.argtypes = None, [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_lock_event_waiters(libusb_context *ctx)
|
||||
try: (libusb_lock_event_waiters:=dll.libusb_lock_event_waiters).restype, libusb_lock_event_waiters.argtypes = None, [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_unlock_event_waiters(libusb_context *ctx)
|
||||
try: (libusb_unlock_event_waiters:=dll.libusb_unlock_event_waiters).restype, libusb_unlock_event_waiters.argtypes = None, [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -726,35 +644,27 @@ struct_timeval._fields_ = [
|
||||
('tv_sec', ctypes.c_int64),
|
||||
('tv_usec', ctypes.c_int64),
|
||||
]
|
||||
# int libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
|
||||
try: (libusb_wait_for_event:=dll.libusb_wait_for_event).restype, libusb_wait_for_event.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(struct_timeval)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv)
|
||||
try: (libusb_handle_events_timeout:=dll.libusb_handle_events_timeout).restype, libusb_handle_events_timeout.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(struct_timeval)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_handle_events_timeout_completed(libusb_context *ctx, struct timeval *tv, int *completed)
|
||||
try: (libusb_handle_events_timeout_completed:=dll.libusb_handle_events_timeout_completed).restype, libusb_handle_events_timeout_completed.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(struct_timeval), ctypes.POINTER(ctypes.c_int32)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_handle_events(libusb_context *ctx)
|
||||
try: (libusb_handle_events:=dll.libusb_handle_events).restype, libusb_handle_events.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_handle_events_completed(libusb_context *ctx, int *completed)
|
||||
try: (libusb_handle_events_completed:=dll.libusb_handle_events_completed).restype, libusb_handle_events_completed.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(ctypes.c_int32)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_handle_events_locked(libusb_context *ctx, struct timeval *tv)
|
||||
try: (libusb_handle_events_locked:=dll.libusb_handle_events_locked).restype, libusb_handle_events_locked.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(struct_timeval)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_pollfds_handle_timeouts(libusb_context *ctx)
|
||||
try: (libusb_pollfds_handle_timeouts:=dll.libusb_pollfds_handle_timeouts).restype, libusb_pollfds_handle_timeouts.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_get_next_timeout(libusb_context *ctx, struct timeval *tv)
|
||||
try: (libusb_get_next_timeout:=dll.libusb_get_next_timeout).restype, libusb_get_next_timeout.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.POINTER(struct_timeval)]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -765,15 +675,12 @@ struct_libusb_pollfd._fields_ = [
|
||||
]
|
||||
libusb_pollfd_added_cb = ctypes.CFUNCTYPE(None, ctypes.c_int32, ctypes.c_int16, ctypes.c_void_p)
|
||||
libusb_pollfd_removed_cb = ctypes.CFUNCTYPE(None, ctypes.c_int32, ctypes.c_void_p)
|
||||
# const struct libusb_pollfd **libusb_get_pollfds(libusb_context *ctx)
|
||||
try: (libusb_get_pollfds:=dll.libusb_get_pollfds).restype, libusb_get_pollfds.argtypes = ctypes.POINTER(ctypes.POINTER(struct_libusb_pollfd)), [ctypes.POINTER(libusb_context)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_free_pollfds(const struct libusb_pollfd **pollfds)
|
||||
try: (libusb_free_pollfds:=dll.libusb_free_pollfds).restype, libusb_free_pollfds.argtypes = None, [ctypes.POINTER(ctypes.POINTER(struct_libusb_pollfd))]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_set_pollfd_notifiers(libusb_context *ctx, libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, void *user_data)
|
||||
try: (libusb_set_pollfd_notifiers:=dll.libusb_set_pollfd_notifiers).restype, libusb_set_pollfd_notifiers.argtypes = None, [ctypes.POINTER(libusb_context), libusb_pollfd_added_cb, libusb_pollfd_removed_cb, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -786,19 +693,15 @@ libusb_hotplug_flag = CEnum(ctypes.c_uint32)
|
||||
LIBUSB_HOTPLUG_ENUMERATE = libusb_hotplug_flag.define('LIBUSB_HOTPLUG_ENUMERATE', 1)
|
||||
|
||||
libusb_hotplug_callback_fn = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.POINTER(struct_libusb_context), ctypes.POINTER(struct_libusb_device), libusb_hotplug_event, ctypes.c_void_p)
|
||||
# int libusb_hotplug_register_callback(libusb_context *ctx, int events, int flags, int vendor_id, int product_id, int dev_class, libusb_hotplug_callback_fn cb_fn, void *user_data, libusb_hotplug_callback_handle *callback_handle)
|
||||
try: (libusb_hotplug_register_callback:=dll.libusb_hotplug_register_callback).restype, libusb_hotplug_register_callback.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), ctypes.c_int32, ctypes.c_int32, ctypes.c_int32, ctypes.c_int32, ctypes.c_int32, libusb_hotplug_callback_fn, ctypes.c_void_p, ctypes.POINTER(libusb_hotplug_callback_handle)]
|
||||
except AttributeError: pass
|
||||
|
||||
# void libusb_hotplug_deregister_callback(libusb_context *ctx, libusb_hotplug_callback_handle callback_handle)
|
||||
try: (libusb_hotplug_deregister_callback:=dll.libusb_hotplug_deregister_callback).restype, libusb_hotplug_deregister_callback.argtypes = None, [ctypes.POINTER(libusb_context), libusb_hotplug_callback_handle]
|
||||
except AttributeError: pass
|
||||
|
||||
# void *libusb_hotplug_get_user_data(libusb_context *ctx, libusb_hotplug_callback_handle callback_handle)
|
||||
try: (libusb_hotplug_get_user_data:=dll.libusb_hotplug_get_user_data).restype, libusb_hotplug_get_user_data.argtypes = ctypes.c_void_p, [ctypes.POINTER(libusb_context), libusb_hotplug_callback_handle]
|
||||
except AttributeError: pass
|
||||
|
||||
# int libusb_set_option(libusb_context *ctx, enum libusb_option option, ...)
|
||||
try: (libusb_set_option:=dll.libusb_set_option).restype, libusb_set_option.argtypes = ctypes.c_int32, [ctypes.POINTER(libusb_context), enum_libusb_option]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1347,7 +1347,6 @@ MTLIOCompressionMethodLZMA = enum_MTLIOCompressionMethod.define('MTLIOCompressio
|
||||
MTLIOCompressionMethodLZBitmap = enum_MTLIOCompressionMethod.define('MTLIOCompressionMethodLZBitmap', 4)
|
||||
|
||||
MTLIOCompressionMethod = enum_MTLIOCompressionMethod
|
||||
# __attribute__((visibility("default"))) extern id<MTLDevice> _Nullable MTLCreateSystemDefaultDevice(void) __attribute__((ns_returns_retained)) __attribute__((availability(macos, introduced=10.11))) __attribute__((availability(ios, introduced=8.0)))
|
||||
try: (MTLCreateSystemDefaultDevice:=dll.MTLCreateSystemDefaultDevice).restype, MTLCreateSystemDefaultDevice.argtypes = MTLDevice, []
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -1359,7 +1358,6 @@ try: MTLDeviceRemovalRequestedNotification = MTLDeviceNotificationName.in_dll(dl
|
||||
except (ValueError,AttributeError): pass
|
||||
try: MTLDeviceWasRemovedNotification = MTLDeviceNotificationName.in_dll(dll, 'MTLDeviceWasRemovedNotification')
|
||||
except (ValueError,AttributeError): pass
|
||||
# __attribute__((visibility("default"))) extern void MTLRemoveDeviceObserver(id<NSObject> _Nonnull observer) __attribute__((availability(macos, introduced=10.13))) __attribute__((availability(ios, unavailable)))
|
||||
try: (MTLRemoveDeviceObserver:=dll.MTLRemoveDeviceObserver).restype, MTLRemoveDeviceObserver.argtypes = None, [NSObject]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
@@ -30,60 +30,46 @@ NVJITLINK_INPUT_LIBRARY = nvJitLinkInputType.define('NVJITLINK_INPUT_LIBRARY', 6
|
||||
class struct_nvJitLink(Struct): pass
|
||||
nvJitLinkHandle = ctypes.POINTER(struct_nvJitLink)
|
||||
uint32_t = ctypes.c_uint32
|
||||
# nvJitLinkResult nvJitLinkCreate(nvJitLinkHandle *handle, uint32_t numOptions, const char **options)
|
||||
try: (nvJitLinkCreate:=dll.nvJitLinkCreate).restype, nvJitLinkCreate.argtypes = nvJitLinkResult, [ctypes.POINTER(nvJitLinkHandle), uint32_t, ctypes.POINTER(ctypes.POINTER(ctypes.c_char))]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkDestroy(nvJitLinkHandle *handle)
|
||||
try: (nvJitLinkDestroy:=dll.nvJitLinkDestroy).restype, nvJitLinkDestroy.argtypes = nvJitLinkResult, [ctypes.POINTER(nvJitLinkHandle)]
|
||||
except AttributeError: pass
|
||||
|
||||
size_t = ctypes.c_uint64
|
||||
# nvJitLinkResult nvJitLinkAddData(nvJitLinkHandle handle, nvJitLinkInputType inputType, const void *data, size_t size, const char *name)
|
||||
try: (nvJitLinkAddData:=dll.nvJitLinkAddData).restype, nvJitLinkAddData.argtypes = nvJitLinkResult, [nvJitLinkHandle, nvJitLinkInputType, ctypes.c_void_p, size_t, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkAddFile(nvJitLinkHandle handle, nvJitLinkInputType inputType, const char *fileName)
|
||||
try: (nvJitLinkAddFile:=dll.nvJitLinkAddFile).restype, nvJitLinkAddFile.argtypes = nvJitLinkResult, [nvJitLinkHandle, nvJitLinkInputType, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkComplete(nvJitLinkHandle handle)
|
||||
try: (nvJitLinkComplete:=dll.nvJitLinkComplete).restype, nvJitLinkComplete.argtypes = nvJitLinkResult, [nvJitLinkHandle]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkGetLinkedCubinSize(nvJitLinkHandle handle, size_t *size)
|
||||
try: (nvJitLinkGetLinkedCubinSize:=dll.nvJitLinkGetLinkedCubinSize).restype, nvJitLinkGetLinkedCubinSize.argtypes = nvJitLinkResult, [nvJitLinkHandle, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkGetLinkedCubin(nvJitLinkHandle handle, void *cubin)
|
||||
try: (nvJitLinkGetLinkedCubin:=dll.nvJitLinkGetLinkedCubin).restype, nvJitLinkGetLinkedCubin.argtypes = nvJitLinkResult, [nvJitLinkHandle, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkGetLinkedPtxSize(nvJitLinkHandle handle, size_t *size)
|
||||
try: (nvJitLinkGetLinkedPtxSize:=dll.nvJitLinkGetLinkedPtxSize).restype, nvJitLinkGetLinkedPtxSize.argtypes = nvJitLinkResult, [nvJitLinkHandle, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkGetLinkedPtx(nvJitLinkHandle handle, char *ptx)
|
||||
try: (nvJitLinkGetLinkedPtx:=dll.nvJitLinkGetLinkedPtx).restype, nvJitLinkGetLinkedPtx.argtypes = nvJitLinkResult, [nvJitLinkHandle, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkGetErrorLogSize(nvJitLinkHandle handle, size_t *size)
|
||||
try: (nvJitLinkGetErrorLogSize:=dll.nvJitLinkGetErrorLogSize).restype, nvJitLinkGetErrorLogSize.argtypes = nvJitLinkResult, [nvJitLinkHandle, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkGetErrorLog(nvJitLinkHandle handle, char *log)
|
||||
try: (nvJitLinkGetErrorLog:=dll.nvJitLinkGetErrorLog).restype, nvJitLinkGetErrorLog.argtypes = nvJitLinkResult, [nvJitLinkHandle, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkGetInfoLogSize(nvJitLinkHandle handle, size_t *size)
|
||||
try: (nvJitLinkGetInfoLogSize:=dll.nvJitLinkGetInfoLogSize).restype, nvJitLinkGetInfoLogSize.argtypes = nvJitLinkResult, [nvJitLinkHandle, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkGetInfoLog(nvJitLinkHandle handle, char *log)
|
||||
try: (nvJitLinkGetInfoLog:=dll.nvJitLinkGetInfoLog).restype, nvJitLinkGetInfoLog.argtypes = nvJitLinkResult, [nvJitLinkHandle, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvJitLinkResult nvJitLinkVersion(unsigned int *major, unsigned int *minor)
|
||||
try: (nvJitLinkVersion:=dll.nvJitLinkVersion).restype, nvJitLinkVersion.argtypes = nvJitLinkResult, [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
@@ -23,90 +23,69 @@ NVRTC_ERROR_NO_LOWERED_NAMES_BEFORE_COMPILATION = nvrtcResult.define('NVRTC_ERRO
|
||||
NVRTC_ERROR_NAME_EXPRESSION_NOT_VALID = nvrtcResult.define('NVRTC_ERROR_NAME_EXPRESSION_NOT_VALID', 10)
|
||||
NVRTC_ERROR_INTERNAL_ERROR = nvrtcResult.define('NVRTC_ERROR_INTERNAL_ERROR', 11)
|
||||
|
||||
# const char *nvrtcGetErrorString(nvrtcResult result)
|
||||
try: (nvrtcGetErrorString:=dll.nvrtcGetErrorString).restype, nvrtcGetErrorString.argtypes = ctypes.POINTER(ctypes.c_char), [nvrtcResult]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcVersion(int *major, int *minor)
|
||||
try: (nvrtcVersion:=dll.nvrtcVersion).restype, nvrtcVersion.argtypes = nvrtcResult, [ctypes.POINTER(ctypes.c_int32), ctypes.POINTER(ctypes.c_int32)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetNumSupportedArchs(int *numArchs)
|
||||
try: (nvrtcGetNumSupportedArchs:=dll.nvrtcGetNumSupportedArchs).restype, nvrtcGetNumSupportedArchs.argtypes = nvrtcResult, [ctypes.POINTER(ctypes.c_int32)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetSupportedArchs(int *supportedArchs)
|
||||
try: (nvrtcGetSupportedArchs:=dll.nvrtcGetSupportedArchs).restype, nvrtcGetSupportedArchs.argtypes = nvrtcResult, [ctypes.POINTER(ctypes.c_int32)]
|
||||
except AttributeError: pass
|
||||
|
||||
class struct__nvrtcProgram(Struct): pass
|
||||
nvrtcProgram = ctypes.POINTER(struct__nvrtcProgram)
|
||||
# nvrtcResult nvrtcCreateProgram(nvrtcProgram *prog, const char *src, const char *name, int numHeaders, const char *const *headers, const char *const *includeNames)
|
||||
try: (nvrtcCreateProgram:=dll.nvrtcCreateProgram).restype, nvrtcCreateProgram.argtypes = nvrtcResult, [ctypes.POINTER(nvrtcProgram), ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), ctypes.c_int32, ctypes.POINTER(ctypes.POINTER(ctypes.c_char)), ctypes.POINTER(ctypes.POINTER(ctypes.c_char))]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcDestroyProgram(nvrtcProgram *prog)
|
||||
try: (nvrtcDestroyProgram:=dll.nvrtcDestroyProgram).restype, nvrtcDestroyProgram.argtypes = nvrtcResult, [ctypes.POINTER(nvrtcProgram)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcCompileProgram(nvrtcProgram prog, int numOptions, const char *const *options)
|
||||
try: (nvrtcCompileProgram:=dll.nvrtcCompileProgram).restype, nvrtcCompileProgram.argtypes = nvrtcResult, [nvrtcProgram, ctypes.c_int32, ctypes.POINTER(ctypes.POINTER(ctypes.c_char))]
|
||||
except AttributeError: pass
|
||||
|
||||
size_t = ctypes.c_uint64
|
||||
# nvrtcResult nvrtcGetPTXSize(nvrtcProgram prog, size_t *ptxSizeRet)
|
||||
try: (nvrtcGetPTXSize:=dll.nvrtcGetPTXSize).restype, nvrtcGetPTXSize.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetPTX(nvrtcProgram prog, char *ptx)
|
||||
try: (nvrtcGetPTX:=dll.nvrtcGetPTX).restype, nvrtcGetPTX.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetCUBINSize(nvrtcProgram prog, size_t *cubinSizeRet)
|
||||
try: (nvrtcGetCUBINSize:=dll.nvrtcGetCUBINSize).restype, nvrtcGetCUBINSize.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetCUBIN(nvrtcProgram prog, char *cubin)
|
||||
try: (nvrtcGetCUBIN:=dll.nvrtcGetCUBIN).restype, nvrtcGetCUBIN.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# __attribute__((deprecated("This function will be removed in a future release. Please use nvrtcGetLTOIRSize instead"))) nvrtcResult nvrtcGetNVVMSize(nvrtcProgram prog, size_t *nvvmSizeRet)
|
||||
try: (nvrtcGetNVVMSize:=dll.nvrtcGetNVVMSize).restype, nvrtcGetNVVMSize.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# __attribute__((deprecated("This function will be removed in a future release. Please use nvrtcGetLTOIR instead"))) nvrtcResult nvrtcGetNVVM(nvrtcProgram prog, char *nvvm)
|
||||
try: (nvrtcGetNVVM:=dll.nvrtcGetNVVM).restype, nvrtcGetNVVM.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetLTOIRSize(nvrtcProgram prog, size_t *LTOIRSizeRet)
|
||||
try: (nvrtcGetLTOIRSize:=dll.nvrtcGetLTOIRSize).restype, nvrtcGetLTOIRSize.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetLTOIR(nvrtcProgram prog, char *LTOIR)
|
||||
try: (nvrtcGetLTOIR:=dll.nvrtcGetLTOIR).restype, nvrtcGetLTOIR.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetOptiXIRSize(nvrtcProgram prog, size_t *optixirSizeRet)
|
||||
try: (nvrtcGetOptiXIRSize:=dll.nvrtcGetOptiXIRSize).restype, nvrtcGetOptiXIRSize.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetOptiXIR(nvrtcProgram prog, char *optixir)
|
||||
try: (nvrtcGetOptiXIR:=dll.nvrtcGetOptiXIR).restype, nvrtcGetOptiXIR.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetProgramLogSize(nvrtcProgram prog, size_t *logSizeRet)
|
||||
try: (nvrtcGetProgramLogSize:=dll.nvrtcGetProgramLogSize).restype, nvrtcGetProgramLogSize.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetProgramLog(nvrtcProgram prog, char *log)
|
||||
try: (nvrtcGetProgramLog:=dll.nvrtcGetProgramLog).restype, nvrtcGetProgramLog.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcAddNameExpression(nvrtcProgram prog, const char *const name_expression)
|
||||
try: (nvrtcAddNameExpression:=dll.nvrtcAddNameExpression).restype, nvrtcAddNameExpression.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# nvrtcResult nvrtcGetLoweredName(nvrtcProgram prog, const char *const name_expression, const char **lowered_name)
|
||||
try: (nvrtcGetLoweredName:=dll.nvrtcGetLoweredName).restype, nvrtcGetLoweredName.argtypes = nvrtcResult, [nvrtcProgram, ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.POINTER(ctypes.c_char))]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
@@ -122,456 +122,343 @@ struct__cl_name_version._fields_ = [
|
||||
]
|
||||
cl_name_version = struct__cl_name_version
|
||||
cl_int = ctypes.c_int32
|
||||
# extern cl_int clGetPlatformIDs(cl_uint num_entries, cl_platform_id *platforms, cl_uint *num_platforms)
|
||||
try: (clGetPlatformIDs:=dll.clGetPlatformIDs).restype, clGetPlatformIDs.argtypes = cl_int, [cl_uint, ctypes.POINTER(cl_platform_id), ctypes.POINTER(cl_uint)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetPlatformInfo(cl_platform_id platform, cl_platform_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetPlatformInfo:=dll.clGetPlatformInfo).restype, clGetPlatformInfo.argtypes = cl_int, [cl_platform_id, cl_platform_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetDeviceIDs(cl_platform_id platform, cl_device_type device_type, cl_uint num_entries, cl_device_id *devices, cl_uint *num_devices)
|
||||
try: (clGetDeviceIDs:=dll.clGetDeviceIDs).restype, clGetDeviceIDs.argtypes = cl_int, [cl_platform_id, cl_device_type, cl_uint, ctypes.POINTER(cl_device_id), ctypes.POINTER(cl_uint)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetDeviceInfo(cl_device_id device, cl_device_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetDeviceInfo:=dll.clGetDeviceInfo).restype, clGetDeviceInfo.argtypes = cl_int, [cl_device_id, cl_device_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clCreateSubDevices(cl_device_id in_device, const cl_device_partition_property *properties, cl_uint num_devices, cl_device_id *out_devices, cl_uint *num_devices_ret)
|
||||
try: (clCreateSubDevices:=dll.clCreateSubDevices).restype, clCreateSubDevices.argtypes = cl_int, [cl_device_id, ctypes.POINTER(cl_device_partition_property), cl_uint, ctypes.POINTER(cl_device_id), ctypes.POINTER(cl_uint)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clRetainDevice(cl_device_id device)
|
||||
try: (clRetainDevice:=dll.clRetainDevice).restype, clRetainDevice.argtypes = cl_int, [cl_device_id]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clReleaseDevice(cl_device_id device)
|
||||
try: (clReleaseDevice:=dll.clReleaseDevice).restype, clReleaseDevice.argtypes = cl_int, [cl_device_id]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clSetDefaultDeviceCommandQueue(cl_context context, cl_device_id device, cl_command_queue command_queue)
|
||||
try: (clSetDefaultDeviceCommandQueue:=dll.clSetDefaultDeviceCommandQueue).restype, clSetDefaultDeviceCommandQueue.argtypes = cl_int, [cl_context, cl_device_id, cl_command_queue]
|
||||
except AttributeError: pass
|
||||
|
||||
cl_ulong = ctypes.c_uint64
|
||||
# extern cl_int clGetDeviceAndHostTimer(cl_device_id device, cl_ulong *device_timestamp, cl_ulong *host_timestamp)
|
||||
try: (clGetDeviceAndHostTimer:=dll.clGetDeviceAndHostTimer).restype, clGetDeviceAndHostTimer.argtypes = cl_int, [cl_device_id, ctypes.POINTER(cl_ulong), ctypes.POINTER(cl_ulong)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetHostTimer(cl_device_id device, cl_ulong *host_timestamp)
|
||||
try: (clGetHostTimer:=dll.clGetHostTimer).restype, clGetHostTimer.argtypes = cl_int, [cl_device_id, ctypes.POINTER(cl_ulong)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_context clCreateContext(const cl_context_properties *properties, cl_uint num_devices, const cl_device_id *devices, void (*pfn_notify)(const char *, const void *, size_t, void *), void *user_data, cl_int *errcode_ret)
|
||||
try: (clCreateContext:=dll.clCreateContext).restype, clCreateContext.argtypes = cl_context, [ctypes.POINTER(cl_context_properties), cl_uint, ctypes.POINTER(cl_device_id), ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_char), ctypes.c_void_p, size_t, ctypes.c_void_p), ctypes.c_void_p, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_context clCreateContextFromType(const cl_context_properties *properties, cl_device_type device_type, void (*pfn_notify)(const char *, const void *, size_t, void *), void *user_data, cl_int *errcode_ret)
|
||||
try: (clCreateContextFromType:=dll.clCreateContextFromType).restype, clCreateContextFromType.argtypes = cl_context, [ctypes.POINTER(cl_context_properties), cl_device_type, ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_char), ctypes.c_void_p, size_t, ctypes.c_void_p), ctypes.c_void_p, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clRetainContext(cl_context context)
|
||||
try: (clRetainContext:=dll.clRetainContext).restype, clRetainContext.argtypes = cl_int, [cl_context]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clReleaseContext(cl_context context)
|
||||
try: (clReleaseContext:=dll.clReleaseContext).restype, clReleaseContext.argtypes = cl_int, [cl_context]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetContextInfo(cl_context context, cl_context_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetContextInfo:=dll.clGetContextInfo).restype, clGetContextInfo.argtypes = cl_int, [cl_context, cl_context_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clSetContextDestructorCallback(cl_context context, void (*pfn_notify)(cl_context, void *), void *user_data)
|
||||
try: (clSetContextDestructorCallback:=dll.clSetContextDestructorCallback).restype, clSetContextDestructorCallback.argtypes = cl_int, [cl_context, ctypes.CFUNCTYPE(None, cl_context, ctypes.c_void_p), ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_command_queue clCreateCommandQueueWithProperties(cl_context context, cl_device_id device, const cl_queue_properties *properties, cl_int *errcode_ret)
|
||||
try: (clCreateCommandQueueWithProperties:=dll.clCreateCommandQueueWithProperties).restype, clCreateCommandQueueWithProperties.argtypes = cl_command_queue, [cl_context, cl_device_id, ctypes.POINTER(cl_queue_properties), ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clRetainCommandQueue(cl_command_queue command_queue)
|
||||
try: (clRetainCommandQueue:=dll.clRetainCommandQueue).restype, clRetainCommandQueue.argtypes = cl_int, [cl_command_queue]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clReleaseCommandQueue(cl_command_queue command_queue)
|
||||
try: (clReleaseCommandQueue:=dll.clReleaseCommandQueue).restype, clReleaseCommandQueue.argtypes = cl_int, [cl_command_queue]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetCommandQueueInfo(cl_command_queue command_queue, cl_command_queue_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetCommandQueueInfo:=dll.clGetCommandQueueInfo).restype, clGetCommandQueueInfo.argtypes = cl_int, [cl_command_queue, cl_command_queue_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_mem clCreateBuffer(cl_context context, cl_mem_flags flags, size_t size, void *host_ptr, cl_int *errcode_ret)
|
||||
try: (clCreateBuffer:=dll.clCreateBuffer).restype, clCreateBuffer.argtypes = cl_mem, [cl_context, cl_mem_flags, size_t, ctypes.c_void_p, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_mem clCreateSubBuffer(cl_mem buffer, cl_mem_flags flags, cl_buffer_create_type buffer_create_type, const void *buffer_create_info, cl_int *errcode_ret)
|
||||
try: (clCreateSubBuffer:=dll.clCreateSubBuffer).restype, clCreateSubBuffer.argtypes = cl_mem, [cl_mem, cl_mem_flags, cl_buffer_create_type, ctypes.c_void_p, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_mem clCreateImage(cl_context context, cl_mem_flags flags, const cl_image_format *image_format, const cl_image_desc *image_desc, void *host_ptr, cl_int *errcode_ret)
|
||||
try: (clCreateImage:=dll.clCreateImage).restype, clCreateImage.argtypes = cl_mem, [cl_context, cl_mem_flags, ctypes.POINTER(cl_image_format), ctypes.POINTER(cl_image_desc), ctypes.c_void_p, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_mem clCreatePipe(cl_context context, cl_mem_flags flags, cl_uint pipe_packet_size, cl_uint pipe_max_packets, const cl_pipe_properties *properties, cl_int *errcode_ret)
|
||||
try: (clCreatePipe:=dll.clCreatePipe).restype, clCreatePipe.argtypes = cl_mem, [cl_context, cl_mem_flags, cl_uint, cl_uint, ctypes.POINTER(cl_pipe_properties), ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_mem clCreateBufferWithProperties(cl_context context, const cl_mem_properties *properties, cl_mem_flags flags, size_t size, void *host_ptr, cl_int *errcode_ret)
|
||||
try: (clCreateBufferWithProperties:=dll.clCreateBufferWithProperties).restype, clCreateBufferWithProperties.argtypes = cl_mem, [cl_context, ctypes.POINTER(cl_mem_properties), cl_mem_flags, size_t, ctypes.c_void_p, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_mem clCreateImageWithProperties(cl_context context, const cl_mem_properties *properties, cl_mem_flags flags, const cl_image_format *image_format, const cl_image_desc *image_desc, void *host_ptr, cl_int *errcode_ret)
|
||||
try: (clCreateImageWithProperties:=dll.clCreateImageWithProperties).restype, clCreateImageWithProperties.argtypes = cl_mem, [cl_context, ctypes.POINTER(cl_mem_properties), cl_mem_flags, ctypes.POINTER(cl_image_format), ctypes.POINTER(cl_image_desc), ctypes.c_void_p, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clRetainMemObject(cl_mem memobj)
|
||||
try: (clRetainMemObject:=dll.clRetainMemObject).restype, clRetainMemObject.argtypes = cl_int, [cl_mem]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clReleaseMemObject(cl_mem memobj)
|
||||
try: (clReleaseMemObject:=dll.clReleaseMemObject).restype, clReleaseMemObject.argtypes = cl_int, [cl_mem]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetSupportedImageFormats(cl_context context, cl_mem_flags flags, cl_mem_object_type image_type, cl_uint num_entries, cl_image_format *image_formats, cl_uint *num_image_formats)
|
||||
try: (clGetSupportedImageFormats:=dll.clGetSupportedImageFormats).restype, clGetSupportedImageFormats.argtypes = cl_int, [cl_context, cl_mem_flags, cl_mem_object_type, cl_uint, ctypes.POINTER(cl_image_format), ctypes.POINTER(cl_uint)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetMemObjectInfo(cl_mem memobj, cl_mem_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetMemObjectInfo:=dll.clGetMemObjectInfo).restype, clGetMemObjectInfo.argtypes = cl_int, [cl_mem, cl_mem_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetImageInfo(cl_mem image, cl_image_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetImageInfo:=dll.clGetImageInfo).restype, clGetImageInfo.argtypes = cl_int, [cl_mem, cl_image_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetPipeInfo(cl_mem pipe, cl_pipe_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetPipeInfo:=dll.clGetPipeInfo).restype, clGetPipeInfo.argtypes = cl_int, [cl_mem, cl_pipe_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clSetMemObjectDestructorCallback(cl_mem memobj, void (*pfn_notify)(cl_mem, void *), void *user_data)
|
||||
try: (clSetMemObjectDestructorCallback:=dll.clSetMemObjectDestructorCallback).restype, clSetMemObjectDestructorCallback.argtypes = cl_int, [cl_mem, ctypes.CFUNCTYPE(None, cl_mem, ctypes.c_void_p), ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *clSVMAlloc(cl_context context, cl_svm_mem_flags flags, size_t size, cl_uint alignment)
|
||||
try: (clSVMAlloc:=dll.clSVMAlloc).restype, clSVMAlloc.argtypes = ctypes.c_void_p, [cl_context, cl_svm_mem_flags, size_t, cl_uint]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void clSVMFree(cl_context context, void *svm_pointer)
|
||||
try: (clSVMFree:=dll.clSVMFree).restype, clSVMFree.argtypes = None, [cl_context, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_sampler clCreateSamplerWithProperties(cl_context context, const cl_sampler_properties *sampler_properties, cl_int *errcode_ret)
|
||||
try: (clCreateSamplerWithProperties:=dll.clCreateSamplerWithProperties).restype, clCreateSamplerWithProperties.argtypes = cl_sampler, [cl_context, ctypes.POINTER(cl_sampler_properties), ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clRetainSampler(cl_sampler sampler)
|
||||
try: (clRetainSampler:=dll.clRetainSampler).restype, clRetainSampler.argtypes = cl_int, [cl_sampler]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clReleaseSampler(cl_sampler sampler)
|
||||
try: (clReleaseSampler:=dll.clReleaseSampler).restype, clReleaseSampler.argtypes = cl_int, [cl_sampler]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetSamplerInfo(cl_sampler sampler, cl_sampler_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetSamplerInfo:=dll.clGetSamplerInfo).restype, clGetSamplerInfo.argtypes = cl_int, [cl_sampler, cl_sampler_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_program clCreateProgramWithSource(cl_context context, cl_uint count, const char **strings, const size_t *lengths, cl_int *errcode_ret)
|
||||
try: (clCreateProgramWithSource:=dll.clCreateProgramWithSource).restype, clCreateProgramWithSource.argtypes = cl_program, [cl_context, cl_uint, ctypes.POINTER(ctypes.POINTER(ctypes.c_char)), ctypes.POINTER(size_t), ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_program clCreateProgramWithBinary(cl_context context, cl_uint num_devices, const cl_device_id *device_list, const size_t *lengths, const unsigned char **binaries, cl_int *binary_status, cl_int *errcode_ret)
|
||||
try: (clCreateProgramWithBinary:=dll.clCreateProgramWithBinary).restype, clCreateProgramWithBinary.argtypes = cl_program, [cl_context, cl_uint, ctypes.POINTER(cl_device_id), ctypes.POINTER(size_t), ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)), ctypes.POINTER(cl_int), ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_program clCreateProgramWithBuiltInKernels(cl_context context, cl_uint num_devices, const cl_device_id *device_list, const char *kernel_names, cl_int *errcode_ret)
|
||||
try: (clCreateProgramWithBuiltInKernels:=dll.clCreateProgramWithBuiltInKernels).restype, clCreateProgramWithBuiltInKernels.argtypes = cl_program, [cl_context, cl_uint, ctypes.POINTER(cl_device_id), ctypes.POINTER(ctypes.c_char), ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_program clCreateProgramWithIL(cl_context context, const void *il, size_t length, cl_int *errcode_ret)
|
||||
try: (clCreateProgramWithIL:=dll.clCreateProgramWithIL).restype, clCreateProgramWithIL.argtypes = cl_program, [cl_context, ctypes.c_void_p, size_t, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clRetainProgram(cl_program program)
|
||||
try: (clRetainProgram:=dll.clRetainProgram).restype, clRetainProgram.argtypes = cl_int, [cl_program]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clReleaseProgram(cl_program program)
|
||||
try: (clReleaseProgram:=dll.clReleaseProgram).restype, clReleaseProgram.argtypes = cl_int, [cl_program]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clBuildProgram(cl_program program, cl_uint num_devices, const cl_device_id *device_list, const char *options, void (*pfn_notify)(cl_program, void *), void *user_data)
|
||||
try: (clBuildProgram:=dll.clBuildProgram).restype, clBuildProgram.argtypes = cl_int, [cl_program, cl_uint, ctypes.POINTER(cl_device_id), ctypes.POINTER(ctypes.c_char), ctypes.CFUNCTYPE(None, cl_program, ctypes.c_void_p), ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clCompileProgram(cl_program program, cl_uint num_devices, const cl_device_id *device_list, const char *options, cl_uint num_input_headers, const cl_program *input_headers, const char **header_include_names, void (*pfn_notify)(cl_program, void *), void *user_data)
|
||||
try: (clCompileProgram:=dll.clCompileProgram).restype, clCompileProgram.argtypes = cl_int, [cl_program, cl_uint, ctypes.POINTER(cl_device_id), ctypes.POINTER(ctypes.c_char), cl_uint, ctypes.POINTER(cl_program), ctypes.POINTER(ctypes.POINTER(ctypes.c_char)), ctypes.CFUNCTYPE(None, cl_program, ctypes.c_void_p), ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_program clLinkProgram(cl_context context, cl_uint num_devices, const cl_device_id *device_list, const char *options, cl_uint num_input_programs, const cl_program *input_programs, void (*pfn_notify)(cl_program, void *), void *user_data, cl_int *errcode_ret)
|
||||
try: (clLinkProgram:=dll.clLinkProgram).restype, clLinkProgram.argtypes = cl_program, [cl_context, cl_uint, ctypes.POINTER(cl_device_id), ctypes.POINTER(ctypes.c_char), cl_uint, ctypes.POINTER(cl_program), ctypes.CFUNCTYPE(None, cl_program, ctypes.c_void_p), ctypes.c_void_p, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clSetProgramReleaseCallback(cl_program program, void (*pfn_notify)(cl_program, void *), void *user_data) __attribute__((deprecated("")))
|
||||
try: (clSetProgramReleaseCallback:=dll.clSetProgramReleaseCallback).restype, clSetProgramReleaseCallback.argtypes = cl_int, [cl_program, ctypes.CFUNCTYPE(None, cl_program, ctypes.c_void_p), ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clSetProgramSpecializationConstant(cl_program program, cl_uint spec_id, size_t spec_size, const void *spec_value)
|
||||
try: (clSetProgramSpecializationConstant:=dll.clSetProgramSpecializationConstant).restype, clSetProgramSpecializationConstant.argtypes = cl_int, [cl_program, cl_uint, size_t, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clUnloadPlatformCompiler(cl_platform_id platform)
|
||||
try: (clUnloadPlatformCompiler:=dll.clUnloadPlatformCompiler).restype, clUnloadPlatformCompiler.argtypes = cl_int, [cl_platform_id]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetProgramInfo(cl_program program, cl_program_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetProgramInfo:=dll.clGetProgramInfo).restype, clGetProgramInfo.argtypes = cl_int, [cl_program, cl_program_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetProgramBuildInfo(cl_program program, cl_device_id device, cl_program_build_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetProgramBuildInfo:=dll.clGetProgramBuildInfo).restype, clGetProgramBuildInfo.argtypes = cl_int, [cl_program, cl_device_id, cl_program_build_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_kernel clCreateKernel(cl_program program, const char *kernel_name, cl_int *errcode_ret)
|
||||
try: (clCreateKernel:=dll.clCreateKernel).restype, clCreateKernel.argtypes = cl_kernel, [cl_program, ctypes.POINTER(ctypes.c_char), ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clCreateKernelsInProgram(cl_program program, cl_uint num_kernels, cl_kernel *kernels, cl_uint *num_kernels_ret)
|
||||
try: (clCreateKernelsInProgram:=dll.clCreateKernelsInProgram).restype, clCreateKernelsInProgram.argtypes = cl_int, [cl_program, cl_uint, ctypes.POINTER(cl_kernel), ctypes.POINTER(cl_uint)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_kernel clCloneKernel(cl_kernel source_kernel, cl_int *errcode_ret)
|
||||
try: (clCloneKernel:=dll.clCloneKernel).restype, clCloneKernel.argtypes = cl_kernel, [cl_kernel, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clRetainKernel(cl_kernel kernel)
|
||||
try: (clRetainKernel:=dll.clRetainKernel).restype, clRetainKernel.argtypes = cl_int, [cl_kernel]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clReleaseKernel(cl_kernel kernel)
|
||||
try: (clReleaseKernel:=dll.clReleaseKernel).restype, clReleaseKernel.argtypes = cl_int, [cl_kernel]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clSetKernelArg(cl_kernel kernel, cl_uint arg_index, size_t arg_size, const void *arg_value)
|
||||
try: (clSetKernelArg:=dll.clSetKernelArg).restype, clSetKernelArg.argtypes = cl_int, [cl_kernel, cl_uint, size_t, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clSetKernelArgSVMPointer(cl_kernel kernel, cl_uint arg_index, const void *arg_value)
|
||||
try: (clSetKernelArgSVMPointer:=dll.clSetKernelArgSVMPointer).restype, clSetKernelArgSVMPointer.argtypes = cl_int, [cl_kernel, cl_uint, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clSetKernelExecInfo(cl_kernel kernel, cl_kernel_exec_info param_name, size_t param_value_size, const void *param_value)
|
||||
try: (clSetKernelExecInfo:=dll.clSetKernelExecInfo).restype, clSetKernelExecInfo.argtypes = cl_int, [cl_kernel, cl_kernel_exec_info, size_t, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetKernelInfo(cl_kernel kernel, cl_kernel_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetKernelInfo:=dll.clGetKernelInfo).restype, clGetKernelInfo.argtypes = cl_int, [cl_kernel, cl_kernel_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetKernelArgInfo(cl_kernel kernel, cl_uint arg_indx, cl_kernel_arg_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetKernelArgInfo:=dll.clGetKernelArgInfo).restype, clGetKernelArgInfo.argtypes = cl_int, [cl_kernel, cl_uint, cl_kernel_arg_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetKernelWorkGroupInfo(cl_kernel kernel, cl_device_id device, cl_kernel_work_group_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetKernelWorkGroupInfo:=dll.clGetKernelWorkGroupInfo).restype, clGetKernelWorkGroupInfo.argtypes = cl_int, [cl_kernel, cl_device_id, cl_kernel_work_group_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetKernelSubGroupInfo(cl_kernel kernel, cl_device_id device, cl_kernel_sub_group_info param_name, size_t input_value_size, const void *input_value, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetKernelSubGroupInfo:=dll.clGetKernelSubGroupInfo).restype, clGetKernelSubGroupInfo.argtypes = cl_int, [cl_kernel, cl_device_id, cl_kernel_sub_group_info, size_t, ctypes.c_void_p, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clWaitForEvents(cl_uint num_events, const cl_event *event_list)
|
||||
try: (clWaitForEvents:=dll.clWaitForEvents).restype, clWaitForEvents.argtypes = cl_int, [cl_uint, ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetEventInfo(cl_event event, cl_event_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetEventInfo:=dll.clGetEventInfo).restype, clGetEventInfo.argtypes = cl_int, [cl_event, cl_event_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_event clCreateUserEvent(cl_context context, cl_int *errcode_ret)
|
||||
try: (clCreateUserEvent:=dll.clCreateUserEvent).restype, clCreateUserEvent.argtypes = cl_event, [cl_context, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clRetainEvent(cl_event event)
|
||||
try: (clRetainEvent:=dll.clRetainEvent).restype, clRetainEvent.argtypes = cl_int, [cl_event]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clReleaseEvent(cl_event event)
|
||||
try: (clReleaseEvent:=dll.clReleaseEvent).restype, clReleaseEvent.argtypes = cl_int, [cl_event]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clSetUserEventStatus(cl_event event, cl_int execution_status)
|
||||
try: (clSetUserEventStatus:=dll.clSetUserEventStatus).restype, clSetUserEventStatus.argtypes = cl_int, [cl_event, cl_int]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clSetEventCallback(cl_event event, cl_int command_exec_callback_type, void (*pfn_notify)(cl_event, cl_int, void *), void *user_data)
|
||||
try: (clSetEventCallback:=dll.clSetEventCallback).restype, clSetEventCallback.argtypes = cl_int, [cl_event, cl_int, ctypes.CFUNCTYPE(None, cl_event, cl_int, ctypes.c_void_p), ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clGetEventProfilingInfo(cl_event event, cl_profiling_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
|
||||
try: (clGetEventProfilingInfo:=dll.clGetEventProfilingInfo).restype, clGetEventProfilingInfo.argtypes = cl_int, [cl_event, cl_profiling_info, size_t, ctypes.c_void_p, ctypes.POINTER(size_t)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clFlush(cl_command_queue command_queue)
|
||||
try: (clFlush:=dll.clFlush).restype, clFlush.argtypes = cl_int, [cl_command_queue]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clFinish(cl_command_queue command_queue)
|
||||
try: (clFinish:=dll.clFinish).restype, clFinish.argtypes = cl_int, [cl_command_queue]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueReadBuffer(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, size_t offset, size_t size, void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueReadBuffer:=dll.clEnqueueReadBuffer).restype, clEnqueueReadBuffer.argtypes = cl_int, [cl_command_queue, cl_mem, cl_bool, size_t, size_t, ctypes.c_void_p, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueReadBufferRect(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, const size_t *buffer_origin, const size_t *host_origin, const size_t *region, size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueReadBufferRect:=dll.clEnqueueReadBufferRect).restype, clEnqueueReadBufferRect.argtypes = cl_int, [cl_command_queue, cl_mem, cl_bool, ctypes.POINTER(size_t), ctypes.POINTER(size_t), ctypes.POINTER(size_t), size_t, size_t, size_t, size_t, ctypes.c_void_p, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueWriteBuffer(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, size_t offset, size_t size, const void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueWriteBuffer:=dll.clEnqueueWriteBuffer).restype, clEnqueueWriteBuffer.argtypes = cl_int, [cl_command_queue, cl_mem, cl_bool, size_t, size_t, ctypes.c_void_p, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueWriteBufferRect(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, const size_t *buffer_origin, const size_t *host_origin, const size_t *region, size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, const void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueWriteBufferRect:=dll.clEnqueueWriteBufferRect).restype, clEnqueueWriteBufferRect.argtypes = cl_int, [cl_command_queue, cl_mem, cl_bool, ctypes.POINTER(size_t), ctypes.POINTER(size_t), ctypes.POINTER(size_t), size_t, size_t, size_t, size_t, ctypes.c_void_p, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueFillBuffer(cl_command_queue command_queue, cl_mem buffer, const void *pattern, size_t pattern_size, size_t offset, size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueFillBuffer:=dll.clEnqueueFillBuffer).restype, clEnqueueFillBuffer.argtypes = cl_int, [cl_command_queue, cl_mem, ctypes.c_void_p, size_t, size_t, size_t, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueCopyBuffer(cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_buffer, size_t src_offset, size_t dst_offset, size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueCopyBuffer:=dll.clEnqueueCopyBuffer).restype, clEnqueueCopyBuffer.argtypes = cl_int, [cl_command_queue, cl_mem, cl_mem, size_t, size_t, size_t, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueCopyBufferRect(cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_buffer, const size_t *src_origin, const size_t *dst_origin, const size_t *region, size_t src_row_pitch, size_t src_slice_pitch, size_t dst_row_pitch, size_t dst_slice_pitch, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueCopyBufferRect:=dll.clEnqueueCopyBufferRect).restype, clEnqueueCopyBufferRect.argtypes = cl_int, [cl_command_queue, cl_mem, cl_mem, ctypes.POINTER(size_t), ctypes.POINTER(size_t), ctypes.POINTER(size_t), size_t, size_t, size_t, size_t, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueReadImage(cl_command_queue command_queue, cl_mem image, cl_bool blocking_read, const size_t *origin, const size_t *region, size_t row_pitch, size_t slice_pitch, void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueReadImage:=dll.clEnqueueReadImage).restype, clEnqueueReadImage.argtypes = cl_int, [cl_command_queue, cl_mem, cl_bool, ctypes.POINTER(size_t), ctypes.POINTER(size_t), size_t, size_t, ctypes.c_void_p, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueWriteImage(cl_command_queue command_queue, cl_mem image, cl_bool blocking_write, const size_t *origin, const size_t *region, size_t input_row_pitch, size_t input_slice_pitch, const void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueWriteImage:=dll.clEnqueueWriteImage).restype, clEnqueueWriteImage.argtypes = cl_int, [cl_command_queue, cl_mem, cl_bool, ctypes.POINTER(size_t), ctypes.POINTER(size_t), size_t, size_t, ctypes.c_void_p, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueFillImage(cl_command_queue command_queue, cl_mem image, const void *fill_color, const size_t *origin, const size_t *region, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueFillImage:=dll.clEnqueueFillImage).restype, clEnqueueFillImage.argtypes = cl_int, [cl_command_queue, cl_mem, ctypes.c_void_p, ctypes.POINTER(size_t), ctypes.POINTER(size_t), cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueCopyImage(cl_command_queue command_queue, cl_mem src_image, cl_mem dst_image, const size_t *src_origin, const size_t *dst_origin, const size_t *region, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueCopyImage:=dll.clEnqueueCopyImage).restype, clEnqueueCopyImage.argtypes = cl_int, [cl_command_queue, cl_mem, cl_mem, ctypes.POINTER(size_t), ctypes.POINTER(size_t), ctypes.POINTER(size_t), cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueCopyImageToBuffer(cl_command_queue command_queue, cl_mem src_image, cl_mem dst_buffer, const size_t *src_origin, const size_t *region, size_t dst_offset, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueCopyImageToBuffer:=dll.clEnqueueCopyImageToBuffer).restype, clEnqueueCopyImageToBuffer.argtypes = cl_int, [cl_command_queue, cl_mem, cl_mem, ctypes.POINTER(size_t), ctypes.POINTER(size_t), size_t, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueCopyBufferToImage(cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_image, size_t src_offset, const size_t *dst_origin, const size_t *region, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueCopyBufferToImage:=dll.clEnqueueCopyBufferToImage).restype, clEnqueueCopyBufferToImage.argtypes = cl_int, [cl_command_queue, cl_mem, cl_mem, size_t, ctypes.POINTER(size_t), ctypes.POINTER(size_t), cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *clEnqueueMapBuffer(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_map, cl_map_flags map_flags, size_t offset, size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event, cl_int *errcode_ret)
|
||||
try: (clEnqueueMapBuffer:=dll.clEnqueueMapBuffer).restype, clEnqueueMapBuffer.argtypes = ctypes.c_void_p, [cl_command_queue, cl_mem, cl_bool, cl_map_flags, size_t, size_t, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event), ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *clEnqueueMapImage(cl_command_queue command_queue, cl_mem image, cl_bool blocking_map, cl_map_flags map_flags, const size_t *origin, const size_t *region, size_t *image_row_pitch, size_t *image_slice_pitch, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event, cl_int *errcode_ret)
|
||||
try: (clEnqueueMapImage:=dll.clEnqueueMapImage).restype, clEnqueueMapImage.argtypes = ctypes.c_void_p, [cl_command_queue, cl_mem, cl_bool, cl_map_flags, ctypes.POINTER(size_t), ctypes.POINTER(size_t), ctypes.POINTER(size_t), ctypes.POINTER(size_t), cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event), ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueUnmapMemObject(cl_command_queue command_queue, cl_mem memobj, void *mapped_ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueUnmapMemObject:=dll.clEnqueueUnmapMemObject).restype, clEnqueueUnmapMemObject.argtypes = cl_int, [cl_command_queue, cl_mem, ctypes.c_void_p, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueMigrateMemObjects(cl_command_queue command_queue, cl_uint num_mem_objects, const cl_mem *mem_objects, cl_mem_migration_flags flags, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueMigrateMemObjects:=dll.clEnqueueMigrateMemObjects).restype, clEnqueueMigrateMemObjects.argtypes = cl_int, [cl_command_queue, cl_uint, ctypes.POINTER(cl_mem), cl_mem_migration_flags, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueNDRangeKernel(cl_command_queue command_queue, cl_kernel kernel, cl_uint work_dim, const size_t *global_work_offset, const size_t *global_work_size, const size_t *local_work_size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueNDRangeKernel:=dll.clEnqueueNDRangeKernel).restype, clEnqueueNDRangeKernel.argtypes = cl_int, [cl_command_queue, cl_kernel, cl_uint, ctypes.POINTER(size_t), ctypes.POINTER(size_t), ctypes.POINTER(size_t), cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueNativeKernel(cl_command_queue command_queue, void (*user_func)(void *), void *args, size_t cb_args, cl_uint num_mem_objects, const cl_mem *mem_list, const void **args_mem_loc, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueNativeKernel:=dll.clEnqueueNativeKernel).restype, clEnqueueNativeKernel.argtypes = cl_int, [cl_command_queue, ctypes.CFUNCTYPE(None, ctypes.c_void_p), ctypes.c_void_p, size_t, cl_uint, ctypes.POINTER(cl_mem), ctypes.POINTER(ctypes.c_void_p), cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueMarkerWithWaitList(cl_command_queue command_queue, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueMarkerWithWaitList:=dll.clEnqueueMarkerWithWaitList).restype, clEnqueueMarkerWithWaitList.argtypes = cl_int, [cl_command_queue, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueBarrierWithWaitList(cl_command_queue command_queue, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueBarrierWithWaitList:=dll.clEnqueueBarrierWithWaitList).restype, clEnqueueBarrierWithWaitList.argtypes = cl_int, [cl_command_queue, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueSVMFree(cl_command_queue command_queue, cl_uint num_svm_pointers, void *svm_pointers[], void (*pfn_free_func)(cl_command_queue, cl_uint, void **, void *), void *user_data, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueSVMFree:=dll.clEnqueueSVMFree).restype, clEnqueueSVMFree.argtypes = cl_int, [cl_command_queue, cl_uint, (ctypes.c_void_p * 0), ctypes.CFUNCTYPE(None, cl_command_queue, cl_uint, (ctypes.c_void_p * 0), ctypes.c_void_p), ctypes.c_void_p, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueSVMMemcpy(cl_command_queue command_queue, cl_bool blocking_copy, void *dst_ptr, const void *src_ptr, size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueSVMMemcpy:=dll.clEnqueueSVMMemcpy).restype, clEnqueueSVMMemcpy.argtypes = cl_int, [cl_command_queue, cl_bool, ctypes.c_void_p, ctypes.c_void_p, size_t, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueSVMMemFill(cl_command_queue command_queue, void *svm_ptr, const void *pattern, size_t pattern_size, size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueSVMMemFill:=dll.clEnqueueSVMMemFill).restype, clEnqueueSVMMemFill.argtypes = cl_int, [cl_command_queue, ctypes.c_void_p, ctypes.c_void_p, size_t, size_t, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueSVMMap(cl_command_queue command_queue, cl_bool blocking_map, cl_map_flags flags, void *svm_ptr, size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueSVMMap:=dll.clEnqueueSVMMap).restype, clEnqueueSVMMap.argtypes = cl_int, [cl_command_queue, cl_bool, cl_map_flags, ctypes.c_void_p, size_t, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueSVMUnmap(cl_command_queue command_queue, void *svm_ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueSVMUnmap:=dll.clEnqueueSVMUnmap).restype, clEnqueueSVMUnmap.argtypes = cl_int, [cl_command_queue, ctypes.c_void_p, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueSVMMigrateMem(cl_command_queue command_queue, cl_uint num_svm_pointers, const void **svm_pointers, const size_t *sizes, cl_mem_migration_flags flags, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
|
||||
try: (clEnqueueSVMMigrateMem:=dll.clEnqueueSVMMigrateMem).restype, clEnqueueSVMMigrateMem.argtypes = cl_int, [cl_command_queue, cl_uint, ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(size_t), cl_mem_migration_flags, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *clGetExtensionFunctionAddressForPlatform(cl_platform_id platform, const char *func_name)
|
||||
try: (clGetExtensionFunctionAddressForPlatform:=dll.clGetExtensionFunctionAddressForPlatform).restype, clGetExtensionFunctionAddressForPlatform.argtypes = ctypes.c_void_p, [cl_platform_id, ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_mem clCreateImage2D(cl_context context, cl_mem_flags flags, const cl_image_format *image_format, size_t image_width, size_t image_height, size_t image_row_pitch, void *host_ptr, cl_int *errcode_ret) __attribute__((deprecated("")))
|
||||
try: (clCreateImage2D:=dll.clCreateImage2D).restype, clCreateImage2D.argtypes = cl_mem, [cl_context, cl_mem_flags, ctypes.POINTER(cl_image_format), size_t, size_t, size_t, ctypes.c_void_p, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_mem clCreateImage3D(cl_context context, cl_mem_flags flags, const cl_image_format *image_format, size_t image_width, size_t image_height, size_t image_depth, size_t image_row_pitch, size_t image_slice_pitch, void *host_ptr, cl_int *errcode_ret) __attribute__((deprecated("")))
|
||||
try: (clCreateImage3D:=dll.clCreateImage3D).restype, clCreateImage3D.argtypes = cl_mem, [cl_context, cl_mem_flags, ctypes.POINTER(cl_image_format), size_t, size_t, size_t, size_t, size_t, ctypes.c_void_p, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueMarker(cl_command_queue command_queue, cl_event *event) __attribute__((deprecated("")))
|
||||
try: (clEnqueueMarker:=dll.clEnqueueMarker).restype, clEnqueueMarker.argtypes = cl_int, [cl_command_queue, ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueWaitForEvents(cl_command_queue command_queue, cl_uint num_events, const cl_event *event_list) __attribute__((deprecated("")))
|
||||
try: (clEnqueueWaitForEvents:=dll.clEnqueueWaitForEvents).restype, clEnqueueWaitForEvents.argtypes = cl_int, [cl_command_queue, cl_uint, ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueBarrier(cl_command_queue command_queue) __attribute__((deprecated("")))
|
||||
try: (clEnqueueBarrier:=dll.clEnqueueBarrier).restype, clEnqueueBarrier.argtypes = cl_int, [cl_command_queue]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clUnloadCompiler(void) __attribute__((deprecated("")))
|
||||
try: (clUnloadCompiler:=dll.clUnloadCompiler).restype, clUnloadCompiler.argtypes = cl_int, []
|
||||
except AttributeError: pass
|
||||
|
||||
# extern void *clGetExtensionFunctionAddress(const char *func_name) __attribute__((deprecated("")))
|
||||
try: (clGetExtensionFunctionAddress:=dll.clGetExtensionFunctionAddress).restype, clGetExtensionFunctionAddress.argtypes = ctypes.c_void_p, [ctypes.POINTER(ctypes.c_char)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_command_queue clCreateCommandQueue(cl_context context, cl_device_id device, cl_command_queue_properties properties, cl_int *errcode_ret) __attribute__((deprecated("")))
|
||||
try: (clCreateCommandQueue:=dll.clCreateCommandQueue).restype, clCreateCommandQueue.argtypes = cl_command_queue, [cl_context, cl_device_id, cl_command_queue_properties, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_sampler clCreateSampler(cl_context context, cl_bool normalized_coords, cl_addressing_mode addressing_mode, cl_filter_mode filter_mode, cl_int *errcode_ret) __attribute__((deprecated("")))
|
||||
try: (clCreateSampler:=dll.clCreateSampler).restype, clCreateSampler.argtypes = cl_sampler, [cl_context, cl_bool, cl_addressing_mode, cl_filter_mode, ctypes.POINTER(cl_int)]
|
||||
except AttributeError: pass
|
||||
|
||||
# extern cl_int clEnqueueTask(cl_command_queue command_queue, cl_kernel kernel, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) __attribute__((deprecated("")))
|
||||
try: (clEnqueueTask:=dll.clEnqueueTask).restype, clEnqueueTask.argtypes = cl_int, [cl_command_queue, cl_kernel, cl_uint, ctypes.POINTER(cl_event), ctypes.POINTER(cl_event)]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ struct_rocprofiler_thread_trace_decoder_pc_t._fields_ = [
|
||||
]
|
||||
rocprof_trace_decoder_isa_callback_t = ctypes.CFUNCTYPE(rocprofiler_thread_trace_decoder_status_t, ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(ctypes.c_uint64), struct_rocprofiler_thread_trace_decoder_pc_t, ctypes.c_void_p)
|
||||
rocprof_trace_decoder_se_data_callback_t = ctypes.CFUNCTYPE(ctypes.c_uint64, ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)), ctypes.POINTER(ctypes.c_uint64), ctypes.c_void_p)
|
||||
# rocprofiler_thread_trace_decoder_status_t rocprof_trace_decoder_parse_data(rocprof_trace_decoder_se_data_callback_t se_data_callback, rocprof_trace_decoder_trace_callback_t trace_callback, rocprof_trace_decoder_isa_callback_t isa_callback, void *userdata)
|
||||
try: (rocprof_trace_decoder_parse_data:=dll.rocprof_trace_decoder_parse_data).restype, rocprof_trace_decoder_parse_data.argtypes = rocprofiler_thread_trace_decoder_status_t, [rocprof_trace_decoder_se_data_callback_t, rocprof_trace_decoder_trace_callback_t, rocprof_trace_decoder_isa_callback_t, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
@@ -54,16 +53,13 @@ ROCPROFILER_THREAD_TRACE_DECODER_INFO_WAVE_INCOMPLETE = enum_rocprofiler_thread_
|
||||
ROCPROFILER_THREAD_TRACE_DECODER_INFO_LAST = enum_rocprofiler_thread_trace_decoder_info_t.define('ROCPROFILER_THREAD_TRACE_DECODER_INFO_LAST', 4)
|
||||
|
||||
rocprofiler_thread_trace_decoder_info_t = enum_rocprofiler_thread_trace_decoder_info_t
|
||||
# const char *rocprof_trace_decoder_get_info_string(rocprofiler_thread_trace_decoder_info_t info)
|
||||
try: (rocprof_trace_decoder_get_info_string:=dll.rocprof_trace_decoder_get_info_string).restype, rocprof_trace_decoder_get_info_string.argtypes = ctypes.POINTER(ctypes.c_char), [rocprofiler_thread_trace_decoder_info_t]
|
||||
except AttributeError: pass
|
||||
|
||||
# const char *rocprof_trace_decoder_get_status_string(rocprofiler_thread_trace_decoder_status_t status)
|
||||
try: (rocprof_trace_decoder_get_status_string:=dll.rocprof_trace_decoder_get_status_string).restype, rocprof_trace_decoder_get_status_string.argtypes = ctypes.POINTER(ctypes.c_char), [rocprofiler_thread_trace_decoder_status_t]
|
||||
except AttributeError: pass
|
||||
|
||||
rocprofiler_thread_trace_decoder_debug_callback_t = ctypes.CFUNCTYPE(None, ctypes.c_int64, ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char), ctypes.c_void_p)
|
||||
# rocprofiler_thread_trace_decoder_status_t rocprof_trace_decoder_dump_data(const char *data, uint64_t data_size, rocprofiler_thread_trace_decoder_debug_callback_t cb, void *userdata)
|
||||
try: (rocprof_trace_decoder_dump_data:=dll.rocprof_trace_decoder_dump_data).restype, rocprof_trace_decoder_dump_data.argtypes = rocprofiler_thread_trace_decoder_status_t, [ctypes.POINTER(ctypes.c_char), uint64_t, rocprofiler_thread_trace_decoder_debug_callback_t, ctypes.c_void_p]
|
||||
except AttributeError: pass
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+33
-14
@@ -1,6 +1,6 @@
|
||||
from __future__ import annotations
|
||||
from typing import cast, ClassVar
|
||||
import os, ctypes, struct, hashlib, functools, importlib, mmap, errno, array, contextlib, sys, weakref, itertools, collections
|
||||
import os, ctypes, struct, hashlib, functools, importlib, mmap, errno, array, contextlib, sys, weakref, itertools, collections, atexit
|
||||
assert sys.platform != 'win32'
|
||||
from dataclasses import dataclass
|
||||
from tinygrad.runtime.support.hcq import HCQCompiled, HCQAllocator, HCQBuffer, HWQueue, CLikeArgsState, HCQSignal, HCQProgram, FileIOInterface
|
||||
@@ -8,18 +8,20 @@ from tinygrad.runtime.support.hcq import MMIOInterface, BumpAllocator, hcq_filte
|
||||
from tinygrad.uop.ops import sint
|
||||
from tinygrad.device import Compiled, DMAFdRef, BufferSpec, CompilerPairT
|
||||
from tinygrad.helpers import getenv, round_up, data64_le, DEBUG, PROFILE, ProfileEvent, suppress_finalizing, lo32, hi32, colored, prod, ContextVar
|
||||
from tinygrad.helpers import VIZ
|
||||
from tinygrad.renderer.cstyle import AMDRenderer
|
||||
from tinygrad.renderer.llvmir import AMDLLVMRenderer
|
||||
from tinygrad.runtime.autogen import kfd, hsa, pci, sqtt
|
||||
from tinygrad.runtime.autogen.am import am
|
||||
from tinygrad.runtime.support.compiler_amd import HIPCompiler, AMDLLVMCompiler
|
||||
from tinygrad.runtime.support.compiler_amd import HIPCompiler, HIPCCCompiler, AMDLLVMCompiler
|
||||
from tinygrad.runtime.support.elf import elf_loader
|
||||
from tinygrad.runtime.support.am.amdev import AMDev, AMMemoryManager
|
||||
from tinygrad.runtime.support.amd import AMDReg, AMDIP, import_module, import_soc, import_ip_offsets, import_pmc
|
||||
from tinygrad.runtime.support.system import System, PCIIfaceBase, PCIAllocationMeta, PCIDevice, USBPCIDevice, MAP_FIXED, MAP_NORESERVE
|
||||
if getenv("IOCTL"): import extra.hip_gpu_driver.hip_ioctl # noqa: F401 # pylint: disable=unused-import
|
||||
|
||||
SQTT, SQTT_ITRACE_SE_MASK, PMC = ContextVar("SQTT", 0), ContextVar("SQTT_ITRACE_SE_MASK", 0b11), ContextVar("PMC", 0)
|
||||
SQTT, SQTT_ITRACE_SE_MASK, SQTT_LIMIT_SE = ContextVar("SQTT", VIZ.value>=2), ContextVar("SQTT_ITRACE_SE_MASK", 0b11), ContextVar("SQTT_LIMIT_SE", 0)
|
||||
PMC = ContextVar("PMC", 0)
|
||||
EVENT_INDEX_PARTIAL_FLUSH = 4 # based on a comment in nvd.h
|
||||
WAIT_REG_MEM_FUNCTION_EQ = 3 # ==
|
||||
WAIT_REG_MEM_FUNCTION_NEQ = 4 # !=
|
||||
@@ -192,11 +194,18 @@ class AMDComputeQueue(HWQueue):
|
||||
bind_point=(__BIND_POINT_COMPUTE:=1), api_pso_hash=data64_le(prg.libhash[0])))
|
||||
self.sqtt_userdata(sqtt.struct_rgp_sqtt_marker_event(has_thread_dims=1, cmd_id=next(prg.dev.sqtt_next_cmd_id)), *global_size)
|
||||
|
||||
se_cap = max(prod([x if isinstance(x, int) else 1 for x in global_size]) // 4, 1) // 32
|
||||
for xcc in range(self.dev.xccs):
|
||||
with self.pred_exec(xcc_mask=1 << xcc):
|
||||
for i in range(8 if prg.dev.target >= (11,0,0) else 4):
|
||||
self.wreg(getattr(self.gc, f'regCOMPUTE_STATIC_THREAD_MGMT_SE{i}'), min(0xffffffff, (1 << (se_cap + (1 if i == 0 else 0))) - 1))
|
||||
if SQTT_LIMIT_SE:
|
||||
# Calculate number of CUs per SE to enable based on blocks count. 4 is maximum simd per CU, but on rdna we can trace only 1.
|
||||
cu_per_se = prod([x if isinstance(x, int) else 1 for x in global_size]) // (((self.dev.max_cu_id + 1) // self.dev.se_cnt) * 4)
|
||||
for xcc in range(self.dev.xccs):
|
||||
with self.pred_exec(xcc_mask=1 << xcc):
|
||||
for i in range(8 if prg.dev.target >= (11,0,0) else 4):
|
||||
if SQTT_LIMIT_SE > 1: mask = 1 if SQTT_ITRACE_SE_MASK.value & (1 << i) else 0 # only run unmasked shader engines
|
||||
else:
|
||||
sa_mask = (1 << (self.dev.iface.props['cu_per_simd_array'] // 2)) - 1
|
||||
cu_mask = (1 << (cu_per_se + (1 if i == 0 else 0))) - 1
|
||||
mask = lo32((cu_mask & sa_mask) | (cu_mask & (sa_mask << 16)) << 16)
|
||||
self.wreg(getattr(self.gc, f'regCOMPUTE_STATIC_THREAD_MGMT_SE{i}'), mask)
|
||||
|
||||
def sqtt_userdata(self, data, *extra_dwords):
|
||||
data_ints = [x[0] for x in struct.iter_unpack('<I', bytes(data))] + list(extra_dwords)
|
||||
@@ -357,6 +366,7 @@ class AMDComputeQueue(HWQueue):
|
||||
|
||||
def timestamp(self, signal:AMDSignal):
|
||||
with self.pred_exec(xcc_mask=0b1):
|
||||
self.release_mem(cache_flush=False) # ensure all prior writes are done
|
||||
self.release_mem(signal.timestamp_addr, 0, self.pm4.data_sel__mec_release_mem__send_gpu_clock_counter, self.pm4.int_sel__mec_release_mem__none)
|
||||
self.acquire_mem() # ensure timestamp is written
|
||||
return self
|
||||
@@ -774,8 +784,16 @@ class KFDIface:
|
||||
|
||||
raise RuntimeError("\n".join(report))
|
||||
|
||||
def is_in_profile_mode(self):
|
||||
return self.dev.target[0] == 9 or FileIOInterface(f'{self.dev_sysfs_path}/power_dpm_force_performance_level').read()[:16] == 'profile_standard'
|
||||
def require_profile_mode(self, can_set_mode=True):
|
||||
if self.dev.target[0] == 9: return
|
||||
fn = f'{self.dev_sysfs_path}/power_dpm_force_performance_level'
|
||||
if (perflevel:=FileIOInterface(fn).read().strip()) != 'profile_standard':
|
||||
if can_set_mode:
|
||||
atexit.register(lambda: os.system(f"echo '{perflevel}' | sudo tee {fn} > /dev/null"))
|
||||
os.system(f"echo 'profile_standard' | sudo tee {fn} > /dev/null")
|
||||
self.require_profile_mode(can_set_mode=False)
|
||||
else:
|
||||
raise RuntimeError("PMC/SQTT requires stable power state: run `amd-smi set -l stable_std` for KFD iface")
|
||||
|
||||
class PCIIface(PCIIfaceBase):
|
||||
gpus:ClassVar[list[str]] = []
|
||||
@@ -786,7 +804,7 @@ class PCIIface(PCIIfaceBase):
|
||||
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)
|
||||
|
||||
def is_in_profile_mode(self): return True
|
||||
def require_profile_mode(self): return True
|
||||
|
||||
def _setup_adev(self, pci_dev:PCIDevice, dma_regions:list[tuple[int, MMIOInterface]]|None=None):
|
||||
self.dev_impl:AMDev = AMDev(pci_dev, dma_regions)
|
||||
@@ -908,7 +926,8 @@ class AMDDevice(HCQCompiled):
|
||||
self.sdma_queue = self.create_queue(kfd.KFD_IOC_QUEUE_TYPE_SDMA, 0x200 if self.is_usb() else (16 << 20))
|
||||
|
||||
compilers:list[CompilerPairT] = [(functools.partial(AMDRenderer, self.arch), functools.partial(HIPCompiler, self.arch)),
|
||||
(functools.partial(AMDLLVMRenderer, self.arch), functools.partial(AMDLLVMCompiler, self.arch))]
|
||||
(functools.partial(AMDLLVMRenderer, self.arch), functools.partial(AMDLLVMCompiler, self.arch)),
|
||||
(functools.partial(AMDRenderer, self.arch), functools.partial(HIPCCCompiler, self.arch))]
|
||||
|
||||
super().__init__(device, AMDAllocator(self), compilers, functools.partial(AMDProgram, self), AMDSignal,
|
||||
functools.partial(AMDComputeAQLQueue if self.is_aql else AMDComputeQueue, self),
|
||||
@@ -922,7 +941,7 @@ class AMDDevice(HCQCompiled):
|
||||
self.pmc_enabled = PROFILE and PMC > 0
|
||||
if self.pmc_enabled:
|
||||
if self.target[0] not in {9, 11, 12}: raise RuntimeError(f'PMC are not supported on gc:{self.target}')
|
||||
if not self.iface.is_in_profile_mode(): raise RuntimeError("PMC requires stable power state: run `amd-smi set -l stable_std` for KFD iface")
|
||||
self.iface.require_profile_mode()
|
||||
|
||||
self.pmc_sched:list[PMCSample] = []
|
||||
self.pmc_counters = import_pmc(self.target)
|
||||
@@ -940,7 +959,7 @@ class AMDDevice(HCQCompiled):
|
||||
self.sqtt_enabled = PROFILE and SQTT > 0
|
||||
if self.sqtt_enabled:
|
||||
if self.target[0] not in {9, 11, 12}: raise RuntimeError(f'SQ Thread Tracing is not supported on gc:{self.target}')
|
||||
if not self.iface.is_in_profile_mode(): raise RuntimeError("SQTT requires stable power state: run `amd-smi set -l stable_std` for KFD iface")
|
||||
self.iface.require_profile_mode()
|
||||
|
||||
SQTT_BUFFER_SIZE = getenv("SQTT_BUFFER_SIZE", 256) # in mb, per shader engine
|
||||
self.sqtt_buffers = [self.allocator.alloc(SQTT_BUFFER_SIZE << 20, BufferSpec(nolru=True, uncached=True)) for _ in range(self.se_cnt)]
|
||||
|
||||
@@ -360,7 +360,7 @@ class NVKIface:
|
||||
self.dma_class:int = next(c for c in [nv_gpu.BLACKWELL_DMA_COPY_B, nv_gpu.AMPERE_DMA_COPY_B] if c in self.nvclasses)
|
||||
|
||||
usermode = self.rm_alloc(self.dev.subdevice, self.usermode_class)
|
||||
return usermode, MMIOInterface(self._gpu_map_to_cpu(usermode, mmio_sz:=0x10000, flags=2), mmio_sz, fmt='I')
|
||||
return usermode, MMIOInterface(self._gpu_map_to_cpu(usermode, mmio_sz:=0x10000), mmio_sz, fmt='I')
|
||||
|
||||
def setup_vm(self, vaspace):
|
||||
self.rm_control(self.dev.subdevice, nv_gpu.NV2080_CTRL_CMD_GPU_GET_GID_INFO, raw_uuid:=nv_gpu.NV2080_CTRL_GPU_GET_GID_INFO_PARAMS(
|
||||
@@ -514,7 +514,8 @@ class NVDevice(HCQCompiled[HCQSignal]):
|
||||
channel_params = nv_gpu.NV_CHANNEL_GROUP_ALLOCATION_PARAMETERS(engineType=nv_gpu.NV2080_ENGINE_TYPE_GRAPHICS)
|
||||
channel_group = self.iface.rm_alloc(self.nvdevice, nv_gpu.KEPLER_CHANNEL_GROUP_A, channel_params)
|
||||
|
||||
gpfifo_area = self.iface.alloc(0x200000, contiguous=True, cpu_access=True, force_devmem=True, map_flags=0x10d0000)
|
||||
gpfifo_area = self.iface.alloc(0x200000, contiguous=True, cpu_access=True, force_devmem=True,
|
||||
map_flags=(nv_gpu.NVOS33_FLAGS_CACHING_TYPE_WRITECOMBINED<<23))
|
||||
|
||||
ctxshare_params = nv_gpu.NV_CTXSHARE_ALLOCATION_PARAMETERS(hVASpace=vaspace, flags=nv_gpu.NV_CTXSHARE_ALLOCATION_FLAGS_SUBCONTEXT_ASYNC)
|
||||
ctxshare = self.iface.rm_alloc(channel_group, nv_gpu.FERMI_CONTEXT_SHARE_A, ctxshare_params)
|
||||
|
||||
@@ -9,7 +9,7 @@ from tinygrad.runtime.support.hcq import FileIOInterface, MMIOInterface
|
||||
from tinygrad.runtime.autogen import kgsl, adreno
|
||||
from tinygrad.runtime.ops_cl import CLCompiler, CLDevice
|
||||
from tinygrad.renderer.cstyle import QCOMRenderer
|
||||
from tinygrad.helpers import getenv, mv_address, to_mv, round_up, data64_le, prod, fromimport, cpu_profile, lo32, PROFILE
|
||||
from tinygrad.helpers import getenv, mv_address, to_mv, round_up, data64_le, prod, fromimport, cpu_profile, lo32, PROFILE, suppress_finalizing
|
||||
from tinygrad.runtime.support.system import System
|
||||
if getenv("IOCTL"): import extra.qcom_gpu_driver.opencl_ioctl # noqa: F401 # pylint: disable=unused-import
|
||||
|
||||
@@ -317,6 +317,7 @@ class QCOMAllocator(HCQAllocatorBase):
|
||||
self.dev.synchronize()
|
||||
return to_mv(cast(int, src.va_addr), src.size)
|
||||
|
||||
@suppress_finalizing
|
||||
def _free(self, opaque, options:BufferSpec):
|
||||
self.dev.synchronize()
|
||||
self.dev._gpu_free(opaque)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import socket, json, asyncio, threading
|
||||
import socket, json, asyncio, threading, math
|
||||
from contextlib import asynccontextmanager
|
||||
from tinygrad.device import Compiled, Allocator
|
||||
from tinygrad.helpers import DEBUG, getenv
|
||||
@@ -92,9 +92,9 @@ class TinyFSAllocator(Allocator[TinyFSDevice]):
|
||||
if dest.device.op == "LOAD":
|
||||
locs = self.dev.sfile.readline()
|
||||
dest.copyout_queue = json.loads(locs)
|
||||
dest.hash_buf[:] = src.tobytes()
|
||||
dest.hash_buf = src.tobytes()
|
||||
elif dest.device.op == "STORE":
|
||||
expected_hashes = dest.size // Tensor.CHUNK_SIZE
|
||||
expected_hashes = math.ceil(dest.size / Tensor.CHUNK_SIZE)
|
||||
dest.hash_buf = bytearray(expected_hashes * 16)
|
||||
self.dev.sfile.readinto(dest.hash_buf)
|
||||
|
||||
|
||||
@@ -65,7 +65,9 @@ def import_ip_offsets(ip): return type("IPOFF", (object,), import_header(f"inclu
|
||||
|
||||
def import_pmc(ip) -> dict[str, tuple[str, int]]:
|
||||
res:dict[str, tuple[str, int]] = {}
|
||||
arch = f"gfx{ip[0]}{ip[1]:x}{ip[2]:x}"
|
||||
|
||||
# NOTE: precise arch for mi300+, generic for others, since rocm headers lack some archs
|
||||
arch = f"gfx{ip[0]}{ip[1]:x}{ip[2]:x}" if ip[0] == 9 else f"gfx{ip[0]}"
|
||||
|
||||
for sec in header_download("rocprofiler-compute/src/rocprof_compute_soc/profile_configs/counter_defs.yaml", url=ROCM_URL).split('- name: ')[1:]:
|
||||
for arch_spec in sec.split('- architectures:')[1:]:
|
||||
|
||||
+203
-120
@@ -1,182 +1,265 @@
|
||||
import ctypes.util, importlib.metadata, itertools, re, functools, os
|
||||
from tinygrad.helpers import flatten, unwrap, fromimport
|
||||
import ctypes, itertools, re, functools, os
|
||||
from tinygrad.helpers import flatten, unwrap
|
||||
from tinygrad.runtime.autogen import libclang as clang # hmmm
|
||||
from typing import Iterator
|
||||
|
||||
assert importlib.metadata.version('clang')[:2] == "20", 'clang version 20 required, pip install "clang==20.1.0"'
|
||||
from clang.cindex import Config, Index, Cursor, Type, CursorKind as CK, TranslationUnit as TU, LinkageKind as LK, TokenKind as ToK, TypeKind as TK
|
||||
from clang.cindex import PrintingPolicy as PP, PrintingPolicyProperty as PPP, SourceRange
|
||||
def unwrap_cursor(c: clang.CXCursor) -> clang.CXCursor:
|
||||
assert c != clang.clang_getNullCursor()
|
||||
return c
|
||||
|
||||
libclang = functools.partial(fromimport, "tinygrad.runtime.autogen.libclang") # we can't actually import this, because then we can't generate it
|
||||
def children(c: clang.CXCursor) -> list[clang.CXCursor]:
|
||||
ret = []
|
||||
@clang.CXCursorVisitor
|
||||
def visitor(child, _0, _1):
|
||||
nonlocal ret
|
||||
ret.append(child)
|
||||
return clang.CXChildVisit_Continue
|
||||
clang.clang_visitChildren(c, visitor, None)
|
||||
return ret
|
||||
|
||||
if not Config.loaded: Config.set_library_file(os.getenv("LIBCLANG_PATH", ctypes.util.find_library("clang-20")))
|
||||
def fields(t: clang.CXType) -> list[clang.CXCursor]:
|
||||
ret = []
|
||||
@clang.CXFieldVisitor
|
||||
def visitor(child, _):
|
||||
nonlocal ret
|
||||
ret.append(child)
|
||||
return clang.CXVisit_Continue
|
||||
clang.clang_Type_visitFields(t, visitor, None)
|
||||
return ret
|
||||
|
||||
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)
|
||||
for i in range(clang.clang_Cursor_getNumArguments(c) if isinstance(c, clang.CXCursor) else clang.clang_getNumArgTypes(c)))
|
||||
|
||||
class Tokens:
|
||||
def __init__(self, c: clang.CXCursor):
|
||||
clang.clang_tokenize(tu:=clang.clang_Cursor_getTranslationUnit(c), clang.clang_getCursorExtent(c),
|
||||
toks:=(ctypes.POINTER(clang.CXToken)()), cnt:=ctypes.c_uint32())
|
||||
self.tu, self.toks = tu, toks[:cnt.value]
|
||||
for t in self.toks: t._tu = tu
|
||||
|
||||
def __getitem__(self, idx): return self.toks[idx]
|
||||
def __len__(self): return len(self.toks)
|
||||
|
||||
def __del__(self):
|
||||
if self.toks: clang.clang_disposeTokens(self.tu, self.toks[0], len(self.toks))
|
||||
|
||||
def cxs(fn):
|
||||
@functools.wraps(fn)
|
||||
def wrap(*args, **kwargs) -> str:
|
||||
if ctypes.cast(clang.clang_getCString(cxs:=fn(*args, **kwargs)), ctypes.c_void_p).value is None: return ""
|
||||
ret = ctypes.string_at(clang.clang_getCString(cxs)).decode()
|
||||
clang.clang_disposeString(cxs)
|
||||
return ret
|
||||
return wrap
|
||||
|
||||
# TODO: caching this would be nice?
|
||||
@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 fst(c): return next(c.get_children())
|
||||
def last(c): return list(c.get_children())[-1]
|
||||
def readext(f, fst, snd=None):
|
||||
with open(f, "r") as f:
|
||||
f.seek(start:=(fst.start.offset if isinstance(fst, SourceRange) else fst))
|
||||
return f.read((fst.end.offset if isinstance(fst, SourceRange) else snd)-start)
|
||||
def attrs(c): return list(filter(lambda k: (v:=k.value) >= 400 and v < 500, map(lambda c: c.kind, c.get_children())))
|
||||
with open(f, "r") as f: # reopening this every time is dumb...
|
||||
f.seek(start:=loc_off(clang.clang_getRangeStart(fst) if isinstance(fst, clang.CXSourceRange) else fst))
|
||||
return f.read(loc_off(clang.clang_getRangeEnd(fst) if isinstance(fst, clang.CXSourceRange) else snd)-start)
|
||||
def attrs(c): return list(filter(lambda k: (v:=k.value) >= 400 and v < 500, map(lambda c: c.kind, children(c))))
|
||||
|
||||
def protocols(t): yield from (Cursor.from_result(libclang("clang_Type_getObjCProtocolDecl")(t, i), t)
|
||||
for i in range(libclang("clang_Type_getNumObjCProtocolRefs")(t)))
|
||||
def basetype(t): return Type.from_result(libclang("clang_Type_getObjCObjectBaseType")(t), (t,))
|
||||
def protocols(t): yield from (clang.clang_Type_getObjCProtocolDecl(t, i) for i in range(clang.clang_Type_getNumObjCProtocolRefs(t)))
|
||||
def basetype(t): return clang.clang_Type_getObjCObjectBaseType(t)
|
||||
|
||||
base_rules = [(r'\s*\\\n\s*', ' '), (r'\s*\n\s*', ' '), (r'//.*', ''), (r'/\*.*?\*/', ''), (r'\b(0[xX][0-9a-fA-F]+|\d+)[uUlL]+\b', r'\1'),
|
||||
(r'\b0+(?=\d)', ''), (r'\s*&&\s*', r' and '), (r'\s*\|\|\s*', r' or '), (r'\s*!\s*', ' not '),
|
||||
(r'(struct|union|enum)\s*([a-zA-Z_][a-zA-Z0-9_]*\b)', r'\1_\2'),
|
||||
(r'\((unsigned )?(char|uint64_t)\)', ''), (r'^.*\d+:\d+.*$', ''), (r'^.*\w##\w.*$', '')]
|
||||
|
||||
ints = (TK.INT, TK.UINT, TK.LONG, TK.ULONG, TK.LONGLONG, TK.ULONGLONG)
|
||||
specs = (CK.OBJC_SUPER_CLASS_REF,)
|
||||
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 = (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']
|
||||
|
||||
def gen(dll, files, args=[], prolog=[], rules=[], epilog=[], recsym=False, use_errno=False, anon_names={}, types={}, parse_macros=True):
|
||||
macros, lines, anoncnt, types, objc = [], [], itertools.count().__next__, {k:(v,True) for k,v in types.items()}, False
|
||||
def tname(t, suggested_name=None, typedef=None) -> str:
|
||||
suggested_name = anon_names.get(f"{(decl:=t.get_declaration()).location.file}:{decl.location.line}", suggested_name)
|
||||
suggested_name = anon_names.get(f"{loc_file(loc(decl:=clang.clang_getTypeDeclaration(t)))}:{loc_line(loc(decl))}", suggested_name)
|
||||
nonlocal lines, types, anoncnt, objc
|
||||
tmap = {TK.VOID:"None", TK.CHAR_U:"ctypes.c_ubyte", TK.UCHAR:"ctypes.c_ubyte", TK.CHAR_S:"ctypes.c_char", TK.SCHAR:"ctypes.c_char",
|
||||
**{getattr(TK, k):f"ctypes.c_{k.lower()}" for k in ["BOOL", "WCHAR", "FLOAT", "DOUBLE", "LONGDOUBLE"]},
|
||||
**{getattr(TK, k):f"ctypes.c_{'u' if 'U' in k else ''}int{sz}" for sz,k in
|
||||
[(16, "USHORT"), (16, "SHORT"), (32, "UINT"), (32, "INT"), (64, "ULONG"), (64, "LONG"), (64, "ULONGLONG"), (64, "LONGLONG")]}}
|
||||
tmap = {clang.CXType_Void:"None", clang.CXType_Char_U:"ctypes.c_ubyte", clang.CXType_UChar:"ctypes.c_ubyte", clang.CXType_Char_S:"ctypes.c_char",
|
||||
clang.CXType_SChar:"ctypes.c_byte",
|
||||
**{getattr(clang, f'CXType_{k}'):f"ctypes.c_{k.lower()}" for k in ["Bool", "WChar", "Float", "Double", "LongDouble"]},
|
||||
**{getattr(clang, f'CXType_{k}'):f"ctypes.c_{'u' if 'U' in k else ''}int{sz}" for sz,k in
|
||||
[(16, "UShort"), (16, "Short"), (32, "UInt"), (32, "Int"), (64, "ULong"), (64, "Long"), (64, "ULongLong"), (64, "LongLong")]}}
|
||||
|
||||
if t.kind in tmap: return tmap[t.kind]
|
||||
if t.spelling in types and types[t.spelling][1]: return types[t.spelling][0]
|
||||
if ((f:=t).kind in (fks:=(TK.FUNCTIONPROTO, TK.FUNCTIONNOPROTO))) or (t.kind == TK.POINTER and (f:=t.get_pointee()).kind in fks):
|
||||
return f"ctypes.CFUNCTYPE({tname(f.get_result())}{(', '+', '.join(map(tname, f.argument_types()))) if f.kind==TK.FUNCTIONPROTO else ''})"
|
||||
if nm(t) in types and types[nm(t)][1]: return types[nm(t)][0]
|
||||
if ((f:=t).kind in fns) or (t.kind == clang.CXType_Pointer and (f:=clang.clang_getPointeeType(t)).kind in fns):
|
||||
return (f"ctypes.CFUNCTYPE({tname(clang.clang_getResultType(f))}" +
|
||||
((', '+', '.join(map(tname, arguments(f)))) if f.kind==clang.CXType_FunctionProto else '') + ")")
|
||||
match t.kind:
|
||||
case TK.POINTER: return "ctypes.c_void_p" if (ptr:=t.get_pointee()).kind == TK.VOID else f"ctypes.POINTER({tname(ptr)})"
|
||||
case TK.OBJCOBJECTPOINTER: return tname(t.get_pointee()) # TODO: this seems wrong
|
||||
case TK.ELABORATED: return tname(t.get_named_type(), suggested_name)
|
||||
case TK.TYPEDEF if t.spelling == t.get_canonical().spelling: return tname(t.get_canonical())
|
||||
case TK.TYPEDEF:
|
||||
defined, nm = (canon:=t.get_canonical()).spelling in types, tname(canon, typedef=t.spelling.replace('::', '_'))
|
||||
types[t.spelling] = nm if t.spelling.startswith("__") else t.spelling.replace('::', '_'), True
|
||||
case clang.CXType_Pointer:
|
||||
return "ctypes.c_void_p" if (p:=clang.clang_getPointeeType(t)).kind==clang.CXType_Void else f"ctypes.POINTER({tname(p)})"
|
||||
case clang.CXType_ObjCObjectPointer: return tname(clang.clang_getPointeeType(t)) # TODO: this seems wrong
|
||||
case clang.CXType_Elaborated: return tname(clang.clang_Type_getNamedType(t), suggested_name)
|
||||
case clang.CXType_Typedef if nm(t) == nm(canon:=clang.clang_getCanonicalType(t)): return tname(canon)
|
||||
case clang.CXType_Typedef:
|
||||
defined, cnm = nm(canon:=clang.clang_getCanonicalType(t)) in types, tname(canon, typedef=nm(t).replace('::', '_'))
|
||||
types[nm(t)] = cnm if nm(t).startswith("__") else nm(t).replace('::', '_'), True
|
||||
# RECORDs need to handle typedefs specially to allow for self-reference
|
||||
if canon.kind != TK.RECORD or defined: lines.append(f"{t.spelling.replace('::', '_')} = {nm}")
|
||||
return types[t.spelling][0]
|
||||
case TK.RECORD:
|
||||
if canon.kind != clang.CXType_Record or defined: lines.append(f"{nm(t).replace('::', '_')} = {cnm}")
|
||||
return types[nm(t)][0]
|
||||
case clang.CXType_Record:
|
||||
# TODO: packed unions
|
||||
# check for forward declaration
|
||||
if t.spelling in types: types[t.spelling] = (nm:=types[t.spelling][0]), len(list(t.get_fields())) != 0
|
||||
if nm(t) in types: types[nm(t)] = (tnm:=types[nm(t)][0]), len(fields(t)) != 0
|
||||
else:
|
||||
if decl.is_anonymous():
|
||||
types[t.spelling] = (nm:=(suggested_name or (f"_anon{'struct' if decl.kind == CK.STRUCT_DECL else 'union'}{anoncnt()}")), True)
|
||||
else: types[t.spelling] = (nm:=t.spelling.replace(' ', '_').replace('::', '_')), len(list(t.get_fields())) != 0
|
||||
lines.append(f"class {nm}({'Struct' if decl.kind==CK.STRUCT_DECL else 'ctypes.Union'}): pass")
|
||||
if typedef: lines.append(f"{typedef} = {nm}")
|
||||
if (is_packed:=(CK.PACKED_ATTR in attrs(decl)) or ((N:=t.get_align()) != max([f.type.get_align() for f in t.get_fields()], default=N))):
|
||||
if t.get_align() != 1:
|
||||
print(f"WARNING: ignoring alignment={t.get_align()} on {t.spelling}")
|
||||
if clang.clang_Cursor_isAnonymous(decl):
|
||||
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(t)}")
|
||||
is_packed = False
|
||||
acnt = itertools.count().__next__
|
||||
ll=[" ("+((fn:=f"'_{acnt()}'")+f", {tname(f.type, nm+fn[1:-1])}" if f.is_anonymous_record_decl() else f"'{f.spelling}', "+
|
||||
tname(f.type, f'{nm}_{f.spelling}'))+(f',{f.get_bitfield_width()}' if f.is_bitfield() else '')+")," for f in t.get_fields()]
|
||||
lines.extend(([f"{nm}._anonymous_ = ["+", ".join(f"'_{i}'" for i in range(n))+"]"] if (n:=acnt()) else [])+
|
||||
([f"{nm}._packed_ = True"] * is_packed)+([f"{nm}._fields_ = [",*ll,"]"] if ll else []))
|
||||
return nm
|
||||
case TK.ENUM:
|
||||
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 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
|
||||
case clang.CXType_Enum:
|
||||
# TODO: C++ and GNU C have forward declared enums
|
||||
if decl.is_anonymous(): types[t.spelling] = suggested_name or f"_anonenum{anoncnt()}", True
|
||||
else: types[t.spelling] = t.spelling.replace(' ', '_').replace('::', '_'), True
|
||||
lines.append(f"{types[t.spelling][0]} = CEnum({tname(decl.enum_type)})\n" +
|
||||
"\n".join(f"{e.spelling} = {types[t.spelling][0]}.define('{e.spelling}', {e.enum_value})" for e in decl.get_children()
|
||||
if e.kind == CK.ENUM_CONSTANT_DECL) + "\n")
|
||||
return types[t.spelling][0]
|
||||
case TK.CONSTANTARRAY:
|
||||
return f"({tname(t.get_array_element_type(), suggested_name.rstrip('s') if suggested_name else None)} * {t.get_array_size()})"
|
||||
case TK.INCOMPLETEARRAY: return f"({tname(t.get_array_element_type(), suggested_name.rstrip('s') if suggested_name else None)} * 0)"
|
||||
case TK.OBJCINTERFACE:
|
||||
is_defn = bool([f.kind for f in decl.get_children() if f.kind in (CK.OBJC_INSTANCE_METHOD_DECL, CK.OBJC_CLASS_METHOD_DECL)])
|
||||
if (nm:=t.spelling) not in types: lines.append(f"class {nm}(objc.Spec): pass")
|
||||
types[nm] = nm, is_defn
|
||||
if clang.clang_Cursor_isAnonymous(decl): types[nm(t)] = suggested_name or f"_anonenum{anoncnt()}", True
|
||||
else: types[nm(t)] = nm(t).replace(' ', '_').replace('::', '_'), True
|
||||
ety = clang.clang_getEnumDeclIntegerType(decl)
|
||||
def value(e): return (clang.clang_getEnumConstantDeclUnsignedValue if ety.kind in uints else clang.clang_getEnumConstantDeclValue)(e)
|
||||
lines.append(f"{types[nm(t)][0]} = CEnum({tname(ety)})\n" +
|
||||
"\n".join(f"{nm(e)} = {types[nm(t)][0]}.define('{nm(e)}', {value(e)})" for e in children(decl)
|
||||
if e.kind == clang.CXCursor_EnumConstantDecl) + "\n")
|
||||
return types[nm(t)][0]
|
||||
case clang.CXType_ConstantArray:
|
||||
return f"({tname(clang.clang_getArrayElementType(t),suggested_name.rstrip('s') if suggested_name else None)} * {clang.clang_getArraySize(t)})"
|
||||
case clang.CXType_IncompleteArray:
|
||||
return f"({tname(clang.clang_getArrayElementType(t), suggested_name.rstrip('s') if suggested_name else None)} * 0)"
|
||||
case clang.CXType_ObjCInterface:
|
||||
is_defn = bool([f.kind for f in children(decl) if f.kind in (clang.CXCursor_ObjCInstanceMethodDecl, clang.CXCursor_ObjCClassMethodDecl)])
|
||||
if (tnm:=nm(t)) not in types: lines.append(f"class {tnm}(objc.Spec): pass")
|
||||
types[tnm] = tnm, is_defn
|
||||
if is_defn:
|
||||
ims, cms = parse_objc_spec(decl, t.spelling, CK.OBJC_INSTANCE_METHOD_DECL), parse_objc_spec(decl, t.spelling, CK.OBJC_CLASS_METHOD_DECL)
|
||||
lines.extend([*([f"{nm}._bases_ = [{', '.join(bs)}]"] if (bs:=[tname(b.type) for b in decl.get_children() if b.kind in specs]) else []),
|
||||
*([f"{nm}._methods_ = [", *ims, ']'] if ims else []), *([f"{nm}._classmethods_ = [", *cms, ']'] if cms else [])])
|
||||
return nm
|
||||
case TK.OBJCSEL: return "objc.id_"
|
||||
case TK.OBJCID: return (objc:=True, "objc.id_")[1]
|
||||
case TK.OBJCOBJECT:
|
||||
if basetype(t).kind != TK.OBJCID: raise NotImplementedError(f"generics unsupported: {t.spelling}")
|
||||
ps = [proto(p) for p in protocols(t)]
|
||||
if len(ps) == 0:
|
||||
types[t.spelling] = "objc.id_", True
|
||||
ims, cms = parse_objc_spec(decl, tnm, clang.CXCursor_ObjCInstanceMethodDecl), parse_objc_spec(decl, tnm, clang.CXCursor_ObjCClassMethodDecl)
|
||||
bases = [tname(clang.clang_getCursorType(b)) for b in children(decl) if b.kind in specs]
|
||||
lines.extend([*([f"{tnm}._bases_ = [{', '.join(bases)}]"] if bases else []),
|
||||
*([f"{tnm}._methods_ = [", *ims, ']'] if ims else []), *([f"{tnm}._classmethods_ = [", *cms, ']'] if cms else [])])
|
||||
return tnm
|
||||
case clang.CXType_ObjCSel: return "objc.id_"
|
||||
case clang.CXType_ObjCId: return (objc:=True, "objc.id_")[1]
|
||||
case clang.CXType_ObjCObject:
|
||||
if basetype(t).kind != clang.CXType_ObjCId: raise NotImplementedError(f"generics unsupported: {nm(t)}")
|
||||
if len(ps:=[proto(p) for p in protocols(t)]) == 0:
|
||||
types[nm(t)] = "objc.id_", True
|
||||
return "objc.id_"
|
||||
if len(ps) == 1:
|
||||
types[t.spelling] = ps[0], True
|
||||
types[nm(t)] = ps[0], True
|
||||
return ps[0]
|
||||
types[t.spelling] = (nm:=f"_anondynamic{anoncnt()}"), True
|
||||
lines.append(f"class {nm}({', '.join(p for p in ps)}): pass # {t.spelling}")
|
||||
return nm
|
||||
types[nm(t)] = (tnm:=f"_anondynamic{anoncnt()}"), True
|
||||
lines.append(f"class {tnm}({', '.join(ps)}): pass # {nm(t)}")
|
||||
return tnm
|
||||
case _: raise NotImplementedError(f"unsupported type {t.kind}")
|
||||
|
||||
# parses an objc @interface or @protocol, returning a list of declerations that objc.Spec can parse, for the specified kind
|
||||
# NB: ivars are unsupported
|
||||
def parse_objc_spec(decl:Cursor, nm:str, kind:CK) -> list[str]:
|
||||
def parse_objc_spec(decl:clang.CXCursor, dnm:str, kind) -> list[str]:
|
||||
nonlocal lines, types
|
||||
if decl is None: return []
|
||||
ms = []
|
||||
for d in filter(lambda d: d.kind == kind, decl.get_children()):
|
||||
for d in filter(lambda d: d.kind == kind, children(decl)):
|
||||
rollback = lines, types
|
||||
try: ms.append(f" ('{d.spelling}', {repr('instancetype') if (rt:=d.result_type).spelling=='instancetype' else tname(rt)}, "
|
||||
f"[{', '.join('instancetype' if a.spelling == 'instancetype' else tname(a.type) for a in d.get_arguments())}]" +
|
||||
(", True" if CK.NS_RETURNS_RETAINED in attrs(d) or (any(d.spelling.startswith(s) for s in arc_families) and rt.kind!=TK.VOID) else "") + "),")
|
||||
try: ms.append(f" ('{nm(d)}', {repr('instancetype') if nm(rt:=clang.clang_getCursorResultType(d))=='instancetype' else tname(rt)}, " +
|
||||
f"[{', '.join('instancetype' if nm(a) == 'instancetype' else tname(clang.clang_getCursorType(a)) for a in arguments(d))}]" +
|
||||
(", True" * (clang.CXCursor_NSReturnsRetained in attrs(d) or (any(nm(d).startswith(s) for s in arc_families) and rt.kind!=clang.CXType_Void)))
|
||||
+ "),")
|
||||
except NotImplementedError as e:
|
||||
print(f"skipping {nm}.{d.spelling}: {e}")
|
||||
print(f"skipping {dnm}.{nm(d)}: {e}")
|
||||
lines, types = rollback
|
||||
return ms
|
||||
|
||||
# libclang doesn't have a "type" for @protocol, so we have to do this here...
|
||||
def proto(decl):
|
||||
nonlocal lines, types
|
||||
if (nm:=decl.spelling) in types and types[nm][1]: return types[nm][0]
|
||||
if (dnm:=nm(decl)) in types and types[dnm][1]: return types[dnm][0]
|
||||
# check if this is a forward declaration
|
||||
is_defn = bool([f.kind for f in decl.get_children() if f.kind in (CK.OBJC_INSTANCE_METHOD_DECL, CK.OBJC_CLASS_METHOD_DECL)])
|
||||
if nm not in types: lines.append(f"class {nm}(objc.Spec): pass")
|
||||
types[nm] = nm, is_defn
|
||||
is_defn = bool([f.kind for f in children(decl) if f.kind in (clang.CXCursor_ObjCInstanceMethodDecl, clang.CXCursor_ObjCClassMethodDecl)])
|
||||
if dnm not in types: lines.append(f"class {dnm}(objc.Spec): pass")
|
||||
types[dnm] = dnm, is_defn
|
||||
if is_defn:
|
||||
bs = [proto(b) for b in decl.get_children() if b.kind==CK.OBJC_PROTOCOL_REF and b.spelling != decl.spelling]
|
||||
ims, cms = parse_objc_spec(decl, nm, CK.OBJC_INSTANCE_METHOD_DECL), parse_objc_spec(decl, nm, CK.OBJC_CLASS_METHOD_DECL)
|
||||
lines.extend([*([f"{nm}._bases_ = [{', '.join(bs)}]"] if bs else []),
|
||||
*([f"{nm}._methods_ = [", *ims, "]"] if ims else []), *([f"{nm}._classmethods_ = [", *cms, "]"] if cms else [])])
|
||||
return nm
|
||||
bases = [proto(b) for b in children(decl) if b.kind==clang.CXCursor_ObjCProtocolRef and nm(b) != nm(decl)]
|
||||
ims, cms = parse_objc_spec(decl, dnm, clang.CXCursor_ObjCInstanceMethodDecl), parse_objc_spec(decl, dnm, clang.CXCursor_ObjCClassMethodDecl)
|
||||
lines.extend([*([f"{dnm}._bases_ = [{', '.join(bases)}]"] if bases else []),
|
||||
*([f"{dnm}._methods_ = [", *ims, "]"] if ims else []), *([f"{dnm}._classmethods_ = [", *cms, "]"] if cms else [])])
|
||||
return dnm
|
||||
|
||||
for f in files:
|
||||
tu = Index.create().parse(f, args, options=TU.PARSE_DETAILED_PROCESSING_RECORD)
|
||||
(pp:=PP.create(tu.cursor)).set_property(PPP.TerseOutput, 1)
|
||||
for c in tu.cursor.walk_preorder():
|
||||
if str(c.location.file) != str(f) and (not recsym or c.kind not in (CK.FUNCTION_DECL,)): continue
|
||||
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)
|
||||
# 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:
|
||||
case CK.FUNCTION_DECL if c.linkage == LK.EXTERNAL and dll:
|
||||
case clang.CXCursor_FunctionDecl if clang.clang_getCursorLinkage(c) == clang.CXLinkage_External and dll:
|
||||
# TODO: we could support name-mangling
|
||||
lines.append(f"# {c.pretty_printed(pp)}\ntry: ({c.spelling}:=dll.{c.spelling}).restype, {c.spelling}.argtypes = "
|
||||
f"{tname(c.result_type)}, [{', '.join(tname(arg.type) for arg in c.get_arguments())}]\nexcept AttributeError: pass\n")
|
||||
if CK.NS_RETURNS_RETAINED in attrs(c): lines.append(f"{c.spelling} = objc.returns_retained({c.spelling})")
|
||||
case CK.STRUCT_DECL | CK.UNION_DECL | CK.TYPEDEF_DECL | CK.ENUM_DECL | CK.OBJC_INTERFACE_DECL: tname(c.type)
|
||||
case CK.MACRO_DEFINITION if parse_macros and len(toks:=list(c.get_tokens())) > 1:
|
||||
if toks[1].spelling == '(' and toks[0].extent.end.column == toks[1].extent.start.column:
|
||||
lines.append(f"try: ({nm(c)}:=dll.{nm(c)}).restype, {nm(c)}.argtypes = {tname(clang.clang_getCursorResultType(c))}, "
|
||||
f"[{', '.join(tname(clang.clang_getCursorType(arg)) for arg in arguments(c))}]\nexcept AttributeError: pass\n")
|
||||
if clang.CXCursor_NSReturnsRetained in attrs(c): lines.append(f"{nm(c)} = objc.returns_retained({nm(c)})")
|
||||
case (clang.CXCursor_StructDecl | clang.CXCursor_UnionDecl | clang.CXCursor_TypedefDecl | clang.CXCursor_EnumDecl
|
||||
| clang.CXCursor_ObjCInterfaceDecl): tname(clang.clang_getCursorType(c))
|
||||
case clang.CXCursor_MacroDefinition if parse_macros and len(toks:=Tokens(c)) > 1:
|
||||
if nm(toks[1])=='(' and clang.clang_equalLocations(clang.clang_getRangeEnd(extent(toks[0])), clang.clang_getRangeStart(extent(toks[1]))):
|
||||
it = iter(toks[1:])
|
||||
_args = [t.spelling for t in itertools.takewhile(lambda t:t.spelling!=')', it) if t.kind == ToK.IDENTIFIER]
|
||||
_args = [nm(t) for t in itertools.takewhile(lambda t:nm(t)!=')', it) if clang.clang_getTokenKind(t) == clang.CXToken_Identifier]
|
||||
if len(body:=list(it)) == 0: continue
|
||||
macros += [f"{c.spelling} = lambda {','.join(_args)}: {readext(f, body[0].location.offset, toks[-1].extent.end.offset)}"]
|
||||
else: macros += [f"{c.spelling} = {readext(f, toks[1].location.offset, toks[-1].extent.end.offset)}"]
|
||||
case CK.VAR_DECL if c.linkage == LK.INTERNAL:
|
||||
if (c.type.kind == TK.CONSTANTARRAY and c.type.get_array_element_type().get_canonical().kind in ints and
|
||||
(init:=last(c)).kind == CK.INIT_LIST_EXPR and all(re.match(r"\[.*\].*=", readext(f, c.extent)) for c in init.get_children())):
|
||||
cs = init.get_children()
|
||||
macros += [f"{c.spelling} = {{{','.join(f'{readext(f,next(it:=c.get_children()).extent)}:{readext(f,next(it).extent)}' for c in cs)}}}"]
|
||||
elif c.type.get_canonical().kind in ints: macros += [f"{c.spelling} = {readext(f, last(c).extent)}"]
|
||||
else: macros += [f"{c.spelling} = {tname(c.type)}({readext(f, last(c).extent)})"]
|
||||
case CK.VAR_DECL if c.linkage == LK.EXTERNAL and dll:
|
||||
lines.append(f"try: {c.spelling} = {tname(c.type)}.in_dll(dll, '{c.spelling}')\nexcept (ValueError,AttributeError): pass")
|
||||
case CK.OBJC_PROTOCOL_DECL: proto(c)
|
||||
macros += [f"{nm(c)} = lambda{' ' * bool(_args)}{','.join(_args)}: {readext(f,loc(body[0]),clang.clang_getRangeEnd(extent(toks[-1])))}"]
|
||||
else: macros += [f"{nm(c)} = {readext(f, loc(toks[1]), clang.clang_getRangeEnd(extent(toks[-1])))}"]
|
||||
case clang.CXCursor_VarDecl if clang.clang_getCursorLinkage(c) == clang.CXLinkage_Internal:
|
||||
ty = clang.clang_getCursorType(c)
|
||||
if (ty.kind == clang.CXType_ConstantArray and clang.clang_getCanonicalType(clang.clang_getArrayElementType(ty)).kind in ints and
|
||||
(init:=children(c)[-1]).kind == clang.CXCursor_InitListExpr
|
||||
and all(re.match(r"\[.*\].*=", readext(f, extent(c))) for c in children(init))):
|
||||
cs = children(init)
|
||||
macros += [f"{nm(c)} = {{{','.join(f'{readext(f, extent(next(it:=iter(children(c)))))}:{readext(f, extent(next(it)))}' for c in cs)}}}"]
|
||||
elif clang.clang_getCanonicalType(ty).kind in ints: macros += [f"{nm(c)} = {readext(f, extent(children(c)[-1]))}"]
|
||||
else: macros += [f"{nm(c)} = {tname(ty)}({readext(f, extent(children(c)[-1]))})"]
|
||||
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)
|
||||
except NotImplementedError as e:
|
||||
print(f"skipping {c.spelling}: {e}")
|
||||
print(f"skipping {nm(c)}: {e}")
|
||||
lines, types = rollback
|
||||
clang.clang_disposeTranslationUnit(tu)
|
||||
clang.clang_disposeIndex(idx)
|
||||
main = (f"# mypy: ignore-errors\nimport ctypes{', os' if any('os' in s for s in dll) else ''}\n"
|
||||
"from tinygrad.helpers import unwrap\nfrom tinygrad.runtime.support.c import Struct, CEnum, _IO, _IOW, _IOR, _IOWR\n" + '\n'.join([*prolog,
|
||||
*(["from ctypes.util import find_library"]*any('find_library' in s for s in dll)), *(["from tinygrad.runtime.support import objc"]*objc),
|
||||
|
||||
@@ -32,6 +32,7 @@ def CEnum(typ: type[ctypes._SimpleCData]):
|
||||
|
||||
def __eq__(self, other): return self.value == other
|
||||
def __repr__(self): return self.get(self) if self.value in self.__class__._val_to_name_ else str(self.value)
|
||||
def __hash__(self): return hash(self.value)
|
||||
|
||||
return _CEnum
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user