-
Notifications
You must be signed in to change notification settings - Fork 55
/
Copy pathmetal_tests.jl
86 lines (64 loc) · 3.1 KB
/
metal_tests.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
@testitem "Metal" setup=[Metal, Helpers] begin
using LLVM
############################################################################################
@testset "IR" begin
@testset "kernel functions" begin
@testset "byref aggregates" begin
kernel(x) = return
ir = sprint(io->Metal.code_llvm(io, kernel, Tuple{Tuple{Int}}))
@test occursin(r"@\w*kernel\w*\(({ i64 }|\[1 x i64\])\*", ir) ||
occursin(r"@\w*kernel\w*\(ptr", ir)
# for kernels, every pointer argument needs to take an address space
ir = sprint(io->Metal.code_llvm(io, kernel, Tuple{Tuple{Int}}; kernel=true))
@test occursin(r"@\w*kernel\w*\(({ i64 }|\[1 x i64\]) addrspace\(1\)\*", ir) ||
occursin(r"@\w*kernel\w*\(ptr addrspace\(1\)", ir)
end
@testset "byref primitives" begin
kernel(x) = return
ir = sprint(io->Metal.code_llvm(io, kernel, Tuple{Int}))
@test occursin(r"@\w*kernel\w*\(i64 ", ir)
# for kernels, every pointer argument needs to take an address space
ir = sprint(io->Metal.code_llvm(io, kernel, Tuple{Int}; kernel=true))
@test occursin(r"@\w*kernel\w*\(i64 addrspace\(1\)\*", ir) ||
occursin(r"@\w*kernel\w*\(ptr addrspace\(1\)", ir)
end
@testset "module metadata" begin
kernel() = return
ir = sprint(io->Metal.code_llvm(io, kernel, Tuple{};
dump_module=true, kernel=true))
@test occursin("air.version", ir)
@test occursin("air.language_version", ir)
@test occursin("air.max_device_buffers", ir)
end
@testset "argument metadata" begin
kernel(x) = return
ir = sprint(io->Metal.code_llvm(io, kernel, Tuple{Int};
dump_module=true, kernel=true))
@test occursin("air.buffer", ir)
# XXX: perform more exhaustive testing of argument passing metadata here,
# or just defer to execution testing in Metal.jl?
end
@testset "input arguments" begin
function kernel(ptr)
idx = ccall("extern julia.air.thread_position_in_threadgroup.i32", llvmcall, UInt32, ()) + 1
unsafe_store!(ptr, 42, idx)
return
end
ir = sprint(io->Metal.code_llvm(io, kernel, Tuple{Core.LLVMPtr{Int,1}}))
@test occursin(r"@\w*kernel\w*\(.* addrspace\(1\)\* %.+\)", ir) ||
occursin(r"@\w*kernel\w*\(ptr addrspace\(1\) %.+\)", ir)
@test occursin(r"call i32 @julia.air.thread_position_in_threadgroup.i32", ir)
ir = sprint(io->Metal.code_llvm(io, kernel, Tuple{Core.LLVMPtr{Int,1}}; kernel=true))
@test occursin(r"@\w*kernel\w*\(.* addrspace\(1\)\* %.+, i32 %thread_position_in_threadgroup\)", ir) ||
occursin(r"@\w*kernel\w*\(ptr addrspace\(1\) %.+, i32 %thread_position_in_threadgroup\)", ir)
@test !occursin(r"call i32 @julia.air.thread_position_in_threadgroup.i32", ir)
end
@testset "vector intrinsics" begin
foo(x, y) = ccall("llvm.smax.v2i64", llvmcall, NTuple{2, VecElement{Int64}},
(NTuple{2, VecElement{Int64}}, NTuple{2, VecElement{Int64}}), x, y)
ir = sprint(io->Metal.code_llvm(io, foo, (NTuple{2, VecElement{Int64}}, NTuple{2, VecElement{Int64}})))
@test occursin("air.max.s.v2i64", ir)
end
end
end
end