| # 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. |
| """Arm Compute Library runtime tests.""" |
| |
| import numpy as np |
| |
| import tvm |
| from tvm import relay |
| |
| from .infrastructure import skip_runtime_test, build_and_run, verify |
| from .infrastructure import Device |
| |
| |
| def test_multiple_ops(): |
| """ |
| Test multiple operators destined for ACL. |
| The ACL runtime will expect these ops as 2 separate functions for |
| the time being. |
| """ |
| Device.load("test_config.json") |
| |
| if skip_runtime_test(): |
| return |
| |
| device = Device() |
| np.random.seed(0) |
| |
| def get_model(input_shape, var_names): |
| """Return a model and any parameters it may have.""" |
| a = relay.var(next(var_names), shape=input_shape, dtype="float32") |
| out = relay.reshape(a, (1, 1, 1000)) |
| out = relay.reshape(out, (1, 1000)) |
| return out |
| |
| inputs = {"a": tvm.nd.array(np.random.uniform(0, 1, (1, 1, 1, 1000)).astype("float32"))} |
| |
| outputs = [] |
| for acl in [False, True]: |
| func = get_model(inputs["a"].shape, iter(inputs)) |
| outputs.append( |
| build_and_run(func, inputs, 1, None, device, enable_acl=acl, acl_partitions=2)[0] |
| ) |
| verify(outputs, atol=0.002, rtol=0.01) |
| |
| |
| def test_heterogeneous(): |
| """ |
| Test to check if offloading only supported operators works, |
| while leaving unsupported operators computed via tvm. |
| """ |
| Device.load("test_config.json") |
| |
| if skip_runtime_test(): |
| return |
| |
| device = Device() |
| np.random.seed(0) |
| |
| def get_model(input_shape, var_names): |
| """Return a model and any parameters it may have.""" |
| a = relay.var(next(var_names), shape=input_shape, dtype="float32") |
| out = relay.reshape(a, (1, 1, 1000)) |
| out = relay.sigmoid(out) |
| out = relay.reshape(out, (1, 1000)) |
| return out |
| |
| inputs = {"a": tvm.nd.array(np.random.uniform(-127, 128, (1, 1, 1, 1000)).astype("float32"))} |
| |
| outputs = [] |
| for acl in [False, True]: |
| func = get_model(inputs["a"].shape, iter(inputs)) |
| outputs.append( |
| build_and_run( |
| func, inputs, 1, None, device, enable_acl=acl, tvm_ops=1, acl_partitions=2 |
| )[0] |
| ) |
| verify(outputs, atol=0.002, rtol=0.01) |
| |
| |
| def test_multiple_runs(): |
| """ |
| Test that multiple runs of an operator work. |
| """ |
| Device.load("test_config.json") |
| |
| if skip_runtime_test(): |
| return |
| |
| device = Device() |
| |
| def get_model(): |
| a = relay.var("a", shape=(1, 28, 28, 512), dtype="float32") |
| w = tvm.nd.array(np.ones((256, 1, 1, 512), dtype="float32")) |
| weights = relay.const(w, "float32") |
| conv = relay.nn.conv2d( |
| a, |
| weights, |
| kernel_size=(1, 1), |
| data_layout="NHWC", |
| kernel_layout="OHWI", |
| strides=(1, 1), |
| padding=(0, 0), |
| dilation=(1, 1), |
| ) |
| params = {"w": w} |
| return conv, params |
| |
| inputs = { |
| "a": tvm.nd.array(np.random.uniform(-127, 128, (1, 28, 28, 512)).astype("float32")), |
| } |
| |
| func, params = get_model() |
| outputs = build_and_run(func, inputs, 1, params, device, enable_acl=True, no_runs=3) |
| verify(outputs, atol=0.002, rtol=0.01) |
| |
| |
| if __name__ == "__main__": |
| test_multiple_ops() |
| test_heterogeneous() |
| test_multiple_runs() |