Esempio n. 1
0
def create_torus(width=1, height=None):
    """
	Returns a mapping of boards containing width * height threeboards connected in
	a torus with corresponding hexagonal coordinates. If height is not specified,
	height = width.
	"""

    height = width if height is None else height

    boards = {}

    # Create the boards
    for coord in topology.threeboards(width, height):
        boards[coordinates.Hexagonal(*coord)] = Board()

    # Link the boards together
    for coord in boards:
        for direction in [topology.EAST, topology.NORTH_EAST, topology.NORTH]:
            # Get the coordinate of the neighbour in each direction
            n_coord = topology.wrap_around(
                topology.add_direction(list(coord) + [0], direction),
                (width, height))

            # Connect the boards together
            boards[coord].connect_wire(boards[n_coord], direction)

    return [(b, c) for (c, b) in boards.iteritems()]
Esempio n. 2
0
	def test_connections(self):
		# Try with several sizes
		for torus_size in SpiNNakerTorusTests.TORUS_SIZES:
			self.generate_torus(*torus_size)
			
			# Get a dictionary of chips to their locations
			chips = {}
			for board in self.torus.boards.itervalues():
				for chip in board.chips.itervalues():
					chips[chip.get_mesh_position()] = chip
			
			# Check each chip is connected with their neighbours N, NE, W
			for pos, chip in chips.iteritems():
				for direction in [topology.NORTH, topology.NORTH_EAST, topology.WEST]:
					other_pos = topology.to_xy(
						topology.add_direction(topology.zero_pad(pos), direction))
					other_chip = chips[( other_pos[0]%(self.torus.width*12)
					                   , other_pos[1]%(self.torus.height*12)
					                   , )]
					
					other_direction = topology.opposite(direction)
					
					# Make sure we share links
					self.assertEqual(chip.get_in_link(direction),
					                 other_chip.get_out_link(other_direction))
					self.assertEqual(chip.get_out_link(direction),
					                 other_chip.get_in_link(other_direction))
Esempio n. 3
0
def create_torus(width = 1, height = None):
	"""
	Returns a mapping of boards containing width * height threeboards connected in
	a torus with corresponding hexagonal coordinates. If height is not specified,
	height = width.
	"""
	
	height = width if height is None else height
	
	boards = {}
	
	# Create the boards
	for coord in topology.threeboards(width, height):
		boards[coordinates.Hexagonal(*coord)] = Board()
	
	# Link the boards together
	for coord in boards:
		for direction in [ topology.EAST
		                 , topology.NORTH_EAST
		                 , topology.NORTH
		                 ]:
			# Get the coordinate of the neighbour in each direction
			n_coord = topology.wrap_around(
			            topology.add_direction(list(coord)+[0], direction), (width, height))
			
			# Connect the boards together
			boards[coord].connect_wire(boards[n_coord], direction)
	
	return [(b, c) for (c, b) in boards.iteritems()]
Esempio n. 4
0
	def test_fully_connect_chips_pair_of_chips_no_wrap_around(self):
		"""
		Test that a model.fully_connect_chips connects (and leaves disconnected)
		the correct links when a pair of touching chips are created.
		"""
		# Test with the neighbouring chip being on every possible edge.
		for direction in [ topology.EAST
		                 , topology.NORTH_EAST
		                 , topology.NORTH
		                 , topology.WEST
		                 , topology.SOUTH_WEST
		                 , topology.SOUTH
		                 ]:
			other_chip_position = topology.to_xy(topology.add_direction((0,0,0), direction))
			chips = { (0,0)               : model.make_chip((0,0))
			        , other_chip_position : model.make_chip(other_chip_position)
			        }
			model.fully_connect_chips(chips)
			
			# Only the touching ports are connected
			for port in model.Router.EXTERNAL_PORTS:
				if port == direction:
					# Touching port
					self.assertEqual( chips[(0,0)].router.connections[port]
					                , chips[other_chip_position].router
					                )
					self.assertEqual( chips[other_chip_position].router.connections[topology.opposite(port)]
					                , chips[(0,0)].router
					                )
				else:
					# Non-touching port
					self.assertIsNone(chips[(0,0)].router.connections[port])
					self.assertIsNone(chips[other_chip_position].router.connections[topology.opposite(port)])
Esempio n. 5
0
	def test_fully_connect_chips_pair_of_chips_no_wrap_around(self):
		"""
		Test that a model.fully_connect_chips connects (and leaves disconnected)
		the correct links when a pair of touching chips are created.
		"""
		# Test with the neighbouring chip being on every possible edge.
		for direction in [ topology.EAST
		                 , topology.NORTH_EAST
		                 , topology.NORTH
		                 , topology.WEST
		                 , topology.SOUTH_WEST
		                 , topology.SOUTH
		                 ]:
			other_chip_position = topology.to_xy(topology.add_direction((0,0,0), direction))
			chips = { (0,0)               : model.make_chip((0,0))
			        , other_chip_position : model.make_chip(other_chip_position)
			        }
			model.fully_connect_chips(chips)
			
			# Only the touching ports are connected
			for port in model.Router.EXTERNAL_PORTS:
				if port == direction:
					# Touching port
					self.assertEqual( chips[(0,0)][0].connections[port]
					                , chips[other_chip_position][0]
					                )
					self.assertEqual( chips[other_chip_position][0].connections[topology.opposite(port)]
					                , chips[(0,0)][0]
					                )
				else:
					# Non-touching port
					self.assertIsNone(chips[(0,0)][0].connections[port])
					self.assertIsNone(chips[other_chip_position][0].connections[topology.opposite(port)])
Esempio n. 6
0
	def test_hexagon_edge_link(self):
		# Get the set of edge nodes for a 4-layer hexagon
		all_nodes   = set(topology.hexagon(4))
		inner_nodes = set(topology.hexagon(3))
		outer_nodes = all_nodes - inner_nodes
		
		directions = [
			topology.EAST,
			topology.NORTH_EAST,
			topology.NORTH,
			topology.WEST,
			topology.SOUTH_WEST,
			topology.SOUTH
		]
		
		edges = [
			topology.EDGE_TOP_LEFT,
			topology.EDGE_TOP,
			topology.EDGE_TOP_RIGHT,
			topology.EDGE_BOTTOM_RIGHT,
			topology.EDGE_BOTTOM,
		  topology.EDGE_BOTTOM_LEFT,
		]
		
		# Get the set of outward-facing links as (node_xy,direction) pairs
		outward_facing_links = []
		for node in all_nodes:
			for direction in directions:
				# Get the node that this link would connect to
				facing_node = topology.to_xy(
					topology.add_direction(topology.zero_pad(node), direction))
				# If that node isn't part of our set, it is an edge link
				if facing_node not in all_nodes:
					outward_facing_links.append((node, direction))
		
		# Get the set of outward facing links according to the function under test
		all_links = []
		for edge in edges:
			for num in range(8):
				all_links.append(topology.hexagon_edge_link(edge, num, 4))
		
		# No duplicates
		self.assertEqual(len(all_links), len(set(all_links)))
		
		# The algorithm gets every outward facing edge
		self.assertEqual(set(all_links), set(outward_facing_links))
Esempio n. 7
0
def fully_connect_chips(chips, wrap_around = False):
	"""
	Given a set of chips (i.e. (router, cores) tuples), fully interconnects the
	chips optionally including wrap-around links.
	"""
	# Calculate the bounds of the system's size (in case wrap_around is used)
	width  = max(x for (x,y) in chips.iterkeys()) + 1
	height = max(y for (x,y) in chips.iterkeys()) + 1
	
	# Connect up the nodes to their neighbours
	for position, (router, cores) in chips.iteritems():
		for direction in [topology.EAST, topology.NORTH_EAST, topology.NORTH]:
			next_x, next_y = topology.to_xy(
				topology.add_direction(topology.to_xyz(position), direction))
			
			if wrap_around:
				next_x %= width
				next_y %= height
			
			# Only connect up to nodes which actually exist...
			if (next_x, next_y) in chips:
				router.connect(direction, chips[(next_x, next_y)][0], topology.opposite(direction))
Esempio n. 8
0
	def test_chips(self):
		# A board should have chips in the correct locations and no repeats
		self.assertEqual(len(self.board.chips), 48)
		self.assertEqual(set(self.board.chips.iterkeys()),
		                 set(topology.hexagon(4)))
		
		# For all inputs & outputs, if there is a chip in that direction it must be
		# connected via a SilistixLink and if not it should be attached to a
		# DeadLink.
		for src_pos, src_chip in self.board.chips.iteritems():
			for direction in ( topology.EAST
			                 , topology.NORTH_EAST
			                 , topology.NORTH
			                 , topology.WEST
			                 , topology.SOUTH_WEST
			                 , topology.SOUTH
			                 ):
				in_link  = src_chip.get_in_link(direction)
				out_link = src_chip.get_out_link(direction)
				
				dst_pos = topology.to_xy(topology.add_direction(topology.zero_pad(src_pos),
				                                                direction))
				if dst_pos in self.board.chips:
					# There is a chip opposite this connection
					dst_chip = self.board.chips[dst_pos]
					direction = topology.opposite(direction)
					
					# Check that they have the same link (connected to opposite ports)
					self.assertEqual(out_link, dst_chip.get_in_link(direction))
					self.assertEqual(in_link,  dst_chip.get_out_link(direction))
					
					# And that they're SilistixLinks
					self.assertEqual(type(in_link), SilistixLink)
					self.assertEqual(type(out_link), SilistixLink)
				else:
					# No adjacent chip so should be DeadLinks
					self.assertEqual(type(in_link), DeadLink)
					self.assertEqual(type(out_link), DeadLink)
Esempio n. 9
0
def fully_connect_chips(chips, wrap_around=False):
    """
	Given a set of chips (i.e. (router, cores) tuples), fully interconnects the
	chips optionally including wrap-around links.
	"""
    # Calculate the bounds of the system's size (in case wrap_around is used)
    width = max(x for (x, y) in chips.iterkeys()) + 1
    height = max(y for (x, y) in chips.iterkeys()) + 1

    # Connect up the nodes to their neighbours
    for position, (router, cores) in chips.iteritems():
        for direction in [topology.EAST, topology.NORTH_EAST, topology.NORTH]:
            next_x, next_y = topology.to_xy(
                topology.add_direction(topology.to_xyz(position), direction))

            if wrap_around:
                next_x %= width
                next_y %= height

            # Only connect up to nodes which actually exist...
            if (next_x, next_y) in chips:
                router.connect(direction, chips[(next_x, next_y)][0],
                               topology.opposite(direction))
Esempio n. 10
0
	def __init__( self
	            , scheduler
	            , system
	            
	            , link_send_cycles        # SilistixLink
	            , link_ack_cycles         # SilistixLink
	            
	            , injection_buffer_length # SpiNNaker101
	            
	            , router_period           # SpiNNakerRouter
	            , wait_before_emergency   # SpiNNakerRouter
	            , wait_before_drop        # SpiNNakerRouter
	            
	            , core_period             # SpiNNakerTrafficGenerator
	            , packet_prob             # SpiNNakerTrafficGenerator
	            , distance_std = None     # SpiNNakerTrafficGenerator
	            ):
		"""
		link_send_cycles see SilistixLink
		link_ack_cycles see SilistixLink
		
		injection_buffer_length see SpiNNaker101
		
		router_period see SpiNNakerRouter
		wait_before_emergency see SpiNNakerRouter
		wait_before_drop see SpiNNakerRouter
		
		core_period see SpiNNakerTrafficGenerator
		packet_prob see SpiNNakerTrafficGenerator
		distance_std see SpiNNakerTrafficGenerator
		"""
		
		self.scheduler               = scheduler
		self.system                  = system
		
		# A dictionary { (x,y): SpiNNaker101, ... } of all contained chips. The
		# coordinates are relative to the central chip (created first in the
		# hexagon).
		self.chips = { }
		
		# Utility function to add a new chip to the chips dict.
		def add_chip(position):
			"Add a chip at the specified position"
			self.chips[position] = SpiNNaker101( self.scheduler
			                                   , self.system
			                                   , injection_buffer_length
			                                   , router_period
			                                   , wait_before_emergency
			                                   , wait_before_drop
			                                   , core_period
			                                   , packet_prob
			                                   , distance_std
			                                   )
		# Create the chips in a hexagonal pattern
		for position in topology.hexagon(4):
			add_chip(position)
		
		# Put SilistixLinks between them
		for src_pos, src_chip in self.chips.iteritems():
			# Try and link this chip to all other neighbours which are towards the
			# top/right of the chip
			for direction in (topology.NORTH, topology.NORTH_EAST, topology.EAST):
				dst_pos = topology.to_xy(
					topology.add_direction(topology.zero_pad(src_pos), direction))
				
				# If the chip exists, put links in this direction
				if dst_pos in self.chips:
					dst_chip = self.chips[dst_pos]
					
					in_link  = SilistixLink(self.scheduler, link_send_cycles, link_ack_cycles)
					out_link = SilistixLink(self.scheduler, link_send_cycles, link_ack_cycles)
					
					src_chip.set_out_link(direction, out_link)
					src_chip.set_in_link(direction, in_link)
					
					dst_chip.set_in_link(topology.opposite(direction), out_link)
					dst_chip.set_out_link(topology.opposite(direction), in_link)