diff --git a/c_common/front_end_common_lib/src/recording.c b/c_common/front_end_common_lib/src/recording.c index 31bf986e22..66ecbda810 100644 --- a/c_common/front_end_common_lib/src/recording.c +++ b/c_common/front_end_common_lib/src/recording.c @@ -195,8 +195,8 @@ bool recording_initialize( sark_heap_max(sv->sdram_heap, 0)); return false; } - log_info("Allocated %u bytes for recording channel %u at 0x%08x", - space, i, region->data); +// log_info("Allocated %u bytes for recording channel %u at 0x%08x", +// space, i, region->data); if (recording_flags != NULL) { *recording_flags = (*recording_flags | (1 << i)); } diff --git a/c_common/front_end_common_lib/src/simulation.c b/c_common/front_end_common_lib/src/simulation.c index aa57c3fe6a..52b110084d 100644 --- a/c_common/front_end_common_lib/src/simulation.c +++ b/c_common/front_end_common_lib/src/simulation.c @@ -197,15 +197,15 @@ static void simulation_control_scp_callback(uint mailbox, UNUSED uint port) { log_info("Calling pre-exit function"); stored_exit_function(); } - log_info("Exiting"); +// log_info("Exiting"); spin1_exit(0); break; case CMD_RUNTIME: - log_info("Setting the runtime of this model to %d starting at %d", - msg->arg1, msg->arg3); - log_info("Setting the flag of infinite run for this model to %d", - msg->arg2); + log_info("Setting the runtime of this model to %d starting at %d (flag %d)", + msg->arg1, msg->arg3, msg->arg2); +// log_info("Setting the flag of infinite run for this model to %d", +// msg->arg2); // resetting the simulation time pointer *pointer_to_simulation_time = msg->arg1; diff --git a/spinn_front_end_common/interface/interface_functions/placements_provenance_gatherer.py b/spinn_front_end_common/interface/interface_functions/placements_provenance_gatherer.py index c98e13091f..6e433bc779 100644 --- a/spinn_front_end_common/interface/interface_functions/placements_provenance_gatherer.py +++ b/spinn_front_end_common/interface/interface_functions/placements_provenance_gatherer.py @@ -17,7 +17,7 @@ from spinn_utilities.log import FormatAdapter from spinn_utilities.progress_bar import ProgressBar from spinn_front_end_common.interface.provenance import ( - AbstractProvidesProvenanceDataFromMachine) + AbstractProvidesProvenanceDataFromMachine, ProvenanceWriter) logger = FormatAdapter(logging.getLogger(__name__)) @@ -38,6 +38,7 @@ def placements_provenance_gatherer(n_placements, placements): # retrieve provenance data from any cores that provide data for placement in progress.over(placements): _add_placement_provenance(placement, errors) + _add_structured_provenance(placement, errors) if errors: logger.warning("Errors found during provenance gathering:") for error in errors: @@ -50,11 +51,47 @@ def _add_placement_provenance(placement, errors): :param list(str) errors: """ # retrieve provenance data from any cores that provide data - if isinstance( - placement.vertex, AbstractProvidesProvenanceDataFromMachine): + if isinstance(placement.vertex, AbstractProvidesProvenanceDataFromMachine): # get data try: placement.vertex.get_provenance_data_from_machine(placement) except Exception: # pylint: disable=broad-except errors.append(traceback.format_exc()) + + +def _add_structured_provenance(placement, errors): + """ + :param ~.Placement placement: + :param list(str) errors: + """ + # Insert structured provenance data to database for cores that have data + if isinstance(placement.vertex, AbstractProvidesProvenanceDataFromMachine): + + # Custom provenance presentation from SpiNNCer + # write provenance to file here in a useful way + columns = ['pop', 'label', 'min_atom', 'max_atom', 'no_atoms', + 'fixed_sdram', 'sdram_per_timestep'] + + pop = placement.vertex.label.split(":")[0] + fixed_sdram = placement.vertex.sdram_required.fixed + sdram_per_timestep = placement.vertex.sdram_required.per_timestep + + label = placement.vertex.label + vertex_slice = placement.vertex.vertex_slice + max_atom = vertex_slice.hi_atom + min_atom = vertex_slice.lo_atom + no_atoms = vertex_slice.n_atoms + + structured_provenance = [ + pop, label, min_atom, max_atom, no_atoms, + fixed_sdram, sdram_per_timestep] + + # get data + try: + with ProvenanceWriter() as db: + for n in range(len(columns)): + db.insert_core(placement.x, placement.y, placement.p, + columns[n], structured_provenance[n]) + except Exception: # pylint: disable=broad-except + errors.append(traceback.format_exc()) diff --git a/spinn_front_end_common/interface/provenance/provenance_reader.py b/spinn_front_end_common/interface/provenance/provenance_reader.py index 551e06e5de..925a570a57 100644 --- a/spinn_front_end_common/interface/provenance/provenance_reader.py +++ b/spinn_front_end_common/interface/provenance/provenance_reader.py @@ -147,7 +147,7 @@ def get_provenance_for_router(self, x, y): f"{ row[0] }: { row[1] }" for row in self.run_query(query, [int(x), int(y)])) - def get_cores_with_provenace(self): + def get_cores_with_provenance(self): """ Gets the cores with provenance. @@ -233,10 +233,10 @@ def demo(): print(row) print("\nCORES WITH LATE SPIKES:") print(pr.cores_with_late_spikes()) - print("\nROUETER (0,0) PROVENANCE:") + print("\nROUTER (0,0) PROVENANCE:") print(pr.get_provenance_for_router(0, 0)) print("\nCORES WITH PROVENACE") - print(pr.get_cores_with_provenace()) + print(pr.get_cores_with_provenance()) if __name__ == '__main__': diff --git a/spinn_front_end_common/interface/provenance/provenance_writer.py b/spinn_front_end_common/interface/provenance/provenance_writer.py index 17d0ae1f5a..19d3aad24a 100644 --- a/spinn_front_end_common/interface/provenance/provenance_writer.py +++ b/spinn_front_end_common/interface/provenance/provenance_writer.py @@ -196,3 +196,24 @@ def insert_board_provenance(self, connections): VALUES (?, ?, ?) """, ((x, y, ipaddress) for ((x, y), ipaddress) in connections.items())) + + def insert_lut( + self, pre_population, post_population, the_type, description, + the_value): + """ + Inserts edge data into the lut_provenance + :param str pre_population: Name of the pre population / vertex + :param str post_population: Name of the post population / vertex + :param str the_type: Class of the rule of the LUT + :param str description: type of value + :param float the_value: data + """ + self.execute( + """ + INSERT OR IGNORE INTO lut_provenance( + pre_population, post_population, the_type, description, + the_value) + VALUES(?, ?, ?, ?, ?) + """, + [pre_population, post_population, 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..e251a9be53 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 LUT provenance +CREATE TABLE IF NOT EXISTS lut_provenance( + connector_id INTEGER PRIMARY KEY AUTOINCREMENT, + pre_population STRING NOT NULL, + post_population 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..1ff88b2649 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_lut(self): + with ProvenanceWriter() as db: + db.insert_lut("the pre", "A post", "OneToOne", "foo", 0.5) + with ProvenanceReader() as db: + data = db.run_query("Select * from lut_provenance") + expected = [(1, 'the pre', 'A post', 'OneToOne', 'foo', 0.5)] + self.assertListEqual(expected, data) + def test_log(self): db1 = LogStoreDB() db2 = LogStoreDB()