def test_free_cpu_3_workloads(self):
        # Add 3 workloads sequentially, and then remove the 2nd one added.
        for allocator in ALLOCATORS:
            cpu = get_cpu()

            workloads = {}
            w0 = get_test_workload(123, 3, STATIC)
            w1 = get_test_workload(456, 2, STATIC)
            w2 = get_test_workload(789, 4, STATIC)

            request = get_no_usage_threads_request(cpu, [w0])
            cpu = allocator.assign_threads(request).get_cpu()

            request = get_no_usage_threads_request(cpu, [w0, w1])
            cpu = allocator.assign_threads(request).get_cpu()

            request = get_no_usage_threads_request(cpu, [w0, w1, w2])
            cpu = allocator.assign_threads(request).get_cpu()
            self.assertEqual(3 + 4 + 2, len(cpu.get_claimed_threads()))

            request = get_no_usage_threads_request(cpu, [w0, w2, w1])
            cpu = allocator.free_threads(request).get_cpu()
            self.assertEqual(3 + 4, len(cpu.get_claimed_threads()))

            workload_ids_left = set()
            for t in cpu.get_threads():
                if t.is_claimed():
                    for w_id in t.get_workload_ids():
                        workload_ids_left.add(w_id)

            self.assertListEqual(sorted(list(workload_ids_left)), [123, 789])
    def test_balance_forecast_ip(self):
        allocator = forecast_ip_alloc_simple
        cpu = get_cpu()

        w_a = get_test_workload("a", 2, STATIC)
        w_b = get_test_workload("b", 4, BURST)

        workloads = [w_a]
        request = get_no_usage_threads_request(cpu, workloads)
        cpu = allocator.assign_threads(request).get_cpu()

        workloads = [w_a, w_b]
        request = get_no_usage_threads_request(cpu, workloads)
        cpu = allocator.assign_threads(request).get_cpu()

        request = get_no_usage_rebalance_request(cpu, workloads)
        cpu = allocator.rebalance(request).get_cpu()

        self.assertLessEqual(2 + 4, len(cpu.get_claimed_threads()))

        w2t = cpu.get_workload_ids_to_thread_ids()
        self.assertEqual(2, len(w2t["a"]))
        self.assertLessEqual(4, len(w2t["b"]))  # burst got at least 4

        for _ in range(20):
            request = get_no_usage_rebalance_request(cpu, workloads)
            cpu = allocator.rebalance(request).get_cpu()

        w2t = cpu.get_workload_ids_to_thread_ids()
        self.assertEqual(2, len(w2t["a"]))
        self.assertLessEqual(4, len(w2t["b"]))
    def test_fill_cpu(self):
        """
        Workload 0: 8 cores
        Workload 1: 4 cores
        Workload 2: 2 cores
        Workload 3: 1 core
        Workload 4: 1 core
        --------------------
        Total:      16 cores
        """
        for allocator in ALLOCATORS:
            cpu = get_cpu()
            workloads = [
                get_test_workload("v", 8, STATIC),
                get_test_workload("w", 4, STATIC),
                get_test_workload("x", 2, STATIC),
                get_test_workload("y", 1, STATIC),
                get_test_workload("z", 1, STATIC)
            ]

            tot_req = 0
            __workloads = []
            for w in workloads:
                __workloads.append(w)
                request = get_no_usage_threads_request(cpu, __workloads)
                cpu = allocator.assign_threads(request).get_cpu()
                log.info(cpu)
                tot_req += w.get_thread_count()
                self.assertEqual(tot_req, len(cpu.get_claimed_threads()))
    def test_assign_ten_threads_empty_cpu_ip(self):
        """
        Workload 0: 10 threads --> (p:0 c:[0-7] t:[0-9])
        | 1 | 1 | 1 | 1 |
        | 1 | 1 |   |   |
        | ------------- |
        | 1 | 1 | 1 | 1 |
        |   |   |   |   |
        """
        for allocator in [
                IntegerProgramCpuAllocator(), forecast_ip_alloc_simple
        ]:
            cpu = get_cpu()
            w = get_test_workload(uuid.uuid4(), 10, STATIC)

            request = get_no_usage_threads_request(cpu, [w])
            cpu = allocator.assign_threads(request).get_cpu()
            self.assertEqual(10, len(cpu.get_claimed_threads()))

            threads_per_socket = []
            for p in cpu.get_packages():
                ths = []
                for c in p.get_cores():
                    for t in c.get_threads():
                        if t.is_claimed():
                            ths.append(t)
                threads_per_socket.append(len(ths))

            self.assertEqual(5, threads_per_socket[0])
            self.assertEqual(5, threads_per_socket[1])
    def test_assign_two_workloads_empty_cpu_greedy(self):
        """
        Workload 0: 2 threads --> (p:0 c:0 t:0) (p:0 c:0 t:1)
        Workload 1: 1 thread  --> (p:1 c:0 t:0)
        """
        cpu = get_cpu()
        allocator = GreedyCpuAllocator()
        w0 = get_test_workload(uuid.uuid4(), 2, STATIC)
        w1 = get_test_workload(uuid.uuid4(), 1, STATIC)

        request0 = get_no_usage_threads_request(cpu, [w0])
        cpu = allocator.assign_threads(request0).get_cpu()

        request1 = get_no_usage_threads_request(cpu, [w0, w1])
        cpu = allocator.assign_threads(request1).get_cpu()

        self.assertEqual(3, len(cpu.get_claimed_threads()))

        packages = cpu.get_packages()

        # WORKLOAD 0
        core00 = packages[0].get_cores()[0]
        thread0 = core00.get_threads()[0]
        self.assertEqual(0, thread0.get_id())
        self.assertTrue(thread0.is_claimed())
        thread1 = core00.get_threads()[1]
        self.assertEqual(8, thread1.get_id())
        self.assertTrue(thread1.is_claimed())

        # WORKLOAD 1
        core00 = packages[1].get_cores()[0]
        thread4 = core00.get_threads()[0]
        self.assertEqual(4, thread4.get_id())
        self.assertTrue(thread4.is_claimed())
    def test_forecast_ip_burst_pool_with_usage(self):
        class UsagePredictorWithBurst:
            def __init__(self):
                self.__model = TestPredictor()

            def predict(self, workload: Workload,
                        cpu_usage_last_hour: np.array,
                        pred_env: PredEnvironment) -> float:
                if workload.get_id() == 'static_a':
                    return workload.get_thread_count() * 0.8
                elif workload.get_id() == 'static_b':
                    return workload.get_thread_count() * 0.01
                elif workload.get_id() == 'burst_c':
                    return workload.get_thread_count() * 0.9

            def get_model(self):
                return self.__model

        upm = TestCpuUsagePredictorManager(UsagePredictorWithBurst())
        cm = ConfigManager(
            TestPropertyProvider({BURST_CORE_COLLOC_USAGE_THRESH: 0.9}))
        allocator = ForecastIPCpuAllocator(
            upm, cm, OversubscribeFreeThreadProvider(0.1))

        cpu = get_cpu(package_count=2, cores_per_package=16)
        w_a = get_test_workload("static_a", 14, STATIC)
        w_b = get_test_workload("static_b", 14, STATIC)
        w_c = get_test_workload("burst_c", 2, BURST)

        request = get_no_usage_threads_request(cpu, [w_a])
        cpu = allocator.assign_threads(request).get_cpu()

        request = get_no_usage_threads_request(cpu, [w_a, w_c])
        cpu = allocator.assign_threads(request).get_cpu()
        # with an aggressive burst pool expansion, burst should be collocated with static on cores:
        self.assertLess(40, len(cpu.get_claimed_threads()))
        num_burst_1 = len(cpu.get_workload_ids_to_thread_ids()[w_c.get_id()])

        request = get_no_usage_threads_request(cpu, [w_a, w_c, w_b])
        cpu = allocator.assign_threads(request).get_cpu()
        # burst should retract, and prefer collocation with b over a:
        num_burst_2 = len(cpu.get_workload_ids_to_thread_ids()[w_c.get_id()])
        self.assertLessEqual(num_burst_2, num_burst_1)

        colloc_a = 0
        colloc_b = 0
        for p in cpu.get_packages():
            for c in p.get_cores():
                t1 = c.get_threads()[0]
                t2 = c.get_threads()[1]
                if t1.is_claimed() and t2.is_claimed():
                    wt1 = t1.get_workload_ids()[0]
                    wt2 = t2.get_workload_ids()[0]
                    if (wt1 == w_a.get_id() and wt2 == w_c.get_id()) or (
                            wt1 == w_c.get_id() and wt2 == w_a.get_id()):
                        colloc_a += 1
                    elif (wt1 == w_b.get_id() and wt2 == w_c.get_id()) or (
                            wt1 == w_c.get_id() and wt2 == w_b.get_id()):
                        colloc_b += 1
        self.assertLessEqual(colloc_a, colloc_b)
Пример #7
0
    def test_assign_two_workloads_empty_cpu_ip(self):
        """
        Workload 0: 2 threads --> (p:0 c:0 t:0) (p:0 c:1 t:0)
        Workload 1: 1 thread  --> (p:1 c:0 t:0)
        """
        cpu = get_cpu()
        allocator = IntegerProgramCpuAllocator(cpu)
        w0 = Workload(uuid.uuid4(), 2, STATIC)
        w1 = Workload(uuid.uuid4(), 1, STATIC)

        allocator.assign_threads(w0)
        allocator.assign_threads(w1)
        self.assertEqual(3, len(cpu.get_claimed_threads()))

        packages = cpu.get_packages()

        # WORKLOAD 0
        core00 = packages[0].get_cores()[0]
        core01 = packages[0].get_cores()[1]
        thread0 = core00.get_threads()[0]
        self.assertEqual(0, thread0.get_id())
        self.assertTrue(thread0.is_claimed())
        thread1 = core01.get_threads()[0]
        self.assertEqual(1, thread1.get_id())
        self.assertTrue(thread1.is_claimed())

        # WORKLOAD 1
        core00 = packages[1].get_cores()[0]
        thread4 = core00.get_threads()[0]
        self.assertEqual(4, thread4.get_id())
        self.assertTrue(thread4.is_claimed())
    def test_is_isolated(self):
        real_allocators = [GreedyCpuAllocator(), IntegerProgramCpuAllocator()]
        for allocator in real_allocators:
            wm = WorkloadManager(get_cpu(), MockCgroupManager(), allocator)
            self.assertFalse(wm.is_isolated(uuid.uuid4()))

        for allocator in real_allocators:
            workload = get_test_workload(uuid.uuid4(),
                                         DEFAULT_TOTAL_THREAD_COUNT, STATIC)
            wm = WorkloadManager(get_cpu(), MockCgroupManager(), allocator)
            wm.add_workload(workload)
            self.assertTrue(wm.is_isolated(workload.get_id()))

        wm = WorkloadManager(get_cpu(), MockCgroupManager(),
                             NoopCpuAllocator())
        self.assertTrue(wm.is_isolated(uuid.uuid4()))
    def test_remove_unknown_workload(self):
        for allocator in ALLOCATORS:
            unknown_workload_id = "unknown"
            thread_count = 2
            workload = get_test_workload(uuid.uuid4(), thread_count, STATIC)

            workload_manager = WorkloadManager(get_cpu(), MockCgroupManager(),
                                               allocator)

            # Remove from empty set
            workload_manager.remove_workload(unknown_workload_id)

            # Add workload
            workload_manager.add_workload(workload)
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT - thread_count,
                len(workload_manager.get_cpu().get_empty_threads()))

            # Removal of an unknown workload should have no effect
            workload_manager.remove_workload(unknown_workload_id)
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT - thread_count,
                len(workload_manager.get_cpu().get_empty_threads()))

            # Remove workload with unknown workload, real workload should be removed
            workload_manager.remove_workload(unknown_workload_id)
            workload_manager.remove_workload(workload.get_id())
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT,
                len(workload_manager.get_cpu().get_empty_threads()))
Пример #10
0
    def test_shared_core_violation(self):
        allocator = IntegerProgramCpuAllocator()

        # Claim all thread but one
        cpu = get_cpu()
        w = get_test_workload(uuid.uuid4(), len(cpu.get_threads()) - 1, STATIC)
        workloads = {w.get_id(): w}
        request = AllocateThreadsRequest(cpu, w.get_id(), workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.assign_threads(request).get_cpu()
        log.info("{}".format(cpu))
        violations = get_shared_core_violations(cpu)
        log.info("shared core violations: {}".format(violations))
        self.assertEqual(0, len(violations))

        # Assign another workload which will force core sharing
        w = get_test_workload(uuid.uuid4(), 1, STATIC)
        workloads[w.get_id()] = w
        request = AllocateThreadsRequest(cpu, w.get_id(), workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.assign_threads(request).get_cpu()
        log.info("{}".format(cpu))
        violations = get_shared_core_violations(cpu)
        log.info("shared core violations: {}".format(violations))
        self.assertEqual(1, len(violations))
Пример #11
0
    def test_single_static_workload_lifecycle(self):
        for allocator_class in [
                GreedyCpuAllocator, IntegerProgramCpuAllocator
        ]:
            thread_count = 2
            workload = Workload(uuid.uuid4(), thread_count, STATIC)

            cgroup_manager = MockCgroupManager()
            workload_manager = WorkloadManager(get_cpu(),
                                               cgroup_manager,
                                               allocator_class=allocator_class)

            # Add workload
            workload_manager.add_workload(workload)
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT - thread_count,
                len(workload_manager.get_cpu().get_empty_threads()))
            self.assertEqual(
                1, cgroup_manager.container_update_counts[workload.get_id()])

            # Remove workload
            workload_manager.remove_workload(workload.get_id())
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT,
                len(workload_manager.get_cpu().get_empty_threads()))
    def test_assign_two_workloads_empty_cpu_ip(self):
        """
        Workload 0: 2 threads --> (p:0 c:0 t:0) (p:0 c:1 t:0)
        Workload 1: 1 thread  --> (p:1 c:0 t:0)
        """
        for allocator in [
                IntegerProgramCpuAllocator(), forecast_ip_alloc_simple
        ]:
            cpu = get_cpu()
            w0 = get_test_workload(uuid.uuid4(), 2, STATIC)
            w1 = get_test_workload(uuid.uuid4(), 1, STATIC)

            request0 = get_no_usage_threads_request(cpu, [w0])
            cpu = allocator.assign_threads(request0).get_cpu()

            request1 = get_no_usage_threads_request(cpu, [w0, w1])
            cpu = allocator.assign_threads(request1).get_cpu()

            self.assertEqual(3, len(cpu.get_claimed_threads()))

            ids_per_socket = []
            for pid, p in enumerate(cpu.get_packages()):
                r = []
                for cid, c in enumerate(p.get_cores()):
                    for tid, t in enumerate(c.get_threads()):
                        if t.is_claimed():
                            self.assertEqual(1, len(t.get_workload_ids()))
                            r.append((t.get_workload_ids()[0], c.get_id()))
                ids_per_socket.append(r)

            for r in ids_per_socket:
                # each workload should be on a different socket
                self.assertEqual(1, len(set([e[0] for e in r])))
Пример #13
0
    def test_single_burst_workload_lifecycle(self):
        for allocator_class in [
                GreedyCpuAllocator, IntegerProgramCpuAllocator
        ]:
            thread_count = 2
            workload = Workload(uuid.uuid4(), thread_count, BURST)

            cgroup_manager = MockCgroupManager()
            workload_manager = WorkloadManager(get_cpu(),
                                               cgroup_manager,
                                               allocator_class=allocator_class)

            # Add workload
            workload_manager.add_workload(workload)
            self.assertEqual(
                2, cgroup_manager.container_update_counts[workload.get_id()])

            # All threads should have been assigned to the only burst workload.
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT,
                len(cgroup_manager.container_update_map[workload.get_id()]))

            # No threads should have been consumed from the cpu model perspective.
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT,
                len(workload_manager.get_cpu().get_empty_threads()))

            # Remove workload
            workload_manager.remove_workload(workload.get_id())
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT,
                len(workload_manager.get_cpu().get_empty_threads()))
    def test_single_burst_workload_lifecycle(self):
        for allocator in ALLOCATORS:
            requested_thread_count = 2
            workload = get_test_workload(uuid.uuid4(), requested_thread_count,
                                         BURST)

            cgroup_manager = MockCgroupManager()
            workload_manager = WorkloadManager(get_cpu(), cgroup_manager,
                                               allocator)

            # Add workload
            workload_manager.add_workload(workload)
            self.assertEqual(
                1, cgroup_manager.container_update_counts[workload.get_id()])

            # More than the requested threads should have been assigned to the only burst workload.
            self.assertTrue(
                len(cgroup_manager.container_update_map[workload.get_id()]) >
                requested_thread_count)

            # Remove workload
            workload_manager.remove_workload(workload.get_id())
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT,
                len(workload_manager.get_cpu().get_empty_threads()))
Пример #15
0
    def test_cache_ip(self):
        """
        [add a=2, add b=2, remove b=2, add c=2, remove a=2, add d=2] should lead to the following cache entries:
        (state=[], req=[2])
        (state=[2], req=[2,2])
        (state=[2,2], req=[2,0])
        [cache hit]
        [cache hit]
        (state=[2,2], req=[2,2]) but different layout
        """
        cpu = get_cpu()
        allocator = IntegerProgramCpuAllocator(cpu)

        allocator.assign_threads(Workload("a", 2, STATIC))
        self.assertEqual(1, len(allocator._IntegerProgramCpuAllocator__cache))

        allocator.assign_threads(Workload("b", 2, STATIC))
        self.assertEqual(2, len(allocator._IntegerProgramCpuAllocator__cache))

        allocator.free_threads("b")
        self.assertEqual(3, len(allocator._IntegerProgramCpuAllocator__cache))

        allocator.assign_threads(Workload("c", 2, STATIC))
        self.assertEqual(3, len(allocator._IntegerProgramCpuAllocator__cache))

        allocator.free_threads("a")
        self.assertEqual(4, len(allocator._IntegerProgramCpuAllocator__cache))

        allocator.assign_threads(Workload("d", 2, STATIC))
        self.assertEqual(5, len(allocator._IntegerProgramCpuAllocator__cache))
Пример #16
0
    def test_fill_cpu(self):
        """
        Workload 0: 8 cores
        Workload 1: 4 cores
        Workload 2: 2 cores
        Workload 3: 1 core
        Workload 4: 1 core
        --------------------
        Total:      16 cores
        """
        for allocator_class in ALLOCATORS:
            cpu = get_cpu()
            allocator = allocator_class(cpu)
            workloads = [
                Workload(uuid.uuid4(), 8, STATIC),
                Workload(uuid.uuid4(), 4, STATIC),
                Workload(uuid.uuid4(), 2, STATIC),
                Workload(uuid.uuid4(), 1, STATIC),
                Workload(uuid.uuid4(), 1, STATIC)]

            tot_req = 0
            for w in workloads:
                allocator.assign_threads(w)
                tot_req += w.get_thread_count()
                self.assertEqual(tot_req, len(cpu.get_claimed_threads()))
Пример #17
0
    def test_remove_unknown_workload(self):
        for allocator_class in [
                GreedyCpuAllocator, IntegerProgramCpuAllocator
        ]:
            unknown_workload_id = "unknown"
            thread_count = 2
            workload = Workload(uuid.uuid4(), thread_count, STATIC)

            workload_manager = WorkloadManager(get_cpu(),
                                               MockCgroupManager(),
                                               allocator_class=allocator_class)

            # Remove from empty set
            workload_manager.remove_workload([unknown_workload_id])

            # Add workload
            workload_manager.add_workload(workload)
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT - thread_count,
                len(workload_manager.get_cpu().get_empty_threads()))

            # Removal of an unknown workload should have no effect
            workload_manager.remove_workload([unknown_workload_id])
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT - thread_count,
                len(workload_manager.get_cpu().get_empty_threads()))

            # Remove workload with unknown workload, real workload should be removed
            workload_manager.remove_workload(unknown_workload_id)
            workload_manager.remove_workload(workload.get_id())
            self.assertEqual(
                DEFAULT_TOTAL_THREAD_COUNT,
                len(workload_manager.get_cpu().get_empty_threads()))
Пример #18
0
    def test_occupies_entire_cpu(self):
        cpu = get_cpu()

        workload = get_test_workload("a", len(cpu.get_threads()), STATIC)
        self.assertTrue(_occupies_entire_cpu(workload, cpu))

        workload = get_test_workload("a", len(cpu.get_threads()) - 1, STATIC)
        self.assertFalse(_occupies_entire_cpu(workload, cpu))
Пример #19
0
    def test_one_cross_package_violation(self):
        cpu = get_cpu()
        allocator = IntegerProgramCpuAllocator(cpu)
        w = Workload(uuid.uuid4(), 9, STATIC)

        allocator.assign_threads(w)
        violations = get_cross_package_violations(cpu)
        self.assertEqual(1, len(violations))
Пример #20
0
    def test_parse_cpu(self):
        cpu_in = get_cpu()
        log.info("cpu_in : {}".format(cpu_in))

        cpu_out = parse_cpu(cpu_in.to_dict())
        log.info("cpu_out: {}".format(cpu_out))

        self.assertEqual(cpu_in.to_dict(), cpu_out.to_dict())
    def test_thread_allocation_computation(self):
        for allocator in [IntegerProgramCpuAllocator(), GreedyCpuAllocator()]:
            static_thread_count = 2
            burst_thread_count = 4
            w_static = get_test_workload("s", static_thread_count, STATIC)
            w_burst = get_test_workload("b", burst_thread_count, BURST)

            cgroup_manager = MockCgroupManager()
            registry = Registry()

            workload_manager = WorkloadManager(get_cpu(), cgroup_manager,
                                               allocator)
            workload_manager.set_registry(registry, {})
            workload_manager.add_workload(w_static)
            workload_manager.add_workload(w_burst)

            workload_manager.report_metrics({})
            total_thread_count = len(workload_manager.get_cpu().get_threads())
            expected_burst_allocation_size = total_thread_count - static_thread_count
            self.assertTrue(
                gauge_value_equals(registry, ALLOCATED_SIZE_KEY,
                                   total_thread_count))
            self.assertTrue(
                gauge_value_equals(registry, UNALLOCATED_SIZE_KEY, 0))
            self.assertTrue(
                gauge_value_equals(registry, STATIC_ALLOCATED_SIZE_KEY,
                                   static_thread_count))
            self.assertTrue(
                gauge_value_equals(registry, BURST_ALLOCATED_SIZE_KEY,
                                   expected_burst_allocation_size))
            self.assertTrue(
                gauge_value_equals(registry, BURST_REQUESTED_SIZE_KEY,
                                   burst_thread_count))
            self.assertTrue(
                gauge_value_equals(registry, OVERSUBSCRIBED_THREADS_KEY, 0))

            # Claim every thread for the burst workload which will oversubscribe the static threads
            for t in workload_manager.get_cpu().get_threads():
                t.claim(w_burst.get_id())

            workload_manager.report_metrics({})
            self.assertTrue(
                gauge_value_equals(registry, ALLOCATED_SIZE_KEY,
                                   total_thread_count))
            self.assertTrue(
                gauge_value_equals(registry, UNALLOCATED_SIZE_KEY, 0))
            self.assertTrue(
                gauge_value_equals(registry, STATIC_ALLOCATED_SIZE_KEY,
                                   static_thread_count))
            self.assertTrue(
                gauge_value_equals(registry, BURST_ALLOCATED_SIZE_KEY,
                                   total_thread_count))
            self.assertTrue(
                gauge_value_equals(registry, BURST_REQUESTED_SIZE_KEY,
                                   burst_thread_count))
            self.assertTrue(
                gauge_value_equals(registry, OVERSUBSCRIBED_THREADS_KEY,
                                   static_thread_count))
Пример #22
0
    def test_one_cross_package_violation(self):
        cpu = get_cpu()
        allocator = IntegerProgramCpuAllocator()
        w = get_test_workload(uuid.uuid4(), 9, STATIC)

        request = get_no_usage_threads_request(cpu, [w])
        cpu = allocator.assign_threads(request).get_cpu()
        violations = get_cross_package_violations(cpu)
        self.assertEqual(1, len(violations))
Пример #23
0
 def __init__(self, docker_client=MockDockerClient(), cpu=None):
     if cpu is None:
         cpu = get_cpu()
     self.__docker_client = docker_client
     self.__workload_manager = WorkloadManager(cpu, MockCgroupManager())
     self.__event_logger = EventLogger()
     self.__create_event_handler = CreateEventHandler(
         self.__workload_manager)
     self.__free_event_handler = FreeEventHandler(self.__workload_manager)
Пример #24
0
    def test_filling_holes_ip(self):
        """
        Initialize with fragmented placement, then fill the instance. Result should be
        less fragmented, with the first workload completely filling a socket.
        | a |   | a |   |
        |   | a |   | a |
        | ------------- |
        |   | a |   | a |
        | a |   | a |   |
        """
        cpu = get_cpu()
        allocator = IntegerProgramCpuAllocator()

        # Initialize fragmented workload
        wa = get_test_workload(uuid.uuid4(), 8, STATIC)

        p0 = cpu.get_packages()[0]
        p0.get_cores()[0].get_threads()[0].claim(wa.get_id())
        p0.get_cores()[1].get_threads()[1].claim(wa.get_id())
        p0.get_cores()[2].get_threads()[0].claim(wa.get_id())
        p0.get_cores()[3].get_threads()[1].claim(wa.get_id())

        p1 = cpu.get_packages()[1]
        p1.get_cores()[0].get_threads()[1].claim(wa.get_id())
        p1.get_cores()[1].get_threads()[0].claim(wa.get_id())
        p1.get_cores()[2].get_threads()[1].claim(wa.get_id())
        p1.get_cores()[3].get_threads()[0].claim(wa.get_id())

        self.assertEqual(8, len(cpu.get_empty_threads()))

        # Fill the rest of the CPU
        w0 = get_test_workload(uuid.uuid4(), 2, STATIC)
        w1 = get_test_workload(uuid.uuid4(), 3, STATIC)
        w2 = get_test_workload(uuid.uuid4(), 1, STATIC)
        w3 = get_test_workload(uuid.uuid4(), 2, STATIC)

        workload_map = {wa.get_id(): wa}
        workloads = [w0, w1, w2, w3]
        __workloads = [wa]
        for w in workloads:
            __workloads.append(w)
            workload_map[w.get_id()] = w
            request = get_no_usage_threads_request(cpu, __workloads)
            cpu = allocator.assign_threads(request).get_cpu()

        self.assertEqual(0, len(cpu.get_empty_threads()))

        # first workload should be filling completely a socket to avoid cross-socket job layout
        for package in cpu.get_packages():
            if package.get_cores()[0].get_threads()[0].get_workload_ids(
            ) != wa.get_id():
                continue
            ids = [
                t.get_workload_ids() for core in package.get_cores()
                for t in core.get_threads()
            ]
            self.assertListEqual(ids, [wa.get_id()] * 8)
def assign_threads(workload: Workload) -> Cpu:
    cpu = get_cpu()
    threads = cpu.get_threads()

    total_thread_count = workload.get_thread_count(
    ) + workload.get_opportunistic_thread_count()
    for i in range(total_thread_count):
        threads[i].claim(workload.get_id())

    return cpu
Пример #26
0
    def test_one_cross_package_violation(self):
        cpu = get_cpu()
        allocator = IntegerProgramCpuAllocator()
        w = get_test_workload(uuid.uuid4(), 9, STATIC)

        request = AllocateThreadsRequest(cpu, w.get_id(), {w.get_id(): w}, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.assign_threads(request).get_cpu()
        violations = get_cross_package_violations(cpu)
        self.assertEqual(1, len(violations))
Пример #27
0
    def test_no_fallback_should_error(self):

        wm = WorkloadManager(get_cpu(2, 2, 2),
                             MockCgroupManager(),
                             allocator_class=CrashingAssignAllocator,
                             fallback_allocator_class=None)

        wm.add_workload(Workload("foo", 1, STATIC))

        self.assertEqual(1, wm.get_error_count())
Пример #28
0
 def __init__(self, cpu=None, allocator=IntegerProgramCpuAllocator()):
     if cpu is None:
         cpu = get_cpu()
     self.__workload_manager = WorkloadManager(cpu, MockCgroupManager(),
                                               allocator)
     self.__create_event_handler = CreateEventHandler(
         self.__workload_manager)
     self.__free_event_handler = FreeEventHandler(self.__workload_manager)
     self.__rebalance_event_handler = RebalanceEventHandler(
         self.__workload_manager)
Пример #29
0
    def test_reconcile_no_workloads(self):
        cpu = get_cpu()

        reconciler = Reconciler(MockCgroupManager(), EXIT_HANDLER)
        reconciler.reconcile(cpu)
        self.__validate_state(reconciler,
                              EXIT_HANDLER,
                              exit_code=None,
                              expected_success_count=1,
                              expected_skip_count=0)
Пример #30
0
    def __test_uniform_usage(self, usage, provider):
        # Assign a workload to a CPU
        cpu = get_cpu()
        workload = get_test_workload("a", TEST_WORKLOAD_THREAD_COUNT, STATIC)

        cpu = self.__assign_workload(cpu, workload)
        log.info(cpu)
        w_usage = {"a": usage}

        return provider.get_free_threads(cpu, {workload.get_id(): workload},
                                         w_usage)