def test_collect_memory(capsys, helpers, pcs_full, memory_collect_job, memory_collect_no_debug_job): """Test collecting the profile using the memory collector""" # Fixme: Add check that the profile was correctly generated before_object_count = helpers.count_contents_on_path( pcs_full.get_path())[0] head = vcs.get_minor_version_info(vcs.get_minor_head()) memory_collect_job += ([head], ) runner.run_single_job(*memory_collect_job) # Assert that nothing was removed after_object_count = helpers.count_contents_on_path(pcs_full.get_path())[0] assert before_object_count + 1 == after_object_count profiles = os.listdir(os.path.join(pcs_full.get_path(), 'jobs')) new_profile = profiles[0] assert len(profiles) == 1 assert new_profile.endswith(".perf") cmd, args, _, colls, posts, _ = memory_collect_job runner.run_single_job(cmd, args, ["hello"], colls, posts, [head], **{ 'no_func': 'fun', 'sampling': 0.1 }) profiles = os.listdir(os.path.join(pcs_full.get_path(), 'jobs')) new_smaller_profile = [p for p in profiles if p != new_profile][0] assert len(profiles) == 2 assert new_smaller_profile.endswith(".perf") # Assert that nothing was removed after_second_object_count = helpers.count_contents_on_path( pcs_full.get_path())[0] assert after_object_count + 1 == after_second_object_count # Fixme: Add check that the profile was correctly generated memory_collect_no_debug_job += ([head], ) runner.run_single_job(*memory_collect_no_debug_job) last_object_count = helpers.count_contents_on_path(pcs_full.get_path())[0] _, err = capsys.readouterr() assert after_second_object_count == last_object_count assert 'debug info' in err target_bin = memory_collect_job[0][0] collector_unit = Unit('memory', {'all': False, 'no_func': 'main'}) job = Job('memory', [], str(target_bin), '', '') _, prof = runner.run_collector(collector_unit, job) assert len(list(query.all_resources_of(prof))) == 2 collector_unit = Unit('memory', { 'all': False, 'no_source': 'memory_collect_test.c' }) job = Job('memory', [], str(target_bin), '', '') _, prof = runner.run_collector(collector_unit, job) assert len(list(query.all_resources_of(prof))) == 0
def generic_profile_provider(profile, of_key, per_key, **_): """Data provider for trace collector profiling output. :param dict profile: the trace profile dictionary :param str of_key: key for which we are finding the model :param str per_key: key of the independent variable :param dict _: rest of the key arguments :returns generator: each subsequent call returns tuple: x points list, y points list, function name """ # Get the file resources contents resources = list(map(itemgetter(1), query.all_resources_of(profile))) # Sort the dictionaries by function name for easier traversing resources = sorted(resources, key=resource_sort_key) x_points_list = [] y_points_list = [] function_name = convert.flatten(resources[0]['uid']) # Store all the points until the function name changes for resource in resources: if convert.flatten(resource['uid']) != function_name: if x_points_list: # Function name changed, yield the list of data points yield x_points_list, y_points_list, function_name x_points_list = [resource[per_key]] y_points_list = [resource[of_key]] function_name = convert.flatten(resource['uid']) else: # Add the data points x_points_list.append(resource[per_key]) y_points_list.append(resource[of_key]) # End of resources, yield the current lists if x_points_list: yield x_points_list, y_points_list, function_name
def test_memory_prof_resources_empty(query_profiles): """Test 'all_resources_of' on memory profile that has none. Expected 0 resources. """ # Acquire the memory query profile with empty resources mem_profile = profile_filter(query_profiles, 'memory-empty-resources.perf') assert mem_profile is not None # Get all resource fields of the memory profile resources = list(query.all_resources_of(mem_profile)) assert not resources
def test_resources_corrupted(query_profiles): """Test 'all_resources_of' on corrupted profiles. Expected IncorrectProfileFormatException-s. """ # Acquire the query profile with corrupted global section corrupted_profile = profile_filter(query_profiles, 'corrupted-global.perf') assert corrupted_profile is not None # Get all resources in profile that has corrupted global structure with pytest.raises(exceptions.IncorrectProfileFormatException): list(query.all_resources_of(corrupted_profile)) # Acquire the query profile with corrupted global section corrupted_profile = profile_filter(query_profiles, 'corrupted-snapshots.perf') assert corrupted_profile is not None # Get all resources in profile that has corrupted snapshots structure with pytest.raises(exceptions.IncorrectProfileFormatException): list(query.all_resources_of(corrupted_profile))
def test_memory_prof_resources(query_profiles): """Test 'all_resources_of' on memory profile that has some. Expected _MEMORY_RESOURCES_COUNT resources. """ # Acquire the memory query profile mem_profile = profile_filter(query_profiles, 'memory-2017-08-25-16-03-47.perf') assert mem_profile is not None # Get all resource fields of the memory profile resources = list(query.all_resources_of(mem_profile)) assert len(resources) == _MEMORY_RESOURCES_COUNT
def test_complexity_prof_resources_empty(query_profiles): """Test 'all_resources_of' on complexity profile that has none. Expected 0 resources. """ # Acquire the complexity query profile with empty resources complexity_profile = profile_filter(query_profiles, 'complexity-empty-resources.perf') assert complexity_profile is not None # Get all resource fields of the complexity profile resources = list(query.all_resources_of(complexity_profile)) assert not resources
def test_complexity_prof_resources(query_profiles): """Test 'all_resources_of' on complexity profile that has some. Expected _COMPLEXITY_RESOURCES_COUNT resources. """ # Acquire the complexity query profile complexity_profile = profile_filter(query_profiles, 'complexity-2017-08-25-19-19-16.perf') assert complexity_profile is not None # Get all resource fields of the complexity profile resources = list(query.all_resources_of(complexity_profile)) assert len(resources) == _COMPLEXITY_RESOURCES_COUNT
def get_malloced_resources(profile): """Helper function for getting resources that were allocated by malloc :param dict profile: dictionary with resources :return: list of resources allocated by malloc """ resources = list( map(operator.itemgetter(1), query.all_resources_of(profile))) resources.sort(key=clusterizer.resource_sort_key) malloced = [] for group, members in itertools.groupby(resources, clusterizer.resource_group_key): if group[1] == 'malloc': malloced.extend(list(members)) return malloced
def resources_to_pandas_dataframe(profile): """Converts the profile (w.r.t :ref:`profile-spec`) to format supported by `pandas`_ library. Queries through all of the resources in the `profile`, and flattens each key and value to the tabular representation. Refer to `pandas`_ libray for more possibilities how to work with the tabular representation of collected resources. E.g. given `time` and `memory` profiles ``tprof`` and ``mprof`` respectively, one can obtain the following formats:: >>> convert.resources_to_pandas_dataframe(tprof) amount snapshots uid 0 0.616s 0 real 1 0.500s 0 user 2 0.125s 0 sys >>> convert.resources_to_pandas_dataframe(mmprof) address amount snapshots subtype trace type 0 19284560 4 0 malloc malloc:unreachabl... memory 1 19284560 0 0 free free:unreachable:... memory uid uid:function uid:line uid:source 0 main:../memo...:22 main 22 ../memory_collect_test.c 1 main:../memo...:27 main 27 ../memory_collect_test.c :param dict profile: dictionary with profile w.r.t. :ref:`profile-spec` :returns: converted profile to ``pandas.DataFramelist`` with resources flattened as a pandas dataframe """ resource_keys = list(query.all_resource_fields_of(profile)) values = {key: [] for key in resource_keys} values['snapshots'] = [] for (snapshot, resource) in query.all_resources_of(profile): values['snapshots'].append(snapshot) flattened_resource = dict(list(query.all_items_of(resource))) for resource_key in resource_keys: values[resource_key].append( flattened_resource.get(resource_key, numpy.nan)) return pandas.DataFrame(values)
def postprocess(profile, strategy, **kwargs): """Takes the given profile and according to the set strategy computes clusters of resources All of the resources are first sorted according to their uid and amounts. Then they are group according to their uid and for each group we compute the clusters in isolation :param dict profile: performance profile that will be clusterized :param str strategy: name of the used strategy (one of clustering.SUPPORTED_STRATEGIES :param kwargs: :return: """ # Flatten the resources to sorted list of resources resources = list( map(operator.itemgetter(1), query.all_resources_of(profile))) resources.sort(key=resource_sort_key) # For debug purposes, print the results if log.is_verbose_enough(log.VERBOSE_INFO): print_groups(resources) # Call the concrete strategy, for each group of resources groups = itertools.groupby(resources, resource_group_key) for group, members in groups: log.info("clusterizing group {}{}@{}".format( group[0], "({})".format(group[1]) if group[1] else "", group[2])) utils.dynamic_module_function_call('perun.postprocess.clusterizer', strategy, 'clusterize', list(members), **kwargs) # For debug purposes, print the results if log.is_verbose_enough(log.VERBOSE_INFO): print_groups(resources) # Return that everything is ok return PostprocessStatus.OK, "Sucessfully clusterized the profile", dict( kwargs)
def test_all_items_of_memory_resources(query_profiles): """Test 'all_items_of' on profile with resources. Expected _MEMORY_RESOURCE_ITEMS_COUNT items and content match. """ # Acquire the memory query profile mem_profile = profile_filter(query_profiles, 'memory-2017-08-25-16-03-47.perf') assert mem_profile is not None # Get the first resource in the profile _, resources = next(query.all_resources_of(mem_profile)) items = list(query.all_items_of(resources)) # Sort the resources and flattened key to allow comparison items.sort() items[_MEMORY_TRACE_IDX] = (items[_MEMORY_TRACE_IDX][0], sort_flattened_structure( items[_MEMORY_TRACE_IDX][1])) items[_MEMORY_UID_IDX] = (items[_MEMORY_UID_IDX][0], sort_flattened_structure( items[_MEMORY_UID_IDX][1])) # TODO: compare assert len(items) == _MEMORY_RESOURCE_ITEMS_COUNT