blob: d18097861a1b15b715e59cfa9c0155067eb3cf1a [file]
# -------------------------------------------------------------
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# -------------------------------------------------------------
import unittest
from systemds.scuro.drsearch.algebra import ANY_TYPE, operator_signature
from systemds.scuro.drsearch.operator_registry import Registry, load_builtin_operators
from systemds.scuro.modality.type import ModalityType
from systemds.scuro.representations.aggregated_representation import (
AggregatedRepresentation,
)
from systemds.scuro.representations.concatenation import Concatenation
from systemds.scuro.representations.lstm import LSTM
from systemds.scuro.representations.mlp_averaging import MLPAveraging
from systemds.scuro.representations.sum import Sum
from systemds.scuro.representations.window_aggregation import WindowAggregation
load_builtin_operators(ANY_TYPE, include_fusion=True)
REGISTERED = sorted(
{
(op, kind, modality)
for kind, lists in [
("encode", Registry._representations),
("context", Registry._context_operators),
("reduce", Registry._dimensionality_reduction_operators),
]
for modality, ops in lists.items()
for op in ops
},
key=lambda t: (t[0].__name__, t[1], t[2].name),
) + [(op, "fuse", None) for op in Registry().get_fusion_operators()]
RANK_CASES = [
(Sum, {}, ("fuse", "n", "vector", "vector")),
(
Concatenation,
{"preserve_leading_axis": False},
("fuse", "n", "vector", "vector"),
),
(Concatenation, {"preserve_leading_axis": True}, ("fuse", "n", "seq", "seq")),
(LSTM, {}, ("fuse", "n", "seq", "vector")),
(AggregatedRepresentation, {}, ("aggregate", 1, "seq", "vector")),
(WindowAggregation, {}, ("context", 1, "seq", "windows")),
(MLPAveraging, {}, ("reduce", 1, "vector", "vector")),
(None, {}, ("task", 1, "any", "any")),
]
class TestOperatorSignatures(unittest.TestCase):
def test_every_registered_operator_has_a_signature(self):
for op, kind, modality in REGISTERED:
with self.subTest(
op=op.__name__, kind=kind, modality=getattr(modality, "name", None)
):
sig = operator_signature(op)
self.assertEqual(sig.kind, kind)
if modality is not None:
self.assertIn(modality, sig.input_types)
if kind in ("encode", "fuse"):
self.assertIsInstance(sig.output_type, ModalityType)
def test_rank_rules(self):
for op, params, expected in RANK_CASES:
with self.subTest(op=getattr(op, "__name__", None), params=params):
sig = operator_signature(op, params)
self.assertEqual(
(sig.kind, sig.arity, sig.input_rank, sig.output_rank), expected
)
if __name__ == "__main__":
unittest.main()