mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-30 20:18:08 +00:00
Add tests for all unary aten ops supported in eager mode (#12087)
* Add tests for all uniary aten ops supported in eager mode
* fixing the PR draft
* fixing the merge
* changing eval to be at compile time
* adding requirements for eager
* 1.adding function to {ops}_out
2.cleaning the code
and adding comments
* editing the code according to code review
Co-authored-by: root <root@AHA-LIRONKESE-1>
This commit is contained in:
parent
73310b2a0f
commit
9647a3be40
3 changed files with 127 additions and 30 deletions
|
|
@ -8,6 +8,57 @@ import unittest
|
|||
import numpy as np
|
||||
import onnxruntime_pybind11_state as torch_ort
|
||||
import torch
|
||||
from parameterized import parameterized
|
||||
|
||||
# OPS - is a list of list of [test_operator, the tested_tensor].
|
||||
# The default value for tested_tensor is torch.rand (6)- size of 6 uniform distribution on the interval [0, 1).
|
||||
# for floor and erf the ort- produce a roundoff error for floor(NaN), compare to cpu- stay NaN. thus, nan_to_num change nan to zero.
|
||||
ops = [
|
||||
["abs", torch.tensor([-1, -2, 3, -6, -7])],
|
||||
["acos"],
|
||||
["acosh"],
|
||||
["asinh"],
|
||||
["atanh"],
|
||||
["asin"],
|
||||
["atan"],
|
||||
["ceil"],
|
||||
["cos"],
|
||||
["cosh"],
|
||||
["erf", torch.nan_to_num(torch.rand(5))],
|
||||
["exp"],
|
||||
["floor", torch.nan_to_num(torch.rand(5))],
|
||||
["log"],
|
||||
["reciprocal"],
|
||||
["neg"],
|
||||
["round"],
|
||||
["relu"],
|
||||
["sigmoid"],
|
||||
["sin"],
|
||||
["sinh"],
|
||||
["sqrt"],
|
||||
["tan"],
|
||||
["tanh"],
|
||||
]
|
||||
# the following unary ops not been tested:
|
||||
# ["isnan", torch.tensor([1, float('nan'), 2])]]
|
||||
# ["selu", torch.randn(10)]]
|
||||
# ["nonzero", torch.tensor([0, 2, 1, 3])]]
|
||||
# ["sign", ]]
|
||||
# ["hardsigmoid", ],
|
||||
# ["isinf", ],
|
||||
# ["det" ]]
|
||||
|
||||
|
||||
def rename_func_to_op(testcase_func, param_num, param):
|
||||
return f"test_{parameterized.to_safe_name(str(param.args[0]))}"
|
||||
|
||||
|
||||
def rename_func_to_inplace(testcase_func, param_num, param):
|
||||
return f"test_{parameterized.to_safe_name(str(param.args[0]))}_"
|
||||
|
||||
|
||||
def rename_func_to_out(testcase_func, param_num, param):
|
||||
return f"test_{parameterized.to_safe_name(str(param.args[0]))}_out"
|
||||
|
||||
|
||||
class OrtOpTests(unittest.TestCase):
|
||||
|
|
@ -200,6 +251,50 @@ class OrtOpTests(unittest.TestCase):
|
|||
assert torch.allclose(cpu_result, ort_result.cpu())
|
||||
assert cpu_result.dim() == ort_result.dim()
|
||||
|
||||
# @parameterized.expand generate test methods for ops and using name_func we renaming the test to be test_{ops}
|
||||
@parameterized.expand(ops, name_func=rename_func_to_op)
|
||||
def test_op(self, test_name, tensor_test=torch.rand(6)):
|
||||
# compile eval- creates a code object that evaluates the operator (for example torch.abs(tensor_test)) and returns its result.
|
||||
cpu_result = eval(compile("torch." + test_name + "(tensor_test)", "<string>", "eval"))
|
||||
ort_result = eval(compile("torch." + test_name + "(tensor_test.to(self.get_device()))", "<string>", "eval"))
|
||||
assert torch.allclose(cpu_result, ort_result.cpu(), equal_nan=True)
|
||||
|
||||
@parameterized.expand(ops, name_func=rename_func_to_inplace)
|
||||
def test_op_inplace(self, test_name, tensor_test=torch.rand(6)):
|
||||
device = self.get_device()
|
||||
|
||||
cpu_tensor = tensor_test
|
||||
ort_tensor = cpu_tensor.to(device)
|
||||
|
||||
eval(compile("torch." + test_name + "_(cpu_tensor)", "<string>", "eval"))
|
||||
eval(compile("torch." + test_name + "_(ort_tensor)", "<string>", "eval"))
|
||||
|
||||
assert torch.allclose(cpu_tensor, ort_tensor.cpu(), equal_nan=True)
|
||||
|
||||
@parameterized.expand(ops, name_func=rename_func_to_out)
|
||||
def test_op_out(self, test_name, tensor_test=torch.rand(6)):
|
||||
##relu -don't have output
|
||||
if test_name == "relu":
|
||||
self.skipTest(f"no {test_name}_output")
|
||||
### troubleshoot later: the following tests are Failing.
|
||||
if test_name == "asin" or test_name == "log" or test_name == "atanh":
|
||||
self.skipTest(f" {test_name}_output Fails - skipping for now")
|
||||
device = self.get_device()
|
||||
cpu_tensor = tensor_test
|
||||
ort_tensor = cpu_tensor.to(device)
|
||||
|
||||
cpu_out_tensor = torch.tensor([], dtype=tensor_test.dtype)
|
||||
ort_out_tensor = cpu_out_tensor.to(device)
|
||||
|
||||
st_cpu = f"torch.{test_name}(cpu_tensor, out=cpu_out_tensor)"
|
||||
st_ort = f"torch.{test_name}(ort_tensor, out=ort_out_tensor)"
|
||||
cpu_result = eval(compile(st_cpu, "<string>", "eval"))
|
||||
ort_result = eval(compile(st_ort, "<string>", "eval"))
|
||||
|
||||
assert torch.allclose(cpu_result, ort_result.cpu(), equal_nan=True)
|
||||
assert torch.allclose(cpu_out_tensor, ort_out_tensor.cpu(), equal_nan=True)
|
||||
assert torch.allclose(ort_result.cpu(), ort_out_tensor.cpu(), equal_nan=True)
|
||||
|
||||
def test_resize(self):
|
||||
device = self.get_device()
|
||||
|
||||
|
|
@ -258,26 +353,6 @@ class OrtOpTests(unittest.TestCase):
|
|||
self.assertEqual(cpu_tensor.size(), ort_tensor.size())
|
||||
self.assertTrue(torch.allclose(cpu_tensor, ort_tensor.cpu()))
|
||||
|
||||
def test_abs(self):
|
||||
device = self.get_device()
|
||||
cpu_tensor = torch.tensor([-1, -2, 3, -6, -7])
|
||||
ort_tensor = cpu_tensor.to(device)
|
||||
|
||||
cpu_result = torch.abs(cpu_tensor)
|
||||
ort_result = torch.abs(ort_tensor)
|
||||
|
||||
assert torch.equal(cpu_result, ort_result.cpu())
|
||||
|
||||
def test_abs_(self):
|
||||
device = self.get_device()
|
||||
cpu_tensor = torch.tensor([-1, -2, 3, -6, -7])
|
||||
ort_tensor = cpu_tensor.to(device)
|
||||
|
||||
torch.abs_(cpu_tensor)
|
||||
torch.abs_(ort_tensor)
|
||||
|
||||
assert torch.equal(cpu_tensor, ort_tensor.cpu())
|
||||
|
||||
def test_abs_out(self):
|
||||
device = self.get_device()
|
||||
cpu_tensor = torch.tensor([-1, -2, 3, -6, -7])
|
||||
|
|
@ -305,8 +380,12 @@ class OrtOpTests(unittest.TestCase):
|
|||
print(f"Testing {func} with type {tensor_type}")
|
||||
cpu_out_tensor = torch.tensor([], dtype=tensor_type)
|
||||
ort_out_tensor = cpu_out_tensor.to(device)
|
||||
cpu_a_b_eq_result = eval("torch." + func + "(cpu_a, cpu_b, out=cpu_out_tensor)")
|
||||
ort_a_b_eq_result = eval("torch." + func + "(ort_a, ort_b, out=ort_out_tensor)")
|
||||
cpu_a_b_eq_result = eval(
|
||||
compile("torch." + func + "(cpu_a, cpu_b, out=cpu_out_tensor)", "<string>", "eval")
|
||||
)
|
||||
ort_a_b_eq_result = eval(
|
||||
compile("torch." + func + "(ort_a, ort_b, out=ort_out_tensor)", "<string>", "eval")
|
||||
)
|
||||
assert torch.equal(cpu_a_b_eq_result.to(device), ort_a_b_eq_result)
|
||||
assert torch.equal(cpu_out_tensor, ort_out_tensor.to("cpu"))
|
||||
assert ort_out_tensor.dtype == tensor_type
|
||||
|
|
@ -332,15 +411,31 @@ class OrtOpTests(unittest.TestCase):
|
|||
ort_out_tensor = cpu_out_tensor.to(device)
|
||||
|
||||
for func in {"eq", "ne"}:
|
||||
cpu_int_int_result = eval("torch." + func + "(cpu_tensor_int, cpu_scalar_int, out=cpu_out_tensor)")
|
||||
cpu_int_int_not_result = eval("torch." + func + "(cpu_tensor_int, cpu_scalar_int_not)")
|
||||
cpu_float_float_result = eval("torch." + func + "(cpu_tensor_float, cpu_scalar_float)")
|
||||
cpu_float_float_not_result = eval("torch." + func + "(cpu_tensor_float, cpu_scalar_float_not)")
|
||||
cpu_int_int_result = eval(
|
||||
compile("torch." + func + "(cpu_tensor_int, cpu_scalar_int, out=cpu_out_tensor)", "<string>", "eval")
|
||||
)
|
||||
cpu_int_int_not_result = eval(
|
||||
compile("torch." + func + "(cpu_tensor_int, cpu_scalar_int_not)", "<string>", "eval")
|
||||
)
|
||||
cpu_float_float_result = eval(
|
||||
compile("torch." + func + "(cpu_tensor_float, cpu_scalar_float)", "<string>", "eval")
|
||||
)
|
||||
cpu_float_float_not_result = eval(
|
||||
compile("torch." + func + "(cpu_tensor_float, cpu_scalar_float_not)", "<string>", "eval")
|
||||
)
|
||||
|
||||
ort_int_int_result = eval("torch." + func + "(ort_tensor_int, ort_scalar_int, out=ort_out_tensor)")
|
||||
ort_int_int_not_result = eval("torch." + func + "(ort_tensor_int, ort_scalar_int_not)")
|
||||
ort_float_float_result = eval("torch." + func + "(ort_tensor_float, ort_scalar_float)")
|
||||
ort_float_float_not_result = eval("torch." + func + "(ort_tensor_float, ort_scalar_float_not)")
|
||||
ort_int_int_result = eval(
|
||||
compile("torch." + func + "(ort_tensor_int, ort_scalar_int, out=ort_out_tensor)", "<string>", "eval")
|
||||
)
|
||||
ort_int_int_not_result = eval(
|
||||
compile("torch." + func + "(ort_tensor_int, ort_scalar_int_not)", "<string>", "eval")
|
||||
)
|
||||
ort_float_float_result = eval(
|
||||
compile("torch." + func + "(ort_tensor_float, ort_scalar_float)", "<string>", "eval")
|
||||
)
|
||||
ort_float_float_not_result = eval(
|
||||
compile("torch." + func + "(ort_tensor_float, ort_scalar_float_not)", "<string>", "eval")
|
||||
)
|
||||
|
||||
assert torch.equal(cpu_out_tensor, ort_out_tensor.to("cpu"))
|
||||
assert torch.equal(cpu_int_int_result, ort_int_int_result.to("cpu"))
|
||||
|
|
|
|||
|
|
@ -7,3 +7,4 @@ h5py
|
|||
sklearn
|
||||
numpy
|
||||
pandas
|
||||
parameterized
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@ wheel
|
|||
numpy
|
||||
typing_extensions
|
||||
torch==1.11.0
|
||||
parameterized
|
||||
|
|
|
|||
Loading…
Reference in a new issue