From b12bf0df872925873171d77174e661436590b98e Mon Sep 17 00:00:00 2001 From: Masahiro Masuda Date: Tue, 9 Mar 2021 20:33:05 +0900 Subject: [PATCH 1/6] Fix push constant offset for 32 bit value --- src/target/spirv/ir_builder.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/target/spirv/ir_builder.cc b/src/target/spirv/ir_builder.cc index 273fc48c3e30..3a9de4e077dc 100644 --- a/src/target/spirv/ir_builder.cc +++ b/src/target/spirv/ir_builder.cc @@ -222,7 +222,14 @@ Value IRBuilder::DeclarePushConstant(const std::vector& value_types) { DataType t = value_types[i].type; uint32_t nbits = t.bits() * t.lanes(); ICHECK_EQ(nbits % 8, 0); - offset += nbits / 8; + uint32_t bytes = (nbits / 8); + if (t.bits() == 32) { + // In our Vulkan runtime, each push constant always occupies 64 bit. + offset += bytes * 2; + } else { + ICHECK_EQ(t.bits(), 64); + offset += bytes; + } } // Decorate push constants as UBO this->Decorate(spv::OpDecorate, struct_type, spv::DecorationBlock); From a7c5559131d5ae056418f986f7e61c4b1bfc99ff Mon Sep 17 00:00:00 2001 From: Masahiro Masuda Date: Tue, 9 Mar 2021 20:53:47 +0900 Subject: [PATCH 2/6] add test --- .../unittest/test_target_codegen_spirv.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/python/unittest/test_target_codegen_spirv.py b/tests/python/unittest/test_target_codegen_spirv.py index 2cbf0bea9257..c0a4317c96e6 100644 --- a/tests/python/unittest/test_target_codegen_spirv.py +++ b/tests/python/unittest/test_target_codegen_spirv.py @@ -17,6 +17,7 @@ import tvm import tvm.testing from tvm import te +from tvm import relay from tvm.topi.math import cast import numpy as np @@ -71,5 +72,40 @@ def do_copy(A, B, n): tvm.testing.assert_allclose(b.asnumpy(), ref) +def check_result( + args, + mod, + expected, + flatten=False, + assert_shape=False, + only_vm=False, + targets=None, +): + for kind in ["debug", "vm"]: + targets = targets or tvm.testing.enabled_targets() + for tgt, ctx in targets: + ex = relay.create_executor(kind, mod=mod, ctx=ctx, target=tgt) + result = ex.evaluate()(*args) + for r, e in zip(result, expected): + tvm.testing.assert_allclose(r, e, atol=2e-6) + + +def test_pushconstants(): + # This will have three 32 bit pushconstants + dtype = "float32" + x = relay.var("x", shape=(relay.Any(),), dtype=dtype) + mod = tvm.IRModule() + mod["main"] = relay.Function([x], relay.sqrt(x)) + x_np = np.random.uniform(size=(3,)).astype(dtype) + res_np = np.sqrt(x_np) + + tgt = "vulkan" + ctx = tvm.context("vulkan", 0) + ex = relay.create_executor("vm", mod=mod, ctx=ctx, target=tgt) + res = ex.evaluate()(x_np).asnumpy() + tvm.testing.assert_allclose(res, res_np, atol=1e-5) + + if __name__ == "__main__": test_bool_load() + test_pushconstants() From 469689aa3213ae7b5fb477ce9892ef2724c7cd44 Mon Sep 17 00:00:00 2001 From: Masahiro Masuda Date: Tue, 9 Mar 2021 20:56:36 +0900 Subject: [PATCH 3/6] remove unused function from test --- .../unittest/test_target_codegen_spirv.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/tests/python/unittest/test_target_codegen_spirv.py b/tests/python/unittest/test_target_codegen_spirv.py index c0a4317c96e6..3a87185dfa71 100644 --- a/tests/python/unittest/test_target_codegen_spirv.py +++ b/tests/python/unittest/test_target_codegen_spirv.py @@ -72,24 +72,6 @@ def do_copy(A, B, n): tvm.testing.assert_allclose(b.asnumpy(), ref) -def check_result( - args, - mod, - expected, - flatten=False, - assert_shape=False, - only_vm=False, - targets=None, -): - for kind in ["debug", "vm"]: - targets = targets or tvm.testing.enabled_targets() - for tgt, ctx in targets: - ex = relay.create_executor(kind, mod=mod, ctx=ctx, target=tgt) - result = ex.evaluate()(*args) - for r, e in zip(result, expected): - tvm.testing.assert_allclose(r, e, atol=2e-6) - - def test_pushconstants(): # This will have three 32 bit pushconstants dtype = "float32" From 8552c8261edd6ec4f66335f18e1da94a08581e19 Mon Sep 17 00:00:00 2001 From: Masahiro Masuda Date: Tue, 9 Mar 2021 21:17:40 +0900 Subject: [PATCH 4/6] add dynamic cumsum test --- .../unittest/test_target_codegen_spirv.py | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/tests/python/unittest/test_target_codegen_spirv.py b/tests/python/unittest/test_target_codegen_spirv.py index 3a87185dfa71..f861e77457ad 100644 --- a/tests/python/unittest/test_target_codegen_spirv.py +++ b/tests/python/unittest/test_target_codegen_spirv.py @@ -73,19 +73,32 @@ def do_copy(A, B, n): def test_pushconstants(): - # This will have three 32 bit pushconstants + def check_mod(mod, x_np, res_np): + tgt = "vulkan" + ctx = tvm.context("vulkan", 0) + ex = relay.create_executor("vm", mod=mod, ctx=ctx, target=tgt) + res = ex.evaluate()(x_np).asnumpy() + tvm.testing.assert_allclose(res, res_np, atol=1e-5) + + # Three 32 bit pushconstants: any_dim, stride, stride dtype = "float32" x = relay.var("x", shape=(relay.Any(),), dtype=dtype) mod = tvm.IRModule() mod["main"] = relay.Function([x], relay.sqrt(x)) - x_np = np.random.uniform(size=(3,)).astype(dtype) + x_np = np.random.uniform(size=(10,)).astype(dtype) res_np = np.sqrt(x_np) - tgt = "vulkan" - ctx = tvm.context("vulkan", 0) - ex = relay.create_executor("vm", mod=mod, ctx=ctx, target=tgt) - res = ex.evaluate()(x_np).asnumpy() - tvm.testing.assert_allclose(res, res_np, atol=1e-5) + check_mod(mod, x_np, res_np) + + # One 64 bit and one 32 bit constants + dtype = "int32" + x = relay.var("x", shape=(5,), dtype=dtype) + mod = tvm.IRModule() + mod["main"] = relay.Function([x], relay.cumsum(x)) + x_np = np.random.randint(0, high=10, size=(10,)).astype(dtype) + res_np = np.cumsum(x_np) + + check_mod(mod, x_np, res_np) if __name__ == "__main__": From f080976bc3771a8e2b2e3769f78c9acce2d3a1f8 Mon Sep 17 00:00:00 2001 From: Masahiro Masuda Date: Tue, 9 Mar 2021 21:36:05 +0900 Subject: [PATCH 5/6] skip if vulkan is not enabled --- tests/python/unittest/test_target_codegen_spirv.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/python/unittest/test_target_codegen_spirv.py b/tests/python/unittest/test_target_codegen_spirv.py index f861e77457ad..1c25a884803d 100644 --- a/tests/python/unittest/test_target_codegen_spirv.py +++ b/tests/python/unittest/test_target_codegen_spirv.py @@ -73,10 +73,13 @@ def do_copy(A, B, n): def test_pushconstants(): + if not tvm.testing.device_enabled("vulkan"): + return + def check_mod(mod, x_np, res_np): - tgt = "vulkan" - ctx = tvm.context("vulkan", 0) - ex = relay.create_executor("vm", mod=mod, ctx=ctx, target=tgt) + target = "vulkan" + ctx = tvm.context(target, 0) + ex = relay.create_executor("vm", mod=mod, ctx=ctx, target=target) res = ex.evaluate()(x_np).asnumpy() tvm.testing.assert_allclose(res, res_np, atol=1e-5) @@ -92,7 +95,7 @@ def check_mod(mod, x_np, res_np): # One 64 bit and one 32 bit constants dtype = "int32" - x = relay.var("x", shape=(5,), dtype=dtype) + x = relay.var("x", shape=(relay.Any(),), dtype=dtype) mod = tvm.IRModule() mod["main"] = relay.Function([x], relay.cumsum(x)) x_np = np.random.randint(0, high=10, size=(10,)).astype(dtype) From 815255c119ee62fb5a5b4d60e3fdbf8c8d26675d Mon Sep 17 00:00:00 2001 From: Masahiro Masuda Date: Wed, 10 Mar 2021 04:32:05 +0900 Subject: [PATCH 6/6] replace dynamic cumsum test with dynamic argsort for now --- tests/python/unittest/test_target_codegen_spirv.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/python/unittest/test_target_codegen_spirv.py b/tests/python/unittest/test_target_codegen_spirv.py index 1c25a884803d..68be5c480358 100644 --- a/tests/python/unittest/test_target_codegen_spirv.py +++ b/tests/python/unittest/test_target_codegen_spirv.py @@ -97,9 +97,9 @@ def check_mod(mod, x_np, res_np): dtype = "int32" x = relay.var("x", shape=(relay.Any(),), dtype=dtype) mod = tvm.IRModule() - mod["main"] = relay.Function([x], relay.cumsum(x)) + mod["main"] = relay.Function([x], relay.argsort(x)) x_np = np.random.randint(0, high=10, size=(10,)).astype(dtype) - res_np = np.cumsum(x_np) + res_np = np.argsort(x_np) check_mod(mod, x_np, res_np)