Exemple #1
0
 def get_scheduler(self, cluster_id, date):
     scheduler = None
     try:
         query = """SELECT Id, Date, Cluster, Content
                     FROM schedulers 
                     WHERE Status = %s AND Cluster =  %s AND Date = DATE_FORMAT(%s, "%Y-%m-%d");"""
         data_tuple = (1, cluster_id, date)
         self.curr.execute(query, data_tuple)
         result = self.curr.fetchone()
         if result is not None:
             scheduler = Scheduler(result[0], result[1], result[2],
                                   result[3])
     except mysql.connector.Error as error:
         logging.error('MySQL server is disconnected: ', str(error))
         logging.info('Reconnect to Mysql server..')
         self.connect()
         self.get_scheduler(cluster_id, date)
     return scheduler
	def __init__(self, resultfile_prefix=""):
		self.console = ExperimentConsole()
		
		with self.console.timer("Initialising simulation..."):
			self.scheduler = Scheduler()
			self.system    = SpiNNakerSystem( self.scheduler
			                                , Simulation.TIME_PHASE_PERIOD)
			self.torus     = SpiNNakerTorus( self.scheduler
			                               , self.system
			                               , Simulation.WIDTH
			                               , Simulation.HEIGHT
			                               , Simulation.USE_SATA_LINKS
			                               , Simulation.SATA_ACCEPT_PERIOD
			                               , Simulation.SATA_BUFFER_LENGTH
			                               , Simulation.SATA_LATENCY
			                               , Simulation.SILISTIX_SEND_CYCLES
			                               , Simulation.SILISTIX_ACK_CYCLES
			                               , Simulation.INJECTION_BUFFER_LENGTH
			                               , Simulation.ROUTER_PERIOD
			                               , Simulation.WAIT_BEFORE_EMERGENCY
			                               , Simulation.WAIT_BEFORE_DROP
			                               , Simulation.CORE_PERIOD
			                               , Simulation.PACKET_PROB
			                               , Simulation.DISTANCE_STD
			                               )
		
		self.resultfile_prefix = resultfile_prefix
		
		# A set of functions which are expected to be generators which are initially
		# called with an argument of a file to use to store results. The generator's
		# .next() is called every simulation cycle with a boolean indicating if the
		# cycle was the first of a new clock cycle. At the end of the simulation,
		# a StopExperiment is raised in the generator
		self.measurements = []
		for name, f in inspect.getmembers(self, predicate=inspect.ismethod):
			if name.startswith("measurement_"):
				self.measurements.append(f)
class Simulation(object):
	
	# The simulator will run at 150MHz
	
	TIME_PHASE_PERIOD = 10000
	
	WIDTH  = 1
	HEIGHT = 1
	
	# Use S-ATA links between boards?
	USE_SATA_LINKS = True
	
	# The FPGA accepts one packet every cycle... probably...
	SATA_ACCEPT_PERIOD = 1
	
	# S-ATA link probably negledgable but we have 6GBit/s
	# link which is 1 150MHz cycle for 32bits and frames
	# with 8 packets in are 12 32bit words so 12 cycles
	# per frame. Four stage pipeline at each FPGA to
	# produce and extract frames. This may be optimistic
	SATA_LATENCY = 12 + 4 + 4
	
	# Not really sure what to make this, as such I'm just giving it one buffer
	# entry for each cycle of sata latency...
	SATA_BUFFER_LENGTH = 12 + 4 + 4
	
	SILISTIX_SEND_CYCLES = 23 # 250MBit/s (24 cycles per 40 bit word)
	SILISTIX_ACK_CYCLES  = 1
	
	INJECTION_BUFFER_LENGTH = 4
	
	ROUTER_PERIOD         = 1 # 150MHz
	WAIT_BEFORE_EMERGENCY = 240   # This or 4096 depending on the tool...
	WAIT_BEFORE_DROP      = 240*2
	
	CORE_PERIOD  = 1 # 150MHz
	PACKET_PROB  = 0.01
	DISTANCE_STD = None
	
	
	class StopExperiment(Exception):
		pass
	
	
	def __init__(self, resultfile_prefix=""):
		self.console = ExperimentConsole()
		
		with self.console.timer("Initialising simulation..."):
			self.scheduler = Scheduler()
			self.system    = SpiNNakerSystem( self.scheduler
			                                , Simulation.TIME_PHASE_PERIOD)
			self.torus     = SpiNNakerTorus( self.scheduler
			                               , self.system
			                               , Simulation.WIDTH
			                               , Simulation.HEIGHT
			                               , Simulation.USE_SATA_LINKS
			                               , Simulation.SATA_ACCEPT_PERIOD
			                               , Simulation.SATA_BUFFER_LENGTH
			                               , Simulation.SATA_LATENCY
			                               , Simulation.SILISTIX_SEND_CYCLES
			                               , Simulation.SILISTIX_ACK_CYCLES
			                               , Simulation.INJECTION_BUFFER_LENGTH
			                               , Simulation.ROUTER_PERIOD
			                               , Simulation.WAIT_BEFORE_EMERGENCY
			                               , Simulation.WAIT_BEFORE_DROP
			                               , Simulation.CORE_PERIOD
			                               , Simulation.PACKET_PROB
			                               , Simulation.DISTANCE_STD
			                               )
		
		self.resultfile_prefix = resultfile_prefix
		
		# A set of functions which are expected to be generators which are initially
		# called with an argument of a file to use to store results. The generator's
		# .next() is called every simulation cycle with a boolean indicating if the
		# cycle was the first of a new clock cycle. At the end of the simulation,
		# a StopExperiment is raised in the generator
		self.measurements = []
		for name, f in inspect.getmembers(self, predicate=inspect.ismethod):
			if name.startswith("measurement_"):
				self.measurements.append(f)
	
	
	def measurement_simulator_load(self, datafile):
		"""
		Measure the number of steps the simulator is executing for each clock cycle
		"""
		# Set up
		datafile.write("#clock number_of_steps\n") 
		yield
		
		# Measure how much work the simulator is doing
		step = 0
		try:
			while True:
				if (yield):
					datafile.write("%d %d\n"%(self.scheduler.clock, step))
					step = 0
				else:
					step += 1
		except Simulation.StopExperiment:
			pass
			# Nothing to write at the end of simulation
		
	
	
	def run(self, num_clock_cycles):
		# Get the iterator for the scheduler
		it = self.scheduler.run()
		
		# Start all the (measurer, file, name) and open their files
		gen_files = []
		for measurement in self.measurements:
			# A little introspection to get the function name
			name = measurement.__name__.partition("measurement_")[2]
			
			# Open a file [prefix][function name].log to store the results of that
			# measurer
			f = open("%s%s.log"%(self.resultfile_prefix, name),"w")
			
			# Start the measurer
			with self.console.timer("Initialising measurer '%s'..."%name):
				g = measurement(f)
				g.next()
			
			# Put the running measurer and its file into the dictionary...
			gen_files.append((g, f, name))
		
		# Store the last observed clock value to allow us to detect when it changes
		with self.console.timer("Running simulation...") as timer:
			clock = 0
			timer.set_progress(clock, num_clock_cycles)
			
			# Run the experiment for the prescribed number of cycles
			while it.next() < num_clock_cycles:
				# Has the clock changed?
				clock_changed = clock != self.scheduler.clock
				clock = self.scheduler.clock
				
				# Some progress output
				if (clock_changed and clock%10 == 0):
					timer.set_progress(clock, num_clock_cycles)
				
				# Run each measurer informing it if the clock changed
				for gen, _, _ in gen_files:
					gen.send(clock_changed)
		
		# Terminate each measurer
		for gen, f, name in gen_files:
			with self.console.timer("Finalising measurer '%s'..."%name):
				try:
					gen.throw(Simulation.StopExperiment())
				except StopIteration:
					pass
				f.close()