diff --git a/spinn_front_end_common/interface/ds/data_type.py b/spinn_front_end_common/interface/ds/data_type.py index 95ffb20114..28c7031fbb 100644 --- a/spinn_front_end_common/interface/ds/data_type.py +++ b/spinn_front_end_common/interface/ds/data_type.py @@ -18,6 +18,16 @@ import numpy as np +def _round_to_int(value): + """ Rounds a number to the closest integer + :param float value: The value to round + :rtype: int + """ + if isinstance(value, int): + return value + return int(round(value)) + + class DataType(Enum): """ Supported data types. @@ -49,7 +59,7 @@ class DataType(Enum): decimal.Decimal("1"), "B", False, - int, + _round_to_int, np.uint8, "8-bit unsigned integer") #: 16-bit unsigned integer @@ -60,7 +70,7 @@ class DataType(Enum): decimal.Decimal("1"), "H", False, - int, + _round_to_int, np.uint16, "16-bit unsigned integer") #: 32-bit unsigned integer @@ -71,7 +81,7 @@ class DataType(Enum): decimal.Decimal("1"), "I", False, - int, + _round_to_int, np.uint32, "32-bit unsigned integer") #: 64-bit unsigned integer @@ -82,7 +92,7 @@ class DataType(Enum): decimal.Decimal("1"), "Q", False, - int, + _round_to_int, np.uint64, "64-bit unsigned integer") #: 8-bit signed integer @@ -93,7 +103,7 @@ class DataType(Enum): decimal.Decimal("1"), "b", False, - int, + _round_to_int, np.int8, "8-bit signed integer") #: 16-bit signed integer @@ -104,7 +114,7 @@ class DataType(Enum): decimal.Decimal("1"), "h", False, - int, + _round_to_int, np.int16, "16-bit signed integer") #: 32-bit signed integer @@ -115,7 +125,7 @@ class DataType(Enum): decimal.Decimal("1"), "i", False, - int, + _round_to_int, np.int32, "32-bit signed integer") #: 64-bit signed integer @@ -126,7 +136,7 @@ class DataType(Enum): decimal.Decimal("1"), "q", False, - int, + _round_to_int, np.int64, "64-bit signed integer") #: 8.8 unsigned fixed point number @@ -402,6 +412,31 @@ def numpy_typename(self): """ return self._numpy_typename + def closest_representable_value(self, value): + """ + Returns the closest value to the given value that can be represented + by this type + + :param value: + :type value: float or in + :rtype: float + """ + return self.decode_from_int(self.encode_as_int(value)) + + def closest_representable_value_above(self, value): + """ + Returns the closest value above the given value that can be + represented by this type. + + :param value: + :type value: float or in + :rtype: float + """ + closest_value = self.decode_from_int(self.encode_as_int(value)) + if closest_value >= value: + return closest_value + return self.decode_from_int(self.encode_as_int(value)+1) + def encode_as_int(self, value): """ Returns the value as an integer, according to this type. @@ -425,6 +460,15 @@ def encode_as_int(self, value): return self._force_cast(value) return value + def decode_from_int(self, value): + """ + Decode a single value represented as an int according to this type. + + :param int array: + :rtype: float or int + """ + return value / float(self._scale) + def encode_as_numpy_int(self, value): """ Returns the value as a numpy integer, according to this type. diff --git a/spinn_front_end_common/interface/provenance/provenance_writer.py b/spinn_front_end_common/interface/provenance/provenance_writer.py index 17d0ae1f5a..98e781b4d5 100644 --- a/spinn_front_end_common/interface/provenance/provenance_writer.py +++ b/spinn_front_end_common/interface/provenance/provenance_writer.py @@ -196,3 +196,21 @@ def insert_board_provenance(self, connections): VALUES (?, ?, ?) """, ((x, y, ipaddress) for ((x, y), ipaddress) in connections.items())) + + def insert_app_vertex( + self, label, the_type, description, the_value): + """ + Inserts app level data into the app_vertex_provenance + + :param str label: Label of the app_vertex + :param str the_type: Class of the app_vertex + :param str description: type of value + :param float the_value: data + """ + self.execute( + """ + INSERT OR IGNORE INTO app_vertex_provenance( + label, the_type, description, the_value) + VALUES(?, ?, ?, ?) + """, + [label, the_type, description, the_value]) diff --git a/spinn_front_end_common/utilities/db.sql b/spinn_front_end_common/utilities/db.sql index 2b77c2e4f1..d417d4ccfe 100644 --- a/spinn_front_end_common/utilities/db.sql +++ b/spinn_front_end_common/utilities/db.sql @@ -225,3 +225,13 @@ CREATE TABLE IF NOT EXISTS boards_provenance( ip_addres STRING NOT NULL, ethernet_x INTEGER NOT NULL, ethernet_y INTEGER NOT NULL); + +--------------------------------------------------------------------- +-- A table app vertex provenance +CREATE TABLE IF NOT EXISTS app_vertex_provenance( + app_vertex_id INTEGER PRIMARY KEY AUTOINCREMENT, + label STRING NOT NULL, + the_type STRING NOT NULL, + description STRING NOT NULL, + the_value FLOAT NOT NULL); + diff --git a/unittests/interface/provenance/test_provenance_database.py b/unittests/interface/provenance/test_provenance_database.py index 6535535d25..ecdc49c211 100644 --- a/unittests/interface/provenance/test_provenance_database.py +++ b/unittests/interface/provenance/test_provenance_database.py @@ -185,6 +185,14 @@ def test_board(self): with ProvenanceWriter() as db: db.insert_board_provenance(data) + def test_app_vertex(self): + with ProvenanceWriter() as db: + db.insert_app_vertex("pop", "type", "description", 0.5) + with ProvenanceReader() as db: + data = db.run_query("Select * from app_vertex_provenance") + expected = [(1, 'pop', 'type', 'description', 0.5)] + self.assertListEqual(expected, data) + def test_log(self): db1 = LogStoreDB() db2 = LogStoreDB()