Ejemplo n.º 1
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())
Ejemplo n.º 2
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))
Ejemplo n.º 3
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))
Ejemplo n.º 4
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)
Ejemplo n.º 5
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))
Ejemplo n.º 6
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))
Ejemplo n.º 7
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()
        workloads = {}

        workload = get_test_workload("a", 2, STATIC)
        workloads[workload.get_id()] = workload
        request = AllocateThreadsRequest(cpu, workload.get_id(), workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.assign_threads(request).get_cpu()
        self.assertEqual(1, len(allocator._IntegerProgramCpuAllocator__cache))

        workload = get_test_workload("b", 2, STATIC)
        workloads[workload.get_id()] = workload
        request = AllocateThreadsRequest(cpu, workload.get_id(), workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.assign_threads(request).get_cpu()
        self.assertEqual(2, len(allocator._IntegerProgramCpuAllocator__cache))

        request = AllocateThreadsRequest(cpu, "b", workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.free_threads(request).get_cpu()
        self.assertEqual(3, len(allocator._IntegerProgramCpuAllocator__cache))
        workloads.pop("b")

        workload = get_test_workload("c", 2, STATIC)
        workloads[workload.get_id()] = workload
        request = AllocateThreadsRequest(cpu, workload.get_id(), workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.assign_threads(request).get_cpu()
        self.assertEqual(3, len(allocator._IntegerProgramCpuAllocator__cache))

        request = AllocateThreadsRequest(cpu, "a", workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.free_threads(request).get_cpu()
        self.assertEqual(4, len(allocator._IntegerProgramCpuAllocator__cache))
        workloads.pop("a")

        workload = get_test_workload("d", 2, STATIC)
        workloads[workload.get_id()] = workload
        request = AllocateThreadsRequest(cpu, workload.get_id(), workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        allocator.assign_threads(request).get_cpu()
        self.assertEqual(5, len(allocator._IntegerProgramCpuAllocator__cache))
Ejemplo n.º 8
0
    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_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])))
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
    def test_ip_fallback(self):

        w_a = get_test_workload("a", 3, STATIC)
        w_b = get_test_workload("b", 2, STATIC)
        w_c = get_test_workload("c", 1, STATIC)
        w_d = get_test_workload("d", 2, STATIC)

        cpu = get_cpu(package_count=2, cores_per_package=2, threads_per_core=2)

        allocator = FallbackCpuAllocator(CrashingAllocator(), IntegerProgramCpuAllocator())

        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_b])
        cpu = allocator.assign_threads(request).get_cpu()

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

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

        request = get_no_usage_threads_request(cpu, [w_c, w_b])
        cpu = allocator.free_threads(request).get_cpu()

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

        self.assertEqual(3, len(cpu.get_claimed_threads()))
        self.assertEqual(6, allocator.get_fallback_allocator_calls_count())
    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))
Ejemplo n.º 13
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()

        w_a = get_test_workload("a", 2, STATIC)
        w_b = get_test_workload("b", 2, STATIC)
        w_c = get_test_workload("c", 2, STATIC)
        w_d = get_test_workload("d", 2, STATIC)

        workloads = [w_a]
        request = get_no_usage_threads_request(cpu, workloads)
        cpu = allocator.assign_threads(request).get_cpu()
        self.assertEqual(1, len(allocator._IntegerProgramCpuAllocator__cache))

        workloads = [w_a, w_b]
        request = get_no_usage_threads_request(cpu, workloads)
        allocator.assign_threads(request).get_cpu()
        self.assertEqual(2, len(allocator._IntegerProgramCpuAllocator__cache))

        cpu = allocator.free_threads(request).get_cpu()
        self.assertEqual(3, len(allocator._IntegerProgramCpuAllocator__cache))

        workloads = [w_a, w_c]
        request = get_no_usage_threads_request(cpu, workloads)
        cpu = allocator.assign_threads(request).get_cpu()
        self.assertEqual(3, len(allocator._IntegerProgramCpuAllocator__cache))

        workloads = [w_c, w_a]
        request = get_no_usage_threads_request(cpu, workloads)
        cpu = allocator.free_threads(request).get_cpu()
        self.assertEqual(4, len(allocator._IntegerProgramCpuAllocator__cache))

        workloads = [w_c, w_d]
        request = get_no_usage_threads_request(cpu, workloads)
        allocator.assign_threads(request).get_cpu()
        self.assertEqual(5, len(allocator._IntegerProgramCpuAllocator__cache))
Ejemplo n.º 14
0
    def test_assign_two_threads_empty_cpu_ip(self):
        """
        Workload 0: 2 threads --> (p:0 c:0 t:0) (p:0 c:1 t:0)
        """
        cpu = get_cpu()
        allocator = IntegerProgramCpuAllocator(cpu)
        w = Workload(uuid.uuid4(), 2, STATIC)

        allocator.assign_threads(w)
        self.assertEqual(2, len(cpu.get_claimed_threads()))

        # Expected core and threads
        core00 = cpu.get_packages()[0].get_cores()[0]
        core01 = cpu.get_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())
Ejemplo n.º 15
0
    def test_shared_core_violation(self):
        allocator = IntegerProgramCpuAllocator()

        # Claim all thread but one
        cpu = get_cpu()
        w_0 = get_test_workload(uuid.uuid4(), len(cpu.get_threads()) - 1, STATIC)
        request = get_no_usage_threads_request(cpu, [w_0])
        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_1 = get_test_workload(uuid.uuid4(), 1, STATIC)
        request = get_no_usage_threads_request(cpu, [w_0, w_1])
        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))
Ejemplo n.º 16
0
    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 |
        |   |   |   |   |
        """
        cpu = get_cpu()
        allocator = IntegerProgramCpuAllocator(cpu)
        w = Workload(uuid.uuid4(), 10, STATIC)

        allocator.assign_threads(w)
        self.assertEqual(10, len(cpu.get_claimed_threads()))

        expected_thread_ids = [0, 1, 2, 3, 4, 5, 6, 7, 8, 12]

        thread_ids = [thread.get_id() for thread in cpu.get_claimed_threads()]
        thread_ids.sort()

        self.assertEqual(expected_thread_ids, thread_ids)
Ejemplo n.º 17
0
    def test_shared_core_violation(self):
        cpu = get_cpu()
        violations = get_shared_core_violations(cpu)
        log.info("shared core violations: {}".format(violations))
        self.assertEqual(0, len(violations))

        # Claim 1 thread on every core
        dummy_workload_id = uuid.uuid4()
        for p in cpu.get_packages():
            for c in p.get_cores():
                c.get_threads()[0].claim(dummy_workload_id)

        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
        allocator = IntegerProgramCpuAllocator(cpu)
        w = Workload(uuid.uuid4(), 2, STATIC)
        allocator.assign_threads(w)
        violations = get_shared_core_violations(cpu)
        log.info("shared core violations: {}".format(violations))
        self.assertEqual(2, len(violations))
    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()))
Ejemplo n.º 19
0
    def test_ip_fallback(self):

        w_a = get_test_workload("a", 3, STATIC)
        w_b = get_test_workload("b", 2, STATIC)
        w_c = get_test_workload("c", 1, STATIC)
        w_d = get_test_workload("d", 2, STATIC)

        cpu = get_cpu(package_count=2, cores_per_package=2, threads_per_core=2)

        allocator = FallbackCpuAllocator(CrashingAllocator(),
                                         IntegerProgramCpuAllocator())
        workloads = {}

        workloads[w_a.get_id()] = w_a
        request = AllocateThreadsRequest(cpu, w_a.get_id(), workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.assign_threads(request).get_cpu()

        workloads[w_b.get_id()] = w_b
        request = AllocateThreadsRequest(cpu, w_b.get_id(), workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.assign_threads(request).get_cpu()

        request = AllocateThreadsRequest(cpu, "a", workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.free_threads(request).get_cpu()
        workloads.pop("a")

        workloads[w_c.get_id()] = w_c
        request = AllocateThreadsRequest(cpu, w_c.get_id(), workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.assign_threads(request).get_cpu()

        request = AllocateThreadsRequest(cpu, "b", workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.free_threads(request).get_cpu()
        workloads.pop("b")

        workloads[w_d.get_id()] = w_d
        request = AllocateThreadsRequest(cpu, w_d.get_id(), workloads, {},
                                         DEFAULT_TEST_REQUEST_METADATA)
        cpu = allocator.assign_threads(request).get_cpu()

        self.assertEqual(3, len(cpu.get_claimed_threads()))
        self.assertEqual(6, allocator.get_fallback_allocator_calls_count())
    def test_no_cross_packages_placement_no_bad_affinity_ip(self):
        w_a = get_test_workload("a", 3, STATIC)
        w_b = get_test_workload("b", 2, STATIC)
        w_c = get_test_workload("c", 1, STATIC)
        w_d = get_test_workload("d", 2, STATIC)

        cpu = get_cpu(package_count=2, cores_per_package=2, threads_per_core=2)

        workload_manager = WorkloadManager(cpu, MockCgroupManager(),
                                           IntegerProgramCpuAllocator())
        workload_manager.add_workload(w_a)
        workload_manager.add_workload(w_b)
        workload_manager.add_workload(w_c)
        workload_manager.add_workload(w_d)

        self.assertEqual(
            0, len(get_cross_package_violations(workload_manager.get_cpu())))
        self.assertEqual(0,
                         len(workload_manager.get_cpu().get_empty_threads()))
Ejemplo n.º 21
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)
        """
        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 = AllocateThreadsRequest(cpu, w0.get_id(),
                                              {w0.get_id(): w0}, {},
                                              DEFAULT_TEST_REQUEST_METADATA)
            cpu = allocator.assign_threads(request0).get_cpu()

            request1 = AllocateThreadsRequest(cpu, w1.get_id(), {
                w0.get_id(): w0,
                w1.get_id(): w1
            }, {}, DEFAULT_TEST_REQUEST_METADATA)
            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])))
                # assigned threads should be on different coreds
                core_ids = [e[1] for e in r]
                self.assertEqual(len(set(core_ids)), len(core_ids))
 def __assign_workload(cpu, workload):
     request = get_no_usage_threads_request(cpu, [workload])
     return IntegerProgramCpuAllocator().assign_threads(request).get_cpu()
Ejemplo n.º 23
0
 def __assign_workload(cpu, workload):
     request = AllocateThreadsRequest(cpu, workload.get_id(),
                                      {workload.get_id(): workload}, {},
                                      DEFAULT_TEST_REQUEST_METADATA)
     return IntegerProgramCpuAllocator().assign_threads(request).get_cpu()
Ejemplo n.º 24
0
 def __get_default_workload_manager():
     cpu = get_cpu()
     return WorkloadManager(cpu, MockCgroupManager(),
                            IntegerProgramCpuAllocator())
Ejemplo n.º 25
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))
    OVERSUBSCRIBED_THREADS_KEY, STATIC_ALLOCATED_SIZE_KEY, BURST_ALLOCATED_SIZE_KEY, \
    BURST_REQUESTED_SIZE_KEY, ALLOCATED_SIZE_KEY, UNALLOCATED_SIZE_KEY
from titus_isolate.model.processor.config import get_cpu
from titus_isolate.model.processor.utils import DEFAULT_TOTAL_THREAD_COUNT, is_cpu_full
from titus_isolate.monitor.oversubscribe_free_thread_provider import OversubscribeFreeThreadProvider
from titus_isolate.utils import set_config_manager, set_workload_monitor_manager

config_logs(logging.DEBUG)
set_config_manager(ConfigManager(TestPropertyProvider({})))
set_workload_monitor_manager(TestWorkloadMonitorManager())

forecast_ip_alloc_simple = ForecastIPCpuAllocator(
    TestCpuUsagePredictorManager(), ConfigManager(TestPropertyProvider({})),
    OversubscribeFreeThreadProvider(DEFAULT_TOTAL_THRESHOLD))

LEGACY_ALLOCATORS = [IntegerProgramCpuAllocator(), GreedyCpuAllocator()]
OVERSUBSCRIBING_ALLOCATORS = [forecast_ip_alloc_simple]
ALLOCATORS = LEGACY_ALLOCATORS + OVERSUBSCRIBING_ALLOCATORS


class TestWorkloadManager(unittest.TestCase):
    def test_single_static_workload_lifecycle(self):
        for allocator in ALLOCATORS:
            thread_count = 2
            workload = get_test_workload(uuid.uuid4(), thread_count, STATIC)

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

            # Add workload
Ejemplo n.º 27
0
        self.pod = None

    def set_pod(self, pod: V1Pod):
        self.pod = pod

    def get_pod(self, pod_name: str) -> Optional[V1Pod]:
        return self.pod


forecast_ip_alloc_simple = ForecastIPCpuAllocator(
    TestCpuUsagePredictorManager(), ConfigManager(TestPropertyProvider({})),
    OversubscribeFreeThreadProvider(0.1))

ALLOCATORS = [
    NaiveCpuAllocator(),
    IntegerProgramCpuAllocator(),
    GreedyCpuAllocator(), forecast_ip_alloc_simple
]
OVER_ALLOCATORS = [NaiveCpuAllocator(), forecast_ip_alloc_simple]

set_workload_monitor_manager(TestWorkloadMonitorManager())


class TestCpu(unittest.TestCase):
    def test_assign_one_thread_empty_cpu(self):
        """
        Workload 0: 1 thread --> (p:0 c:0 t:0)
        """
        for allocator in ALLOCATORS:
            cpu = get_cpu()
            self.assertEqual(DEFAULT_TOTAL_THREAD_COUNT,