def test_construction(self): p0 = Package(0, [ Core(0, [Thread(0), Thread(4)]), Core(1, [Thread(1), Thread(5)])]) p1 = Package(1, [ Core(0, [Thread(2), Thread(6)]), Core(1, [Thread(3), Thread(7)])]) packages = [p0, p1] cpu = Cpu(packages) self.assertEqual(packages, cpu.get_packages())
def _get_assign_threads(cpu: Cpu, thread_count: int) -> List[Thread]: empty_threads = cpu.get_empty_threads() if len(empty_threads) >= thread_count: random.shuffle(empty_threads) return empty_threads[:thread_count] # If there aren't enough empty threads, fill the gap with random claimed threads claimed_threads = cpu.get_claimed_threads() random.shuffle(claimed_threads) claimed_threads = claimed_threads[:thread_count - len(empty_threads)] return empty_threads + claimed_threads
def get_free_cores(threshold: float, cpu: Cpu, workload_map: Dict[str, Workload], cpu_usage: Dict[str, float]) -> List[Core]: return [ c for c in cpu.get_cores() if is_core_below_threshold(threshold, c, cpu_usage, workload_map) ]
def _get_allocated_size(cpu: Cpu, workload_map: dict, w_type: str) -> int: allocation_size = 0 for t in cpu.get_threads(): if _is_thread_occupied(t, workload_map, w_type): allocation_size += 1 return allocation_size
def get_oversubscribed_thread_count(cpu: Cpu, workload_map: dict) -> int: oversubscribed_thread_count = 0 for t in cpu.get_threads(): if _is_thread_occupied(t, workload_map, BURST) and _is_thread_occupied( t, workload_map, STATIC): oversubscribed_thread_count += 1 return oversubscribed_thread_count
def test_get_emptiest_package(self): t0 = Thread(0) t1 = Thread(1) t2 = Thread(2) t3 = Thread(3) t4 = Thread(4) t5 = Thread(5) t6 = Thread(6) t7 = Thread(7) p0 = Package(0, [Core(0, [t0, t4]), Core(1, [t1, t5])]) p1 = Package(1, [Core(0, [t2, t6]), Core(1, [t3, t7])]) cpu = Cpu([p0, p1]) # The first package should be the emptiest self.assertEqual(p0, cpu.get_emptiest_package()) # The second package should be the emptiest after we claim a thread on the first t5.claim(uuid.uuid4()) self.assertEqual(p1, cpu.get_emptiest_package()) # The first package should be the emptiest again, after we release the claimed thread t5.clear() self.assertEqual(p0, cpu.get_emptiest_package()) # The first package should be emptiest when we claim a thread on the second t3.claim(uuid.uuid4()) self.assertEqual(p0, cpu.get_emptiest_package()) # When an equal number of threads are claimed on both packages, the first should be returned t4.claim(uuid.uuid4()) self.assertEqual(p0, cpu.get_emptiest_package())
def get_workloads(cpu: Cpu): workloads = {} for t in cpu.get_threads(): for w_id in t.get_workload_ids(): if w_id in workloads: workloads[w_id].append(t.get_id()) else: workloads[w_id] = [t.get_id()] return workloads
def __assert_array_structure(self, cpu: Cpu, workloads_per_thread: int): cpu_array = cpu.to_array() self.assertEqual(DEFAULT_PACKAGE_COUNT, len(cpu_array)) for package in cpu_array: self.assertEqual(DEFAULT_CORE_COUNT, len(package)) for core in package: self.assertEqual(DEFAULT_THREAD_COUNT, len(core)) for thread in core: self.assertEqual(workloads_per_thread, len(thread))
def get_cpu( package_count=DEFAULT_PACKAGE_COUNT, cores_per_package=DEFAULT_CORE_COUNT, threads_per_core=DEFAULT_THREAD_COUNT): print("package count: " + str(package_count) + " cores_per_package:" + str(cores_per_package) + " threads_per_core:" + str(threads_per_core)) packages = [] for p_i in range(package_count): cores = [] for c_i in range(cores_per_package): cores.append( Core(c_i, __get_threads(p_i, c_i, package_count, cores_per_package, threads_per_core))) packages.append(Package(p_i, cores)) print("-------------") print(Cpu(packages)) print(Cpu(packages).get_threads()) print(len(Cpu(packages).get_threads())) print("-------------") return Cpu(packages)
def get_free_threads(self, cpu: Cpu, workload_map: Dict[str, Workload], cpu_usage: Dict[str, float] = None) -> List[Thread]: free_cores = [ c.get_threads() for c in cpu.get_cores() if len(c.get_empty_threads()) == 2 ] if len(free_cores) == 0: return [] return reduce(list.__add__, free_cores)
def test_equality(self): t_0_0 = Thread(0) t_0_1 = Thread(1) c_x = Core(0, [t_0_0, t_0_1]) p_x = Package(0, [c_x]) cpu_x = Cpu([p_x]) t_1_0 = Thread(0) t_1_1 = Thread(1) c_y = Core(0, [t_1_0, t_1_1]) p_y = Package(0, [c_y]) cpu_y = Cpu([p_y]) self.assertEqual(cpu_x, cpu_y) t_0_1.claim("a") self.assertNotEqual(cpu_x, cpu_y) t_1_1.claim("a") self.assertEqual(cpu_x, cpu_y) t_0_0.claim("b") t_1_0.claim("b") self.assertEqual(cpu_x, cpu_y)
def parse_cpu(cpu_dict: dict) -> Cpu: packages = [] for p in cpu_dict["packages"]: cores = [] for c in p["cores"]: threads = [] for t in c["threads"]: thread = Thread(t["id"]) for w_id in t["workload_id"]: thread.claim(w_id) threads.append(thread) cores.append(Core(c["id"], threads)) packages.append(Package(p["id"], cores)) return Cpu(packages)
def get_free_threads( self, cpu: Cpu, workload_map: Dict[str, Workload], cpu_usage: Dict[str, float] = None) -> List[Thread]: if cpu_usage is None: log.error("CPU usage is required, defaulting to EMPTY threads being free.") return cpu.get_empty_threads() free_threads = [] for c in get_free_cores(self.__threshold, cpu, workload_map, cpu_usage): free_threads += c.get_threads() return free_threads
def get_cpu(package_count=DEFAULT_PACKAGE_COUNT, cores_per_package=DEFAULT_CORE_COUNT, threads_per_core=DEFAULT_THREAD_COUNT): packages = [] for p_i in range(package_count): cores = [] for c_i in range(cores_per_package): cores.append( Core( c_i, __get_threads(p_i, c_i, package_count, cores_per_package, threads_per_core))) packages.append(Package(p_i, cores)) return Cpu(packages)
def get_allocated_size(cpu: Cpu) -> int: return len([t for t in cpu.get_threads() if t.is_claimed()])
def test_invalid_cpu(self): with self.assertRaises(ValueError): Cpu([])
def _occupies_entire_cpu(workload: Workload, cpu: Cpu): return len(cpu.get_threads()) == workload.get_thread_count()
def get_free_threads(self, cpu: Cpu, workload_map: Dict[str, Workload], cpu_usage: Dict[str, float] = None) -> List[Thread]: return [t for t in cpu.get_threads() if len(t.get_workload_ids()) == 0]