18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/compiler.h> 38c2ecf20Sopenharmony_ci#include <string.h> 48c2ecf20Sopenharmony_ci#include <perf/cpumap.h> 58c2ecf20Sopenharmony_ci#include <perf/evlist.h> 68c2ecf20Sopenharmony_ci#include "metricgroup.h" 78c2ecf20Sopenharmony_ci#include "tests.h" 88c2ecf20Sopenharmony_ci#include "pmu-events/pmu-events.h" 98c2ecf20Sopenharmony_ci#include "evlist.h" 108c2ecf20Sopenharmony_ci#include "rblist.h" 118c2ecf20Sopenharmony_ci#include "debug.h" 128c2ecf20Sopenharmony_ci#include "expr.h" 138c2ecf20Sopenharmony_ci#include "stat.h" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistatic struct pmu_event pme_test[] = { 168c2ecf20Sopenharmony_ci{ 178c2ecf20Sopenharmony_ci .metric_expr = "inst_retired.any / cpu_clk_unhalted.thread", 188c2ecf20Sopenharmony_ci .metric_name = "IPC", 198c2ecf20Sopenharmony_ci .metric_group = "group1", 208c2ecf20Sopenharmony_ci}, 218c2ecf20Sopenharmony_ci{ 228c2ecf20Sopenharmony_ci .metric_expr = "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalted.thread / 2 ) * " 238c2ecf20Sopenharmony_ci "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk ) )))", 248c2ecf20Sopenharmony_ci .metric_name = "Frontend_Bound_SMT", 258c2ecf20Sopenharmony_ci}, 268c2ecf20Sopenharmony_ci{ 278c2ecf20Sopenharmony_ci .metric_expr = "l1d\\-loads\\-misses / inst_retired.any", 288c2ecf20Sopenharmony_ci .metric_name = "dcache_miss_cpi", 298c2ecf20Sopenharmony_ci}, 308c2ecf20Sopenharmony_ci{ 318c2ecf20Sopenharmony_ci .metric_expr = "l1i\\-loads\\-misses / inst_retired.any", 328c2ecf20Sopenharmony_ci .metric_name = "icache_miss_cycles", 338c2ecf20Sopenharmony_ci}, 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci .metric_expr = "(dcache_miss_cpi + icache_miss_cycles)", 368c2ecf20Sopenharmony_ci .metric_name = "cache_miss_cycles", 378c2ecf20Sopenharmony_ci .metric_group = "group1", 388c2ecf20Sopenharmony_ci}, 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci .metric_expr = "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hit", 418c2ecf20Sopenharmony_ci .metric_name = "DCache_L2_All_Hits", 428c2ecf20Sopenharmony_ci}, 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci .metric_expr = "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + " 458c2ecf20Sopenharmony_ci "l2_rqsts.pf_miss + l2_rqsts.rfo_miss", 468c2ecf20Sopenharmony_ci .metric_name = "DCache_L2_All_Miss", 478c2ecf20Sopenharmony_ci}, 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci .metric_expr = "dcache_l2_all_hits + dcache_l2_all_miss", 508c2ecf20Sopenharmony_ci .metric_name = "DCache_L2_All", 518c2ecf20Sopenharmony_ci}, 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci .metric_expr = "d_ratio(dcache_l2_all_hits, dcache_l2_all)", 548c2ecf20Sopenharmony_ci .metric_name = "DCache_L2_Hits", 558c2ecf20Sopenharmony_ci}, 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci .metric_expr = "d_ratio(dcache_l2_all_miss, dcache_l2_all)", 588c2ecf20Sopenharmony_ci .metric_name = "DCache_L2_Misses", 598c2ecf20Sopenharmony_ci}, 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci .metric_expr = "ipc + m2", 628c2ecf20Sopenharmony_ci .metric_name = "M1", 638c2ecf20Sopenharmony_ci}, 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci .metric_expr = "ipc + m1", 668c2ecf20Sopenharmony_ci .metric_name = "M2", 678c2ecf20Sopenharmony_ci}, 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci .metric_expr = "1/m3", 708c2ecf20Sopenharmony_ci .metric_name = "M3", 718c2ecf20Sopenharmony_ci}, 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci .name = NULL, 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci}; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic struct pmu_events_map map = { 788c2ecf20Sopenharmony_ci .cpuid = "test", 798c2ecf20Sopenharmony_ci .version = "1", 808c2ecf20Sopenharmony_ci .type = "core", 818c2ecf20Sopenharmony_ci .table = pme_test, 828c2ecf20Sopenharmony_ci}; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistruct value { 858c2ecf20Sopenharmony_ci const char *event; 868c2ecf20Sopenharmony_ci u64 val; 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic u64 find_value(const char *name, struct value *values) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci struct value *v = values; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci while (v->event) { 948c2ecf20Sopenharmony_ci if (!strcmp(name, v->event)) 958c2ecf20Sopenharmony_ci return v->val; 968c2ecf20Sopenharmony_ci v++; 978c2ecf20Sopenharmony_ci }; 988c2ecf20Sopenharmony_ci return 0; 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistatic void load_runtime_stat(struct runtime_stat *st, struct evlist *evlist, 1028c2ecf20Sopenharmony_ci struct value *vals) 1038c2ecf20Sopenharmony_ci{ 1048c2ecf20Sopenharmony_ci struct evsel *evsel; 1058c2ecf20Sopenharmony_ci u64 count; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci evlist__for_each_entry(evlist, evsel) { 1088c2ecf20Sopenharmony_ci count = find_value(evsel->name, vals); 1098c2ecf20Sopenharmony_ci perf_stat__update_shadow_stats(evsel, count, 0, st); 1108c2ecf20Sopenharmony_ci } 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistatic double compute_single(struct rblist *metric_events, struct evlist *evlist, 1148c2ecf20Sopenharmony_ci struct runtime_stat *st, const char *name) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci struct metric_expr *mexp; 1178c2ecf20Sopenharmony_ci struct metric_event *me; 1188c2ecf20Sopenharmony_ci struct evsel *evsel; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci evlist__for_each_entry(evlist, evsel) { 1218c2ecf20Sopenharmony_ci me = metricgroup__lookup(metric_events, evsel, false); 1228c2ecf20Sopenharmony_ci if (me != NULL) { 1238c2ecf20Sopenharmony_ci list_for_each_entry (mexp, &me->head, nd) { 1248c2ecf20Sopenharmony_ci if (strcmp(mexp->metric_name, name)) 1258c2ecf20Sopenharmony_ci continue; 1268c2ecf20Sopenharmony_ci return test_generic_metric(mexp, 0, st); 1278c2ecf20Sopenharmony_ci } 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci } 1308c2ecf20Sopenharmony_ci return 0.; 1318c2ecf20Sopenharmony_ci} 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistatic int __compute_metric(const char *name, struct value *vals, 1348c2ecf20Sopenharmony_ci const char *name1, double *ratio1, 1358c2ecf20Sopenharmony_ci const char *name2, double *ratio2) 1368c2ecf20Sopenharmony_ci{ 1378c2ecf20Sopenharmony_ci struct rblist metric_events = { 1388c2ecf20Sopenharmony_ci .nr_entries = 0, 1398c2ecf20Sopenharmony_ci }; 1408c2ecf20Sopenharmony_ci struct perf_cpu_map *cpus; 1418c2ecf20Sopenharmony_ci struct runtime_stat st; 1428c2ecf20Sopenharmony_ci struct evlist *evlist; 1438c2ecf20Sopenharmony_ci int err; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci /* 1468c2ecf20Sopenharmony_ci * We need to prepare evlist for stat mode running on CPU 0 1478c2ecf20Sopenharmony_ci * because that's where all the stats are going to be created. 1488c2ecf20Sopenharmony_ci */ 1498c2ecf20Sopenharmony_ci evlist = evlist__new(); 1508c2ecf20Sopenharmony_ci if (!evlist) 1518c2ecf20Sopenharmony_ci return -ENOMEM; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci cpus = perf_cpu_map__new("0"); 1548c2ecf20Sopenharmony_ci if (!cpus) { 1558c2ecf20Sopenharmony_ci evlist__delete(evlist); 1568c2ecf20Sopenharmony_ci return -ENOMEM; 1578c2ecf20Sopenharmony_ci } 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci perf_evlist__set_maps(&evlist->core, cpus, NULL); 1608c2ecf20Sopenharmony_ci runtime_stat__init(&st); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci /* Parse the metric into metric_events list. */ 1638c2ecf20Sopenharmony_ci err = metricgroup__parse_groups_test(evlist, &map, name, 1648c2ecf20Sopenharmony_ci false, false, 1658c2ecf20Sopenharmony_ci &metric_events); 1668c2ecf20Sopenharmony_ci if (err) 1678c2ecf20Sopenharmony_ci goto out; 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci err = perf_evlist__alloc_stats(evlist, false); 1708c2ecf20Sopenharmony_ci if (err) 1718c2ecf20Sopenharmony_ci goto out; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci /* Load the runtime stats with given numbers for events. */ 1748c2ecf20Sopenharmony_ci load_runtime_stat(&st, evlist, vals); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci /* And execute the metric */ 1778c2ecf20Sopenharmony_ci if (name1 && ratio1) 1788c2ecf20Sopenharmony_ci *ratio1 = compute_single(&metric_events, evlist, &st, name1); 1798c2ecf20Sopenharmony_ci if (name2 && ratio2) 1808c2ecf20Sopenharmony_ci *ratio2 = compute_single(&metric_events, evlist, &st, name2); 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ciout: 1838c2ecf20Sopenharmony_ci /* ... clenup. */ 1848c2ecf20Sopenharmony_ci metricgroup__rblist_exit(&metric_events); 1858c2ecf20Sopenharmony_ci runtime_stat__exit(&st); 1868c2ecf20Sopenharmony_ci perf_evlist__free_stats(evlist); 1878c2ecf20Sopenharmony_ci perf_cpu_map__put(cpus); 1888c2ecf20Sopenharmony_ci evlist__delete(evlist); 1898c2ecf20Sopenharmony_ci return err; 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic int compute_metric(const char *name, struct value *vals, double *ratio) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci return __compute_metric(name, vals, name, ratio, NULL, NULL); 1958c2ecf20Sopenharmony_ci} 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_cistatic int compute_metric_group(const char *name, struct value *vals, 1988c2ecf20Sopenharmony_ci const char *name1, double *ratio1, 1998c2ecf20Sopenharmony_ci const char *name2, double *ratio2) 2008c2ecf20Sopenharmony_ci{ 2018c2ecf20Sopenharmony_ci return __compute_metric(name, vals, name1, ratio1, name2, ratio2); 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic int test_ipc(void) 2058c2ecf20Sopenharmony_ci{ 2068c2ecf20Sopenharmony_ci double ratio; 2078c2ecf20Sopenharmony_ci struct value vals[] = { 2088c2ecf20Sopenharmony_ci { .event = "inst_retired.any", .val = 300 }, 2098c2ecf20Sopenharmony_ci { .event = "cpu_clk_unhalted.thread", .val = 200 }, 2108c2ecf20Sopenharmony_ci { .event = NULL, }, 2118c2ecf20Sopenharmony_ci }; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("failed to compute metric", 2148c2ecf20Sopenharmony_ci compute_metric("IPC", vals, &ratio) == 0); 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("IPC failed, wrong ratio", 2178c2ecf20Sopenharmony_ci ratio == 1.5); 2188c2ecf20Sopenharmony_ci return 0; 2198c2ecf20Sopenharmony_ci} 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_cistatic int test_frontend(void) 2228c2ecf20Sopenharmony_ci{ 2238c2ecf20Sopenharmony_ci double ratio; 2248c2ecf20Sopenharmony_ci struct value vals[] = { 2258c2ecf20Sopenharmony_ci { .event = "idq_uops_not_delivered.core", .val = 300 }, 2268c2ecf20Sopenharmony_ci { .event = "cpu_clk_unhalted.thread", .val = 200 }, 2278c2ecf20Sopenharmony_ci { .event = "cpu_clk_unhalted.one_thread_active", .val = 400 }, 2288c2ecf20Sopenharmony_ci { .event = "cpu_clk_unhalted.ref_xclk", .val = 600 }, 2298c2ecf20Sopenharmony_ci { .event = NULL, }, 2308c2ecf20Sopenharmony_ci }; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("failed to compute metric", 2338c2ecf20Sopenharmony_ci compute_metric("Frontend_Bound_SMT", vals, &ratio) == 0); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("Frontend_Bound_SMT failed, wrong ratio", 2368c2ecf20Sopenharmony_ci ratio == 0.45); 2378c2ecf20Sopenharmony_ci return 0; 2388c2ecf20Sopenharmony_ci} 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cistatic int test_cache_miss_cycles(void) 2418c2ecf20Sopenharmony_ci{ 2428c2ecf20Sopenharmony_ci double ratio; 2438c2ecf20Sopenharmony_ci struct value vals[] = { 2448c2ecf20Sopenharmony_ci { .event = "l1d-loads-misses", .val = 300 }, 2458c2ecf20Sopenharmony_ci { .event = "l1i-loads-misses", .val = 200 }, 2468c2ecf20Sopenharmony_ci { .event = "inst_retired.any", .val = 400 }, 2478c2ecf20Sopenharmony_ci { .event = NULL, }, 2488c2ecf20Sopenharmony_ci }; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("failed to compute metric", 2518c2ecf20Sopenharmony_ci compute_metric("cache_miss_cycles", vals, &ratio) == 0); 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("cache_miss_cycles failed, wrong ratio", 2548c2ecf20Sopenharmony_ci ratio == 1.25); 2558c2ecf20Sopenharmony_ci return 0; 2568c2ecf20Sopenharmony_ci} 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci/* 2608c2ecf20Sopenharmony_ci * DCache_L2_All_Hits = l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hi 2618c2ecf20Sopenharmony_ci * DCache_L2_All_Miss = max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + 2628c2ecf20Sopenharmony_ci * l2_rqsts.pf_miss + l2_rqsts.rfo_miss 2638c2ecf20Sopenharmony_ci * DCache_L2_All = dcache_l2_all_hits + dcache_l2_all_miss 2648c2ecf20Sopenharmony_ci * DCache_L2_Hits = d_ratio(dcache_l2_all_hits, dcache_l2_all) 2658c2ecf20Sopenharmony_ci * DCache_L2_Misses = d_ratio(dcache_l2_all_miss, dcache_l2_all) 2668c2ecf20Sopenharmony_ci * 2678c2ecf20Sopenharmony_ci * l2_rqsts.demand_data_rd_hit = 100 2688c2ecf20Sopenharmony_ci * l2_rqsts.pf_hit = 200 2698c2ecf20Sopenharmony_ci * l2_rqsts.rfo_hi = 300 2708c2ecf20Sopenharmony_ci * l2_rqsts.all_demand_data_rd = 400 2718c2ecf20Sopenharmony_ci * l2_rqsts.pf_miss = 500 2728c2ecf20Sopenharmony_ci * l2_rqsts.rfo_miss = 600 2738c2ecf20Sopenharmony_ci * 2748c2ecf20Sopenharmony_ci * DCache_L2_All_Hits = 600 2758c2ecf20Sopenharmony_ci * DCache_L2_All_Miss = MAX(400 - 100, 0) + 500 + 600 = 1400 2768c2ecf20Sopenharmony_ci * DCache_L2_All = 600 + 1400 = 2000 2778c2ecf20Sopenharmony_ci * DCache_L2_Hits = 600 / 2000 = 0.3 2788c2ecf20Sopenharmony_ci * DCache_L2_Misses = 1400 / 2000 = 0.7 2798c2ecf20Sopenharmony_ci */ 2808c2ecf20Sopenharmony_cistatic int test_dcache_l2(void) 2818c2ecf20Sopenharmony_ci{ 2828c2ecf20Sopenharmony_ci double ratio; 2838c2ecf20Sopenharmony_ci struct value vals[] = { 2848c2ecf20Sopenharmony_ci { .event = "l2_rqsts.demand_data_rd_hit", .val = 100 }, 2858c2ecf20Sopenharmony_ci { .event = "l2_rqsts.pf_hit", .val = 200 }, 2868c2ecf20Sopenharmony_ci { .event = "l2_rqsts.rfo_hit", .val = 300 }, 2878c2ecf20Sopenharmony_ci { .event = "l2_rqsts.all_demand_data_rd", .val = 400 }, 2888c2ecf20Sopenharmony_ci { .event = "l2_rqsts.pf_miss", .val = 500 }, 2898c2ecf20Sopenharmony_ci { .event = "l2_rqsts.rfo_miss", .val = 600 }, 2908c2ecf20Sopenharmony_ci { .event = NULL, }, 2918c2ecf20Sopenharmony_ci }; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("failed to compute metric", 2948c2ecf20Sopenharmony_ci compute_metric("DCache_L2_Hits", vals, &ratio) == 0); 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("DCache_L2_Hits failed, wrong ratio", 2978c2ecf20Sopenharmony_ci ratio == 0.3); 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("failed to compute metric", 3008c2ecf20Sopenharmony_ci compute_metric("DCache_L2_Misses", vals, &ratio) == 0); 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("DCache_L2_Misses failed, wrong ratio", 3038c2ecf20Sopenharmony_ci ratio == 0.7); 3048c2ecf20Sopenharmony_ci return 0; 3058c2ecf20Sopenharmony_ci} 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_cistatic int test_recursion_fail(void) 3088c2ecf20Sopenharmony_ci{ 3098c2ecf20Sopenharmony_ci double ratio; 3108c2ecf20Sopenharmony_ci struct value vals[] = { 3118c2ecf20Sopenharmony_ci { .event = "inst_retired.any", .val = 300 }, 3128c2ecf20Sopenharmony_ci { .event = "cpu_clk_unhalted.thread", .val = 200 }, 3138c2ecf20Sopenharmony_ci { .event = NULL, }, 3148c2ecf20Sopenharmony_ci }; 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("failed to find recursion", 3178c2ecf20Sopenharmony_ci compute_metric("M1", vals, &ratio) == -1); 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("failed to find recursion", 3208c2ecf20Sopenharmony_ci compute_metric("M3", vals, &ratio) == -1); 3218c2ecf20Sopenharmony_ci return 0; 3228c2ecf20Sopenharmony_ci} 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_cistatic int test_metric_group(void) 3258c2ecf20Sopenharmony_ci{ 3268c2ecf20Sopenharmony_ci double ratio1, ratio2; 3278c2ecf20Sopenharmony_ci struct value vals[] = { 3288c2ecf20Sopenharmony_ci { .event = "cpu_clk_unhalted.thread", .val = 200 }, 3298c2ecf20Sopenharmony_ci { .event = "l1d-loads-misses", .val = 300 }, 3308c2ecf20Sopenharmony_ci { .event = "l1i-loads-misses", .val = 200 }, 3318c2ecf20Sopenharmony_ci { .event = "inst_retired.any", .val = 400 }, 3328c2ecf20Sopenharmony_ci { .event = NULL, }, 3338c2ecf20Sopenharmony_ci }; 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("failed to find recursion", 3368c2ecf20Sopenharmony_ci compute_metric_group("group1", vals, 3378c2ecf20Sopenharmony_ci "IPC", &ratio1, 3388c2ecf20Sopenharmony_ci "cache_miss_cycles", &ratio2) == 0); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("group IPC failed, wrong ratio", 3418c2ecf20Sopenharmony_ci ratio1 == 2.0); 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("group cache_miss_cycles failed, wrong ratio", 3448c2ecf20Sopenharmony_ci ratio2 == 1.25); 3458c2ecf20Sopenharmony_ci return 0; 3468c2ecf20Sopenharmony_ci} 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ciint test__parse_metric(struct test *test __maybe_unused, int subtest __maybe_unused) 3498c2ecf20Sopenharmony_ci{ 3508c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("IPC failed", test_ipc() == 0); 3518c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("frontend failed", test_frontend() == 0); 3528c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("cache_miss_cycles failed", test_cache_miss_cycles() == 0); 3538c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("DCache_L2 failed", test_dcache_l2() == 0); 3548c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("recursion fail failed", test_recursion_fail() == 0); 3558c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("test metric group", test_metric_group() == 0); 3568c2ecf20Sopenharmony_ci return 0; 3578c2ecf20Sopenharmony_ci} 358