"""Construct and actually execute a deterministic CPU model: y = 2*x + 1."""
from pathlib import Path
import numpy as np
import onnx
from onnx import TensorProto, helper, numpy_helper
import onnxruntime as ort
root = Path(__file__).resolve().parent
x = helper.make_tensor_value_info('x', TensorProto.FLOAT, [1,3])
y = helper.make_tensor_value_info('y', TensorProto.FLOAT, [1,3])
graph = helper.make_graph([
    helper.make_node('Mul',['x','two'],['scaled']),
    helper.make_node('Add',['scaled','one'],['y'])], 'learning-linear', [x], [y],
    [numpy_helper.from_array(np.array([2],np.float32),'two'), numpy_helper.from_array(np.array([1],np.float32),'one')])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid('',18)])
model.ir_version = 9
onnx.checker.check_model(model)
onnx.save(model, root/'linear.onnx')
session = ort.InferenceSession(str(root/'linear.onnx'), providers=['CPUExecutionProvider'])
actual = session.run(['y'], {'x':np.array([[1,2,3]],np.float32)})[0]
np.testing.assert_allclose(actual, [[3,5,7]])
try:
    session.run(['y'], {'x':np.array([[1,2]],np.float32)})
except ort.capi.onnxruntime_pybind11_state.InvalidArgument:
    pass
else:
    raise AssertionError('invalid shape accepted')
print(f'PASS: ONNX {onnx.__version__}, ORT {ort.__version__}; output [[3,5,7]], wrong shape rejected')
