示例#1
0
	def get_packet_destination(self, packet, in_dir):
		"""
		Given a packet, return the (link, emergency_link) pair to which the packet
		should be sent. The emergency link may be the same as the regular link.
		"""
		
		if packet.emergency:
			assert(in_dir is not None)
			
			# The packet is being emergency-routed, send it to its original target
			# which is the link counter-clockwise to the link it arrived
			route = self.out_links[topology.next_ccw(in_dir)]
			return (route, route)
		elif packet.destination == self.mesh_position:
			# Packet was destined to end up at this node
			return (self.exit_link, self.exit_link)
		else:
			# Find the shortest path to the destination
			shortest_path = topology.get_path(topology.zero_pad(self.mesh_position),
			                                  topology.zero_pad(packet.destination),
			                                  self.mesh_dimensions)
			
			# Do direction-order-routing
			if   shortest_path[0] > 0: direction = topology.EAST
			elif shortest_path[0] < 0: direction = topology.WEST
			elif shortest_path[1] > 0: direction = topology.NORTH
			elif shortest_path[1] < 0: direction = topology.SOUTH
			elif shortest_path[2] > 0: direction = topology.SOUTH_WEST
			elif shortest_path[2] < 0: direction = topology.NORTH_EAST
			else: assert(False)
			
			# The emergency route takes the link counter-clockwise to the intended
			# direction
			return (self.out_links[direction], self.out_links[topology.next_ccw(direction)])
示例#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))
示例#3
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))
示例#4
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)
示例#5
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)