Skip to content

Commit 2b7f740

Browse files
Keluaamaleadt
andauthored
Use Pygments' highlighting for PTX and GCN (#659)
Co-authored-by: Tim Besard <[email protected]>
1 parent 97386e2 commit 2b7f740

File tree

4 files changed

+108
-82
lines changed

4 files changed

+108
-82
lines changed

res/pygments/ptx.py

Lines changed: 0 additions & 72 deletions
This file was deleted.

src/gcn.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ GCNCompilerTarget(dev_isa; features="") = GCNCompilerTarget(dev_isa, features)
1212

1313
llvm_triple(::GCNCompilerTarget) = "amdgcn-amd-amdhsa"
1414

15+
source_code(target::GCNCompilerTarget) = "gcn"
16+
1517
function llvm_machine(target::GCNCompilerTarget)
1618
@static if :AMDGPU LLVM.backends()
1719
return nothing

src/reflection.jl

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,92 @@ function pygmentize()
1616
return _pygmentize[]
1717
end
1818

19+
const _pygmentize_version = Ref{Union{VersionNumber, Nothing}}()
20+
function pygmentize_version()
21+
isassigned(_pygmentize_version) && return _pygmentize_version[]
22+
23+
pygmentize_cmd = pygmentize()
24+
if isnothing(pygmentize_cmd)
25+
return _pygmentize_version[] = nothing
26+
end
27+
28+
cmd = `$pygmentize_cmd -V`
29+
@static if Sys.iswindows()
30+
# Avoid encoding issues with pipes on Windows by using cmd.exe to capture stdout for us
31+
cmd = `cmd.exe /C $cmd`
32+
cmd = addenv(cmd, "PYTHONUTF8" => 1)
33+
end
34+
version_str = readchomp(cmd)
35+
36+
pos = findfirst("Pygments version ", version_str)
37+
if !isnothing(pos)
38+
version_start = last(pos) + 1
39+
version_end = findnext(',', version_str, version_start) - 1
40+
version = tryparse(VersionNumber, version_str[version_start:version_end])
41+
else
42+
version = nothing
43+
end
44+
45+
if isnothing(version)
46+
@warn "Could not parse Pygments version:\n$version_str"
47+
end
48+
49+
return _pygmentize_version[] = version
50+
end
51+
52+
function pygmentize_support(lexer)
53+
highlighter_ver = pygmentize_version()
54+
if isnothing(highlighter_ver)
55+
@warn "Syntax highlighting of $lexer code relies on Pygments.\n\
56+
Use `pip install pygments` to install the lastest version" maxlog = 1
57+
return false
58+
elseif lexer == "ptx"
59+
if highlighter_ver < v"2.16"
60+
@warn "Pygments supports PTX highlighting starting from version 2.16\n\
61+
Detected version $highlighter_ver\n\
62+
Please update with `pip install pygments -U`" maxlog = 1
63+
return false
64+
end
65+
return true
66+
elseif lexer == "gcn"
67+
if highlighter_ver < v"2.8"
68+
@warn "Pygments supports GCN highlighting starting from version 2.8\n\
69+
Detected version $highlighter_ver\n\
70+
Please update with `pip install pygments -U`" maxlog = 1
71+
return false
72+
end
73+
return true
74+
else
75+
return false
76+
end
77+
end
78+
1979
function highlight(io::IO, code, lexer)
20-
highlighter = pygmentize()
2180
have_color = get(io, :color, false)
2281
if !have_color
2382
print(io, code)
2483
elseif lexer == "llvm"
2584
InteractiveUtils.print_llvm(io, code)
26-
elseif highlighter !== nothing
27-
custom_lexer = joinpath(dirname(@__DIR__), "res", "pygments", "$lexer.py")
28-
if isfile(custom_lexer)
29-
lexer = `$custom_lexer -x`
85+
elseif pygmentize_support(lexer)
86+
lexer = lexer == "gcn" ? "amdgpu" : lexer
87+
pygments_args = String[pygmentize(), "-f", "terminal", "-P", "bg=dark", "-l", lexer]
88+
@static if Sys.iswindows()
89+
# Avoid encoding issues with pipes on Windows by using a temporary file
90+
mktemp() do tmp_path, tmp_io
91+
println(tmp_io, code)
92+
close(tmp_io)
93+
push!(pygments_args, "-o", tmp_path, tmp_path)
94+
cmd = Cmd(pygments_args)
95+
wait(open(cmd)) # stdout and stderr go to devnull
96+
print(io, read(tmp_path, String))
97+
end
98+
else
99+
cmd = Cmd(pygments_args)
100+
pipe = open(cmd, "r+")
101+
print(pipe, code)
102+
close(pipe.in)
103+
print(io, read(pipe, String))
30104
end
31-
32-
pipe = open(`$highlighter -f terminal -P bg=dark -l $lexer`, "r+")
33-
print(pipe, code)
34-
close(pipe.in)
35-
print(io, read(pipe, String))
36105
else
37106
print(io, code)
38107
end

test/utils.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,30 @@ end
4545
# problematic examples
4646
@test mangle(identity, String, Matrix{Float32}, Broadcast.Broadcasted{Broadcast.ArrayStyle{Matrix{Float32}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(sin)}, Broadcast.Extruded{Matrix{Float32}, Tuple{Bool, Bool}, Tuple{Int64, Int64}}}}) == "identity(String, Array<Float32, 2>, Broadcasted<ArrayStyle<Array<Float32, 2>>, Tuple<OneTo<Int64>, OneTo<Int64>>, literal_pow, Tuple<RefValue<sin>, Extruded<Array<Float32, 2>, Tuple<Bool, Bool>, Tuple<Int64, Int64>>>>)"
4747
end
48+
49+
@testset "highlighting" begin
50+
ansi_color = "\x1B[3" # beginning of any foreground color change
51+
52+
@testset "PTX" begin
53+
sample = """
54+
max.s64 %rd24, %rd18, 0;
55+
add.s64 %rd7, %rd23, -1;
56+
setp.lt.u64 %p2, %rd7, %rd24;
57+
@%p2 bra \$L__BB0_3;
58+
"""
59+
can_highlight = GPUCompiler.pygmentize_support("ptx")
60+
highlighted = sprint(GPUCompiler.highlight, sample, "ptx"; context = (:color => true))
61+
@test occursin(ansi_color, highlighted) skip = !can_highlight
62+
end
63+
64+
@testset "GCN" begin
65+
sample = """
66+
v_add_u32 v3, vcc, s0, v0
67+
v_mov_b32 v4, s1
68+
v_addc_u32 v4, vcc, v4, 0, vcc
69+
"""
70+
can_highlight = GPUCompiler.pygmentize_support("gcn")
71+
highlighted = sprint(GPUCompiler.highlight, sample, "gcn"; context = (:color => true))
72+
@test occursin(ansi_color, highlighted) skip = !can_highlight
73+
end
74+
end

0 commit comments

Comments
 (0)