676 lines
21 KiB
Python
676 lines
21 KiB
Python
# 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.
|
|
# ruff: noqa: E501, F401, F841
|
|
"""CLML integration operator tests."""
|
|
|
|
import inspect
|
|
import json
|
|
import os
|
|
|
|
import numpy as np
|
|
import pytest
|
|
from mod_utils import (
|
|
get_avgpool_expected_codegen,
|
|
get_batchnorm_mod,
|
|
get_binary_op_mod,
|
|
get_clml_conv2d_codegen,
|
|
get_conv2d_transpose_expected_codegen,
|
|
get_dequant_matmul_module,
|
|
get_dequant_vec_matmul_module,
|
|
get_global_avgpool_expected_codegen,
|
|
get_global_maxpool_expected_codegen,
|
|
get_maxpool_expected_codegen,
|
|
get_relax_avgpool_mod,
|
|
get_relax_conv2d_mod,
|
|
get_relax_conv2d_transpose_mod,
|
|
get_relax_global_avgpool_mod,
|
|
get_relax_global_maxpool_mod,
|
|
get_relax_maxpool_mod,
|
|
get_relax_reshape_codegen,
|
|
get_relax_reshape_mod,
|
|
get_unary_op_mod,
|
|
)
|
|
from utils import skip_unless_adreno_clml, verify_results
|
|
|
|
import tvm
|
|
import tvm.testing
|
|
from tvm import relax, rpc
|
|
from tvm.relax.backend.adreno import clml
|
|
from tvm.relax.backend.adreno.clml import OpenCLMLOffLoad, OpenCLMLOffLoadForLLM
|
|
from tvm.script import ir as I
|
|
from tvm.script import relax as R
|
|
from tvm.script import tirx as T
|
|
from tvm.script.ir_builder import IRBuilder
|
|
from tvm.script.ir_builder import relax as relax_builder
|
|
|
|
CLML_VERSION = clml.clml_sdk_version()
|
|
TARGET_CLML_VERSION = int(os.environ.get("ADRENO_TARGET_CLML_VERSION", 4))
|
|
clml_target = tvm.target.Target("qcom/adreno-opencl-clml")
|
|
ref_target = tvm.target.Target("opencl")
|
|
|
|
|
|
def verify_clml_codegen(clml_mod, clml_codegen):
|
|
clml_mod = OpenCLMLOffLoadForLLM(clml_target)(clml_mod)
|
|
clml_mod = OpenCLMLOffLoad()(clml_mod)
|
|
|
|
source = clml_mod.attrs["external_mods"][0].inspect_source()
|
|
codegen = json.loads(source)["nodes"]
|
|
for node in range(len(codegen)):
|
|
if codegen[node]["op"] == "input" or codegen[node]["op"] == "const":
|
|
codegen[node]["name"] = ""
|
|
if codegen[node]["op"] == "kernel":
|
|
codegen[node]["name"] = ""
|
|
|
|
codegen_str = json.dumps(codegen, sort_keys=True, indent=2)
|
|
known_good_codegen_str = json.dumps(clml_codegen, sort_keys=True, indent=2)
|
|
assert codegen_str == known_good_codegen_str, (
|
|
f"The JSON produced by codegen does not match the expected result. \n"
|
|
f"Actual={codegen_str} \n"
|
|
f"Expected={known_good_codegen_str}"
|
|
)
|
|
|
|
|
|
def verify(
|
|
mod, clml_codegen, inputs_np, params_np, target_minimum_clml_version=None, target_test=True
|
|
):
|
|
mod = tvm.relax.transform.BindParams("main", params_np)(mod)
|
|
codegen_mod, clml_mod = mod.clone(), mod
|
|
verify_clml_codegen(codegen_mod, clml_codegen)
|
|
|
|
if (
|
|
target_minimum_clml_version is not None
|
|
and TARGET_CLML_VERSION < target_minimum_clml_version
|
|
):
|
|
print(f"Skipped Eval Tests for {inspect.stack()[1].function} function", flush=True)
|
|
return
|
|
|
|
if "ADRENO_TARGET" not in os.environ:
|
|
return
|
|
|
|
if target_test:
|
|
verify_results(clml_mod, target=clml_target, ref_target=ref_target)
|
|
|
|
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
@pytest.mark.parametrize("dtype", ["float32"])
|
|
@pytest.mark.parametrize(
|
|
"kernel_h, kernel_w, padding, stride, dilation, out_channels, shape, has_bias, has_bn, has_activation, has_pad, is_depthwise",
|
|
[
|
|
(3, 3, (1, 1), (1, 1), (1, 1), 64, (3, 224, 224), False, True, False, True, False),
|
|
(3, 3, (1, 1), (1, 1), (1, 1), 64, (3, 224, 224), False, True, False, False, False),
|
|
# (5, 5, (2, 2), (1, 1), (1, 1), 16, (16, 64, 64), False, True, True, False, False),
|
|
# (7, 7, (3, 3), (2, 2), (1, 1), 32, (3, 224, 224), True, False, True, True, False),
|
|
(3, 3, (0, 0), (1, 1), (1, 1), 512, (256, 14, 14), True, False, True, False, False),
|
|
(1, 1, (0, 0), (1, 1), (1, 1), 1024, (512, 7, 7), True, False, True, False, False),
|
|
(1, 3, (0, 0), (1, 1), (1, 1), 64, (64, 7, 7), True, False, True, False, False),
|
|
(3, 1, (0, 0), (1, 1), (1, 1), 64, (64, 7, 7), False, True, True, True, False),
|
|
],
|
|
)
|
|
def test_conv2d_offload(
|
|
kernel_h,
|
|
kernel_w,
|
|
padding,
|
|
stride,
|
|
dilation,
|
|
out_channels,
|
|
shape,
|
|
has_bias,
|
|
has_bn,
|
|
has_activation,
|
|
has_pad,
|
|
is_depthwise,
|
|
dtype,
|
|
):
|
|
low, high = -0.01, 0.01
|
|
rtol, atol = 1e-3, 1e-3
|
|
if CLML_VERSION > 3:
|
|
rtol, atol = 1e-2, 1e-2 # @clml precision
|
|
|
|
data_shape = (1, *shape)
|
|
if is_depthwise:
|
|
groups = data_shape[1] // out_channels
|
|
else:
|
|
groups = 1
|
|
padding = (padding[0], padding[1], padding[0], padding[1])
|
|
|
|
weight_format = "IOHW" if is_depthwise else "OIHW"
|
|
weight_shape = (out_channels, data_shape[1] // groups, kernel_h, kernel_w)
|
|
|
|
data = np.random.uniform(low, high, size=data_shape).astype(dtype)
|
|
weight = np.random.uniform(low, high, size=weight_shape).astype(dtype)
|
|
bias = np.random.uniform(low, high, size=(1, weight_shape[0], 1, 1)).astype(dtype)
|
|
|
|
gamma = np.random.uniform(low, high, size=(weight_shape[0],)).astype(dtype)
|
|
beta = np.random.uniform(low, high, size=(weight_shape[0],)).astype(dtype)
|
|
mean = np.random.uniform(low, high, size=(weight_shape[0],)).astype(dtype)
|
|
variance = np.random.uniform(low, high, size=(weight_shape[0],)).astype(dtype)
|
|
|
|
inputs_np = [data]
|
|
params_np = {"weight": weight}
|
|
if has_bias:
|
|
params_np["bias"] = bias
|
|
if has_bn:
|
|
params_np.update({"gamma": gamma, "beta": beta, "mean": mean, "variance": variance})
|
|
|
|
mod = get_relax_conv2d_mod(
|
|
data_shape,
|
|
weight_shape,
|
|
stride=stride,
|
|
dilation=dilation,
|
|
padding=padding,
|
|
weight_layout=weight_format,
|
|
groups=groups,
|
|
dtype=dtype,
|
|
has_bias=has_bias,
|
|
has_bn=has_bn,
|
|
has_activation=has_activation,
|
|
has_pad=has_pad,
|
|
is_depthwise=is_depthwise,
|
|
)
|
|
clml_codegen = get_clml_conv2d_codegen(
|
|
data_shape,
|
|
weight_shape,
|
|
stride=stride,
|
|
dilation=dilation,
|
|
padding=padding,
|
|
weight_layout=weight_format,
|
|
groups=groups,
|
|
dtype=dtype,
|
|
has_bias=has_bias,
|
|
has_bn=has_bn,
|
|
has_activation=has_activation,
|
|
has_pad=has_pad,
|
|
is_depthwise=is_depthwise,
|
|
)
|
|
verify(mod, clml_codegen, inputs_np, params_np)
|
|
|
|
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
@pytest.mark.parametrize("dtype", ["float32"])
|
|
@pytest.mark.parametrize(
|
|
"dshape, kshape, channels, kernel_size, strides, padding, out_shape",
|
|
[
|
|
((1, 256, 100, 100), (64, 256, 4, 4), 64, (4, 4), (2, 2), (0, 0, 0, 0), (1, 64, 202, 202)),
|
|
((1, 64, 200, 200), (64, 64, 4, 4), 64, (4, 4), (2, 2), (1, 1, 1, 1), (1, 64, 400, 400)),
|
|
((1, 64, 200, 200), (64, 64, 4, 4), 64, (4, 4), (2, 2), (1, 1, 1, 1), (1, 64, 400, 400)),
|
|
((1, 64, 400, 400), (16, 64, 4, 4), 16, (4, 4), (2, 2), (1, 1, 1, 1), (1, 16, 800, 800)),
|
|
],
|
|
)
|
|
def test_conv2d_transpose(
|
|
dshape, kshape, channels, kernel_size, strides, padding, dtype, out_shape
|
|
):
|
|
low, high = -1, 1
|
|
|
|
data = np.random.uniform(low, high, size=dshape).astype(dtype)
|
|
weight = np.random.uniform(low, high, size=kshape).astype(dtype)
|
|
|
|
inputs_np = [data]
|
|
params_np = {"weight": weight}
|
|
|
|
mod = get_relax_conv2d_transpose_mod(
|
|
dshape,
|
|
kshape,
|
|
channels=channels,
|
|
stride=strides,
|
|
padding=padding,
|
|
dtype=dtype,
|
|
)
|
|
|
|
clml_codegen = get_conv2d_transpose_expected_codegen(
|
|
dshape=dshape,
|
|
kshape=kshape,
|
|
channels=channels,
|
|
kernel_size=kernel_size,
|
|
strides=strides,
|
|
padding=padding,
|
|
dilation=(1, 1),
|
|
dtype=dtype,
|
|
output_shape=out_shape,
|
|
)
|
|
verify(mod, clml_codegen, inputs_np, params_np, target_test=False)
|
|
|
|
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
@pytest.mark.skipif(
|
|
CLML_VERSION < 3,
|
|
reason="Requires compiler supporting CLML v5 or above",
|
|
)
|
|
@pytest.mark.parametrize("dtype", ["float32"])
|
|
@pytest.mark.parametrize(
|
|
"trials",
|
|
[
|
|
[(1, 64, 14, 14), 1, 3e-4],
|
|
[(1, 14, 256, 256), 1, 3e-4],
|
|
[(1, 14, 256, 256), 1, 3e-4],
|
|
[(1, 256, 1, 1), 1, 3e-4],
|
|
],
|
|
)
|
|
def test_batchnorm(dtype, trials):
|
|
low, high = 0, 1
|
|
(input_shape, axis, epsilon) = trials
|
|
channels = input_shape[axis]
|
|
|
|
def _get_axis_tuple(axis):
|
|
if axis == 0:
|
|
return (1, 2, 3)
|
|
elif axis == 1:
|
|
return (0, 2, 3)
|
|
elif axis == 2:
|
|
return (0, 1, 3)
|
|
else:
|
|
return (0, 1, 2)
|
|
|
|
data = np.random.uniform(low, high, size=(input_shape)).astype(dtype)
|
|
gamma = np.random.uniform(low, high, size=(channels)).astype(dtype)
|
|
beta = np.random.uniform(low, high, size=(channels)).astype(dtype)
|
|
mean = np.mean(data, _get_axis_tuple(axis), keepdims=False)
|
|
variance = np.var(data, _get_axis_tuple(axis), keepdims=False)
|
|
|
|
inputs_np = [data]
|
|
params_np = {"gamma": gamma, "beta": beta, "moving_mean": mean, "moving_var": variance}
|
|
mod = get_batchnorm_mod(input_shape, channels, axis, epsilon, dtype)
|
|
clml_codegen = [
|
|
{
|
|
"attrs": {"dtype": [dtype], "shape": [input_shape]},
|
|
"name": "",
|
|
"op": "input",
|
|
},
|
|
{"attrs": {"dtype": [dtype], "shape": [[channels]]}, "name": "", "op": "const"},
|
|
{"attrs": {"dtype": [dtype], "shape": [[channels]]}, "name": "", "op": "const"},
|
|
{"attrs": {"dtype": [dtype], "shape": [[channels]]}, "name": "", "op": "const"},
|
|
{"attrs": {"dtype": [dtype], "shape": [[channels]]}, "name": "", "op": "const"},
|
|
{
|
|
"attrs": {
|
|
"axis": axis,
|
|
"center": 1,
|
|
"dtype": [dtype],
|
|
"momentum": 0.10000000000000001,
|
|
"epsilon": 0.00029999999999999997,
|
|
"num_inputs": 5,
|
|
"num_outputs": 1,
|
|
"scale": 1,
|
|
"training": 1,
|
|
"shape": [input_shape],
|
|
},
|
|
"inputs": [[0, 0, 0], [1, 0, 0], [2, 0, 0], [3, 0, 0], [4, 0, 0]],
|
|
"name": "",
|
|
"op": "kernel",
|
|
},
|
|
]
|
|
verify(mod, clml_codegen, inputs_np, params_np)
|
|
|
|
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
@pytest.mark.parametrize("dtype", ["float32"])
|
|
@pytest.mark.parametrize(
|
|
"a_shape, b_shape, op",
|
|
[
|
|
((1, 64, 14, 14), (1, 64, 14, 14), R.add),
|
|
((1, 256), (1, 256), R.add),
|
|
((1, 64, 14, 14), (1, 64, 14, 14), R.subtract),
|
|
((1, 256), (1, 256), R.subtract),
|
|
((1, 64, 14, 14), (1, 64, 14, 14), R.multiply),
|
|
((1, 256), (1, 256), R.multiply),
|
|
((1, 64, 14, 14), (1, 64, 14, 14), R.divide),
|
|
((1, 256), (1, 256), R.divide),
|
|
((1, 64, 14, 14), (1, 64, 14, 14), R.minimum),
|
|
((1, 256), (1, 256), R.minimum),
|
|
((1, 64, 14, 14), (1, 64, 14, 14), R.maximum),
|
|
((1, 256), (1, 256), R.maximum),
|
|
],
|
|
)
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
def test_binary_ops(a_shape, b_shape, op, dtype):
|
|
(mod, inputs_np) = get_binary_op_mod(a_shape, b_shape, op, dtype)
|
|
clml_codegen = [
|
|
{
|
|
"attrs": {
|
|
"dtype": [dtype],
|
|
"shape": [a_shape],
|
|
},
|
|
"name": "",
|
|
"op": "input",
|
|
},
|
|
{
|
|
"attrs": {
|
|
"dtype": [dtype],
|
|
"shape": [b_shape],
|
|
},
|
|
"name": "",
|
|
"op": "input",
|
|
},
|
|
{
|
|
"attrs": {
|
|
"dtype": [dtype],
|
|
"num_inputs": 2,
|
|
"num_outputs": 1,
|
|
"shape": [a_shape],
|
|
},
|
|
"inputs": [[0, 0, 0], [1, 0, 0]],
|
|
"name": "",
|
|
"op": "kernel",
|
|
},
|
|
]
|
|
verify(mod, clml_codegen, inputs_np, {})
|
|
|
|
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
@pytest.mark.parametrize(
|
|
"dtype",
|
|
[
|
|
"float32",
|
|
],
|
|
)
|
|
@pytest.mark.parametrize(
|
|
"a_shape, op",
|
|
[
|
|
((1, 64, 14, 14), R.nn.relu),
|
|
((1, 256, 1, 1), R.nn.relu),
|
|
((1, 14, 256, 256), R.nn.relu),
|
|
((1, 14, 14, 256), R.nn.relu),
|
|
],
|
|
)
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
def test_unary_ops(a_shape, op, dtype):
|
|
(mod, inputs_np) = get_unary_op_mod(a_shape, op, dtype)
|
|
clml_codegen = [
|
|
{
|
|
"attrs": {
|
|
"dtype": [dtype],
|
|
"shape": [a_shape],
|
|
},
|
|
"name": "",
|
|
"op": "input",
|
|
},
|
|
{
|
|
"attrs": {
|
|
"activation_type": "relu",
|
|
"dtype": [dtype],
|
|
"num_inputs": 1,
|
|
"num_outputs": 1,
|
|
"shape": [a_shape],
|
|
},
|
|
"inputs": [[0, 0, 0]],
|
|
"name": "",
|
|
"op": "kernel",
|
|
},
|
|
]
|
|
verify(mod, clml_codegen, inputs_np, {})
|
|
|
|
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
@pytest.mark.parametrize("dtype", ["float32"])
|
|
@pytest.mark.parametrize(
|
|
"trials",
|
|
[
|
|
[(1, 64, 147, 147), (3, 3), (2, 2), (1, 1), (0, 0, 0, 0), False],
|
|
[(1, 256, 17, 17), (3, 3), (1, 1), (1, 1), (0, 0, 0, 0), False],
|
|
[(1, 1024, 14, 14), (3, 3), (1, 1), (1, 1), (0, 0, 0, 0), False],
|
|
# With padding is realized as nn.pad + pool
|
|
# [(1, 32, 256, 256), (3, 3), (2, 2), (1, 1), (1, 1, 1, 1), True],
|
|
# [(1, 32, 256, 256), (3, 3), (2, 2), (1, 1), (0, 1, 0, 1), True],
|
|
# [(1, 32, 256, 256), (2, 2), (2, 2), (1, 1), (1, 1, 1, 1), True],
|
|
# [(1, 32, 256, 256), (2, 2), (2, 2), (1, 1), (1, 0, 1, 0), True],
|
|
],
|
|
)
|
|
def test_max_pool(dtype, trials):
|
|
low, high = -1, 1
|
|
(input_shape, pool_size, stride, dilation, padding, has_pad) = trials
|
|
mod = get_relax_maxpool_mod(input_shape, dtype, pool_size, stride, dilation, padding, has_pad)
|
|
clml_codegen = get_maxpool_expected_codegen(
|
|
input_shape, pool_size, stride, padding, "maxpool2d", dtype
|
|
)
|
|
|
|
inputs_np = [np.random.uniform(low, high, size=input_shape).astype(dtype)]
|
|
verify(mod, clml_codegen, inputs_np, {})
|
|
|
|
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
@pytest.mark.parametrize("dtype", ["float32"])
|
|
@pytest.mark.parametrize(
|
|
"trials",
|
|
[
|
|
[(1, 64, 147, 147), (3, 3), (2, 2), (1, 1), (0, 0, 0, 0), False],
|
|
[(1, 256, 17, 17), (3, 3), (1, 1), (1, 1), (0, 0, 0, 0), False],
|
|
[(1, 1024, 14, 14), (3, 3), (1, 1), (1, 1), (0, 0, 0, 0), False],
|
|
# With padding is realized as nn.pad + pool
|
|
# [(1, 32, 256, 256), (3, 3), (2, 2), (1, 1), (1, 1, 1, 1), True],
|
|
# [(1, 32, 256, 256), (3, 3), (2, 2), (1, 1), (0, 1, 0, 1), True],
|
|
# [(1, 32, 256, 256), (2, 2), (2, 2), (1, 1), (1, 1, 1, 1), True],
|
|
# [(1, 32, 256, 256), (2, 2), (2, 2), (1, 1), (1, 0, 1, 0), True],
|
|
],
|
|
)
|
|
def test_avg_pool(dtype, trials):
|
|
low, high = -1, 1
|
|
(input_shape, pool_size, stride, dilation, padding, has_pad) = trials
|
|
mod = get_relax_avgpool_mod(input_shape, dtype, pool_size, stride, dilation, padding, has_pad)
|
|
clml_codegen = get_avgpool_expected_codegen(
|
|
input_shape, pool_size, stride, padding, "avg_pool2d", dtype
|
|
)
|
|
|
|
inputs_np = [np.random.uniform(low, high, size=input_shape).astype(dtype)]
|
|
params_np = {}
|
|
verify(mod, clml_codegen, inputs_np, {})
|
|
|
|
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
@pytest.mark.parametrize("dtype", ["float32"])
|
|
@pytest.mark.parametrize(
|
|
"trials",
|
|
[
|
|
[(1, 3, 32, 32), (1, 4, -1, 32)],
|
|
[(1, 4, 8, 32), (1, 4, -1, 16)],
|
|
[(1, 64, 3, 3), (1, 32, 3, -1)],
|
|
],
|
|
)
|
|
def test_reshape(dtype, trials):
|
|
low, high = -1, 1
|
|
(input_shape, output_shape) = trials
|
|
mod = get_relax_reshape_mod(input_shape, output_shape, dtype)
|
|
clml_codegen = get_relax_reshape_codegen(input_shape, output_shape, dtype)
|
|
|
|
inputs_np = [np.random.uniform(low, high, size=input_shape).astype(dtype)]
|
|
verify(mod, clml_codegen, inputs_np, {})
|
|
|
|
|
|
@pytest.mark.skip(reason="Codegen Comparision Failing")
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
@pytest.mark.parametrize("dtype", ["float32"])
|
|
@pytest.mark.parametrize(
|
|
"trials",
|
|
[
|
|
[(1, 64, 147, 147), True],
|
|
[(1, 256, 17, 17), False],
|
|
[(1, 1024, 14, 14), True],
|
|
[(1, 32, 256, 256), False],
|
|
],
|
|
)
|
|
def test_global_avg_pool(dtype, trials):
|
|
"""Test function for global average pooling."""
|
|
low, high = -1, 1
|
|
(input_shape, keep_dims) = trials
|
|
N, C, H, W = input_shape
|
|
pool_size, stride, padding = (H, W), (1, 1), (0, 0, 0, 0)
|
|
mod = get_relax_global_avgpool_mod(input_shape, keep_dims, dtype)
|
|
clml_codegen = get_global_maxpool_expected_codegen(
|
|
input_shape, pool_size, stride, padding, "global_max", dtype
|
|
)
|
|
|
|
inputs_np = [np.random.uniform(low, high, size=input_shape).astype(dtype)]
|
|
verify(mod, clml_codegen, inputs_np, {})
|
|
|
|
|
|
@pytest.mark.gpu
|
|
@skip_unless_adreno_clml
|
|
@pytest.mark.parametrize("dtype", ["float32"])
|
|
@pytest.mark.parametrize(
|
|
"trials",
|
|
[
|
|
[(1, 64, 147, 147), True],
|
|
[(1, 256, 17, 17), False],
|
|
[(1, 1024, 14, 14), True],
|
|
[(1, 32, 256, 256), False],
|
|
],
|
|
)
|
|
def test_global_max_pool(dtype, trials):
|
|
"""Test function for global average pooling."""
|
|
low, high = -1, 1
|
|
(input_shape, keep_dims) = trials
|
|
N, C, H, W = input_shape
|
|
pool_size, stride, padding = (H, W), (1, 1), (0, 0, 0, 0)
|
|
mod = get_relax_global_maxpool_mod(input_shape, keep_dims, dtype)
|
|
clml_codegen = get_global_maxpool_expected_codegen(
|
|
input_shape, pool_size, stride, padding, "global_max", dtype
|
|
)
|
|
|
|
inputs_np = [np.random.uniform(low, high, size=input_shape).astype(dtype)]
|
|
verify(mod, clml_codegen, inputs_np, {})
|
|
|
|
|
|
@pytest.mark.skipif(
|
|
CLML_VERSION < 5,
|
|
reason="Requires target device with CLML v5 or above",
|
|
)
|
|
@pytest.mark.parametrize(
|
|
"K, N, M",
|
|
[
|
|
(4096, 11008, 256),
|
|
(2048, 32768, 128),
|
|
(4096, 4096, 512),
|
|
(4096, 22016, 64),
|
|
(16384, 2048, 128),
|
|
(2048, 2560, 1024),
|
|
(3072, 9216, 256),
|
|
(14336, 4096, 128),
|
|
(1536, 17920, 128),
|
|
(8960, 1536, 1024),
|
|
],
|
|
)
|
|
def test_dequant_matmul(K, N, M):
|
|
x_data = np.random.uniform(-0.1, 0.1, size=(1, M, K)).astype("float16")
|
|
weight = np.random.randint(0, 100, size=(K // 8, N)).astype("uint32")
|
|
scale = np.random.uniform(-0.1, 0.1, size=(K // 32, N)).astype("float16")
|
|
|
|
mod = get_dequant_matmul_module(K, N)
|
|
clml_codegen = [
|
|
{
|
|
"op": "input",
|
|
"name": "",
|
|
"attrs": {"shape": [[[K // 8, N]]], "dtype": [["uint32"]]},
|
|
},
|
|
{
|
|
"op": "input",
|
|
"name": "",
|
|
"attrs": {"shape": [[[K // 32, N]]], "dtype": [["float16"]]},
|
|
},
|
|
{
|
|
"op": "input",
|
|
"name": "",
|
|
"attrs": {"shape": [[[1, -1, K]]], "dtype": [["float16"]]},
|
|
},
|
|
{
|
|
"op": "kernel",
|
|
"name": "",
|
|
"inputs": [[0, 0, 0], [1, 0, 0], [2, 0, 0]],
|
|
"attrs": {
|
|
"dtype": ["float16"],
|
|
"num_inputs": 3,
|
|
"num_outputs": 1,
|
|
"out_dtype": ["float16"],
|
|
"shape": [[1, -1, N]],
|
|
},
|
|
},
|
|
]
|
|
|
|
inputs_np = [x_data, weight, scale]
|
|
verify(mod, clml_codegen, inputs_np, {}, target_minimum_clml_version=5)
|
|
|
|
|
|
@pytest.mark.skipif(
|
|
CLML_VERSION < 5,
|
|
reason="Requires compiler supporting CLML v5 or above",
|
|
)
|
|
@pytest.mark.parametrize(
|
|
"K, N",
|
|
[
|
|
(4096, 11008),
|
|
(2048, 32768),
|
|
(4096, 4096),
|
|
(4096, 22016),
|
|
(16384, 2048),
|
|
(2048, 2560),
|
|
(3072, 9216),
|
|
(4096, 28672),
|
|
(14336, 4096),
|
|
(1536, 17920),
|
|
(8960, 1536),
|
|
],
|
|
)
|
|
def test_dequant_vec_matmul(K, N):
|
|
x_data = np.random.uniform(-0.1, 0.1, size=(1, 1, K)).astype("float16")
|
|
weight = np.random.randint(0, 100, size=(K // 8, N)).astype("uint32")
|
|
scale = np.random.uniform(-0.1, 0.1, size=(K // 32, N)).astype("float16")
|
|
|
|
mod = get_dequant_vec_matmul_module(K, N)
|
|
clml_codegen = [
|
|
{
|
|
"op": "input",
|
|
"name": "",
|
|
"attrs": {"shape": [[[K // 8, -1]]], "dtype": [["uint32"]]},
|
|
},
|
|
{
|
|
"op": "input",
|
|
"name": "",
|
|
"attrs": {"shape": [[[K // 32, -1]]], "dtype": [["float16"]]},
|
|
},
|
|
{
|
|
"op": "input",
|
|
"name": "",
|
|
"attrs": {"shape": [[[1, 1, K]]], "dtype": [["float16"]]},
|
|
},
|
|
{
|
|
"op": "kernel",
|
|
"name": "",
|
|
"inputs": [[0, 0, 0], [1, 0, 0], [2, 0, 0]],
|
|
"attrs": {
|
|
"dtype": ["float16"],
|
|
"num_inputs": 3,
|
|
"num_outputs": 1,
|
|
"out_dtype": ["float16"],
|
|
"shape": [[1, 1, -1]],
|
|
},
|
|
},
|
|
]
|
|
|
|
inputs_np = (x_data, weight, scale)
|
|
verify(mod, clml_codegen, inputs_np, {}, target_minimum_clml_version=5)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
tvm.testing.main()
|