def __init__( self, cgroup_path: str, platform: Platform, resgroup: ResGroup = None, allocation_configuration: Optional[AllocationConfiguration] = None, event_names: List[MetricName] = None, enable_derived_metrics: bool = False, wss_reset_cycles: Optional[int] = None, wss_stable_cycles: int = 0, wss_membw_threshold: Optional[float] = None, perf_aggregate_cpus: bool = True, interval: int = 5, sched: Union[bool, Pattern] = False, ): self._cgroup_path = cgroup_path self._name = _sanitize_cgroup_path(self._cgroup_path) assert len(self._name) > 0, 'Container name cannot be empty string!' self._allocation_configuration = allocation_configuration self._platform = platform self._resgroup = resgroup self._event_names = event_names self._perf_aggregate_cpus = perf_aggregate_cpus self._sched = sched self._cgroup = cgroups.Cgroup( cgroup_path=self._cgroup_path, platform=platform, allocation_configuration=allocation_configuration) if wss_reset_cycles is not None: log.debug( 'Enable WSS measurments: interval=%s ' 'wss_reset_cycles=%s wss_stable_cycles=%s wss_membw_threshold=%s', interval, wss_reset_cycles, wss_stable_cycles, wss_membw_threshold) self.wss = wss.WSS( interval=interval, get_pids=self.get_pids, wss_reset_cycles=wss_reset_cycles, wss_stable_cycles=wss_stable_cycles, wss_membw_threshold=wss_membw_threshold, ) else: self.wss = None self._perf_counters = None if self._event_names: self._perf_counters = perf.PerfCounters( self._cgroup_path, event_names=event_names, platform=platform, aggregate_for_all_cpus_with_sum=self._perf_aggregate_cpus, ) self._derived_metrics_generator = None if enable_derived_metrics: self._derived_metrics_generator = \ PerfCgroupDerivedMetricsGenerator(self._get_measurements)
def __init__(self, cgroup_path: str, platform_cpus: int, platform_sockets: int, rdt_information: Optional[RDTInformation], resgroup: ResGroup = None, allocation_configuration: Optional[AllocationConfiguration] = None, event_names: List[str] = None, enable_derived_metrics: bool = False): self._cgroup_path = cgroup_path self._name = _sanitize_cgroup_path(self._cgroup_path) assert len(self._name) > 0, 'Container name cannot be empty string!' self._allocation_configuration = allocation_configuration self._rdt_information = rdt_information self._resgroup = resgroup self._event_names = event_names self._cgroup = cgroups.Cgroup( cgroup_path=self._cgroup_path, platform_cpus=platform_cpus, platform_sockets=platform_sockets, allocation_configuration=allocation_configuration) self._derived_metrics_generator = None if self._event_names: self._perf_counters = perf.PerfCounters(self._cgroup_path, event_names=event_names) if enable_derived_metrics: self._derived_metrics_generator = DerivedMetricsGenerator( event_names, self._perf_counters.get_measurements)
def test_read_metrics(_open_mock, _get_cgroup_fd_mock): prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES]) assert prf.get_measurements() == { metrics.MetricName.CYCLES: 0, metrics.MetricName.SCALING_FACTOR_AVG: 0, metrics.MetricName.SCALING_FACTOR_MAX: 0 }
def test_reset_and_enable_group_event_leaders_enable_fail( _open_mock, _get_cgroup_fd_mock, ioctl_mock): prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES]) # cpu0 group event leader mock prf._group_event_leader_files = {0: Mock()} with pytest.raises(OSError, match="Cannot enable perf counts"): prf._reset_and_enable_group_event_leaders()
def test_reset_and_enable_group_event_leaders(_open_mock, _get_cgroup_fd_mock, ioctl_mock): platform_mock = Mock(Spec=Platform, cpu_model='intel xeon', cpu_codename=CPUCodeName.SKYLAKE) prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES], platform_mock) # cpu0 group event leader mock prf._group_event_leader_files = {0: Mock()} prf._reset_and_enable_group_event_leaders() ioctl_mock.assert_has_calls([mock.ANY] * 2)
def test_reset_and_enable_group_event_leaders(_open_mock, _get_cgroup_fd_mock, ioctl_mock): prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES]) # cpu0 group event leader mock prf._group_event_leader_files = {0: Mock()} prf._reset_and_enable_group_event_leaders() ioctl_mock.assert_has_calls([mock.ANY] * 2)
def test_open_for_cpu_wrong_arg(_open_mock, _get_cgroup_fd_mock): platform_mock = Mock(Spec=Platform, cpu_model='intel xeon', cpu_codename=CPUCodeName.SKYLAKE) prf = perf.PerfCounters('/mycgroup', [], platform_mock) # let's check non-existent type of measurement with pytest.raises(Exception, match='Unknown event name'): prf._open_for_cpu(0, 'invalid_event_name')
def test_reset_and_enable_group_event_leaders_enable_fail( _open_mock, _get_cgroup_fd_mock, ioctl_mock ): platform_mock = Mock(Spec=Platform, cpu_model='intel xeon', cpu_codename=CPUCodeName.SKYLAKE) prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES], platform_mock) # cpu0 group event leader mock prf._group_event_leader_files = {0: Mock()} with pytest.raises(OSError, match="Cannot enable perf counts"): prf._reset_and_enable_group_event_leaders()
def test_perf_counters_init(_open_mock, _get_cgroup_fd_mock): platform_mock = Mock(Spec=Platform, cpu_model='intel xeon', cpu_codename=CPUCodeName.SKYLAKE) prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.TASK_CYCLES], platform_mock) assert prf._group_event_leader_files == {} _get_cgroup_fd_mock.assert_called_once() _open_mock.assert_called_once()
def test_read_metrics_aggregated(*args): platform_mock = Mock(Spec=Platform, cpu_model='intel xeon', cpu_codename=CPUCodeName.SKYLAKE) prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.TASK_CYCLES], platform_mock, aggregate_for_all_cpus_with_sum=True) prf._group_event_leader_files[0] = {0: mock_open()} assert prf.get_measurements() == {metrics.MetricName.TASK_CYCLES: 2, metrics.MetricName.TASK_INSTRUCTIONS: 4, metrics.MetricName.TASK_SCALING_FACTOR_AVG: 2, metrics.MetricName.TASK_SCALING_FACTOR_MAX: 3}
def test_cleanup(_open_mock, _get_cgroup_fd_mock, os_close_mock): platform_mock = Mock(Spec=Platform, cpu_model='intel xeon', cpu_codename=CPUCodeName.SKYLAKE) prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES], platform_mock) file_descriptor_mock = Mock() file_descriptor_mock.close = Mock() prf._group_event_leader_files = {'mock1': file_descriptor_mock, 'mock2': file_descriptor_mock} prf._event_files = [file_descriptor_mock] * 3 prf.cleanup() os_close_mock.assert_called_once_with(10) file_descriptor_mock.close.assert_has_calls( [mock.call()] * (len(prf._event_files) + len(prf._group_event_leader_files)))
def __init__( self, cgroup_path: str, platform: Platform, resgroup: ResGroup = None, allocation_configuration: Optional[AllocationConfiguration] = None, event_names: List[MetricName] = None, enable_derived_metrics: bool = False, wss_reset_interval: int = 0, wss_stable_duration: int = 30, wss_threshold_divider: int = 100, perf_aggregate_cpus: bool = True, interval: int = 5): self._cgroup_path = cgroup_path self._name = _sanitize_cgroup_path(self._cgroup_path) assert len(self._name) > 0, 'Container name cannot be empty string!' self._allocation_configuration = allocation_configuration self._platform = platform self._resgroup = resgroup self._event_names = event_names self._perf_aggregate_cpus = perf_aggregate_cpus self.parent_measurements = None self._cgroup = cgroups.Cgroup( cgroup_path=self._cgroup_path, platform=platform, allocation_configuration=allocation_configuration) if wss_reset_interval != 0: self.wss = wss.WSS( interval=interval, get_pids=self.get_pids, wss_reset_interval=wss_reset_interval, wss_stable_duration=wss_stable_duration, wss_threshold_divider=wss_threshold_divider, ) else: self.wss = None self._perf_counters = None if self._event_names: self._perf_counters = perf.PerfCounters( self._cgroup_path, event_names=event_names, platform=platform, aggregate_for_all_cpus_with_sum=self._perf_aggregate_cpus, ) self._derived_metrics_generator = None if enable_derived_metrics: self._derived_metrics_generator = \ PerfCgroupDerivedMetricsGenerator(self._get_measurements)
def test_open_for_cpu(_open_mock, _get_cgroup_fd_mock, _perf_event_open_mock, fdopen_mock): prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES]) prf._open_for_cpu(0, metrics.MetricName.CYCLES) assert prf._group_event_leader_files == {0: mock.ANY} assert prf._event_files == [] # perf_event_open call for the event group leader _perf_event_open_mock.assert_called_once_with(perf_event_attr=mock.ANY, pid=10, cpu=0, group_fd=-1, flags=pc.PERF_FLAG_PID_CGROUP | pc.PERF_FLAG_FD_CLOEXEC) fdopen_mock.assert_called_once_with(5, 'rb')
def test_cleanup(_open_mock, _get_cgroup_fd_mock, os_close_mock): prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES]) file_descriptor_mock = Mock() file_descriptor_mock.close = Mock() prf._group_event_leader_files = { 'mock1': file_descriptor_mock, 'mock2': file_descriptor_mock } prf._event_files = [file_descriptor_mock] * 3 prf.cleanup() os_close_mock.assert_called_once_with(10) file_descriptor_mock.close.assert_has_calls( [mock.call()] * (len(prf._event_files) + len(prf._group_event_leader_files)))
def test_open_for_cpu(_open_mock, _get_cgroup_fd_mock, _perf_event_open_mock, fdopen_mock): platform_mock = Mock(Spec=Platform, cpu_model='intel xeon', cpu_codename=CPUCodeName.SKYLAKE) prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES], platform_mock) prf._open_for_cpu(0, metrics.MetricName.CYCLES) assert prf._group_event_leader_files == {0: mock.ANY} assert prf._event_files == [] # perf_event_open call for the event group leader _perf_event_open_mock.assert_called_once_with( perf_event_attr=mock.ANY, pid=10, cpu=0, group_fd=-1, flags=pc.PERF_FLAG_PID_CGROUP | pc.PERF_FLAG_FD_CLOEXEC ) fdopen_mock.assert_called_once_with(5, 'rb')
def test_open_for_cpu_with_existing_event_group_leader(_open_mock, _get_cgroup_fd_mock, _perf_event_open_mock, fdopen_mock): prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES]) # Create event group leader prf._open_for_cpu(0, metrics.MetricName.CYCLES) # Create non leading event prf._open_for_cpu(0, metrics.MetricName.INSTRUCTIONS) assert prf._group_event_leader_files[0].fileno() == 5 assert prf._event_files[0].fileno() == 6 # perf_event_open call for non leading event _perf_event_open_mock.assert_called_with(perf_event_attr=mock.ANY, pid=-1, cpu=0, group_fd=5, flags=pc.PERF_FLAG_FD_CLOEXEC)
def test_open_for_cpu_with_existing_event_group_leader(_open_mock, _get_cgroup_fd_mock, _perf_event_open_mock, fdopen_mock): platform_mock = Mock(Spec=Platform, cpu_model='intel xeon', cpu_codename=CPUCodeName.SKYLAKE) prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.TASK_CYCLES], platform_mock) # Create event group leader prf._open_for_cpu(0, metrics.MetricName.TASK_CYCLES) # Create non leading event prf._open_for_cpu(0, metrics.MetricName.TASK_INSTRUCTIONS) assert prf._group_event_leader_files[0].fileno() == 5 assert prf._event_files[0].fileno() == 6 # perf_event_open call for non leading event _perf_event_open_mock.assert_called_with(perf_event_attr=mock.ANY, pid=-1, cpu=0, group_fd=5, flags=pc.PERF_FLAG_FD_CLOEXEC)
def test_open_for_cpu_wrong_arg(_open_mock, _get_cgroup_fd_mock): prf = perf.PerfCounters('/mycgroup', []) # let's check non-existent type of measurement with pytest.raises(Exception, match='unknown event name'): prf._open_for_cpu(0, 'invalid_event_name')
def test_read_events_zero_values_zero_cpus(_open_mock, _get_cgroup_fd_mock): prf = perf.PerfCounters('/mycgroup', []) prf._group_event_leaders = {} assert prf._read_events() == {}
def test_read_metrics(_open_mock, _get_cgroup_fd_mock): platform_mock = Mock(Spec=Platform, cpu_model='intel xeon', cpu_codename=CPUCodeName.SKYLAKE) prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES], platform_mock) assert prf.get_measurements() == {metrics.MetricName.CYCLES: 0, metrics.MetricName.SCALING_FACTOR_AVG: 0, metrics.MetricName.SCALING_FACTOR_MAX: 0}
def test_read_events_zero_values_one_cpu(_open_mock, _get_cgroup_fd_mock): prf = perf.PerfCounters('/mycgroup', []) # File descriptor mock for single cpu prf._group_event_leaders = {0: Mock()} assert prf._read_events() == {}
def test_read_events_zero_values_zero_cpus(_open_mock, _get_cgroup_fd_mock): platform_mock = Mock(Spec=Platform, cpu_codename=CPUCodeName.SKYLAKE) prf = perf.PerfCounters('/mycgroup', [], platform_mock) prf._group_event_leaders = {} assert prf._read_events() == {}
def test_read_events_zero_values_one_cpu(_open_mock, _get_cgroup_fd_mock): platform_mock = Mock(Spec=Platform, cpu_codename=CPUCodeName.SKYLAKE) prf = perf.PerfCounters('/mycgroup', [], platform_mock) # File descriptor mock for single cpu prf._group_event_leaders = {0: Mock()} assert prf._read_events() == {}
def test_perf_counters_init(_open_mock, _get_cgroup_fd_mock): prf = perf.PerfCounters('/mycgroup', [metrics.MetricName.CYCLES]) assert prf._group_event_leader_files == {} _get_cgroup_fd_mock.assert_called_once() _open_mock.assert_called_once()