Example #1
0
	def test_buffer_link(self):
		s = Scheduler()
		bl = BufferLink(s, 2)
		
		# Can only send
		self.assertTrue(bl.can_send())
		self.assertFalse(bl.can_receive())
		
		bl.send(123)
		
		# Have something to recieve and space left
		self.assertTrue(bl.can_send())
		self.assertTrue(bl.can_receive())
		
		bl.send(456)
		
		# Have something to recieve and no space left
		self.assertFalse(bl.can_send())
		self.assertTrue(bl.can_receive())
		
		# Can peek
		self.assertEqual(bl.peek(), 123)
		self.assertFalse(bl.can_send())
		self.assertTrue(bl.can_receive())
		self.assertEqual(bl.peek(), 123)
		self.assertFalse(bl.can_send())
		self.assertTrue(bl.can_receive())
		
		# In queue order
		self.assertEqual(bl.receive(), 123)
		
		# Still have something to recieve and space left again
		self.assertTrue(bl.can_send())
		self.assertTrue(bl.can_receive())
		
		# Can peek
		self.assertEqual(bl.peek(), 456)
		self.assertTrue(bl.can_send())
		self.assertTrue(bl.can_receive())
		self.assertEqual(bl.peek(), 456)
		self.assertTrue(bl.can_send())
		self.assertTrue(bl.can_receive())
		
		# In queue order
		self.assertEqual(bl.receive(), 456)
		
		# Nothing to recieve and space in buffer
		self.assertTrue(bl.can_send())
		self.assertFalse(bl.can_receive())
		
		# Didn't schedule anything
		self.assertRaises(StopIteration, s.run().next)
Example #2
0
	def test_normal(self):
		# Test that packets are generated appropriately when distributing with a
		# normal distribution.
		
		scheduler = Scheduler()
		system = SpiNNakerSystem(scheduler, 10)
		
		# Share the same link for sending and receiving, that way the module cleans
		# up after itself!
		link = BufferLink(scheduler)
		
		# Uniform generator node
		tg = SpiNNakerTrafficGenerator( scheduler
		                              , system
		                              , 1
		                              , 0.1
		                              , link
		                              , link
		                              , 10
		                              )
		tg.set_mesh_dimensions(100,100)
		tg.set_mesh_position(50,50)
		
		it = scheduler.run()
		
		# Perform 1000 cycles
		while it.next() < 2000 and tg.counters["generator_cycles"] < 1000:
			# We may have a packet
			if link.can_receive():
				# Check the packet is targeted somewhere in the mesh
				packet = link.receive()
				self.assertTrue(all(0 <= dimension < 100 for dimension in packet.destination))
		
		# XXX: Should probably check that distribution is appropriate too but meh...
		
		# Should have done 1000 cycles
		self.assertEqual(tg.counters["generator_cycles"], 1000)
		
		# We should have sent some number of packets that isn't all the time and not
		# never (well, in theory we might not but hey, if this is going wrong you've
		# got a bad day on your hands).
		self.assertTrue(10 < tg.counters["generator_injected_packets"] < 1000)
		
		# None should be dropped
		self.assertEqual(tg.counters["generator_dropped_packets"], 0)
Example #3
0
class RouterTests(unittest.TestCase):
	"""
	Tests the router
	"""
	
	TIME_PHASE_PERIOD     = 200
	ROUTER_PERIOD         = 10
	WAIT_BEFORE_EMERGENCY = 3
	WAIT_BEFORE_DROP      = 6
	
	# We're right in the middle
	MESH_DIMENSIONS       = (3,3)
	MESH_POSITION         = (1,1)
	
	def setUp(self):
		# Before each test build a new scheduler, system and router
		self.scheduler = Scheduler()
		self.system    = SpiNNakerSystem(self.scheduler, RouterTests.TIME_PHASE_PERIOD)
		
		self.injection_link = BufferLink(self.scheduler,1)
		self.exit_link      = BufferLink(self.scheduler,1)
		self.in_links       = [BufferLink(self.scheduler,1) for _ in range(6)]
		self.out_links      = [BufferLink(self.scheduler,1) for _ in range(6)]
		
		# All links
		self.links = ( [self.injection_link, self.exit_link]
		             + self.in_links
		             + self.out_links)
		
		self.router = SpiNNakerRouter( self.scheduler
		                             , self.system
		                             , self.injection_link
		                             , self.exit_link
		                             , self.in_links
		                             , self.out_links
		                             , RouterTests.ROUTER_PERIOD
		                             , RouterTests.WAIT_BEFORE_EMERGENCY
		                             , RouterTests.WAIT_BEFORE_DROP
		                             )
		self.router.set_mesh_dimensions(*RouterTests.MESH_DIMENSIONS)
		self.router.set_mesh_position(*RouterTests.MESH_POSITION)
	
	
	def test_nothing(self):
		# Test that the router does nothing if no packets are given...
		
		it = self.scheduler.run()
		while it.next() < 1000:
			pass
		
		# Nothing was sent/received
		for link in self.links:
			self.assertTrue(link.can_send())
			self.assertFalse(link.can_receive())
		
		# The router remained idle...
		self.assertEqual(self.router.counters["timestamp_packet_timeout"], 0)
		self.assertEqual(self.router.counters["router_packet_timeout"], 0)
		self.assertEqual(self.router.counters["packets_routed"], 0)
		self.assertEqual(self.router.counters["packet_emergency_routed"], 0)
		self.assertEqual(self.router.counters["router_blocked_cycles"], 0)
		
		# Some cycles occurred (i.e. it didn't stop after one)
		self.assertTrue(self.router.counters["router_cycles"] > 10)
		
		# Every cycle was idle
		self.assertEqual(self.router.counters["router_idle_cycles"],
		                 self.router.counters["router_cycles"])
	
	
	def test_loopback(self):
		# Test that the router can forward packets to itself
		
		# A packet to ourselves
		packet = SpiNNakerP2PPacket( self.system
		                           , "Example Data"
		                           , RouterTests.MESH_POSITION
		                           , 32)
		
		self.assertTrue(self.injection_link.can_send())
		self.injection_link.send(packet)
		
		# Run until the packet arrives
		it = self.scheduler.run()
		while it.next() < 1000 and not self.exit_link.can_receive():
			pass
		
		# We got our packet back
		self.assertTrue(self.exit_link.can_receive())
		rec_packet = self.exit_link.receive()
		self.assertEqual(packet, rec_packet)
		
		# Nothing else was sent/received
		for link in self.links:
			self.assertTrue(link.can_send())
			self.assertFalse(link.can_receive())
		
		# The router sent one packet...
		self.assertEqual(self.router.counters["timestamp_packet_timeout"], 0)
		self.assertEqual(self.router.counters["router_packet_timeout"], 0)
		self.assertEqual(self.router.counters["packets_routed"], 1)
		self.assertEqual(self.router.counters["packet_emergency_routed"], 0)
		self.assertEqual(self.router.counters["router_blocked_cycles"], 0)
		self.assertEqual(self.router.counters["router_idle_cycles"], 0)
		
		# This all happened in one cycle
		self.assertEqual(self.router.counters["router_cycles"], 1)
		
		# The packet took one hop
		self.assertEqual(packet.distance, 1)
		
		# Wait counter reset
		self.assertEqual(packet.wait, 0)
		
		# Not emergency routed
		self.assertFalse(packet.emergency)
	
	
	def test_normal_route(self):
		# Test that the router can forward packets to another router
		
		directions = [
			((2,1), topology.EAST),
			((0,1), topology.WEST),
			((1,2), topology.NORTH),
			((1,0), topology.SOUTH),
			((2,2), topology.NORTH_EAST),
			((0,0), topology.SOUTH_WEST),
		]
		
		for router_pos, direction in directions:
			# Reset everything...
			self.setUp()
			
			# A packet to ourselves
			packet = SpiNNakerP2PPacket( self.system
			                           , "Example Data"
			                           , router_pos
			                           , 32)
			
			# Send packet via an arbitrary input (east)
			self.assertTrue(self.in_links[0].can_send())
			self.in_links[0].send(packet)
			
			# Run until the packet arrives
			it = self.scheduler.run()
			while it.next() < 1000 and not self.out_links[direction].can_receive():
				pass
			
			# We got our packet back
			self.assertTrue(self.out_links[direction].can_receive())
			rec_packet = self.out_links[direction].receive()
			self.assertEqual(packet, rec_packet)
			
			# Nothing else was sent/received
			for link in self.links:
				self.assertTrue(link.can_send())
				self.assertFalse(link.can_receive())
			
			# The router sent one packet...
			self.assertEqual(self.router.counters["timestamp_packet_timeout"], 0)
			self.assertEqual(self.router.counters["router_packet_timeout"], 0)
			self.assertEqual(self.router.counters["packets_routed"], 1)
			self.assertEqual(self.router.counters["packet_emergency_routed"], 0)
			self.assertEqual(self.router.counters["router_blocked_cycles"], 0)
			self.assertEqual(self.router.counters["router_idle_cycles"], 0)
			
			# This all happened in one cycle
			self.assertEqual(self.router.counters["router_cycles"], 1)
			
			# The packet took one hop
			self.assertEqual(packet.distance, 1)
			
			# Wait counter reset
			self.assertEqual(packet.wait, 0)
			
			# Not emergency routed
			self.assertFalse(packet.emergency)
	
	
	def test_emergency_on_block(self):
		# Test that the router uses emergency mode when the target link is blocked
		
		directions = [
			((2,1), topology.EAST,      topology.NORTH_EAST),
			((0,1), topology.WEST,      topology.SOUTH_WEST),
			((1,2), topology.NORTH,     topology.WEST),
			((1,0), topology.SOUTH,     topology.EAST),
			((2,2), topology.NORTH_EAST,topology.NORTH),
			((0,0), topology.SOUTH_WEST,topology.SOUTH),
		]
		
		for router_pos, direction, emergency in directions:
			# Reset everything...
			self.setUp()
			
			# A dud packet
			dud = SpiNNakerP2PPacket( self.system , "Dud" , None , 1)
			
			# A packet to ourselves
			packet = SpiNNakerP2PPacket( self.system
			                           , "Example Data"
			                           , router_pos
			                           , 32)
			
			# Send packet via an arbitrary input (east)
			self.assertTrue(self.in_links[0].can_send())
			self.in_links[0].send(packet)
			
			# Block the target port with a dud packet
			self.assertTrue(self.out_links[direction].can_send())
			self.out_links[direction].send(dud)
			
			# Run until the packet arrives
			it = self.scheduler.run()
			while it.next() < 1000 and not self.out_links[emergency].can_receive():
				pass
			
			# We got our packet back
			self.assertTrue(self.out_links[emergency].can_receive())
			rec_packet = self.out_links[emergency].receive()
			self.assertEqual(packet, rec_packet)
			
			# Remove the blockage and make sure it wasn't changed...
			self.assertTrue(self.out_links[direction].can_receive())
			rec_dud = self.out_links[direction].receive()
			self.assertEqual(dud, rec_dud)
			
			# Nothing else was sent/received
			for link in self.links:
				self.assertTrue(link.can_send())
				self.assertFalse(link.can_receive())
			
			# The router sent one packet...
			self.assertEqual(self.router.counters["timestamp_packet_timeout"], 0)
			self.assertEqual(self.router.counters["router_packet_timeout"], 0)
			self.assertEqual(self.router.counters["packets_routed"], 0)
			self.assertEqual(self.router.counters["packet_emergency_routed"], 1)
			self.assertEqual(self.router.counters["router_idle_cycles"], 0)
			
			# We waited only until we could emergency route
			self.assertEqual(self.router.counters["router_blocked_cycles"],
			                 RouterTests.WAIT_BEFORE_EMERGENCY)
			
			# We executed until we waited long enough then sent the packet
			self.assertEqual(self.router.counters["router_cycles"],
			                 RouterTests.WAIT_BEFORE_EMERGENCY + 1)
			
			# The packet took one hop
			self.assertEqual(packet.distance, 1)
			
			# Wait counter reset
			self.assertEqual(packet.wait, 0)
			
			# Emergency routed
			self.assertTrue(packet.emergency)
	
	
	def test_emergency_forward(self):
		# Test that the router can forward packets received in emergency mode
		
		directions = [
			(topology.EAST,      topology.NORTH_EAST),
			(topology.WEST,      topology.SOUTH_WEST),
			(topology.NORTH,     topology.WEST),
			(topology.NORTH_EAST,topology.NORTH),
			(topology.SOUTH_WEST,topology.SOUTH),
		]
		
		for in_link, out_link in directions:
			# Reset everything...
			self.setUp()
			
			# A packet to ourselves
			packet = SpiNNakerP2PPacket( self.system
			                           , "Example Data"
			                           , (0,0) # Doesn't/Shouldn't matter
			                           , 32)
			
			# The packet is in emergency mode
			packet.emergency = True
			
			# Send packet via an arbitrary input (east)
			self.assertTrue(self.in_links[in_link].can_send())
			self.in_links[in_link].send(packet)
			
			# Run until the packet arrives
			it = self.scheduler.run()
			while it.next() < 1000 and not self.out_links[out_link].can_receive():
				pass
			
			# We got our packet back
			self.assertTrue(self.out_links[out_link].can_receive())
			rec_packet = self.out_links[out_link].receive()
			self.assertEqual(packet, rec_packet)
			
			# Nothing else was sent/received
			for link in self.links:
				self.assertTrue(link.can_send())
				self.assertFalse(link.can_receive())
			
			# The router sent one packet...
			self.assertEqual(self.router.counters["timestamp_packet_timeout"], 0)
			self.assertEqual(self.router.counters["router_packet_timeout"], 0)
			self.assertEqual(self.router.counters["packets_routed"], 1)
			self.assertEqual(self.router.counters["packet_emergency_routed"], 0)
			self.assertEqual(self.router.counters["router_idle_cycles"], 0)
			self.assertEqual(self.router.counters["router_blocked_cycles"], 0)
			
			# Routing took one cycle
			self.assertEqual(self.router.counters["router_cycles"], 1)
			
			# The packet took one hop
			self.assertEqual(packet.distance, 1)
			
			# Wait counter reset
			self.assertEqual(packet.wait, 0)
			
			# The packet is no-longer in emergency mode
			self.assertFalse(packet.emergency)
	
	
	def test_drop_on_block(self):
		# Test that the router drops packets which block
		
		directions = [
			((2,1), topology.EAST,      topology.NORTH_EAST),
			((0,1), topology.WEST,      topology.SOUTH_WEST),
			((1,2), topology.NORTH,     topology.WEST),
			((1,0), topology.SOUTH,     topology.EAST),
			((2,2), topology.NORTH_EAST,topology.NORTH),
			((0,0), topology.SOUTH_WEST,topology.SOUTH),
		]
		
		for router_pos, direction, emergency in directions:
			# Reset everything...
			self.setUp()
			
			# A dud packet
			dud = SpiNNakerP2PPacket( self.system , "Dud" , None , 1)
			
			# A packet to ourselves
			packet = SpiNNakerP2PPacket( self.system
			                           , "Example Data"
			                           , router_pos
			                           , 32)
			
			# Send packet via an arbitrary input (east)
			self.assertTrue(self.in_links[0].can_send())
			self.in_links[0].send(packet)
			
			# Block the target port with a dud packet
			self.assertTrue(self.out_links[direction].can_send())
			self.out_links[direction].send(dud)
			
			# Block the emergency port with a dud packet
			self.assertTrue(self.out_links[emergency].can_send())
			self.out_links[emergency].send(dud)
			
			# Run until the packet is dropped (the input becomes free again)
			it = self.scheduler.run()
			while it.next() < 1000 and self.in_links[0].can_receive():
				pass
			
			# Remove the blockages and make sure they weren't changed...
			self.assertTrue(self.out_links[direction].can_receive())
			rec_dud = self.out_links[direction].receive()
			self.assertEqual(dud, rec_dud)
			
			self.assertTrue(self.out_links[emergency].can_receive())
			rec_dud = self.out_links[emergency].receive()
			self.assertEqual(dud, rec_dud)
			
			# Nothing else was sent/received
			for link in self.links:
				self.assertTrue(link.can_send())
				self.assertFalse(link.can_receive())
			
			# The router dropped one packet...
			self.assertEqual(self.router.counters["timestamp_packet_timeout"], 0)
			self.assertEqual(self.router.counters["router_packet_timeout"], 1)
			self.assertEqual(self.router.counters["packets_routed"], 0)
			self.assertEqual(self.router.counters["packet_emergency_routed"], 0)
			
			# We blocked until the wait threshold was exhausted
			self.assertEqual(self.router.counters["router_blocked_cycles"],
			                 RouterTests.WAIT_BEFORE_DROP + 1)
			
			# One idle cycle where we actually drop the packet
			self.assertEqual(self.router.counters["router_idle_cycles"], 1)
			
			# We blocked until the wait threshold was exhausted plus one idle cycle
			# where we dropped the packet
			self.assertEqual(self.router.counters["router_cycles"],
			                 RouterTests.WAIT_BEFORE_DROP + 1 + 1)
			
			# The packet didn't hop
			self.assertEqual(packet.distance, 0)
			
			# The packet had to wait until the timeout expired
			self.assertEqual(packet.wait, RouterTests.WAIT_BEFORE_DROP + 1)
			
			# Not emergency routed
			self.assertFalse(packet.emergency)