Skip to content

Commit 58206fa

Browse files
b1tgchenyuxyz
andauthored
add amd llvm compiler (tinygrad#9519)
Co-authored-by: b1tg <b1tg@users.noreply.github.com> Co-authored-by: chenyu <chenyu@fastmail.com>
1 parent d8d65e2 commit 58206fa

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

.github/workflows/test.yml

+11
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ jobs:
549549
deps: testing_minimal${{matrix.backend=='ptx'&&',cuda'||matrix.backend=='triton'&&',triton'||''}}
550550
opencl: ${{ matrix.backend == 'gpu' && 'true' }}
551551
amd: ${{ matrix.backend == 'amd' && 'true' }}
552+
llvm: ${{ (matrix.backend == 'amd' || matrix.backend == 'llvm') && 'true' }}
552553
cuda: ${{ (matrix.backend == 'ptx' || matrix.backend == 'triton' || matrix.backend == 'nv') && 'true' }}
553554
- name: Set env
554555
run: printf "${{ matrix.backend == 'llvm' && 'LLVM=1' || matrix.backend == 'cpu' && 'CPU=1' || matrix.backend == 'gpu' && 'GPU=1' || matrix.backend == 'PTX' && 'FORWARD_ONLY=1\nJIT=1\nOPT=2\nCUDA=1\nPTX=1\nMOCKGPU=1' || matrix.backend == 'triton' && 'FORWARD_ONLY=1\nJIT=1\nOPT=2\nNV=1\nMOCKGPU=1\nTRITON=1\nTRITON_PTXAS_PATH=/usr/bin/ptxas' || matrix.backend == 'amd' && 'AMD=1\nMOCKGPU=1\nFORWARD_ONLY=1' || matrix.backend == 'nv' && 'NV=1\nMOCKGPU=1\nFORWARD_ONLY=1' }}" >> $GITHUB_ENV
@@ -565,6 +566,9 @@ jobs:
565566
- name: Run pytest (amd)
566567
if: matrix.backend=='amd'
567568
run: python -m pytest -n=auto test/test_ops.py test/test_dtype.py test/test_dtype_alu.py test/test_linearizer.py test/test_randomness.py test/imported/test_indexing.py test/test_hcq.py test/external/external_test_am.py --durations=20
569+
- name: Run pytest (amd with llvm backend)
570+
if: matrix.backend=='amd'
571+
run: python -m pytest -n=auto test/test_amd_llvm.py --durations=20
568572
- name: Run TRANSCENDENTAL math
569573
run: TRANSCENDENTAL=2 python -m pytest -n=auto test/test_ops.py::TestOps::test_sin test/test_ops.py::TestOps::test_cos test/test_ops.py::TestOps::test_tan test/test_ops.py::TestOps::test_exp test/test_ops.py::TestOps::test_log --durations=20
570574
- name: Run process replay tests
@@ -588,6 +592,7 @@ jobs:
588592
python-version: '3.11'
589593
amd: 'true'
590594
cuda: 'true'
595+
llvm: 'true'
591596
- name: Run real world test
592597
run: JIT=2 METAL=1 python -m pytest -n=auto test/models/test_real_world.py --durations=20
593598
- name: Test models (Metal)
@@ -615,6 +620,12 @@ jobs:
615620
FORWARD_ONLY: 1
616621
run: |
617622
python3 -m pytest -n=auto test/test_hcq.py test/test_tiny.py --durations=20
623+
- name: Run pytest (amd with llvm backend)
624+
env:
625+
MOCKGPU: 1
626+
AMD: 1
627+
run: |
628+
python -m pytest -n=auto test/test_amd_llvm.py --durations=20
618629
- name: Run pytest (ptx)
619630
env:
620631
MOCKGPU: 1

test/test_amd_llvm.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import unittest
2+
import numpy as np
3+
from tinygrad import Device
4+
from tinygrad.helpers import flat_mv
5+
if Device.DEFAULT=="AMD":
6+
from tinygrad.runtime.ops_amd import AMDAllocator, AMDDevice, AMDProgram
7+
from tinygrad.runtime.support.compiler_amd import AMDLLVMCompiler
8+
9+
@unittest.skipUnless(Device.DEFAULT == "AMD", "Runs only on AMD")
10+
class TestAMDLLVM(unittest.TestCase):
11+
def test_compiler(self):
12+
src = '''
13+
; https://github.com/llvm/llvm-project/blob/main/llvm/test/CodeGen/AMDGPU/imm.ll
14+
define amdgpu_kernel void @i64_imm_inline_lo(ptr addrspace(1) %out) {
15+
entry:
16+
store i64 1311768464867721221, ptr addrspace(1) %out ; 0x1234567800000005
17+
ret void
18+
}
19+
'''
20+
device = AMDDevice()
21+
compiler = AMDLLVMCompiler("gfx1100")
22+
obj = compiler.compile(src)
23+
allocator = AMDAllocator(device)
24+
a = allocator.alloc(1*8)
25+
prog = AMDProgram(device, "test", obj)
26+
prog(a, wait=True)
27+
na = np.empty(1, np.uint64)
28+
allocator._copyout(flat_mv(na.data), a)
29+
assert na == [0x1234567800000005]
30+
31+
if __name__ == '__main__':
32+
unittest.main()

tinygrad/runtime/support/compiler_amd.py

+15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ctypes, subprocess
22
import tinygrad.runtime.autogen.comgr as comgr
33
from tinygrad.device import Compiler, CompileError
4+
from tinygrad.runtime.ops_llvm import LLVMCompiler
45

56
def amdgpu_disassemble(lib:bytes):
67
asm = subprocess.check_output(["/opt/rocm/llvm/bin/llvm-objdump", '-d', '-'], input=lib)
@@ -68,3 +69,17 @@ def compile(self, src:str) -> bytes:
6869
try: return compile_hip(src, self.arch, src.split('\n', 1)[0].strip() == '.text')
6970
except RuntimeError as e: raise CompileError(e) from e
7071
def disassemble(self, lib:bytes): amdgpu_disassemble(lib)
72+
73+
class AMDLLVMCompiler(LLVMCompiler):
74+
jit = False
75+
target_arch = "AMDGPU"
76+
def __init__(self, arch: str):
77+
self.arch = arch
78+
super().__init__(self.arch, "+cumode")
79+
def __reduce__(self): return (AMDLLVMCompiler, (self.arch,))
80+
def compile(self, src:str) -> bytes:
81+
try: return super().compile(src)
82+
except RuntimeError as e:
83+
if "undefined value '@llvm.amdgcn." in str(e): raise CompileError(str(e) + "AMD with LLVM backend requires LLVM >= 18") from e
84+
raise CompileError(e) from e
85+
def disassemble(self, lib:bytes): amdgpu_disassemble(lib)

0 commit comments

Comments
 (0)