示例#1
0
class TestTelescopeIngest(unittest.TestCase):
    def setUp(self) -> None:
        self.env = simpy.Environment()
        self.cluster = Cluster(env=self.env, spec=CLUSTER_CONFIG)
        self.buffer = Buffer(env=self.env,
                             cluster=self.cluster,
                             config=BUFFER_CONFIG)
        self.scheduler = Scheduler(env=self.env,
                                   buffer=self.buffer,
                                   cluster=self.cluster,
                                   algorithm=None)
        self.planner = Planner(self.env, 'heft', self.cluster)

    def testIngest(self):
        telescope = Telescope(env=self.env,
                              config=OBSERVATION_CONFIG,
                              planner=self.planner,
                              scheduler=self.scheduler)
        self.assertEqual(0, telescope.telescope_use)
        self.env.process(telescope.run())
        self.scheduler.init()
        self.env.process(self.scheduler.run())
        self.env.run(until=1)
        self.assertEqual(36, telescope.telescope_use)
        self.assertEqual(5, len(self.cluster.available_resources))
        # After 1 timestep, data in the HotBuffer should be 2
        self.assertEqual(496, self.buffer.hot.current_capacity)
        self.env.run(until=10)
        self.assertEqual(460, self.buffer.hot.current_capacity)
        self.env.run(until=12)
        self.assertEqual(0, telescope.telescope_use)
        self.assertEqual(10, len(self.cluster.available_resources))
        self.assertEqual(5, len(self.cluster.finished_tasks))
        self.assertEqual(1, len(self.buffer.waiting_observation_list))
示例#2
0
class Simulation(object):
	"""
	The Simulation class is a wrapper for all Actors; we start the simulation
	through the simulation class, which in turn invokes the initial Actors and
	monitoring, and provides the conditions for checking if the simulation has
	finished.

	Parameters
	----------
	env : simpy.Environment bject
		This is how the TOpSim simulation maintains state across the
		different actors, and interfaces with the simpy processes.

	telescope_config: str
		This is a path to the telescope config that follows the TOpSim config
		specification (JSON). This file will be parsed in the Telescope class
		constructure

	cluster_config: str
		Path to the HPC cluster config that forms the computing component of
		the SDP

	buffer_config: str
		Path to the buffer configuration

	planning_algorithm: Object
		instance of the planning algorithm class interface as defined in
		algorithms.examples/

	scheduling_algorithm: object
		instance of the core.algorithm interface

	event_file: str
		Path to the output file that stores execution of simulation.

	visualisation: bool
		If visualisation is required, True; else, False

	Methods
	-------

    

	Raises
	------
	"""

	def __init__(
			self,
			env,
			telescope_config,
			cluster_config,
			buffer_config,
			planning_algorithm,
			scheduling_algorithm,
			event_file,
			visualisation=False
	):

		self.env = env
		# Event file setup
		self.event_file = event_file
		self.visualisation = visualisation
		if event_file is not None:
			self.monitor = Monitor(self)
		if visualisation:
			self.visualiser = Visualiser(self)
		# Process necessary config files

		# Initiaise Actor and Resource objects

		self.cluster = Cluster(env, cluster_config)
		self.buffer = Buffer(env, self.cluster, config=buffer_config)
		self.planner = Planner(env, planning_algorithm, cluster_config)
		self.scheduler = Scheduler(
			env, self.buffer, self.cluster, scheduling_algorithm
		)

		self.telescope = Telescope(
			env=self.env,
			config=telescope_config,
			planner=self.planner,
			scheduler=self.scheduler
		)

	def start(self, runtime=150):
		"""
		Run the simulation, either for the specified runtime, OR until the
		exit condition is reached:

			* There are no more observations to process,
			* There is nothing left in the Buffer
			* The Scheduler is not waiting to allocate machines to resources
			* There are not tasks still running on the cluster.
		

		Parameters
		----------
		runtime : int
			Nominiated runtime of the simulation. If the simulation length is
			known, pass that as the argument. If not, passing in a negative
			value (typically, just -1) will run the simulation until the
			exit condition is reached.

		Returns
		-------

		"""

		if self.event_file is not None:
			self.env.process(self.monitor.run())
		if self.visualisation:
			self.env.process(self.visualiser.run())

		self.env.process(self.telescope.run())
		self.env.process(self.cluster.run())

		self.scheduler.init()
		self.env.process(self.scheduler.run())
		# Calling env.run() invokes the processes passed in init_process()
		if runtime > 0:
			self.env.run(until=runtime)
		else:
			if not self.is_finished():
				self.env.run()

		logger.info("Simulation Finished @ %s", self.env.now)

	def is_finished(self):
		status = (
				len(self.telescope.observations) == 0
				and self.buffer.observations_for_processing.empty()
				and len(self.scheduler.waiting_observations) == 0
				and len(self.cluster.running_tasks) == 0
		)
		if status:
			# Using compound 'or' doesn't give us a True/False
			return True
		else:
			return False