def test_DArray(self): # primitive elements are properly handled # int are passed as DInt, not DUInt self.check([1, 2, 3], DArray(DInt(), DSize(3))) # for floats use a dot # might be a potential problem, due to python silent type downcasting self.check([1.0, 2.0, 3.0], DArray(DFloat(), DSize(3))) # bool are passed as DBool, not DInt self.check([True, False, False], DArray(DBool(), DSize(3))) # encapsulation of compound types self.check([[1, 2, 3], [4, 5, 6]], DArray(DArray(DInt(), DSize(3)), DSize(2))) with self.assertRaises(DeltaTypeError): self.check([1, 2, 3, 4, 5, 6], DArray(DArray(DInt(), DSize(3)), DSize(2))) with self.assertRaises(AssertionError): self.check([1, 2, 3, 4, 5, 6], DArray(DInt(), DSize(6)), DArray(DArray(DInt(), DSize(3)), DSize(2))) # mixed types self.check([(1, 2, 3), (4, 5, 6)], DArray(DTuple([int, int, int]), DSize(2))) self.check(["hello", "world"], DArray(DStr(DSize(5)), DSize(2))) # numpy self.check_numpy([1, 2, 3, 4, 5], DArray(int, DSize(5)))
def test_DInt_type(self): self.assertEqual(DInt(DSize(8)).as_numpy_type(), np.int8) self.assertEqual(DInt(DSize(16)).as_numpy_type(), np.int16) self.assertEqual(DInt(DSize(32)).as_numpy_type(), np.int32) self.assertEqual(DInt(DSize(64)).as_numpy_type(), np.int64) with self.assertRaises(NotImplementedError): DInt(DSize(128)).as_numpy_type()
def setUp(self): # obligatory and optional ports out_port_obl = OutPort( NamespacedName("port_name", None), DInt(), InPort(NamespacedName("port_name", None), DInt(), None, 0), None ) out_port_opt = OutPort( NamespacedName("port_name", None), DInt(), InPort(NamespacedName("port_name", None), DOptional(DInt()), None, 0), None ) # 4 types of queues self.delta_queue_obl = DeltaQueue(out_port_obl) self.delta_queue_opt = DeltaQueue(out_port_opt) self.const_queue_obl = ConstQueue(out_port_obl) self.const_queue_opt = ConstQueue(out_port_opt) # test messages self.msg1 = QueueMessage(1) self.msg2 = QueueMessage(2) self.msg_with_none = QueueMessage(None) self.msg_unpackable = QueueMessage("abcde") # these messages should be received self.msg1_answer = QueueMessage(1) self.msg2_answer = QueueMessage(2) self.msg_with_none_answer = QueueMessage(None)
def test_as_delta_type(self): """Test conversion from python to Deltaflow data types.""" # special self.assertEqual(as_delta_type(object), Top()) self.assertEqual(as_delta_type(type(object)), Top()) self.assertEqual(as_delta_type(type), Top()) self.assertEqual(as_delta_type(Void), Void) with self.assertRaises(DeltaTypeError): as_delta_type(None) with self.assertRaises(DeltaTypeError): as_delta_type(type(None)) # primitive self.assertNotEqual(as_delta_type(bool), DUInt(DSize(1))) self.assertEqual(as_delta_type(bool), DBool()) self.assertEqual(as_delta_type(np.bool_), DBool()) self.assertEqual(as_delta_type(int), DInt(DSize(32))) self.assertEqual(as_delta_type(np.int8), DChar()) self.assertEqual(as_delta_type(np.int16), DInt(DSize(16))) self.assertEqual(as_delta_type(np.int32), DInt(DSize(32))) self.assertEqual(as_delta_type(np.int64), DInt(DSize(64))) self.assertEqual(as_delta_type(np.uint8), DChar()) self.assertEqual(as_delta_type(np.uint16), DUInt(DSize(16))) self.assertEqual(as_delta_type(np.uint32), DUInt(DSize(32))) self.assertEqual(as_delta_type(np.uint64), DUInt(DSize(64))) self.assertEqual(as_delta_type(float), DFloat()) self.assertEqual(as_delta_type(np.float32), DFloat(DSize(32))) self.assertEqual(as_delta_type(np.float64), DFloat(DSize(64))) self.assertEqual(as_delta_type(complex), DComplex()) self.assertEqual(as_delta_type(np.complex64), DComplex(DSize(64))) self.assertEqual(as_delta_type(np.complex128), DComplex(DSize(128))) # compound with self.assertRaises(DeltaTypeError): as_delta_type(Tuple[int, bool]) with self.assertRaises(DeltaTypeError): as_delta_type(List[int]) self.assertNotEqual(as_delta_type(str), DArray(DChar(), DSize(1024))) self.assertEqual(as_delta_type(str), DStr()) self.assertEqual(as_delta_type(RecBI), DRecord(RecBI)) # numpy compound self.assertEqual(as_delta_type(DArray(int, DSize(5)).as_numpy_type()), DArray(int, DSize(5))) self.assertEqual(as_delta_type(DStr().as_numpy_type()), DStr()) self.assertEqual( as_delta_type(DTuple([int, bool, float]).as_numpy_type()), DTuple([int, bool, float]) ) self.assertEqual(as_delta_type(DRecord(RecBI).as_numpy_type()), DRecord(RecBI)) self.assertEqual( as_delta_type(DUnion([bool, float, int]).as_numpy_type()), DUnion([bool, float, int]))
def test_delta_type(self): """Test mapping python objects to Deltaflow data types.""" # special with self.assertRaises(DeltaTypeError): delta_type(None) # primitive self.assertEqual(delta_type(False), DBool()) self.assertEqual(delta_type(np.bool_(False)), DBool()) self.assertEqual(delta_type(5), DInt(DSize(32))) self.assertEqual(delta_type(np.int16(5)), DInt(DSize(16))) self.assertEqual(delta_type(np.int32(5)), DInt(DSize(32))) self.assertEqual(delta_type(np.int64(5)), DInt(DSize(64))) self.assertEqual(delta_type(np.uint16(5)), DUInt(DSize(16))) self.assertEqual(delta_type(np.uint32(5)), DUInt(DSize(32))) self.assertEqual(delta_type(np.uint64(5)), DUInt(DSize(64))) self.assertEqual(delta_type(4.2), DFloat(DSize(32))) self.assertEqual(delta_type(np.float32(4.2)), DFloat(DSize(32))) self.assertEqual(delta_type(np.float64(4.2)), DFloat(DSize(64))) self.assertEqual(delta_type(3+1j), DComplex(DSize(64))) self.assertEqual(delta_type(np.complex64(3+1j)), DComplex(DSize(64))) self.assertEqual(delta_type(np.complex128(3+1j)), DComplex(DSize(128))) self.assertEqual(delta_type('c'), DChar()) # compound self.assertEqual(delta_type((1, True, 3.7)), DTuple([int, bool, float])) self.assertEqual(delta_type([1, 2, 4]), DArray(int, DSize(3))) self.assertEqual(delta_type(RecBI(True, 5)), DRecord(RecBI)) # numpy compound self.assertEqual(delta_type(np.array([1, 2, 3, 4, 5])), DArray(DInt(DSize(64)), DSize(5))) self.assertEqual(delta_type(np.array([1, 2.0, 3, 4, 5])), DArray(DFloat(DSize(64)), DSize(5))) self.assertEqual(delta_type( DStr(DSize(5)).as_numpy_object("abcde")), DStr(DSize(5))) self.assertEqual( delta_type(DTuple([int, float, bool] ).as_numpy_object((1, 2.0, True))), DTuple([int, float, bool]) ) self.assertEqual( delta_type(DRecord(RecBI).as_numpy_object(RecBI(True, 2))), DRecord(RecBI) ) self.assertEqual( delta_type(DUnion([bool, float, int]).as_numpy_object(5.0)), DUnion([bool, float, int]) ) # different combinations self.assertEqual(delta_type([(4, 4.3), (2, 3.3)]), DArray(DTuple([int, float]), DSize(2)))
def test_primitive_types(self): """Strict typing without subtyping.""" self.assertTrue(DeltaGraph.check_wire(DInt(), DInt())) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DInt(), DUInt()) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DUInt(), DInt()) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(int, int)
def test_DInt(self): """Only 8, 16, 32 and 64 bits are supported.""" for bits in (8, 16, 32, 64): self.check(-2**(bits-1), DInt(DSize(bits))) self.check(2**(bits-1) - 1, DInt(DSize(bits))) for _ in range(1000): self.check(random.randint(-2**(bits-1), 2**(bits-1) - 1), DInt(DSize(bits))) self.assertTrue(DeltaGraph.check_wire(DRaw(int), DRaw(int))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DRaw(DInt(DSize(32))), DRaw(DInt(DSize(64))))
def test_types_comparison(self): """Various tests of types comparison.""" # primitive self.assertEqual(DInt(DSize(32)), DInt()) self.assertNotEqual(DInt(), DUInt()) self.assertNotEqual(DInt(), DInt(DSize(64))) # compound self.assertEqual(DTuple([int, bool]), DTuple([int, bool])) self.assertNotEqual(DTuple([int, bool]), DTuple([bool, int])) self.assertEqual(DArray(int, DSize(4)), DArray(int, DSize(4))) self.assertEqual(DArray(int, DSize(4)), DArray(DInt(), DSize(4))) self.assertNotEqual(DArray(int, DSize(4)), DArray(int, DSize(5))) self.assertNotEqual(DStr(), DStr(DSize(100))) self.assertEqual(DRecord(RecBI), DRecord(RecBI)) # compound: DUnion self.assertEqual(DUnion([int, bool]), DUnion([bool, int])) self.assertEqual(DUnion([int, DUnion([int, bool])]), DUnion([int, bool])) self.assertEqual(DUnion([int, DUnion([int, DUnion([int, bool])])]), DUnion([int, bool])) self.assertEqual(DUnion([int, int]), DUnion([int])) self.assertNotEqual(DUnion([DInt()]), DInt()) # special self.assertEqual(ForkedReturn(dict(x=int, y=bool, z=str)), ForkedReturn(dict(x=int, y=bool, z=str)))
def test_in_port_capnp_optional(self): """Generate optional in port.""" in_port = InPort(NamespacedName("node_name", "index"), DOptional(int), None, 0) capnp_in_port = dotdf_capnp.InPort.new_message() in_port.capnp(capnp_in_port) self.assertEqual(capnp_in_port.name, "index") self.assertEqual(dill.loads(capnp_in_port.type), DInt()) self.assertEqual(capnp_in_port.optional, True)
def test_DInt(self): """Only 8, 16, 32, and 64 bits are supported.""" for bits in (8, 16, 32, 64): self.check(-2**(bits-1), DInt(DSize(bits))) self.check(2**(bits-1) - 1, DInt(DSize(bits))) for _ in range(1000): self.check(random.randint(-2**(bits-1), 2**(bits-1) - 1), DInt(DSize(bits))) # Booleans can be packed self.check(True, DInt(DSize(bits))) self.check(False, DInt(DSize(bits))) # Floats, strings and overflowing or # complex numbers are not packable self.assertFalse(DInt(DSize(bits)).is_packable(3.5)) self.assertFalse(DInt(DSize(bits)).is_packable(3.0)) self.assertFalse(DInt(DSize(bits)).is_packable("abc")) self.assertFalse(DInt(DSize(bits)).is_packable(2**bits-1)) self.assertFalse(DInt(DSize(bits)).is_packable(3+5j))
def test_str(self): """Test string representation of data types.""" # primitive self.assertEqual(str(DInt()), "DInt32") self.assertEqual(str(DInt(DSize(64))), "DInt64") self.assertEqual(str(DUInt()), "DUInt32") self.assertEqual(str(DUInt(DSize(64))), "DUInt64") self.assertEqual(str(DBool()), "DBool") self.assertEqual(str(DChar()), "DChar8") self.assertEqual(str(DFloat()), "DFloat32") self.assertEqual(str(DFloat(DSize(64))), "DFloat64") # compound self.assertEqual(str(DArray(int, DSize(8))), "[DInt32 x 8]") self.assertEqual(str(DStr()), "DStr8192") self.assertEqual(str(DStr(DSize(100))), "DStr800") self.assertEqual(str(DTuple([int, bool])), "(DInt32, DBool)") self.assertEqual(str(DRecord(RecBIS)), "{x: DBool, y: DInt32, z: DStr8192}") self.assertEqual(str(DUnion([int, bool])), "<DBool | DInt32>") # compound: DUnion self.assertEqual(str(DUnion([int])), "<DInt32>") self.assertEqual(str(DUnion([int, DUnion([int, bool])])), "<DBool | DInt32>") self.assertEqual(str(DUnion([int, DUnion([int, DUnion([int, bool])])])), "<DBool | DInt32>") # encapsulation of various types self.assertEqual(str(DUnion([int, DTuple([int, bool])])), "<(DInt32, DBool) | DInt32>") self.assertEqual(str(DArray(DTuple([int, bool]), DSize(8))), "[(DInt32, DBool) x 8]") # special self.assertEqual(str(Top()), "T") self.assertEqual(str(DSize(5)), "5") self.assertEqual(str(DSize(NamespacedName("a", "b"))), "(a.b)") self.assertEqual(str(ForkedReturn(dict(x=int, y=bool, z=str))), "ForkedReturn(x:DInt32, y:DBool, z:DStr8192)")
def test_as_python_type(self): """Test conversion of Deltaflow data types to python.""" # special self.assertEqual(Top().as_python_type(), Any) # primitive self.assertEqual(DInt(DSize(32)).as_python_type(), int) self.assertEqual(DInt(DSize(64)).as_python_type(), int) self.assertEqual(DUInt(DSize(32)).as_python_type(), int) self.assertEqual(DUInt(DSize(64)).as_python_type(), int) self.assertEqual(DBool().as_python_type(), bool) with self.assertRaises(NotImplementedError): DChar().as_python_type() self.assertEqual(DFloat(DSize(32)).as_python_type(), float) self.assertEqual(DFloat(DSize(64)).as_python_type(), float) self.assertEqual(DComplex(DSize(64)).as_python_type(), complex) self.assertEqual(DComplex(DSize(128)).as_python_type(), complex) # compound self.assertEqual(DTuple([int, bool]).as_python_type(), Tuple[int, bool]) self.assertEqual(DTuple([int, DTuple([int, bool])]).as_python_type(), Tuple[int, Tuple[int, bool]]) self.assertEqual(DArray(int, DSize(3)).as_python_type(), List[int]) self.assertEqual(DStr().as_python_type(), str) self.assertEqual(DStr(DSize(10)).as_python_type(), str) self.assertEqual(DRecord(RecBI).as_python_type(), RecBI) self.assertEqual(DRecord(RecBDi).as_python_type(), RecBDi) self.assertNotEqual(DRecord(RecBI).as_python_type(), RecBI_copy) # compound: DUnion self.assertEqual(DUnion([bool, int]).as_python_type(), Union[bool, int]) self.assertEqual(DUnion([bool, DTuple([int, bool])]).as_python_type(), Union[bool, Tuple[int, bool]])
def test_Top(self): """Everything can be accepted as Top().""" self.assertTrue(DeltaGraph.check_wire(DInt(), Top())) self.assertTrue(DeltaGraph.check_wire(DUInt(), Top())) self.assertTrue(DeltaGraph.check_wire(DBool(), Top())) self.assertTrue(DeltaGraph.check_wire(DTuple([int, bool]), Top())) self.assertTrue(DeltaGraph.check_wire(DUnion([int, bool]), Top())) self.assertTrue(DeltaGraph.check_wire(DArray(int, DSize(8)), Top())) self.assertTrue(DeltaGraph.check_wire(DStr(), Top())) self.assertTrue(DeltaGraph.check_wire(DRecord(RecBI), Top())) self.assertTrue(DeltaGraph.check_wire(Top(), Top())) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(Top(), DInt()) # however it's not true if Top is used within a non-primitive type with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DTuple([int, int]), DTuple([int, Top()])) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DArray(int, DSize(8)), DArray(Top(), DSize(8))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DRecord(RecBI), DRecord(RecBT))
def migen_body(self, template): inp = template.add_pa_in_port('inp', DOptional(DInt())) trigger = template.add_pa_in_port('trigger', DOptional(DInt())) out = template.add_pa_out_port('out', DInt()) # Declare input and output ports always happy to receive/transmit data self.comb += ( inp.ready.eq(1), trigger.ready.eq(1), out.ready.eq(1), ) commander_fsm = FSM(reset_state="IDLE") self.submodules.commander_fsm = commander_fsm commander_fsm.act("IDLE", If(inp.valid == 1, NextState("LOADING"))) commander_fsm.act( "LOADING", If(trigger.valid & trigger.data == 1, NextState("RETURN")).Else( NextValue(out.data, out.data + inp.data), )) commander_fsm.act("RETURN", NextValue(out.valid, 1), NextState("IDLE"))
def test_DUnion(self): """Test wires with DUnion.""" # examples of obvious behaiviour self.assertTrue(DeltaGraph.check_wire(DUnion([int, bool]), DUnion([int, bool]))) self.assertTrue(DeltaGraph.check_wire(DUnion([int, bool]), DUnion([bool, int]))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DUnion([int, bool]), DInt()) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DUnion([int, bool, float]), DUnion([int, bool])) # strict typing even with DUnion, i.e. all subtypes should match with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DUnion([bool, int]), DUnion([bool, int, float])) # DUnion changes packing method, thus these tests should fail with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DInt(), DUnion([int])) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DUnion([int]), DInt())
def test_DRecord(self): # primitive self.check(RecBI(True, 5), DRecord(RecBI)) self.check(-4, DInt()) self.check(RecBII(True, 5, -4), DRecord(RecBII)) # mixed self.check(RecIT(-4.0, (1, 2)), DRecord(RecIT)) self.check(RecATI([1, 2], (3.0, 4), 5), DRecord(RecATI)) self.check((RecIT(-4.0, (1, 2)), 1), DTuple([DRecord(RecIT), int])) self.check([RecIT(-4.0, (1, 2)), RecIT(5.0, (-3, -4))], DArray(DRecord(RecIT), DSize(2))) self.assertTrue(DeltaGraph.check_wire(DRaw(DRecord(RecIT)), DRaw(DRecord(RecIT))))
def test_size(self): """Test how many bits each data type takes.""" # primitive self.assertEqual(DInt().size, DSize(32)) self.assertEqual(DUInt().size, DSize(32)) self.assertEqual(DBool().size, DSize(1)) self.assertEqual(DChar().size, DSize(8)) self.assertEqual(DFloat().size, DSize(32)) # compound self.assertEqual(DTuple([int, bool]).size, DSize(33)) self.assertEqual(DArray(int, DSize(10)).size, DSize(320)) self.assertEqual(DStr().size, DSize(8192)) self.assertEqual(DRecord(RecBI).size, DSize(33)) # compound: DUnion self.assertEqual(DUnion([bool]).size, DSize(9)) self.assertEqual(DUnion([int, bool]).size, DSize(40)) self.assertEqual(DUnion([int, DTuple([int, int])]).size, DSize(2*32+8))
def test_compound_objects(self): t = DArray(DTuple([bool, int]), DSize(3)) val = [(True, 1), (False, 2), (True, 3), (False, 4), (True, 5)] self.check(val, t) t = DTuple([int, DTuple([bool, int])]) val = (12, (True, 8)) self.check(val, t) t = DTuple([int, DArray(int, DSize(2))]) val = (12, [14, 18]) self.check(val, t) t = DTuple([int, DStr()]) val = (12, "hello") self.check(val, t) t = DTuple([int, DRecord(RecBI)]) val = (12, RecBI(True, 8)) self.check(val, t) t = DTuple([int, DUnion([bool, int])]) val = (12, True) np_val = t.as_numpy_object(val) self.assertEqual(DInt().from_numpy_object(np_val[0][0]), 12) self.assertEqual(DBool().from_numpy_object(np_val[0][1][1]), True) t = DRecord(RecATI) val = RecATI([1, 2], (3.0, 4), 5) self.check(val, t) t = DUnion([DArray(int, DSize(2)), int]) val = [1, 2] np_val = t.as_numpy_object(val) new_val = DArray(int, DSize(2)).from_numpy_object(np_val[0][1]) self.assertEqual(val, new_val) t = DUnion([str, int]) val = "abcde" np_val = t.as_numpy_object(val) new_val = DStr().from_numpy_object(np_val[0][1]) self.assertEqual(val, new_val)
def test_DRecord(self): # primitive self.check(RecBI(True, 5), DRecord(RecBI)) self.check(-4, DInt()) self.check(RecBII(True, 5, -4), DRecord(RecBII)) with self.assertRaises(DeltaTypeError): self.check(RecBI(True, 5), DRecord(RecIB)) # mixed self.check(RecIT(-4.0, (1, 2)), DRecord(RecIT)) self.check(RecATI([1, 2], (3.0, 4), 5), DRecord(RecATI)) self.check((RecIT(-4.0, (1, 2)), 1), DTuple([DRecord(RecIT), int])) self.check([RecIT(-4.0, (1, 2)), RecIT(5.0, (-3, -4))], DArray(DRecord(RecIT), DSize(2))) # numpy self.check_numpy(RecBI(False, 2), DRecord(RecBI))
def test_DSize(self): """Test various use DSize.""" with self.assertRaises(DeltaTypeError): DInt(5) with self.assertRaises(ValueError): DSize(-1) with self.assertRaises(ValueError): dummy = DSize(4) + DSize(NamespacedName("a", "b")) # add d16_32 = DSize(16) d16_32 += DSize(32) self.assertEqual(d16_32, DSize(48)) self.assertEqual(DSize(4) + DSize(5), DSize(9)) # sub d32_16 = DSize(32) d32_16 -= DSize(16) self.assertEqual(d32_16, DSize(16)) self.assertEqual(DSize(5) - DSize(2), DSize(3)) with self.assertRaises(ValueError): dummy = DSize(5) - DSize(6) # mul self.assertEqual(DSize(4) * 5, DSize(20)) self.assertEqual(5 * DSize(4), DSize(20)) d16x4 = DSize(16) d16x4 *= 4 self.assertEqual(d16x4, DSize(64)) d16x4 = DSize(16) d16x4 *= DSize(4) self.assertEqual(d16x4, DSize(64)) # comparison self.assertTrue(DSize(8) == DSize(8)) self.assertTrue(DSize(8) > DSize(6)) self.assertTrue(DSize(4) < DSize(6))
def test_DOptiona_of_DUnion(self): port = InPort(NamespacedName("test_name", None), DOptional(DUnion([DInt(), DFloat()])), None, 0) self.assertEqual(port.port_type, DUnion([DInt(), DFloat()])) self.assertEqual(port.is_optional, True)
def test_DUnion_of_single(self): """DUnion of a single type is not converted to a single type.""" port = InPort(NamespacedName("test_name", None), DUnion([DInt()]), None, 0) self.assertEqual(port.port_type, DUnion([DInt()])) self.assertEqual(port.is_optional, False)
def test_DOptional(self): port = InPort(NamespacedName("test_name", None), DOptional(DInt()), None, 0) self.assertEqual(port.port_type, DInt()) self.assertEqual(port.is_optional, True)
def test_DInt_object(self): self.check(5, DInt(DSize(8))) self.check(10, DInt(DSize(16))) self.check(15, DInt(DSize(32))) self.check(20, DInt(DSize(64)))
class RecBDi: x: bool = attr.ib() y: DInt() = attr.ib()
def test_non_DOptional(self): port = OutPort(NamespacedName("test_name", None), DInt(), None, None) self.assertEqual(port.port_type, DInt())
def test_DOptional(self): port = OutPort(NamespacedName("test_name", None), DOptional(DInt()), None, None) with self.assertRaises(TypeError): dummy = port.port_type
def test_ForkedReturn(self): self.assertTrue(DeltaGraph.check_wire(TwoIntsT.elem_dict['x'], DInt()))