from __future__ import print_function
import argparse
import re
import string
import textwrap
from itertools import product
def get_llvm_geom(geom_ptx):
geom = {
"1d" : "1d",
"2d" : "2d",
"3d" : "3d",
"a1d" : "1d.array",
"a2d" : "2d.array",
"cube" : "cube",
"acube" : "cube.array"
}
return geom[geom_ptx]
def get_ptx_reg(ty):
reg = {
"b8" : "%rs{{[0-9]+}}",
"b16" : "%rs{{[0-9]+}}",
"b32" : "%r{{[0-9]+}}",
"b64" : "%rd{{[0-9]+}}",
"f32" : "%f{{[0-9]+}}",
"u32" : "%r{{[0-9]+}}",
"s32" : "%r{{[0-9]+}}"
}
return reg[ty]
def get_ptx_vec_reg(vec, ty):
vec_reg = {
"" : "{{{reg}}}",
"v2" : "{{{reg}, {reg}}}",
"v4" : "{{{reg}, {reg}, {reg}, {reg}}}"
}
return vec_reg[vec].format(reg=get_ptx_reg(ty))
def get_llvm_type(ty):
if ty[0] in ("b", "s", "u"):
return "i" + ty[1:]
if ty == "f16":
return "half"
if ty == "f32":
return "float"
raise RuntimeError("invalid type: " + ty)
def get_llvm_vec_type(vec, ty_ptx):
ty = get_llvm_type(ty_ptx)
if ty == "i8":
ty = "i16"
vec_ty = {
"" : "{ty}",
"v2" : "{{ {ty}, {ty} }}",
"v4" : "{{ {ty}, {ty}, {ty}, {ty} }}"
}
return vec_ty[vec].format(ty=ty)
def get_llvm_value(vec, ty_ptx):
ty = get_llvm_type(ty_ptx)
if ty == "i8":
ty = "i16"
value = {
"" : "{ty} %v1",
"v2" : "{ty} %v1, {ty} %v2",
"v4" : "{ty} %v1, {ty} %v2, {ty} %v3, {ty} %v4"
}
return value[vec].format(ty=ty)
def get_llvm_value_type(vec, ty_ptx):
ty = get_llvm_type(ty_ptx)
if ty == "i8":
ty = "i16"
value = {
"" : "{ty}",
"v2" : "{ty}, {ty}",
"v4" : "{ty}, {ty}, {ty}, {ty}"
}
return value[vec].format(ty=ty)
def gen_triple(target):
if target == "cuda":
print("target triple = \"nvptx64-unknown-cuda\"\n")
elif target == "nvcl":
print("target triple = \"nvptx64-unknown-nvcl\"\n")
else:
raise RuntimeError("invalid target: " + target)
def gen_globals(target, surf_name, tex_name, sampler_name):
print("declare i64 @llvm.nvvm.texsurf.handle.internal.p1i64(i64 addrspace(1)*)")
print("; CHECK: .global .surfref {}".format(surf_name))
print("; CHECK: .global .texref {}".format(tex_name))
print("@{} = internal addrspace(1) global i64 0, align 8".format(surf_name))
print("@{} = internal addrspace(1) global i64 1, align 8".format(tex_name))
generated_metadata = [
"!{{i64 addrspace(1)* @{}, !\"surface\", i32 1}}".format(surf_name),
"!{{i64 addrspace(1)* @{}, !\"texture\", i32 1}}".format(tex_name),
]
if not is_unified(target):
print("; CHECK: .global .samplerref {}".format(sampler_name))
print("@{} = internal addrspace(1) global i64 1, align 8".format(
sampler_name))
generated_metadata.append(
"!{{i64 addrspace(1)* @{}, !\"sampler\", i32 1}}".format(sampler_name))
return generated_metadata
def gen_metadata(metadata):
md_values = ["!{}".format(i) for i in range(len(metadata))]
print("!nvvm.annotations = !{{{values}}}".format(values=(", ".join(md_values))))
for i, md in enumerate(metadata):
print("!{} = {}".format(i, md))
def get_llvm_surface_access(geom_ptx):
access = {
"1d" : "i32 %x",
"2d" : "i32 %x, i32 %y",
"3d" : "i32 %x, i32 %y, i32 %z",
"a1d" : "i32 %l, i32 %x",
"a2d" : "i32 %l, i32 %x, i32 %y",
}
return access[geom_ptx]
def get_llvm_surface_access_type(geom_ptx):
access_ty = {
"1d" : "i32",
"2d" : "i32, i32",
"3d" : "i32, i32, i32",
"a1d" : "i32, i32",
"a2d" : "i32, i32, i32",
}
return access_ty[geom_ptx]
def get_ptx_surface_access(geom_ptx):
access_reg = {
"1d" : "{%r{{[0-9]}}}",
"2d" : "{%r{{[0-9]}}, %r{{[0-9]}}}",
"3d" : "{%r{{[0-9]}}, %r{{[0-9]}}, %r{{[0-9]}}, %r{{[0-9]}}}",
"a1d" : "{%r{{[0-9]}}, %r{{[0-9]}}}",
"a2d" : "{%r{{[0-9]}}, %r{{[0-9]}}, %r{{[0-9]}}, %r{{[0-9]}}}",
}
return access_reg[geom_ptx]
def get_ptx_surface(target):
if target == "cuda":
return "%rd{{[0-9]+}}"
elif target == "nvcl":
return "test_{{.*}}_param_0"
raise RuntimeError("invalid target: " + target)
def get_surface_metadata(target, fun_ty, fun_name, has_surface_param):
metadata = []
md_kernel = "!{{{fun_ty} @{fun_name}, !\"kernel\", i32 1}}".format(
fun_ty=fun_ty, fun_name=fun_name)
metadata.append(md_kernel)
if target == "cuda":
has_surface_param = False
if has_surface_param:
md_surface = "!{{{fun_ty} @{fun_name}, !\"rdwrimage\", i32 0}}".format(
fun_ty=fun_ty, fun_name=fun_name)
metadata.append(md_surface)
return metadata
def gen_suld_tests(target, global_surf):
template = """
declare ${retty} @${intrinsic}(i64 %s, ${access});
; CHECK-LABEL: .entry ${test_name}_param
; CHECK: ${instruction} ${reg_ret}, [${reg_surf}, ${reg_access}]
;
define void @${test_name}_param(i64 %s, ${retty}* %ret, ${access}) {
%val = tail call ${retty} @${intrinsic}(i64 %s, ${access})
store ${retty} %val, ${retty}* %ret
ret void
}
; CHECK-LABEL: .entry ${test_name}_global
; CHECK: ${instruction} ${reg_ret}, [${global_surf}, ${reg_access}]
;
define void @${test_name}_global(${retty}* %ret, ${access}) {
%gs = tail call i64 @llvm.nvvm.texsurf.handle.internal.p1i64(i64 addrspace(1)* @${global_surf})
%val = tail call ${retty} @${intrinsic}(i64 %gs, ${access})
store ${retty} %val, ${retty}* %ret
ret void
}
"""
generated_items = []
generated_metadata = []
for geom, vec, dtype, clamp in product(
["1d", "2d", "3d", "a1d", "a2d"],
["", "v2", "v4"],
["b8" , "b16", "b32", "b64"],
["trap", "clamp", "zero"]):
if vec == "v4" and dtype == "b64":
continue
test_name = "test_suld_" + geom + vec + dtype + clamp
params = {
"test_name" : test_name,
"intrinsic" : "llvm.nvvm.suld.{geom}.{dtype}.{clamp}".format(
geom=get_llvm_geom(geom),
dtype=(vec + get_llvm_type(dtype)),
clamp=clamp),
"retty" : get_llvm_vec_type(vec, dtype),
"access" : get_llvm_surface_access(geom),
"global_surf" : global_surf,
"instruction" : "suld.b.{geom}{vec}.{dtype}.{clamp}".format(
geom=geom,
vec=("" if vec == "" else "." + vec),
dtype=dtype,
clamp=clamp),
"reg_ret" : get_ptx_vec_reg(vec, dtype),
"reg_surf" : get_ptx_surface(target),
"reg_access" : get_ptx_surface_access(geom),
}
gen_test(template, params)
generated_items.append((params["intrinsic"], params["instruction"]))
fun_name = test_name + "_param";
fun_ty = "void (i64, {retty}*, {access_ty})*".format(
retty=params["retty"],
access_ty=get_llvm_surface_access_type(geom))
generated_metadata += get_surface_metadata(
target, fun_ty, fun_name, has_surface_param=True)
fun_name = test_name + "_global";
fun_ty = "void ({retty}*, {access_ty})*".format(
retty=params["retty"],
access_ty=get_llvm_surface_access_type(geom))
generated_metadata += get_surface_metadata(
target, fun_ty, fun_name, has_surface_param=False)
return generated_items, generated_metadata
def gen_sust_tests(target, global_surf):
template = """
declare void @${intrinsic}(i64 %s, ${access}, ${value});
; CHECK-LABEL: .entry ${test_name}_param
; CHECK: ${instruction} [${reg_surf}, ${reg_access}], ${reg_value}
;
define void @${test_name}_param(i64 %s, ${value}, ${access}) {
tail call void @${intrinsic}(i64 %s, ${access}, ${value})
ret void
}
; CHECK-LABEL: .entry ${test_name}_global
; CHECK: ${instruction} [${global_surf}, ${reg_access}], ${reg_value}
;
define void @${test_name}_global(${value}, ${access}) {
%gs = tail call i64 @llvm.nvvm.texsurf.handle.internal.p1i64(i64 addrspace(1)* @${global_surf})
tail call void @${intrinsic}(i64 %gs, ${access}, ${value})
ret void
}
"""
generated_items = []
generated_metadata = []
for fmt, geom, vec, ctype, clamp in product(
["b", "p"],
["1d", "2d", "3d", "a1d", "a2d"],
["", "v2", "v4"],
["b8" , "b16", "b32", "b64"],
["trap", "clamp", "zero"]):
if fmt == "p" and geom[0] == "a":
continue
if fmt == "p" and ctype != "b32":
continue
if vec == "v4" and ctype == "b64":
continue
if fmt == "p" and clamp != "trap":
continue
test_name = "test_sust_" + fmt + geom + vec + ctype + clamp
params = {
"test_name" : test_name,
"intrinsic" : "llvm.nvvm.sust.{fmt}.{geom}.{ctype}.{clamp}".format(
fmt=fmt,
geom=get_llvm_geom(geom),
ctype=(vec + get_llvm_type(ctype)),
clamp=clamp),
"access" : get_llvm_surface_access(geom),
"value" : get_llvm_value(vec, ctype),
"global_surf" : global_surf,
"instruction" : "sust.{fmt}.{geom}{vec}.{ctype}.{clamp}".format(
fmt=fmt,
geom=geom,
vec=("" if vec == "" else "." + vec),
ctype=ctype,
clamp=clamp),
"reg_value" : get_ptx_vec_reg(vec, ctype),
"reg_surf" : get_ptx_surface(target),
"reg_access" : get_ptx_surface_access(geom)
}
gen_test(template, params)
generated_items.append((params["intrinsic"], params["instruction"]))
fun_name = test_name + "_param";
fun_ty = "void (i64, {value_ty}, {access_ty})*".format(
value_ty=get_llvm_value_type(vec, ctype),
access_ty=get_llvm_surface_access_type(geom))
generated_metadata += get_surface_metadata(
target, fun_ty, fun_name, has_surface_param=True)
fun_name = test_name + "_global";
fun_ty = "void ({value_ty}, {access_ty})*".format(
value_ty=get_llvm_value_type(vec, ctype),
access_ty=get_llvm_surface_access_type(geom))
generated_metadata += get_surface_metadata(
target, fun_ty, fun_name, has_surface_param=False)
return generated_items, generated_metadata
def is_unified(target):
return target == "cuda"
def get_llvm_texture_access(geom_ptx, ctype, mipmap):
geom_access = {
"1d" : "{ctype} %x",
"2d" : "{ctype} %x, {ctype} %y",
"3d" : "{ctype} %x, {ctype} %y, {ctype} %z",
"cube" : "{ctype} %s, {ctype} %t, {ctype} %r",
"a1d" : "i32 %l, {ctype} %x",
"a2d" : "i32 %l, {ctype} %x, {ctype} %y",
"acube" : "i32 %l, {ctype} %s, {ctype} %t, {ctype} %r",
}
access = geom_access[geom_ptx]
if mipmap == "level":
access += ", {ctype} %lvl"
elif mipmap == "grad":
if geom_ptx in ("1d", "a1d"):
access += ", {ctype} %dpdx1, {ctype} %dpdy1"
elif geom_ptx in ("2d", "a2d"):
access += (", {ctype} %dpdx1, {ctype} %dpdx2" +
", {ctype} %dpdy1, {ctype} %dpdy2")
else:
access += (", {ctype} %dpdx1, {ctype} %dpdx2, {ctype} %dpdx3" +
", {ctype} %dpdy1, {ctype} %dpdy2, {ctype} %dpdy3")
return access.format(ctype=get_llvm_type(ctype))
def get_llvm_texture_access_type(geom_ptx, ctype, mipmap):
geom_access = {
"1d" : "{ctype}",
"2d" : "{ctype}, {ctype}",
"3d" : "{ctype}, {ctype}, {ctype}",
"cube" : "{ctype}, {ctype}, {ctype}",
"a1d" : "i32, {ctype}",
"a2d" : "i32, {ctype}, {ctype}",
"acube" : "i32, {ctype}, {ctype}, {ctype}",
}
access = geom_access[geom_ptx]
if mipmap == "level":
access += ", {ctype}"
elif mipmap == "grad":
if geom_ptx in ("1d", "a1d"):
access += ", {ctype}, {ctype}"
elif geom_ptx in ("2d", "a2d"):
access += (", {ctype}, {ctype}, {ctype}, {ctype}")
else:
access += (", {ctype}, {ctype}, {ctype}" +
", {ctype}, {ctype}, {ctype}")
return access.format(ctype=get_llvm_type(ctype))
def get_ptx_texture_access(geom_ptx, ctype):
access_reg = {
"1d" : "{{{ctype_reg}}}",
"2d" : "{{{ctype_reg}, {ctype_reg}}}",
"3d" : "{{{ctype_reg}, {ctype_reg}, {ctype_reg}, {ctype_reg}}}",
"a1d" : "{{{b32_reg}, {ctype_reg}}}",
"a2d" : "{{{b32_reg}, {ctype_reg}, {ctype_reg}, {ctype_reg}}}",
"cube" : "{{{f32_reg}, {f32_reg}, {f32_reg}, {f32_reg}}}",
"acube" : "{{{b32_reg}, {f32_reg}, {f32_reg}, {f32_reg}}}",
}
return access_reg[geom_ptx].format(ctype_reg=get_ptx_reg(ctype),
b32_reg=get_ptx_reg("b32"),
f32_reg=get_ptx_reg("f32"))
def get_ptx_texture(target):
if target == "cuda":
return "%rd{{[0-9]+}}"
elif target == "nvcl":
return "test_{{.*}}_param_0, test_{{.*}}_param_1"
raise RuntimeError("unknown target: " + target)
def get_llvm_global_sampler(target, global_sampler):
if is_unified(target):
return "", ""
else:
sampler_handle = "i64 %gs,"
get_sampler_handle = (
"%gs = tail call i64 @llvm.nvvm.texsurf.handle.internal.p1i64" +
"(i64 addrspace(1)* @{})".format(global_sampler))
return sampler_handle, get_sampler_handle
def get_ptx_global_sampler(target, global_sampler):
if is_unified(target):
return ""
else:
return global_sampler + ","
def get_texture_metadata(target, fun_ty, fun_name, has_texture_params):
metadata = []
md_kernel = "!{{{fun_ty} @{fun_name}, !\"kernel\", i32 1}}".format(
fun_ty=fun_ty, fun_name=fun_name)
metadata.append(md_kernel)
if target == "cuda":
has_texture_params = False
if has_texture_params:
md_texture = "!{{{fun_ty} @{fun_name}, !\"rdoimage\", i32 0}}".format(
fun_ty=fun_ty, fun_name=fun_name)
metadata.append(md_texture)
if not is_unified(target):
md_sampler = "!{{{fun_ty} @{fun_name}, !\"sampler\", i32 1}}".format(
fun_ty=fun_ty, fun_name=fun_name)
metadata.append(md_sampler)
return metadata
def gen_tex_tests(target, global_tex, global_sampler):
template = """
declare ${retty} @${intrinsic}(i64 %tex, ${sampler} ${access})
; CHECK-LABEL: .entry ${test_name}_param
; CHECK: ${instruction} ${ptx_ret}, [${ptx_tex}, ${ptx_access}]
define void @${test_name}_param(i64 %tex, ${sampler} ${retty}* %ret, ${access}) {
%val = tail call ${retty} @${intrinsic}(i64 %tex, ${sampler} ${access})
store ${retty} %val, ${retty}* %ret
ret void
}
; CHECK-LABEL: .entry ${test_name}_global
; CHECK: ${instruction} ${ptx_ret}, [${global_tex}, ${ptx_global_sampler} ${ptx_access}]
define void @${test_name}_global(${retty}* %ret, ${access}) {
%gt = tail call i64 @llvm.nvvm.texsurf.handle.internal.p1i64(i64 addrspace(1)* @${global_tex})
${get_sampler_handle}
%val = tail call ${retty} @${intrinsic}(i64 %gt, ${sampler} ${access})
store ${retty} %val, ${retty}* %ret
ret void
}
"""
generated_items = []
generated_metadata = []
for mipmap, geom, vec, dtype, ctype in product(
["", "level", "grad"],
["1d", "2d", "3d", "a1d", "a2d", "cube", "acube", "2dms", "a2dms"],
["v2", "v4"],
["u32", "s32", "f16", "f32"],
["s32", "f32"]):
if geom in ("2dms", "a2dms"):
continue
if ctype == "s32" and mipmap != "":
continue
if ctype == "s32" and geom in ("cube", "acube"):
continue
if vec == "v2" or dtype == "f16":
continue
if mipmap == "grad" and geom in ("cube", "acube"):
continue
if vec == "v2" and dtype != "f16":
continue
sampler_handle, get_sampler_handle = get_llvm_global_sampler(
target, global_sampler)
test_name = "test_tex_" + "".join((mipmap, geom, vec, dtype, ctype))
params = {
"test_name" : test_name,
"intrinsic" :
"llvm.nvvm.tex{unified}.{geom}{mipmap}.{vec}{dtype}.{ctype}".format(
unified=(".unified" if is_unified(target) else ""),
geom=get_llvm_geom(geom),
mipmap=("" if mipmap == "" else "." + mipmap),
vec=vec,
dtype=dtype,
ctype=ctype),
"global_tex": global_tex,
"retty" : get_llvm_vec_type(vec, dtype),
"sampler" : sampler_handle,
"access" : get_llvm_texture_access(geom, ctype, mipmap),
"get_sampler_handle" : get_sampler_handle,
"instruction" : "tex{mipmap}.{geom}.{vec}.{dtype}.{ctype}".format(
mipmap=("" if mipmap == "" else "." + mipmap),
geom=geom,
vec=vec,
dtype=dtype,
ctype=ctype),
"ptx_ret" : get_ptx_vec_reg(vec, dtype),
"ptx_tex" : get_ptx_texture(target),
"ptx_access" : get_ptx_texture_access(geom, ctype),
"ptx_global_sampler" : get_ptx_global_sampler(target, global_sampler),
}
gen_test(template, params)
generated_items.append((params["intrinsic"], params["instruction"]))
fun_name = test_name + "_param";
fun_ty = "void (i64, {sampler} {retty}*, {access_ty})*".format(
sampler=("" if is_unified(target) else "i64,"),
retty=params["retty"],
access_ty=get_llvm_texture_access_type(geom, ctype, mipmap))
generated_metadata += get_texture_metadata(
target, fun_ty, fun_name, has_texture_params=True)
fun_name = test_name + "_global";
fun_ty = "void ({retty}*, {access_ty})*".format(
retty=params["retty"],
access_ty=get_llvm_texture_access_type(geom, ctype, mipmap))
generated_metadata += get_texture_metadata(
target, fun_ty, fun_name, has_texture_params=False)
return generated_items, generated_metadata
def get_llvm_tld4_access(geom):
geom_to_access = {
"2d" : "float %x, float %y",
"a2d" : "i32 %l, float %x, float %y",
"cube" : "float %s, float %t, float %r",
"acube" : "i32 %l, float %s, float %t, float %r"
}
return geom_to_access[geom]
def get_llvm_tld4_access_type(geom):
geom_to_access = {
"2d" : "float, float",
"a2d" : "i32, float, float",
"cube" : "float, float, float",
"acube" : "i32, float, float, float"
}
return geom_to_access[geom]
def get_ptx_tld4_access(geom):
geom_to_access = {
"2d" : "{%f{{[0-9]+}}, %f{{[0-9]+}}}",
"a2d" : "{%r{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}}",
"cube" : "{%f{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}}",
"acube" : "{%r{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}}"
}
return geom_to_access[geom]
def gen_tld4_tests(target, global_tex, global_sampler):
template = """
declare ${retty} @${intrinsic}(i64 %tex, ${sampler} ${access})
; CHECK-LABEL: .entry ${test_name}_param
; CHECK: ${instruction} ${ptx_ret}, [${ptx_tex}, ${ptx_access}]
define void @${test_name}_param(i64 %tex, ${sampler} ${retty}* %ret, ${access}) {
%val = tail call ${retty} @${intrinsic}(i64 %tex, ${sampler} ${access})
store ${retty} %val, ${retty}* %ret
ret void
}
; CHECK-LABEL: .entry ${test_name}_global
; CHECK: ${instruction} ${ptx_ret}, [${global_tex}, ${ptx_global_sampler} ${ptx_access}]
define void @${test_name}_global(${retty}* %ret, ${access}) {
%gt = tail call i64 @llvm.nvvm.texsurf.handle.internal.p1i64(i64 addrspace(1)* @${global_tex})
${get_sampler_handle}
%val = tail call ${retty} @${intrinsic}(i64 %gt, ${sampler} ${access})
store ${retty} %val, ${retty}* %ret
ret void
}
"""
generated_items = []
generated_metadata = []
for comp, geom, dtype in product(
["r", "g", "b", "a"],
["2d", "a2d", "cube", "acube"],
["u32", "s32", "f32"]):
if geom in ("a2d", "cube", "acube"):
continue
sampler_handle, get_sampler_handle = get_llvm_global_sampler(
target, global_sampler)
test_name = "test_tld4_" + "".join((comp, geom, dtype))
params = {
"test_name" : test_name,
"intrinsic" :
"llvm.nvvm.tld4{unified}.{comp}.{geom}.v4{dtype}.f32".format(
unified=(".unified" if is_unified(target) else ""),
comp=comp,
geom=get_llvm_geom(geom),
dtype=dtype),
"global_tex" : global_tex,
"retty" : get_llvm_vec_type("v4", dtype),
"sampler" : sampler_handle,
"access" : get_llvm_tld4_access(geom),
"get_sampler_handle" : get_sampler_handle,
"instruction" : "tld4.{comp}.{geom}.v4.{dtype}.f32".format(
comp=comp, geom=geom, dtype=dtype),
"ptx_ret" : get_ptx_vec_reg("v4", dtype),
"ptx_tex" : get_ptx_texture(target),
"ptx_access" : get_ptx_tld4_access(geom),
"ptx_global_sampler" : get_ptx_global_sampler(target, global_sampler),
}
gen_test(template, params)
generated_items.append((params["intrinsic"], params["instruction"]))
fun_name = test_name + "_param";
fun_ty = "void (i64, {sampler} {retty}*, {access_ty})*".format(
sampler=("" if is_unified(target) else "i64,"),
retty=params["retty"],
access_ty=get_llvm_tld4_access_type(geom))
generated_metadata += get_texture_metadata(
target, fun_ty, fun_name, has_texture_params=True)
fun_name = test_name + "_global";
fun_ty = "void ({retty}*, {access_ty})*".format(
retty=params["retty"],
access_ty=get_llvm_tld4_access_type(geom))
generated_metadata += get_texture_metadata(
target, fun_ty, fun_name, has_texture_params=False)
return generated_items, generated_metadata
def gen_test(template, params):
if debug:
print()
for param, value in params.items():
print(";; {}: {}".format(param, value))
print(string.Template(textwrap.dedent(template)).substitute(params))
def gen_tests(target, tests):
gen_triple(target)
items = []
metadata = []
global_surf = "gsurf"
global_tex = "gtex"
global_sampler = "gsam"
metadata += gen_globals(target, global_surf, global_tex, global_sampler)
if "suld" in tests:
suld_items, suld_md = gen_suld_tests(target, global_surf)
items += suld_items
metadata += suld_md
if "sust" in tests:
sust_items, sust_md = gen_sust_tests(target, global_surf)
items += sust_items
metadata += sust_md
if "tex" in tests:
tex_items, tex_md = gen_tex_tests(target, global_tex, global_sampler)
items += tex_items
metadata += tex_md
if "tld4" in tests:
tld4_items, tld4_md = gen_tld4_tests(target, global_tex, global_sampler)
items += tld4_items
metadata += tld4_md
gen_metadata(metadata)
return items
def write_gen_list(filename, append, items):
with open(filename, ("a" if append else "w")) as f:
for intrinsic, instruction in items:
f.write("{} {}\n".format(intrinsic, instruction))
def read_gen_list(filename):
intrinsics = set()
instructions = set()
with open(filename) as f:
for line in f:
intrinsic, instruction = line.split()
intrinsics.add(intrinsic)
instructions.add(instruction)
return (intrinsics, instructions)
def read_td_list(filename, regex):
td_list = set()
with open(filename) as f:
for line in f:
match = re.search(regex, line)
if match:
td_list.add(match.group(1))
if len(td_list) < 30:
raise RuntimeError("found only {} instructions in {}".format(
filename, len(td_list)))
return td_list
def verify_inst_tablegen(path_td, gen_instr):
td_instr = read_td_list(path_td, "\"((suld|sust|tex|tld4)\\..*)\"")
gen_instr.update({
"sust.p.1d.b8.trap",
"sust.p.1d.b16.trap",
"sust.p.1d.v2.b8.trap",
"sust.p.1d.v2.b16.trap",
"sust.p.1d.v4.b8.trap",
"sust.p.1d.v4.b16.trap",
"sust.p.a1d.b8.trap",
"sust.p.a1d.b16.trap",
"sust.p.a1d.v2.b8.trap",
"sust.p.a1d.v2.b16.trap",
"sust.p.a1d.v4.b8.trap",
"sust.p.a1d.v4.b16.trap",
"sust.p.2d.b8.trap",
"sust.p.2d.b16.trap",
"sust.p.2d.v2.b8.trap",
"sust.p.2d.v2.b16.trap",
"sust.p.2d.v4.b8.trap",
"sust.p.2d.v4.b16.trap",
"sust.p.a2d.b8.trap",
"sust.p.a2d.b16.trap",
"sust.p.a2d.v2.b8.trap",
"sust.p.a2d.v2.b16.trap",
"sust.p.a2d.v4.b8.trap",
"sust.p.a2d.v4.b16.trap",
"sust.p.3d.b8.trap",
"sust.p.3d.b16.trap",
"sust.p.3d.v2.b8.trap",
"sust.p.3d.v2.b16.trap",
"sust.p.3d.v4.b8.trap",
"sust.p.3d.v4.b16.trap",
"sust.p.a1d.b32.trap",
"sust.p.a1d.v2.b32.trap",
"sust.p.a1d.v4.b32.trap",
"sust.p.a2d.b32.trap",
"sust.p.a2d.v2.b32.trap",
"sust.p.a2d.v4.b32.trap",
})
td_instr = list(td_instr)
td_instr.sort()
gen_instr = list(gen_instr)
gen_instr.sort()
for i, td in enumerate(td_instr):
if i == len(gen_instr) or td != gen_instr[i]:
raise RuntimeError(
"{} is present in tablegen, but not tested.\n".format(td))
def verify_llvm_tablegen(path_td, gen_intr):
td_intr = read_td_list(
path_td, "\"(llvm\\.nvvm\\.(suld|sust|tex|tld4)\\..*)\"")
gen_intr.update({
"llvm.nvvm.sust.p.1d.i8.trap",
"llvm.nvvm.sust.p.1d.i16.trap",
"llvm.nvvm.sust.p.1d.v2i8.trap",
"llvm.nvvm.sust.p.1d.v2i16.trap",
"llvm.nvvm.sust.p.1d.v4i8.trap",
"llvm.nvvm.sust.p.1d.v4i16.trap",
"llvm.nvvm.sust.p.1d.array.i8.trap",
"llvm.nvvm.sust.p.1d.array.i16.trap",
"llvm.nvvm.sust.p.1d.array.v2i8.trap",
"llvm.nvvm.sust.p.1d.array.v2i16.trap",
"llvm.nvvm.sust.p.1d.array.v4i8.trap",
"llvm.nvvm.sust.p.1d.array.v4i16.trap",
"llvm.nvvm.sust.p.2d.i8.trap",
"llvm.nvvm.sust.p.2d.i16.trap",
"llvm.nvvm.sust.p.2d.v2i8.trap",
"llvm.nvvm.sust.p.2d.v2i16.trap",
"llvm.nvvm.sust.p.2d.v4i8.trap",
"llvm.nvvm.sust.p.2d.v4i16.trap",
"llvm.nvvm.sust.p.2d.array.i8.trap",
"llvm.nvvm.sust.p.2d.array.i16.trap",
"llvm.nvvm.sust.p.2d.array.v2i8.trap",
"llvm.nvvm.sust.p.2d.array.v2i16.trap",
"llvm.nvvm.sust.p.2d.array.v4i8.trap",
"llvm.nvvm.sust.p.2d.array.v4i16.trap",
"llvm.nvvm.sust.p.3d.i8.trap",
"llvm.nvvm.sust.p.3d.i16.trap",
"llvm.nvvm.sust.p.3d.v2i8.trap",
"llvm.nvvm.sust.p.3d.v2i16.trap",
"llvm.nvvm.sust.p.3d.v4i8.trap",
"llvm.nvvm.sust.p.3d.v4i16.trap",
"llvm.nvvm.sust.p.1d.array.i32.trap",
"llvm.nvvm.sust.p.1d.array.v2i32.trap",
"llvm.nvvm.sust.p.1d.array.v4i32.trap",
"llvm.nvvm.sust.p.2d.array.i32.trap",
"llvm.nvvm.sust.p.2d.array.v2i32.trap",
"llvm.nvvm.sust.p.2d.array.v4i32.trap"
})
td_intr = list(td_intr)
td_intr.sort()
gen_intr = list(gen_intr)
gen_intr.sort()
for i, td in enumerate(td_intr):
if i == len(gen_intr) or td != gen_intr[i]:
raise RuntimeError(
"{} is present in tablegen, but not tested.\n".format(td))
parser = argparse.ArgumentParser()
parser.add_argument("--debug", action="store_true")
parser.add_argument("--tests", type=str)
parser.add_argument("--target", type=str)
parser.add_argument("--gen-list", dest="gen_list", type=str)
parser.add_argument("--gen-list-append", dest="gen_list_append",
action="store_true")
parser.add_argument("--verify", action="store_true")
parser.add_argument("--llvm-tablegen", dest="llvm_td", type=str)
parser.add_argument("--inst-tablegen", dest="inst_td", type=str)
args = parser.parse_args()
debug = args.debug
if args.verify:
intrinsics, instructions = read_gen_list(args.gen_list)
verify_inst_tablegen(args.inst_td, instructions)
verify_llvm_tablegen(args.llvm_td, intrinsics)
else:
items = gen_tests(args.target, args.tests.split(","))
if (args.gen_list):
write_gen_list(args.gen_list, args.gen_list_append, items)