From e212f96c6046373de5059e380bf88be8a69a3424 Mon Sep 17 00:00:00 2001 From: Luis Vega Date: Wed, 2 Dec 2020 12:26:23 -0800 Subject: [PATCH] [Backend][Verilator] regression tests (#7000) * add files * update tests * test this * test this case * update jenkins file * fix offload * update * update variables * rollback ci files --- .../python/contrib/test_verilator/__init__.py | 18 ++++ .../contrib/test_verilator/infrastructure.py | 83 +++++++++++++++++++ .../test_verilator/test_verilator_codegen.py | 67 +++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 tests/python/contrib/test_verilator/__init__.py create mode 100644 tests/python/contrib/test_verilator/infrastructure.py create mode 100644 tests/python/contrib/test_verilator/test_verilator_codegen.py diff --git a/tests/python/contrib/test_verilator/__init__.py b/tests/python/contrib/test_verilator/__init__.py new file mode 100644 index 000000000000..4838dc3f4371 --- /dev/null +++ b/tests/python/contrib/test_verilator/__init__.py @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +""" Infrastructure and tests for Verilator codegen """ diff --git a/tests/python/contrib/test_verilator/infrastructure.py b/tests/python/contrib/test_verilator/infrastructure.py new file mode 100644 index 000000000000..1333f484aec9 --- /dev/null +++ b/tests/python/contrib/test_verilator/infrastructure.py @@ -0,0 +1,83 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +"""Verilator utility functions""" + +import sys + +import tvm +from tvm import relay +import tvm.relay.testing +from tvm import runtime +from tvm.relay import transform + + +def _register_verilator_op(op_name, supported=True): + """The helper function to indicate that a given operator can be supported by Verilator. + + Paramters + --------- + op_name : Str + The name of operator that will be registered. + + Returns + ------- + f : callable + A function that returns if the operator is supported by DNNL. + """ + + @tvm.ir.register_op_attr(op_name, "target.verilator") + def _func_wrapper(expr): + return supported + + return _func_wrapper + + +def skip_test(): + """Skip test if it requires the Verilator codegen and it's not present.""" + if not tvm.get_global_func("relay.ext.verilator", True): + print("Skip test because Verilator codegen is not available.") + return True + if sys.platform == "win32": + print("Skip test on Windows for now") + return True + return False + + +def offload(mod): + """Offload ops based on the registered ops""" + + backend = "verilator" + mod = transform.AnnotateTarget([backend])(mod) + mod = transform.PartitionGraph()(mod) + return mod + + +def compile_module(mod): + """Compile Relay module""" + + with relay.build_config(opt_level=3): + exe = relay.vm.compile(mod, target="llvm", params=None) + code, lib = exe.save() + return runtime.vm.Executable.load_exec(code, lib) + + +def run_module(exe, inputs): + """Run Relay module""" + + ctx = tvm.cpu() + vm = runtime.vm.VirtualMachine(exe, ctx) + return vm.run(**inputs) diff --git a/tests/python/contrib/test_verilator/test_verilator_codegen.py b/tests/python/contrib/test_verilator/test_verilator_codegen.py new file mode 100644 index 000000000000..664e254041b2 --- /dev/null +++ b/tests/python/contrib/test_verilator/test_verilator_codegen.py @@ -0,0 +1,67 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +"""Verilator codegen tests""" + +import numpy as np + +import tvm +from tvm import relay + +from test_verilator.infrastructure import ( + _register_verilator_op, + skip_test, + compile_module, + run_module, + offload, +) + + +_register_verilator_op("add") + + +def create_module_add(shape, dtype): + x = relay.var("x", shape=shape, dtype=dtype) + y = relay.var("y", shape=shape, dtype=dtype) + z = relay.add(x, y) + f = relay.Function([x, y], z) + mod = tvm.IRModule() + mod["main"] = f + return mod + + +def run_check_add(exe, shape, dtype): + x_data = np.random.randint(5, size=shape, dtype=dtype) + y_data = np.random.randint(5, size=shape, dtype=dtype) + ref = x_data + y_data + inputs = {"x": x_data, "y": y_data} + out = run_module(exe, inputs) + tvm.testing.assert_allclose(out.asnumpy(), ref, rtol=1e-5, atol=1e-5) + + +def test_add(): + if skip_test(): + return + dtype = "int32" + shape = (8, 4) + mod = create_module_add(shape, dtype) + mod = offload(mod) + exe = compile_module(mod) + run_check_add(exe, shape, dtype) + + +if __name__ == "__main__": + test_add()