Example #1
0
def main(args=None):
    parser = argparse.ArgumentParser(
        description="Print a summary of basic SpiNNaker machine "
                    "and BMP information")
    parser.add_argument("--version", "-V", action="version",
                        version="%(prog)s {}".format(rig.__version__))

    parser.add_argument("hostname", type=str,
                        help="hostname or IP of SpiNNaker system or BMP")

    args = parser.parse_args(args)

    # Determine what type of machine this is and print information accordingly
    try:
        mc = MachineController(args.hostname)
        info = mc.get_software_version(255, 255)
        if "SpiNNaker" in info.version_string:
            for line in get_spinnaker_info(mc):
                print(line)
        elif "BMP" in info.version_string:
            bc = BMPController(args.hostname)
            for line in get_bmp_info(bc):
                print(line)
        else:
            sys.stderr.write("{}: error: unknown architecture '{}'\n".format(
                parser.prog, info.version_string))
            return 2
    except TimeoutError:
        sys.stderr.write("{}: error: command timed out\n".format(
            parser.prog))
        return 1

    return 0
Example #2
0
def main(args=None):
    parser = argparse.ArgumentParser(
        description="Print the contents of IOBUF for a specified core")
    parser.add_argument("--version",
                        "-V",
                        action="version",
                        version="%(prog)s {}".format(rig.__version__))

    parser.add_argument("hostname",
                        type=str,
                        help="hostname or IP of SpiNNaker system")

    parser.add_argument("x", type=int, help="the X coordinate of the chip")
    parser.add_argument("y", type=int, help="the Y coordinate of the chip")
    parser.add_argument("p", type=int, help="the processor number")

    args = parser.parse_args(args)

    try:
        mc = MachineController(args.hostname)
        info = mc.get_software_version(255, 255)
        if "SpiNNaker" in info.version_string:
            sys.stdout.write(mc.get_iobuf(args.p, args.x, args.y))
        else:
            sys.stderr.write("{}: error: unknown architecture '{}'\n".format(
                parser.prog, info.version_string.strip("\x00")))
            return 2
    except TimeoutError:
        sys.stderr.write("{}: error: command timed out\n".format(parser.prog))
        return 1

    return 0
Example #3
0
 def connect2Machine(self):
     self.mc = MachineController(DEF_HOST)
     if BOOT_MACHINE is True:
         if self.mc.boot() is True:
             print "Machine is now booted..."
         else:
             print "Machine is already booted..."
     self.machineInfo = self.mc.get_system_info()
Example #4
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.setCentralWidget(self.mdiArea)
        self.statusTxt = QtGui.QLabel("")
        self.dagFile = QtGui.QLabel("")
        self.statusBar().addWidget(self.dagFile)
        self.statusBar().addWidget(self.statusTxt)

        self.vis = visWidget(self.mdiArea)
        self.vis.setGeometry(0, 0, 1024, 1024)
        #self.vis.scale(0.5,0.5) # put in half size
        self.vis.hide()
        self.action_Visualiser.setCheckable(True)
        #self.action_Visualiser.setChecked(False)

        self.connect(self.action_Quit, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("Quit()"))
        self.connect(self.action_Load_XML, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("loadXML()"))
        self.connect(self.action_Visualiser, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("showVisualiser()"))
        self.connect(self.action_Send_and_Init, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("sendAndInit()"))
        self.connect(self.actionInspect_SpinConf, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("testSpin1()"))
        self.connect(self.actionSet_Tick, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("getSimulationTick()"))
        self.connect(self.actionStart, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("startSim()"))
        self.connect(self.actionStop, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("stopSim()"))

        self.simTick = 1000000  # default value that yield 1second resolution
        self.output = None  # this is a list of list of dict that contains target dependency data
        """
        self.srcTarget = dict()     # this similar to self.output, but just contains target for SOURCE node
                                    # (as a dict of a list), e.g: from dag0020, srcTarget = {0: [4,3,2]}
        """
        self.srcTarget = list(
        )  # now scrTarget becomes simpler, because we don't send the trigger's payload
        self.sdp = sdpComm()
        self.sdp.histUpdate.connect(self.vis.updateHist)
        self.mc = MachineController(DEF_HOST)
        if BOOT_MACHINE is True:
            if self.mc.boot() is True:
                print "Machine is now booted..."
            else:
                print "Machine is already booted..."
        self.machineInfo = self.mc.get_system_info()
        """
        self.mc.iptag_set(0,'192.168.240.2',17892,0,0) # prepare iptag for myTub, because boot in rig doesn't provide this
        if DEF_HOST=='192.168.240.1':
            self.statusTxt.setText("Using SpiNN-5 board at {}".format(DEF_HOST))
        else:
            self.statusTxt.setText("Using SpiNN-3 board at {}".format(DEF_HOST))
        """
        self.setGeometry(0, 0, 1024, 1024)
Example #5
0
    def __init__(self, MACHINE_IP, parent=None):
        super(mainWidget, self).__init__(parent)
        self.setGeometry(0, 0, 640, 480)
        self.setWindowTitle("SpiNNaker Chips Visualizer")

        # get info from rig:
        mc = MachineController(MACHINE_IP)
        mc.boot()
        mInfo = mc.get_system_info()
        w = mInfo.width
        h = mInfo.height
        chipList = mInfo.keys()
        self.vis = visWidget(w, h, chipList, self)
        self.vis.setGeometry(0, 0, self.width(), self.height())
Example #6
0
def main(args=None):
    parser = argparse.ArgumentParser(description="Boot a SpiNNaker board")
    parser.add_argument("--version",
                        "-V",
                        action="version",
                        version="%(prog)s {}".format(rig.__version__))

    parser.add_argument("hostname",
                        type=str,
                        help="hostname or IP of SpiNNaker system")

    # Automatically build a list of available machine parameters by inspecting
    # boot module.
    type_group = parser.add_mutually_exclusive_group()
    for dict_name in dir(boot):
        if dict_name.endswith(BOOT_OPTION_POSTFIX):
            type_name = dict_name[:-len(BOOT_OPTION_POSTFIX)]
            option_name = "--{}".format(type_name)
            option_dict = getattr(boot, dict_name)
            option_help = "use predefined boot options for a {} board".format(
                type_name)
            type_group.add_argument(option_name,
                                    action="store_const",
                                    const=option_dict,
                                    default={},
                                    dest="board_options",
                                    help=option_help)

    args = parser.parse_args(args)

    # Attempt to boot the machine
    mc = MachineController(args.hostname)
    try:
        if mc.boot(**args.board_options):
            return 0
        else:
            # The machine was already booted.
            sys.stderr.write("{}: error: machine already booted.\n".format(
                parser.prog))
            return 1
    except SpiNNakerBootError as e:
        # The machine could not be booted for some reason; show an appropriate
        # message
        sys.stderr.write("{}: error: {}\n".format(parser.prog, str(e)))
        return 2
Example #7
0
    def __init__(self, cli_param, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.setCentralWidget(self.mdiArea)
        self.statusTxt = QtGui.QLabel("")
        self.dagFile = QtGui.QLabel("")
        self.statusBar().addWidget(self.dagFile)
        self.statusBar().addWidget(self.statusTxt)

        # connect to the machine
        if len(cli_param) > 1:
            ip = cli_param[1]
            if len(cli_param) > 2:
                self.myPC = cli_param[2]
            else:
                self.myPC = DEF_MYPC
        else:
            ip, ok = QtGui.QInputDialog.getText(None, "Connect to SpiNNaker",
                                                "Please specify machine IP",
                                                QtGui.QLineEdit.Normal,
                                                DEF_HOST)
            if ok is False:
                ip = ''
        print "Using machine at", ip
        self.mc = MachineController(ip)
        if BOOT_MACHINE is True:
            if self.mc.boot() is True:
                print "Machine is now booted..."
            else:
                print "Machine is already booted..."

        # then use machineInfo to build the map
        self.mInfo = self.mc.get_system_info()
        wMachine = self.mInfo.width
        hMachine = self.mInfo.height
        self.chipList = self.mInfo.keys()
        print "Found", len(self.chipList), "active chips:"
        """
        self.mc.iptag_set(0,'192.168.240.2',17892,0,0) # prepare iptag for myTub, because boot in rig doesn't provide this
        if DEF_HOST=='192.168.240.1':
            self.statusTxt.setText("Using SpiNN-5 board at {}".format(DEF_HOST))
        else:
            self.statusTxt.setText("Using SpiNN-3 board at {}".format(DEF_HOST))
        """

        #self.vis = visWidget(wMachine, hMachine, self.chipList, self.mdiArea)
        # for known dead chips on certain boards
        knownDeadChips = []
        if (len(self.chipList) % 48) != 0:
            # dead chip is detected
            lst = QtGui.QInputDialog.getText(
                self, "Dead chip is detected",
                "Please provide chip coordinate in () separated by space",
                QtGui.QLineEdit.Normal, "(0,2)")
            knownDeadChips = getDeadChipList(lst)
        self.tgvisWidget = visWidget(wMachine, hMachine, self.chipList,
                                     knownDeadChips)
        self.vis = tgViever(self.tgvisWidget)
        #self.vis.setGeometry(0,0,1024,1024)
        #self.vis.scale(0.5,0.5) # put in half size

        self.vis.hide()
        self.action_Visualiser.setCheckable(True)
        #self.action_Visualiser.setChecked(False)

        self.connect(self.action_Quit, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("Quit()"))
        self.connect(self.action_Load_XML, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("loadXML()"))
        self.connect(self.action_Visualiser, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("showVisualiser()"))
        self.connect(self.action_Send_and_Init, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("sendAndInit()"))
        self.connect(self.actionInspect_SpinConf, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("testSpin1()"))
        self.connect(self.actionSet_Tick, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("getSimulationTick()"))
        self.connect(self.actionStart, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("startSim()"))
        self.connect(self.actionStop, QtCore.SIGNAL("triggered()"),
                     QtCore.SLOT("stopSim()"))

        # 22 March 2017 - 11:48 - Buat experiment ambil data untuk paper
        self.timer = QtCore.QTimer(self)
        #self.timer.setInterval(60000) # one minute experiment
        self.timer.timeout.connect(self.timeout)

        # Simulation parameters
        self.simTick = 1000000  # default value that yield 1second resolution
        self.runningTime = 0  # 0 means runs forever
        self.dag = None  # this is a list of list of dict that contains target dependency data
        """
        self.srcTarget = dict()     # this similar to self.dag, but just contains target for SOURCE node
                                    # (as a dict of a list), e.g: from dag0020, srcTarget = {0: [4,3,2]}
        """
        self.srcTarget = list(
        )  # now scrTarget becomes simpler, because we don't send the trigger's payload
        self.sdp = sdpComm(self.chipList, ip)
        self.sdp.histUpdate.connect(self.vis.updateHist)
        self.setGeometry(0, 0, 1024, 1024)
import sys
import pkg_resources
import struct
import time

from rig.machine_control import MachineController
from rig.routing_table import RoutingTableEntry, Routes

binary = pkg_resources.resource_filename("network_tester",
                                         "binaries/network_tester.aplx")

mc = MachineController(sys.argv[1])

with mc.application(0x42):
    num_samples = 1
    num_vals = 4
    commands = [
        0x04,
        2500,  # NT_CMD_TIMESTEP (1.25us is the shortest for 1 in/out)
        0x10,
        (1 << 16) | (1 << 24),  # NT_CMD_RECORD MC sent,received
        0x11,
        0,  # NT_CMD_RECORD_INTERVAL: 0
        0x06,
        0x0202,  # NT_CMD_NUM: One source, one sink
        0x0020,
        0xFFFFFFFF,  # NT_CMD_PROBABILITY[0] 1
        0x0024,
        0xBEEF0000,  # NT_CMD_SOURCE_KEY[0]
        0x0032,
        0xBEEF0000,  # NT_CMD_SINK_KEY[0]
Example #9
0
if __name__ == "__main__":
    # Parse the arguments
    parser = argparse.ArgumentParser()
    parser.add_argument("routing_table")
    parser.add_argument("out_file")
    parser.add_argument("target_length", type=int, default=0, nargs='?')
    parser.add_argument("--memory-profile", type=str)
    args = parser.parse_args()

    # Load and minimise all routing tables
    print("Reading routing tables...")
    with open(args.routing_table, "rb") as f:
        uncompressed = common.read_routing_tables(f)

    # Talk to the machine
    mc = MachineController("192.168.1.1")
    mc.send_signal("stop")

    # Convert the tables into the appropriate formats
    chip_data = {
        chip: pack_table(table, args.target_length)
        for chip, table in iteritems(uncompressed)
    }

    # Allocate memory on the machine
    chip_mem = {(x, y): mc.sdram_alloc_as_filelike(len(data), x=x, y=y, tag=1)
                for (x, y), data in iteritems(chip_data)}

    # Build the targets dictionary
    targets = {chip: {1} for chip in iterkeys(chip_mem)}
Example #10
0
    def __init__(self,
                 network,
                 dt=0.001,
                 period=10.0,
                 timescale=1.0,
                 hostname=None,
                 use_spalloc=None,
                 allocation_fudge_factor=0.6):
        """Create a new Simulator with the given network.

        Parameters
        ----------
        period : float or None
            Duration of one period of the simulator. This determines how much
            memory will be allocated to store precomputed and probed data.
        timescale : float
            Scaling factor to apply to the simulation, e.g., a value of `0.5`
            will cause the simulation to run at half real-time.
        hostname : string or None
            Hostname of the SpiNNaker machine to use; if None then the machine
            specified in the config file will be used.
        use_spalloc : bool or None
            Allocate a SpiNNaker machine for the simulator using ``spalloc``.
            If None then the setting specified in the config file will be used.

        Other Parameters
        ----------------
        allocation_fudge_factor:
           Fudge factor to allocate more cores than really necessary when using
           `spalloc` to ensure that (a) there are sufficient "live" cores in
           the allocated machine, (b) there is sufficient room for a good place
           and route solution. This should generally be more than 0.1 (10% more
           cores than necessary) to account for the usual rate of missing
           chips.
        """
        # Add this simulator to the set of open simulators
        Simulator._add_simulator(self)

        # Create the IO controller
        io_cls = getconfig(network.config, Simulator, "node_io", Ethernet)
        io_kwargs = getconfig(network.config, Simulator, "node_io_kwargs",
                              dict())
        self.io_controller = io_cls(**io_kwargs)

        # Calculate the machine timestep, this is measured in microseconds
        # (hence the 1e6 scaling factor).
        self.timescale = timescale
        machine_timestep = int((dt / timescale) * 1e6)

        # Determine the maximum run-time
        self.max_steps = None if period is None else int(period / dt)

        self.steps = 0  # Steps simulated

        # If the simulator is in "run indefinite" mode (i.e., max_steps=None)
        # then we modify the builders to ignore function of time Nodes and
        # probes.
        builder_kwargs = self.io_controller.builder_kwargs
        if self.max_steps is None:
            raise NotImplementedError

        # Create a model from the network, using the IO controller
        logger.debug("Building model")
        start_build = time.time()
        self.model = Model(dt=dt,
                           machine_timestep=machine_timestep,
                           decoder_cache=get_default_decoder_cache())
        self.model.build(network, **builder_kwargs)

        logger.info("Build took {:.3f} seconds".format(time.time() -
                                                       start_build))

        self.model.decoder_cache.shrink()
        self.dt = self.model.dt
        self._closed = False  # Whether the simulator has been closed or not

        self.host_sim = self._create_host_sim()

        # Holder for probe data
        self.data = {}

        # Holder for profiling data
        self.profiler_data = {}

        # Convert the model into a netlist
        logger.info("Building netlist")
        start = time.time()
        self.netlist = self.model.make_netlist(self.max_steps or 0)

        # Determine whether to use a spalloc machine or not
        if use_spalloc is None:
            # Default is to not use spalloc; this is indicated by either the
            # absence of the option in the config file OR the option being set
            # to false.
            use_spalloc = (rc.has_option("spinnaker_machine", "use_spalloc")
                           and rc.getboolean("spinnaker_machine",
                                             "use_spalloc"))

        # Create a controller for the machine and boot if necessary
        self.job = None
        if not use_spalloc or hostname is not None:
            # Use the specified machine rather than trying to get one
            # allocated.
            if hostname is None:
                hostname = rc.get("spinnaker_machine", "hostname")
        else:
            # Attempt to get a machine allocated to us
            from spalloc import Job

            # Determine how many boards to ask for (assuming 16 usable cores
            # per chip and 48 chips per board).
            n_cores = self.netlist.n_cores * (1.0 + allocation_fudge_factor)
            n_boards = int(np.ceil((n_cores / 16.) / 48.))

            # Request the job
            self.job = Job(n_boards)
            logger.info("Allocated job ID %d...", self.job.id)

            # Wait until we're given the machine
            logger.info("Waiting for machine allocation...")
            self.job.wait_until_ready()

            # spalloc recommends a slight delay before attempting to boot the
            # machine, later versions of spalloc server may relax this
            # requirement.
            time.sleep(5.0)

            # Store the hostname
            hostname = self.job.hostname
            logger.info("Using %d board(s) of \"%s\" (%s)",
                        len(self.job.boards), self.job.machine_name, hostname)

        self.controller = MachineController(hostname)
        self.controller.boot()

        # Get a system-info object to place & route against
        logger.info("Getting SpiNNaker machine specification")
        system_info = self.controller.get_system_info()

        # Place & Route
        logger.info("Placing and routing")
        self.netlist.place_and_route(
            system_info,
            place=getconfig(network.config, Simulator, 'placer',
                            rig.place_and_route.place),
            place_kwargs=getconfig(network.config, Simulator, 'placer_kwargs',
                                   {}),
        )

        logger.info("{} cores in use".format(len(self.netlist.placements)))
        chips = set(six.itervalues(self.netlist.placements))
        logger.info("Using {}".format(chips))

        # Prepare the simulator against the placed, allocated and routed
        # netlist.
        self.io_controller.prepare(self.model, self.controller, self.netlist)

        # Load the application
        logger.info("Loading application")
        self.netlist.load_application(self.controller, system_info)

        # Check if any cores are in bad states
        if self.controller.count_cores_in_state(
            ["exit", "dead", "watchdog", "runtime_exception"]):
            for vertex, (x, y) in six.iteritems(self.netlist.placements):
                p = self.netlist.allocations[vertex][Cores].start
                status = self.controller.get_processor_status(p, x, y)
                if status.cpu_state is not AppState.sync0:
                    print("Core ({}, {}, {}) in state {!s}".format(
                        x, y, p, status))
                    print(self.controller.get_iobuf(p, x, y))
            raise Exception("Unexpected core failures.")

        logger.info("Preparing and loading machine took {:3f} seconds".format(
            time.time() - start))

        logger.info("Setting router timeout to 16 cycles")
        for x, y in system_info.chips():
            with self.controller(x=x, y=y):
                data = self.controller.read(0xf1000000, 4)
                self.controller.write(0xf1000000, data[:-1] + b'\x10')
Example #11
0
def main(args=None):
    parser = argparse.ArgumentParser(
        description="List all applications running on a SpiNNaker machine")
    parser.add_argument("--version",
                        "-V",
                        action="version",
                        version="%(prog)s {}".format(rig.__version__))

    parser.add_argument("hostname",
                        type=str,
                        help="hostname or IP of SpiNNaker system")

    parser.add_argument("x",
                        type=int,
                        nargs="?",
                        help="the X coordinate of the chip to list")
    parser.add_argument("y",
                        type=int,
                        nargs="?",
                        help="the Y coordinate of the chip to list")
    parser.add_argument("p",
                        type=int,
                        nargs="?",
                        help="the core number to list")

    parser.add_argument("--app-id",
                        "-a",
                        type=str,
                        action="append",
                        help="show only applications with an application "
                        "ID matching the supplied regex")
    parser.add_argument("--name",
                        "-n",
                        type=str,
                        action="append",
                        help="list only cores running the application "
                        "whose name matches the supplied regex")
    parser.add_argument("--state",
                        "-s",
                        type=str,
                        action="append",
                        help="list only cores in states matching the "
                        "supplied regex")

    args = parser.parse_args(args)

    if args.x is not None and args.y is None:
        parser.error("both or neither of 'x' and 'y' must be specified")

    try:
        mc = MachineController(args.hostname)
        info = mc.get_software_version(255, 255)
        if "SpiNNaker" in info.version_string:
            print("X   Y   P   State             Application      App ID")
            print("--- --- --- ----------------- ---------------- ------")
            for (x, y, core, state, runtime_exception, application, app_id) \
                    in get_process_list(mc,
                                        args.x, args.y, args.p,
                                        args.app_id, args.name, args.state):
                print("{:3d} {:3d} {:3d} "
                      "{:17s} "
                      "{:16s} "
                      "{:6d} "
                      "{:s}".format(
                          x, y, core, state.name, application, app_id,
                          runtime_exception.name if runtime_exception else ""))
        else:
            sys.stderr.write("{}: error: unknown architecture '{}'\n".format(
                parser.prog, info.version_string.strip("\x00")))
            return 2
    except TimeoutError:
        sys.stderr.write("{}: error: command timed out\n".format(parser.prog))
        return 1

    return 0
    def __init__(self, network, dt=0.001, period=10.0, timescale=1.0):
        """Create a new Simulator with the given network.

        Parameters
        ----------
        period : float or None
            Duration of one period of the simulator. This determines how much
            memory will be allocated to store precomputed and probed data.
        timescale : float
            Scaling factor to apply to the simulation, e.g., a value of `0.5`
            will cause the simulation to run at half real-time.
        """
        # Add this simulator to the set of open simulators
        Simulator._add_simulator(self)

        # Create a controller for the machine and boot if necessary
        hostname = rc.get("spinnaker_machine", "hostname")
        machine_width = rc.getint("spinnaker_machine", "width")
        machine_height = rc.getint("spinnaker_machine", "height")

        self.controller = MachineController(hostname)
        self.controller.boot(machine_width, machine_height)

        # Create the IO controller
        io_cls = getconfig(network.config, Simulator, "node_io", Ethernet)
        io_kwargs = getconfig(network.config, Simulator, "node_io_kwargs",
                              dict())
        self.io_controller = io_cls(**io_kwargs)

        # Calculate the machine timestep, this is measured in microseconds
        # (hence the 1e6 scaling factor).
        self.timescale = timescale
        machine_timestep = int((dt / timescale) * 1e6)

        # Determine the maximum run-time
        self.max_steps = None if period is None else int(period / dt)

        self.steps = 0  # Steps simulated

        # If the simulator is in "run indefinite" mode (i.e., max_steps=None)
        # then we modify the builders to ignore function of time Nodes and
        # probes.
        builder_kwargs = self.io_controller.builder_kwargs
        if self.max_steps is None:
            raise NotImplementedError

        # Create a model from the network, using the IO controller
        logger.debug("Building model")
        start_build = time.time()
        self.model = Model(dt=dt, machine_timestep=machine_timestep,
                           decoder_cache=get_default_decoder_cache())
        self.model.build(network, **builder_kwargs)

        forced_removals = get_force_removal_passnodes(network)
        optimise_out_passthrough_nodes(self.model,
                                       self.io_controller.passthrough_nodes,
                                       network.config, forced_removals)

        logger.info("Build took {:.3f} seconds".format(time.time() -
                                                       start_build))

        self.model.decoder_cache.shrink()
        self.dt = self.model.dt
        self._closed = False  # Whether the simulator has been closed or not

        self.host_sim = self._create_host_sim()

        # Holder for probe data
        self.data = {}

        # Holder for profiling data
        self.profiler_data = {}

        # Convert the model into a netlist
        logger.info("Building netlist")
        start = time.time()
        self.netlist = self.model.make_netlist(self.max_steps or 0)

        # Get a system-info object to place & route against
        logger.info("Getting SpiNNaker machine specification")
        system_info = self.controller.get_system_info()

        # Place & Route
        logger.info("Placing and routing")
        self.netlist.place_and_route(
            system_info,
            place=getconfig(network.config, Simulator,
                            'placer', rig.place_and_route.place),
            place_kwargs=getconfig(network.config, Simulator,
                                   'placer_kwargs', {}),
        )

        logger.info("{} cores in use".format(len(self.netlist.placements)))
        chips = set(six.itervalues(self.netlist.placements))
        logger.info("Using {}".format(chips))

        # Prepare the simulator against the placed, allocated and routed
        # netlist.
        self.io_controller.prepare(self.model, self.controller, self.netlist)

        # Load the application
        logger.info("Loading application")
        self.netlist.load_application(self.controller, system_info)

        # Check if any cores are in bad states
        if self.controller.count_cores_in_state(["exit", "dead", "watchdog",
                                                 "runtime_exception"]):
            for vertex in self.netlist.vertices:
                x, y = self.netlist.placements[vertex]
                p = self.netlist.allocations[vertex][Cores].start
                status = self.controller.get_processor_status(p, x, y)
                if status.cpu_state is not AppState.sync0:
                    print("Core ({}, {}, {}) in state {!s}".format(
                        x, y, p, status.cpu_state))
            raise Exception("Unexpected core failures.")

        logger.info("Preparing and loading machine took {:3f} seconds".format(
            time.time() - start
        ))

        logger.info("Setting router timeout to 16 cycles")
        for x in range(machine_width):
            for y in range(machine_height):
                with self.controller(x=x, y=y):
                    if (x, y) in system_info:
                        data = self.controller.read(0xf1000000, 4)
                        self.controller.write(0xf1000000, data[:-1] + b'\x10')
Example #13
0
def main(argv=None):
    t = Terminal(stream=sys.stderr)

    cfg = config.read_config()

    parser = argparse.ArgumentParser(
        description="Request (and allocate) a SpiNNaker machine.")

    parser.add_argument("--version",
                        "-V",
                        action="version",
                        version=__version__)

    parser.add_argument("--quiet",
                        "-q",
                        action="store_true",
                        default=False,
                        help="suppress informational messages")
    parser.add_argument("--debug",
                        action="store_true",
                        default=False,
                        help="enable additional diagnostic information")
    parser.add_argument("--no-destroy",
                        "-D",
                        action="store_true",
                        default=False,
                        help="do not destroy the job on exit")

    if MachineController is not None:
        parser.add_argument("--boot",
                            "-B",
                            action="store_true",
                            default=False,
                            help="boot the machine once powered on")

    allocation_args = parser.add_argument_group(
        "allocation requirement arguments")
    allocation_args.add_argument("what",
                                 nargs="*",
                                 default=[],
                                 type=int,
                                 metavar="WHAT",
                                 help="what to allocate: nothing or 1 "
                                 "requests 1 SpiNN-5 board, NUM requests "
                                 "at least NUM SpiNN-5 boards, WIDTH "
                                 "HEIGHT means WIDTHxHEIGHT triads of "
                                 "SpiNN-5 boards and X Y Z requests a "
                                 "board the specified logical board "
                                 "coordinate.")
    allocation_args.add_argument("--resume",
                                 "-r",
                                 type=int,
                                 help="if given, resume keeping the "
                                 "specified job alive rather than "
                                 "creating a new job (all allocation "
                                 "requirements will be ignored)")
    allocation_args.add_argument("--machine",
                                 "-m",
                                 nargs="?",
                                 default=cfg["machine"],
                                 help="only allocate boards which are part "
                                 "of a specific machine, or any machine "
                                 "if no machine is given "
                                 "(default: %(default)s)")
    allocation_args.add_argument("--tags",
                                 "-t",
                                 nargs="*",
                                 metavar="TAG",
                                 default=cfg["tags"] or ["default"],
                                 help="only allocate boards which have (at "
                                 "least) the specified flags "
                                 "(default: {})".format(" ".join(cfg["tags"]
                                                                 or [])))
    allocation_args.add_argument("--min-ratio",
                                 type=float,
                                 metavar="RATIO",
                                 default=cfg["min_ratio"],
                                 help="when allocating by number of boards, "
                                 "require that the allocation be at "
                                 "least as square as this ratio "
                                 "(default: %(default)s)")
    allocation_args.add_argument("--max-dead-boards",
                                 type=int,
                                 metavar="NUM",
                                 default=(-1 if cfg["max_dead_boards"] is None
                                          else cfg["max_dead_boards"]),
                                 help="boards allowed to be "
                                 "dead in the allocation, or -1 to allow "
                                 "any number of dead boards "
                                 "(default: %(default)s)")
    allocation_args.add_argument("--max-dead-links",
                                 type=int,
                                 metavar="NUM",
                                 default=(-1 if cfg["max_dead_links"] is None
                                          else cfg["max_dead_links"]),
                                 help="inter-board links allowed to be "
                                 "dead in the allocation, or -1 to allow "
                                 "any number of dead links "
                                 "(default: %(default)s)")
    allocation_args.add_argument(
        "--require-torus",
        "-w",
        action="store_true",
        default=cfg["require_torus"],
        help="require that the allocation contain "
        "torus (a.k.a. wrap-around) "
        "links {}".format("(default)" if cfg["require_torus"] else ""))
    allocation_args.add_argument(
        "--no-require-torus",
        "-W",
        action="store_false",
        dest="require_torus",
        help="do not require that the allocation "
        "contain torus (a.k.a. wrap-around) "
        "links {}".format("" if cfg["require_torus"] else "(default)"))

    command_args = parser.add_argument_group("command wrapping arguments")
    command_args.add_argument("--command",
                              "-c",
                              nargs=argparse.REMAINDER,
                              help="execute the specified command once boards "
                              "have been allocated and deallocate the "
                              "boards when the application exits ({} and "
                              "{hostname} are substituted for the chip "
                              "chip at (0, 0)'s hostname, {w} and "
                              "{h} give the dimensions of the SpiNNaker "
                              "machine in chips, {ethernet_ips} is a "
                              "temporary file containing a CSV with "
                              "three columns: x, y and hostname giving "
                              "the hostname of each Ethernet connected "
                              "SpiNNaker chip)")

    server_args = parser.add_argument_group("spalloc server arguments")

    server_args.add_argument("--owner",
                             default=cfg["owner"],
                             help="by convention, the email address of the "
                             "owner of the job (default: %(default)s)")
    server_args.add_argument("--hostname",
                             "-H",
                             default=cfg["hostname"],
                             help="hostname or IP of the spalloc server "
                             "(default: %(default)s)")
    server_args.add_argument("--port",
                             "-P",
                             default=cfg["port"],
                             type=int,
                             help="port number of the spalloc server "
                             "(default: %(default)s)")
    server_args.add_argument(
        "--keepalive",
        type=int,
        metavar="SECONDS",
        default=(-1 if cfg["keepalive"] is None else cfg["keepalive"]),
        help="the interval at which to require "
        "keepalive messages to be sent to "
        "prevent the server cancelling the "
        "job, or -1 to not require keepalive "
        "messages (default: %(default)s)")
    server_args.add_argument("--reconnect-delay",
                             default=cfg["reconnect_delay"],
                             type=float,
                             metavar="SECONDS",
                             help="seconds to wait before "
                             "reconnecting to the server if the "
                             "connection is lost (default: %(default)s)")
    server_args.add_argument("--timeout",
                             default=cfg["timeout"],
                             type=float,
                             metavar="SECONDS",
                             help="seconds to wait for a response "
                             "from the server (default: %(default)s)")

    args = parser.parse_args(argv)

    # Fail if no owner is defined (unless resuming)
    if not args.owner and args.resume is None:
        parser.error(
            "--owner must be specified (typically your email address)")

    # Fail if server not specified
    if args.hostname is None:
        parser.error("--hostname of spalloc server must be specified")

    # Set universal job arguments
    job_kwargs = {
        "hostname":
        args.hostname,
        "port":
        args.port,
        "reconnect_delay":
        args.reconnect_delay if args.reconnect_delay >= 0.0 else None,
        "timeout":
        args.timeout if args.timeout >= 0.0 else None,
    }

    if args.resume:
        job_args = []
        job_kwargs.update({
            "resume_job_id": args.resume,
        })
    else:
        # Make sure 'what' takes the right form
        if len(args.what) not in (0, 1, 2, 3):
            parser.error("expected either no arguments, one argument, NUM, "
                         "two arguments, WIDTH HEIGHT, or three arguments "
                         "X Y Z")

        # Unpack arguments for the job and server
        job_args = args.what
        job_kwargs.update({
            "owner":
            args.owner,
            "keepalive":
            args.keepalive if args.keepalive >= 0.0 else None,
            "machine":
            args.machine,
            "tags":
            args.tags if args.machine is None else None,
            "min_ratio":
            args.min_ratio,
            "max_dead_boards":
            args.max_dead_boards if args.max_dead_boards >= 0.0 else None,
            "max_dead_links":
            args.max_dead_links if args.max_dead_links >= 0.0 else None,
            "require_torus":
            args.require_torus,
        })

    # Set debug level
    if args.debug:
        logging.basicConfig(level=logging.DEBUG)

    # Create temporary file in which to write CSV of all board IPs
    _, ip_file_filename = tempfile.mkstemp(".csv", "spinnaker_ips_")

    def info(msg):
        if not args.quiet:
            t.stream.write("{}\n".format(msg))

    # Reason for destroying the job
    reason = None

    try:
        # Create the job
        try:
            job = Job(*job_args, **job_kwargs)
        except (OSError, IOError) as e:
            info(t.red("Could not connect to server: {}".format(e)))
            return 6
        try:
            # Wait for it to become ready, keeping the user informed along the
            # way
            old_state = None
            cur_state = job.state
            while True:
                # Show debug info on state-change
                if old_state != cur_state:
                    if cur_state == JobState.queued:
                        info(
                            t.update(
                                t.yellow("Job {}: Waiting in queue...".format(
                                    job.id))))
                    elif cur_state == JobState.power:
                        info(
                            t.update(
                                t.yellow(
                                    "Job {}: Waiting for power on...".format(
                                        job.id))))
                    elif cur_state == JobState.ready:
                        # Here we go!
                        break
                    elif cur_state == JobState.destroyed:
                        # Exit with error state
                        try:
                            reason = job.reason
                        except (IOError, OSError):
                            reason = None

                        if reason is not None:
                            info(
                                t.update(
                                    t.red("Job {}: Destroyed: {}".format(
                                        job.id, reason))))
                        else:
                            info(t.red("Job {}: Destroyed.".format(job.id)))
                        return 1
                    elif cur_state == JobState.unknown:
                        info(
                            t.update(
                                t.red("Job {}: Job not recognised by server.".
                                      format(job.id))))
                        return 2
                    else:
                        info(
                            t.update(
                                t.red(
                                    "Job {}: Entered an unrecognised state {}."
                                    .format(job.id, cur_state))))
                        return 3

                try:
                    old_state = cur_state
                    cur_state = job.wait_for_state_change(cur_state)
                except KeyboardInterrupt:
                    # Gracefully terminate from keyboard interrupt
                    info(
                        t.update(
                            t.red("Job {}: Keyboard interrupt.".format(
                                job.id))))
                    reason = "Keyboard interrupt."
                    return 4

            # Machine is now ready
            write_ips_to_csv(job.connections, ip_file_filename)

            # Boot the machine if required
            if MachineController is not None and args.boot:
                info(t.update(t.yellow("Job {}: Booting...".format(job.id))))
                mc = MachineController(job.hostname)
                mc.boot(job.width, job.height)

            info(t.update(t.green("Job {}: Ready!".format(job.id))))

            # Either run the user's application or just print the details.
            if args.command:
                return run_command(args.command, job.id, job.machine_name,
                                   job.connections, job.width, job.height,
                                   ip_file_filename)

            else:
                print_info(job.machine_name, job.connections, job.width,
                           job.height, ip_file_filename)
                return 0
        finally:
            # Destroy job and disconnect client
            if args.no_destroy:
                job.close()
            else:
                job.destroy(reason)
    finally:
        # Delete IP address list file
        os.remove(ip_file_filename)
    parser.add_argument("out_file")
    parser.add_argument("target_length", type=int, default=0, nargs='?')
    parser.add_argument("--memory-profile", type=str)
    args = parser.parse_args()

    # Load and minimise all routing tables
    print("Reading routing tables...")
    with open(args.routing_table, "rb") as f:
        uncompressed = common.read_routing_tables(f)

    # Request a SpiNNaker machine
    print("Waiting for SpiNNaker machine...")
    with spalloc.Job(args.width, args.height) as job:
        # Talk to the machine
        print("Booting...")
        mc = MachineController(job.hostname)
        mc.boot()
        mc.discover_connections()

        # Convert the tables into the appropriate formats
        chip_data = {
            chip: pack_table(table, args.target_length)
            for chip, table in iteritems(uncompressed)
        }

        # Allocate memory on the machine
        chip_mem = {(x, y): mc.sdram_alloc_as_filelike(len(data),
                                                       x=x,
                                                       y=y,
                                                       tag=1)
                    for (x, y), data in iteritems(chip_data)}