Files

110 lines
3.7 KiB
Python

"""Test utils functions."""
import numpy
import pandas
import pytest
import torch
from torus.compiler import check_gpu_enabled
from torch.utils.data import DataLoader, TensorDataset
from torus.ml.common.debugging.custom_assert import assert_true
from torus.ml.common.utils import (
check_compilation_device_is_valid_and_is_cuda,
check_execution_device_is_valid_and_is_cuda,
compute_bits_precision,
)
from torus.ml.pytest.torch_models import QuantCustomModel
from torus.ml.pytest.utils import data_calibration_processing
def get_data(load_data):
"""Get classification data-set."""
x, y = load_data(
QuantCustomModel(n_bits=5, input_shape=6, hidden_shape=100, output_shape=3),
**{
"n_samples": 1000,
"n_classes": 3,
"n_features": 6,
"n_informative": 4,
"n_redundant": 2,
}
)
return x, y
@pytest.mark.parametrize(
"x, expected_n_bits", [(range(2**8), 8), (range(2**8 + 1), 9), (range(8), 3)]
)
def test_compute_bits_precision(x, expected_n_bits):
"""Test the function that computes the number of bits necessary to represent an array."""
assert_true(compute_bits_precision(numpy.array(x)) == expected_n_bits)
@pytest.mark.parametrize("input_type", ["dataloader", "pandas", "list", "numpy", "torch"])
def test_data_processing_valid_input(input_type, load_data):
"""Check if the _update_attr method raises an exception when an undefined attribute is given."""
x, y = get_data(load_data)
if input_type.lower() == "dataloader":
# Turn into `torch.utils.data.dataloader.DataLoader`
x, y = torch.tensor(x), torch.tensor(y)
x = DataLoader(TensorDataset(x, y), batch_size=32)
y = None
if input_type.lower() == "pandas":
# Turn into Pandas
x = pandas.DataFrame(x)
y = pandas.Series(y) if y.ndim == 1 else pandas.DataFrame(y)
elif input_type.lower() == "torch":
# Turn into Torch
x = torch.tensor(x)
y = torch.tensor(y)
elif input_type.lower() == "list":
# Turn into List
y = y.tolist()
x_calib, y = data_calibration_processing(data=x, targets=y, n_sample=1)
assert_true(isinstance(x_calib, (numpy.ndarray)))
assert_true(isinstance(y, (numpy.ndarray)))
@pytest.mark.parametrize("input_type", ["tuple"])
def test_data_processing_invalid_input(input_type, load_data):
"""Check if the _update_attr method raises an exception when an undefined attribute is given."""
x, y = get_data(load_data)
if input_type.lower() == "tuple":
x = tuple(x)
y = tuple(y)
with pytest.raises(TypeError, match="Only numpy arrays, torch tensors and .*"):
_ = data_calibration_processing(data=x, targets=y, n_sample=1)
def test_cuda_compilation_warnings(get_device):
"""Test that cuda compilation options are correctly handled."""
# If testing on a CUDA enabled machine, there will be no warnings
# there's nothing to test
if "cuda" in get_device:
if not check_gpu_enabled():
raise AssertionError(
"Trying to run CUDA test on a non-CUDA machine. "
"Check pytest command line arguments"
)
# On a non-CUDA enabled machine
with pytest.raises(ValueError, match="Model compilation targets given through.*"):
check_compilation_device_is_valid_and_is_cuda("invalid-device")
# On a non-CUDA enabled machine
with pytest.raises(ValueError, match=".*does not support CUDA.*"):
check_compilation_device_is_valid_and_is_cuda("cuda")
with pytest.raises(ValueError, match=".*no compatible CUDA.*"):
check_execution_device_is_valid_and_is_cuda(True, "execute")