Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xlogger #125

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions gfe_integration_tests/test_logger_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright (c) 2017-2019 The University of Manchester
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import math
import os
import unittest
from spinn_front_end_common.utilities import globals_variables


class TestLoggerExample(unittest.TestCase):

def setUp(self):
globals_variables.unset_simulator()

def near_equals(self, a, b):
diff = a - b
if diff == 0:
return True
ratio = diff / a
return abs(ratio) < 0.0001

def check_line(self, line):
if "logger_example.c" not in line:
print("OTHER")
return
parts = line.split(":")
if len(parts) != 4:
return
check = parts[3]
if "==" in check:
tokens = check.split("==")
self.assertEquals(tokens[0].strip(), tokens[1].strip())
elif "=" in check:
tokens = check.split("=")
self.assertEquals(
float(tokens[0].strip()), float(tokens[1].strip()))
elif "~" in check:
tokens = check.split("~")
assert self.near_equals(
float(tokens[0].strip()), float(tokens[1].strip()))
elif "isnan" in check:
tokens = check.split("~")
assert math.isnan(tokens[-1])

def test_logger_example(self):
import spinnaker_graph_front_end.examples.logger_example as le_dir
class_file = le_dir.__file__
path = os.path.dirname(os.path.abspath(class_file))
os.chdir(path)
import spinnaker_graph_front_end.examples.logger_example.logger_example # NOQA
report_directory = globals_variables.get_simulator().\
_report_default_directory
log_path = os.path.join(report_directory, "provenance_data",
"iobuf_for_chip_0_0_processor_id_3.txt")
with open(log_path) as log_file:
for line in log_file:
self.check_line(line)
2 changes: 1 addition & 1 deletion spinnaker_graph_front_end/examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

BUILD_DIRS = hello_world Conways template
BUILD_DIRS = hello_world Conways template logger_example
all: $(BUILD_DIRS)
for d in $(BUILD_DIRS); do (cd $$d; "$(MAKE)") || exit $$?; done

Expand Down
27 changes: 27 additions & 0 deletions spinnaker_graph_front_end/examples/logger_example/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright (c) 2017-2019 The University of Manchester
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

# If SPINN_DIRS is not defined, this is an error!
ifndef SPINN_DIRS
$(error SPINN_DIRS is not set. Please define SPINN_DIRS (possibly by running "source setup" in the spinnaker package folder))
endif

APP = logger_example
SOURCES = logger_example.c

APP_OUTPUT_DIR := $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))/

include $(SPINN_DIRS)/make/local.mk

16 changes: 16 additions & 0 deletions spinnaker_graph_front_end/examples/logger_example/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (c) 2017-2019 The University of Manchester
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

__author__ = 'Christian'
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright (c) 2017-2019 The University of Manchester
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""
Hello World program on SpiNNaker

Each core stores into its region in SDRAM the string:
"Hello World from $chip.x, $chip.y, $core"

We then fetch the written data and print it on the python console.
"""

import logging
import os
import spinnaker_graph_front_end as front_end
from spinnaker_graph_front_end.examples.logger_example.logger_example_vertex \
import LoggerExampleVertex

logger = logging.getLogger(__name__)

front_end.setup(
n_chips_required=1, model_binary_folder=os.path.dirname(__file__))

# Put LoggerExampleVertex onto 1 core
total_number_of_cores = 16
front_end.add_machine_vertex_instance(
LoggerExampleVertex(label="This is an Example"))

front_end.run(10)

placements = front_end.placements()
buffer_manager = front_end.buffer_manager()

for placement in sorted(placements.placements,
key=lambda p: (p.x, p.y, p.p)):

if isinstance(placement.vertex, LoggerExampleVertex):
logger_example = placement.vertex.read(placement, buffer_manager)
logger.info("{}, {}, {} > {}".format(
placement.x, placement.y, placement.p, logger_example))

front_end.stop()
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

# make APP=logger_example
# tubotron &
# visualiser &

iptag 1 set . 17894
app_load logger_example.aplx all 1-16 16
sleep 1
app_sig all 16 sync0

Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Copyright (c) 2017-2019 The University of Manchester
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from enum import Enum
import logging
from spinn_utilities.overrides import overrides
from pacman.model.graphs.machine import MachineVertex
from pacman.model.resources import ResourceContainer, ConstantSDRAM
from spinn_front_end_common.utilities.constants import SYSTEM_BYTES_REQUIREMENT
from spinn_front_end_common.utilities.helpful_functions import (
locate_memory_region_for_placement)
from spinn_front_end_common.abstract_models.impl import (
MachineDataSpecableVertex)
from spinn_front_end_common.interface.buffer_management.buffer_models import (
AbstractReceiveBuffersToHost)
from spinn_front_end_common.interface.buffer_management import (
recording_utilities)
from spinnaker_graph_front_end.utilities import SimulatorVertex
from spinnaker_graph_front_end.utilities.data_utils import (
generate_system_data_region)

logger = logging.getLogger(__name__)


class LoggerExampleVertex(
SimulatorVertex, MachineDataSpecableVertex,
AbstractReceiveBuffersToHost):

DATA_REGIONS = Enum(
value="DATA_REGIONS",
names=[('SYSTEM', 0),
('STRING_DATA', 1)])

def __init__(self, label=None, constraints=None):
super(LoggerExampleVertex, self).__init__(
label, "logger_example.aplx", constraints=constraints)

self._string_data_size = 5000

@property
@overrides(MachineVertex.resources_required)
def resources_required(self):
resources = ResourceContainer(sdram=ConstantSDRAM(
SYSTEM_BYTES_REQUIREMENT +
recording_utilities.get_recording_header_size(1) +
self._string_data_size))

return resources

@overrides(MachineDataSpecableVertex.generate_machine_data_specification)
def generate_machine_data_specification(
self, spec, placement, machine_graph, routing_info, iptags,
reverse_iptags, machine_time_step, time_scale_factor):
# Generate the system data region for simulation .c requirements
generate_system_data_region(spec, self.DATA_REGIONS.SYSTEM.value,
self, machine_time_step, time_scale_factor)

# Reserve SDRAM space for memory areas:

# Create the data regions for hello world
spec.reserve_memory_region(
region=self.DATA_REGIONS.STRING_DATA.value,
size=recording_utilities.get_recording_header_size(1),
label="Recording")

# write data for the simulation data item
spec.switch_write_focus(self.DATA_REGIONS.STRING_DATA.value)
spec.write_array(recording_utilities.get_recording_header_array(
[self._string_data_size]))

# End-of-Spec:
spec.end_specification()

def read(self, placement, buffer_manager):
""" Get the data written into SDRAM

:param placement: the location of this vertex
:param buffer_manager: the buffer manager
:return: string output
"""
raw_data, missing_data = buffer_manager.get_data_by_placement(
placement, 0)
if missing_data:
raise Exception("missing data!")
return str(bytearray(raw_data))

@overrides(AbstractReceiveBuffersToHost.get_recorded_region_ids)
def get_recorded_region_ids(self):
return [0]

@overrides(AbstractReceiveBuffersToHost.get_recording_region_base_address)
def get_recording_region_base_address(self, txrx, placement):
return locate_memory_region_for_placement(
placement, self.DATA_REGIONS.STRING_DATA.value, txrx)
Loading