Files
openvino/tools/pot/tests/test_tensor_statistics.py
Roman Kazantsev 0b2f3347f6 [Tools] Support NumPy 1.24 (#14728)
* [Tools] Avoid use of NumPy deprecated types

Signed-off-by: Kazantsev, Roman <roman.kazantsev@intel.com>

* Revert "[Tools] Avoid use of NumPy deprecated types"

This reverts commit 21ffc167d1.

* Move to 1.24 Numpy

Signed-off-by: Kazantsev, Roman <roman.kazantsev@intel.com>
2022-12-19 23:51:34 -08:00

156 lines
4.9 KiB
Python

# Copyright (C) 2020-2022 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import numpy as np
import pytest
from openvino.tools.pot.statistics.function_selector import AGGREGATION_FN, ACTIVATIONS_STATS_FN, WEIGHTS_STATS_FN, \
get_aggregation_function, get_stats_function_for_activations, get_stats_function_for_weights, PERCHANNEL, PERTENSOR
from openvino.tools.pot.algorithms.quantization.fake_quantize import get_num_levels
INPUT_SHAPES = [(2, 2, 1), (2, 2, 2)]
AGG_INPUTS = [np.reshape(np.array(range(np.prod(shape)), dtype=np.float32), shape) for shape in INPUT_SHAPES]
GOLD_VALUES_AGGREGATION_FUNCTIONS_2_2_1 = {
'mean': 1.5,
'max': 3.,
'min': 0.,
'median': 1.5,
'mean_no_outliers': 1.5,
'median_no_outliers': 1.5,
'hl_estimator': 1.5,
'batch_mean': np.array([[[1], [2]]], dtype=float)
}
GOLD_VALUES_AGGREGATION_FUNCTIONS_2_2_2 = {
'mean': [3., 4.],
'max': [6., 7.],
'min': [0., 1.],
'median': [3., 4.],
'mean_no_outliers': [3., 4.],
'median_no_outliers': [3., 4.],
'hl_estimator': [3., 4.],
'batch_mean': np.array([[[2, 3], [4, 5]]], dtype=float)
}
GOLD_VALUES_AGGREGATION_FUNCTIONS = [
GOLD_VALUES_AGGREGATION_FUNCTIONS_2_2_1,
GOLD_VALUES_AGGREGATION_FUNCTIONS_2_2_2
]
@pytest.mark.parametrize(
'name', AGGREGATION_FN.registry_dict.keys(),
ids=list(AGGREGATION_FN.registry_dict.keys()))
def test_aggregation_function(name):
for i, input_tensor in enumerate(AGG_INPUTS):
fn = get_aggregation_function(name)
result = fn(input_tensor)
expected = GOLD_VALUES_AGGREGATION_FUNCTIONS[i][name]
np.testing.assert_almost_equal(result, expected)
INPUT_SHAPE = (2, 2, 2, 2)
INPUT = np.reshape(np.array(range(np.prod(INPUT_SHAPE)), dtype=np.float32), INPUT_SHAPE)
GOLD_VALUES_ACTIVATION_FUNCTIONS = {
'perchannel': {
'min': [[0., 4.], [8., 12.]],
'max': [[3., 7.], [11., 15.]],
'abs_max': [[3., 7.], [11., 15.]],
'quantile': [[0.03, 4.03], [8.03, 12.03]],
'abs_quantile': [[0.03, 4.03], [8.03, 12.03]],
'mean': [[1.5, 5.5], [9.5, 13.5]],
'mean_axis': [[1.5, 5.5], [9.5, 13.5]]
},
'pertensor': {
'min': [0., 8.],
'max': [7., 15.],
'abs_max': [7., 15.],
'quantile': [0.07, 8.07],
'abs_quantile': [0.07, 8.07]
}
}
ACTIVATIONS_STATS_FUNCTIONS = [
*[(name, PERTENSOR) for name in ACTIVATIONS_STATS_FN[PERTENSOR].registry_dict.keys()],
*[(name, PERCHANNEL) for name in ACTIVATIONS_STATS_FN[PERCHANNEL].registry_dict.keys()],
]
@pytest.mark.parametrize(
'name, scale', ACTIVATIONS_STATS_FUNCTIONS,
ids=['{}_{}'.format(fn[0], fn[1]) for fn in ACTIVATIONS_STATS_FUNCTIONS])
def test_activation_function(name, scale):
fn = get_stats_function_for_activations(name, scale, 'compute_statistic')
if name in ['quantile', 'abs_quantile']:
result = fn(INPUT, q=1e-2)
else:
result = fn(INPUT)
expected = GOLD_VALUES_ACTIVATION_FUNCTIONS[scale][name]
np.testing.assert_almost_equal(result, expected)
GOLD_VALUES_WEIGHT_FUNCTIONS = {
'perchannel': {
'min': [0., 8.],
'max': [7., 15.],
'abs_max': [7., 15.],
'quantile': [0.07, 8.07],
'abs_quantile': [0.07, 8.07]
},
'pertensor': {
'min': 0.,
'max': 15.,
'abs_max': 15.,
'quantile': 0.15,
'abs_quantile': 0.15
}
}
WEIGHTS_STATS_FUNCTIONS = [
*[(name, PERTENSOR) for name in WEIGHTS_STATS_FN[PERTENSOR].registry_dict.keys()],
*[(name, PERCHANNEL) for name in WEIGHTS_STATS_FN[PERCHANNEL].registry_dict.keys()],
]
@pytest.mark.parametrize(
'name, scale', WEIGHTS_STATS_FUNCTIONS,
ids=['{}_{}'.format(fn[0], fn[1]) for fn in WEIGHTS_STATS_FUNCTIONS])
def test_weights_function(name, scale):
fn = get_stats_function_for_weights(name, scale)
if name in ['quantile', 'abs_quantile']:
result = fn(INPUT, q=1e-2)
else:
result = fn(INPUT)
expected = GOLD_VALUES_WEIGHT_FUNCTIONS[scale][name]
np.testing.assert_almost_equal(result, expected)
GOLD_VALUES_CH_TRANS_WEIGHT_FUNCTIONS = {
'min': [0., 4.],
'max': [11., 15.],
'abs_max': [11., 15.],
'quantile': [0.07, 4.07],
'abs_quantile': [0.07, 4.07]
}
WEIGHTS_CH_STATS_FUNCTIONS = [(name, True) for name in
WEIGHTS_STATS_FN[PERCHANNEL].registry_dict.keys()]
NUM_LEVELS_PARAMS = [
(np.random.randint, (0, 2, (3, 100, 100)), 1, 1),
(np.random.randint, (-32, 32, (3, 100, 100)), 64, 1),
(np.random.randint, (-32, 32, (3, 100, 100)), 64, 1/512),
(np.random.rand, (3, 100, 100), -1, 1),
(np.random.randint, (0, 1, (3, 100, 100)), 0, 1)
]
@pytest.mark.parametrize('gen_func,params,expected,coef', NUM_LEVELS_PARAMS)
def test_get_num_levels_function(gen_func, params, expected, coef):
test_1 = gen_func(*params) * coef
result = get_num_levels(test_1)
assert result == expected