# Copyright 2019 The IREE Authors
#
# Licensed under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

import json
import numpy as np
import unittest

from iree import runtime as rt
from iree.runtime.function import (
    FunctionInvoker,
    IMPLICIT_BUFFER_ARG_MEMORY_TYPE,
    IMPLICIT_BUFFER_ARG_USAGE,
)
from iree.runtime._binding import VmVariantList


class MockVmContext:
    def __init__(self, invoke_callback):
        self._invoke_callback = invoke_callback
        self.invocations = []

    def invoke(self, vm_function, arg_list, ret_list):
        self._invoke_callback(arg_list, ret_list)
        self.invocations.append((vm_function, arg_list, ret_list))
        print(f"INVOKE: {arg_list} -> {ret_list}")

    @property
    def mock_arg_reprs(self):
        return repr([arg_list for _, arg_list, _ in self.invocations])


class MockVmFunction:
    def __init__(self, reflection):
        self.reflection = reflection


class FunctionTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # Doesn't matter what device. We just need one.
        config = rt.Config("local-task")
        cls.device = config.device

    def testNoReflectionScalars(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)
            ret_list.push_int(4)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(reflection={})
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker(1, 2)
        self.assertEqual("[<VmVariantList(2): [1, 2]>]", vm_context.mock_arg_reprs)
        self.assertEqual((3, 4), result)

    def testKeywordArgs(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            "i32",
                            ["named", "a", "i32"],
                            ["named", "b", "i32"],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker(-1, a=1, b=2)
        self.assertEqual("[<VmVariantList(3): [-1, 1, 2]>]", vm_context.mock_arg_reprs)
        self.assertEqual(3, result)

    def testListArg(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            ["slist", "i32", "i32"],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        _ = invoker([2, 3])
        self.assertEqual(
            "[<VmVariantList(1): [List[2, 3]]>]", vm_context.mock_arg_reprs
        )

    def testListArgNoReflection(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(reflection={})
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        _ = invoker([2, 3])
        self.assertEqual(
            "[<VmVariantList(1): [List[2, 3]]>]", vm_context.mock_arg_reprs
        )

    def testListArgArityMismatch(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            ["slist", "i32", "i32"],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        with self.assertRaisesRegex(
            ValueError, "expected a sequence with 2 values. got:"
        ):
            _ = invoker([2, 3, 4])

    def testTupleArg(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            ["stuple", "i32", "i32"],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        _ = invoker((2, 3))
        self.assertEqual(
            "[<VmVariantList(1): [List[2, 3]]>]", vm_context.mock_arg_reprs
        )

    def testDictArg(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            ["sdict", ["a", "i32"], ["b", "i32"]],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        _ = invoker({"b": 3, "a": 2})
        self.assertEqual(
            "[<VmVariantList(1): [List[2, 3]]>]", vm_context.mock_arg_reprs
        )

    def testDictArgArityMismatch(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            ["sdict", ["a", "i32"], ["b", "i32"]],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        with self.assertRaisesRegex(ValueError, "expected a dict with 2 values. got:"):
            _ = invoker({"a": 2, "b": 3, "c": 4})

    def testDictArgKeyError(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            ["sdict", ["a", "i32"], ["b", "i32"]],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        with self.assertRaisesRegex(ValueError, "could not get item 'b' from: "):
            _ = invoker({"a": 2, "c": 3})

    def testDictArgNoReflection(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(reflection={})
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        _ = invoker({"b": 3, "a": 2})
        self.assertEqual(
            "[<VmVariantList(1): [List[2, 3]]>]", vm_context.mock_arg_reprs
        )

    def testInlinedResults(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)
            ret_list.push_int(4)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [],
                        "r": [["slist", "i32", "i32"]],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker()
        self.assertEqual([3, 4], result)

    def testNestedResults(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)
            sub_list = VmVariantList(2)
            sub_dict = VmVariantList(2)
            sub_dict.push_int(100)
            sub_dict.push_int(200)
            sub_list.push_list(sub_dict)
            sub_list.push_int(6)
            ret_list.push_list(sub_list)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [],
                        "r": [
                            "i32",
                            [
                                "slist",
                                ["sdict", ["bar", "i32"], ["foo", "i32"]],
                                "i64",
                            ],
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker()
        self.assertEqual((3, [{"bar": 100, "foo": 200}, 6]), result)

    def testMissingPositional(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            "i32",
                            ["named", "a", "i32"],
                            ["named", "b", "i32"],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        with self.assertRaisesRegex(ValueError, "mismatched call arity:"):
            result = invoker(a=1, b=1)

    def testMissingPositionalNdarray(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            ["ndarray", "i32", 1, 1],
                            ["named", "a", ["ndarray", "i32", 1, 1]],
                            ["named", "b", ["ndarray", "i32", 1, 1]],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        with self.assertRaisesRegex(ValueError, "mismatched call arity:"):
            result = invoker(a=1, b=1)

    def testMissingKeyword(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            "i32",
                            ["named", "a", "i32"],
                            ["named", "b", "i32"],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        with self.assertRaisesRegex(ValueError, "mismatched call arity:"):
            result = invoker(-1, a=1)

    def testMissingKeywordNdArray(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            ["ndarray", "i32", 1, 1],
                            ["named", "a", ["ndarray", "i32", 1, 1]],
                            ["named", "b", ["ndarray", "i32", 1, 1]],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        with self.assertRaisesRegex(ValueError, "mismatched call arity:"):
            result = invoker(-1, a=1)

    def testExtraKeyword(self):
        def invoke(arg_list, ret_list):
            ret_list.push_int(3)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [
                            "i32",
                            ["named", "a", "i32"],
                            ["named", "b", "i32"],
                        ],
                        "r": [
                            "i32",
                        ],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        with self.assertRaisesRegex(ValueError, "specified kwarg 'c' is unknown"):
            result = invoker(-1, a=1, b=2, c=3)

    def testNdarrayArg(self):
        arg_array = np.asarray([1, 0], dtype=np.int32)

        invoked_arg_list = None

        def invoke(arg_list, ret_list):
            nonlocal invoked_arg_list
            invoked_arg_list = arg_list

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [["ndarray", "i32", 1, 2]],
                        "r": [],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker(arg_array)
        self.assertEqual(
            "<VmVariantList(1): [HalBufferView(2:0x20000011)]>", repr(invoked_arg_list)
        )

    def testDeviceArrayArg(self):
        # Note that since the device array is set up to disallow implicit host
        # transfers, this also verifies that no accidental/automatic transfers
        # are done as part of marshalling the array to the function.
        arg_array = rt.asdevicearray(
            self.device,
            np.asarray([1, 0], dtype=np.int32),
            implicit_host_transfer=False,
        )

        invoked_arg_list = None

        def invoke(arg_list, ret_list):
            nonlocal invoked_arg_list
            invoked_arg_list = arg_list

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [["ndarray", "i32", 1, 2]],
                        "r": [],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker(arg_array)
        self.assertEqual(
            "<VmVariantList(1): [HalBufferView(2:0x20000011)]>", repr(invoked_arg_list)
        )

    def testBufferViewArg(self):
        arg_buffer_view = self.device.allocator.allocate_buffer_copy(
            memory_type=IMPLICIT_BUFFER_ARG_MEMORY_TYPE,
            allowed_usage=IMPLICIT_BUFFER_ARG_USAGE,
            device=self.device,
            buffer=np.asarray([1, 0], dtype=np.int32),
            element_type=rt.HalElementType.SINT_32,
        )

        invoked_arg_list = None

        def invoke(arg_list, ret_list):
            nonlocal invoked_arg_list
            invoked_arg_list = arg_list

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [["ndarray", "i32", 1, 2]],
                        "r": [],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        _ = invoker(arg_buffer_view)
        self.assertEqual(
            "<VmVariantList(1): [HalBufferView(2:0x20000011)]>", repr(invoked_arg_list)
        )

    def testNdarrayArgNoReflection(self):
        arg_array = np.asarray([1, 0], dtype=np.int32)

        invoked_arg_list = None

        def invoke(arg_list, ret_list):
            nonlocal invoked_arg_list
            invoked_arg_list = arg_list

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(reflection={})
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker(arg_array)
        self.assertEqual(
            "<VmVariantList(1): [HalBufferView(2:0x20000011)]>", repr(invoked_arg_list)
        )

    def testDeviceArrayArgNoReflection(self):
        # Note that since the device array is set up to disallow implicit host
        # transfers, this also verifies that no accidental/automatic transfers
        # are done as part of marshalling the array to the function.
        arg_array = rt.asdevicearray(
            self.device,
            np.asarray([1, 0], dtype=np.int32),
            implicit_host_transfer=False,
        )

        invoked_arg_list = None

        def invoke(arg_list, ret_list):
            nonlocal invoked_arg_list
            invoked_arg_list = arg_list

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(reflection={})
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker(arg_array)
        self.assertEqual(
            "<VmVariantList(1): [HalBufferView(2:0x20000011)]>", repr(invoked_arg_list)
        )

    def testBufferViewArgNoReflection(self):
        arg_buffer_view = self.device.allocator.allocate_buffer_copy(
            memory_type=IMPLICIT_BUFFER_ARG_MEMORY_TYPE,
            allowed_usage=IMPLICIT_BUFFER_ARG_USAGE,
            device=self.device,
            buffer=np.asarray([1, 0], dtype=np.int32),
            element_type=rt.HalElementType.SINT_32,
        )

        invoked_arg_list = None

        def invoke(arg_list, ret_list):
            nonlocal invoked_arg_list
            invoked_arg_list = arg_list

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(reflection={})
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        _ = invoker(arg_buffer_view)
        self.assertEqual(
            "<VmVariantList(1): [HalBufferView(2:0x20000011)]>", repr(invoked_arg_list)
        )

    def testReturnBufferView(self):
        result_array = np.asarray([1, 0], dtype=np.int32)

        def invoke(arg_list, ret_list):
            buffer_view = self.device.allocator.allocate_buffer_copy(
                memory_type=IMPLICIT_BUFFER_ARG_MEMORY_TYPE,
                allowed_usage=IMPLICIT_BUFFER_ARG_USAGE,
                device=self.device,
                buffer=result_array,
                element_type=rt.HalElementType.SINT_32,
            )
            ret_list.push_ref(buffer_view)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [],
                        "r": [["ndarray", "i32", 1, 2]],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker()
        np.testing.assert_array_equal([1, 0], result)

    def testReturnBufferViewNoReflection(self):
        result_array = np.asarray([1, 0], dtype=np.int32)

        def invoke(arg_list, ret_list):
            buffer_view = self.device.allocator.allocate_buffer_copy(
                memory_type=IMPLICIT_BUFFER_ARG_MEMORY_TYPE,
                allowed_usage=IMPLICIT_BUFFER_ARG_USAGE,
                device=self.device,
                buffer=result_array,
                element_type=rt.HalElementType.SINT_32,
            )
            ret_list.push_ref(buffer_view)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(reflection={})
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker()
        np.testing.assert_array_equal([1, 0], result)

    # TODO: Fill out all return types.
    def testReturnTypeNdArrayBool(self):
        result_array = np.asarray([1, 0], dtype=np.int8)

        def invoke(arg_list, ret_list):
            buffer_view = self.device.allocator.allocate_buffer_copy(
                memory_type=IMPLICIT_BUFFER_ARG_MEMORY_TYPE,
                allowed_usage=IMPLICIT_BUFFER_ARG_USAGE,
                device=self.device,
                buffer=result_array,
                element_type=rt.HalElementType.UINT_8,
            )
            ret_list.push_ref(buffer_view)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [],
                        "r": [["ndarray", "i1", 1, 2]],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker()
        # assertEqual on bool arrays is fraught for... reasons.
        np.testing.assert_array_equal([True, False], result)

    def testReturnTypeList(self):
        vm_list = VmVariantList(2)
        vm_list.push_int(1)
        vm_list.push_int(2)

        def invoke(arg_list, ret_list):
            ret_list.push_list(vm_list)

        vm_context = MockVmContext(invoke)
        vm_function = MockVmFunction(
            reflection={
                "iree.abi": json.dumps(
                    {
                        "a": [],
                        "r": [["py_homogeneous_list", "i64"]],
                    }
                )
            }
        )
        invoker = FunctionInvoker(vm_context, self.device, vm_function, tracer=None)
        result = invoker()
        self.assertEqual("[1, 2]", repr(result))


if __name__ == "__main__":
    unittest.main()
