161d77071SPavan Nikhilesh /* SPDX-License-Identifier: BSD-3-Clause
261d77071SPavan Nikhilesh * Copyright(C) 2020 Marvell International Ltd.
361d77071SPavan Nikhilesh */
43c60274cSJie Zhou
53c60274cSJie Zhou #include "test.h"
63c60274cSJie Zhou
761d77071SPavan Nikhilesh #include <inttypes.h>
861d77071SPavan Nikhilesh #include <signal.h>
961d77071SPavan Nikhilesh #include <stdio.h>
1061d77071SPavan Nikhilesh #include <unistd.h>
1161d77071SPavan Nikhilesh
1261d77071SPavan Nikhilesh #include <rte_common.h>
1361d77071SPavan Nikhilesh #include <rte_cycles.h>
1461d77071SPavan Nikhilesh #include <rte_errno.h>
153c60274cSJie Zhou #ifdef RTE_EXEC_ENV_WINDOWS
163c60274cSJie Zhou static int
test_graph_perf_func(void)173c60274cSJie Zhou test_graph_perf_func(void)
183c60274cSJie Zhou {
193c60274cSJie Zhou printf("graph_perf not supported on Windows, skipping test\n");
203c60274cSJie Zhou return TEST_SKIPPED;
213c60274cSJie Zhou }
223c60274cSJie Zhou
233c60274cSJie Zhou #else
243c60274cSJie Zhou
2561d77071SPavan Nikhilesh #include <rte_graph.h>
26a2bc0584SZhirun Yan #include <rte_graph_worker.h>
2761d77071SPavan Nikhilesh #include <rte_lcore.h>
2861d77071SPavan Nikhilesh #include <rte_malloc.h>
2961d77071SPavan Nikhilesh #include <rte_mbuf.h>
3061d77071SPavan Nikhilesh
3161d77071SPavan Nikhilesh #define TEST_GRAPH_PERF_MZ "graph_perf_data"
3261d77071SPavan Nikhilesh #define TEST_GRAPH_SRC_NAME "test_graph_perf_source"
3361d77071SPavan Nikhilesh #define TEST_GRAPH_SRC_BRST_ONE_NAME "test_graph_perf_source_one"
3461d77071SPavan Nikhilesh #define TEST_GRAPH_WRK_NAME "test_graph_perf_worker"
3561d77071SPavan Nikhilesh #define TEST_GRAPH_SNK_NAME "test_graph_perf_sink"
3661d77071SPavan Nikhilesh
3761d77071SPavan Nikhilesh #define SOURCES(map) RTE_DIM(map)
3861d77071SPavan Nikhilesh #define STAGES(map) RTE_DIM(map)
3961d77071SPavan Nikhilesh #define NODES_PER_STAGE(map) RTE_DIM(map[0])
4061d77071SPavan Nikhilesh #define SINKS(map) RTE_DIM(map[0])
4161d77071SPavan Nikhilesh
4261d77071SPavan Nikhilesh #define MAX_EDGES_PER_NODE 7
4361d77071SPavan Nikhilesh
4461d77071SPavan Nikhilesh struct test_node_data {
4561d77071SPavan Nikhilesh uint8_t node_id;
4661d77071SPavan Nikhilesh uint8_t is_sink;
4761d77071SPavan Nikhilesh uint8_t next_nodes[MAX_EDGES_PER_NODE];
4861d77071SPavan Nikhilesh uint8_t next_percentage[MAX_EDGES_PER_NODE];
4961d77071SPavan Nikhilesh };
5061d77071SPavan Nikhilesh
5161d77071SPavan Nikhilesh struct test_graph_perf {
5261d77071SPavan Nikhilesh uint16_t nb_nodes;
5361d77071SPavan Nikhilesh rte_graph_t graph_id;
5461d77071SPavan Nikhilesh struct test_node_data *node_data;
5561d77071SPavan Nikhilesh };
5661d77071SPavan Nikhilesh
5761d77071SPavan Nikhilesh struct graph_lcore_data {
5861d77071SPavan Nikhilesh uint8_t done;
5961d77071SPavan Nikhilesh rte_graph_t graph_id;
6061d77071SPavan Nikhilesh };
6161d77071SPavan Nikhilesh
6261d77071SPavan Nikhilesh static struct test_node_data *
graph_get_node_data(struct test_graph_perf * graph_data,rte_node_t id)6361d77071SPavan Nikhilesh graph_get_node_data(struct test_graph_perf *graph_data, rte_node_t id)
6461d77071SPavan Nikhilesh {
6561d77071SPavan Nikhilesh struct test_node_data *node_data = NULL;
6661d77071SPavan Nikhilesh int i;
6761d77071SPavan Nikhilesh
6861d77071SPavan Nikhilesh for (i = 0; i < graph_data->nb_nodes; i++)
6961d77071SPavan Nikhilesh if (graph_data->node_data[i].node_id == id) {
7061d77071SPavan Nikhilesh node_data = &graph_data->node_data[i];
7161d77071SPavan Nikhilesh break;
7261d77071SPavan Nikhilesh }
7361d77071SPavan Nikhilesh
7461d77071SPavan Nikhilesh return node_data;
7561d77071SPavan Nikhilesh }
7661d77071SPavan Nikhilesh
7761d77071SPavan Nikhilesh static int
test_node_ctx_init(const struct rte_graph * graph,struct rte_node * node)7861d77071SPavan Nikhilesh test_node_ctx_init(const struct rte_graph *graph, struct rte_node *node)
7961d77071SPavan Nikhilesh {
8061d77071SPavan Nikhilesh struct test_graph_perf *graph_data;
8161d77071SPavan Nikhilesh struct test_node_data *node_data;
8261d77071SPavan Nikhilesh const struct rte_memzone *mz;
8361d77071SPavan Nikhilesh rte_node_t nid = node->id;
8461d77071SPavan Nikhilesh rte_edge_t edge = 0;
8561d77071SPavan Nikhilesh int i;
8661d77071SPavan Nikhilesh
8761d77071SPavan Nikhilesh RTE_SET_USED(graph);
8861d77071SPavan Nikhilesh
8961d77071SPavan Nikhilesh mz = rte_memzone_lookup(TEST_GRAPH_PERF_MZ);
902e908855SPavan Nikhilesh if (mz == NULL)
912e908855SPavan Nikhilesh return -ENOMEM;
9261d77071SPavan Nikhilesh graph_data = mz->addr;
9361d77071SPavan Nikhilesh node_data = graph_get_node_data(graph_data, nid);
9461d77071SPavan Nikhilesh node->ctx[0] = node->nb_edges;
9561d77071SPavan Nikhilesh for (i = 0; i < node->nb_edges && !node_data->is_sink; i++, edge++) {
9661d77071SPavan Nikhilesh node->ctx[i + 1] = edge;
9761d77071SPavan Nikhilesh node->ctx[i + 9] = node_data->next_percentage[i];
9861d77071SPavan Nikhilesh }
9961d77071SPavan Nikhilesh
10061d77071SPavan Nikhilesh return 0;
10161d77071SPavan Nikhilesh }
10261d77071SPavan Nikhilesh
10361d77071SPavan Nikhilesh /* Source node function */
10461d77071SPavan Nikhilesh static uint16_t
test_perf_node_worker_source(struct rte_graph * graph,struct rte_node * node,void ** objs,uint16_t nb_objs)10561d77071SPavan Nikhilesh test_perf_node_worker_source(struct rte_graph *graph, struct rte_node *node,
10661d77071SPavan Nikhilesh void **objs, uint16_t nb_objs)
10761d77071SPavan Nikhilesh {
10861d77071SPavan Nikhilesh uint16_t count;
10961d77071SPavan Nikhilesh int i;
11061d77071SPavan Nikhilesh
11161d77071SPavan Nikhilesh RTE_SET_USED(objs);
11261d77071SPavan Nikhilesh RTE_SET_USED(nb_objs);
11361d77071SPavan Nikhilesh
11461d77071SPavan Nikhilesh /* Create a proportional stream for every next */
11561d77071SPavan Nikhilesh for (i = 0; i < node->ctx[0]; i++) {
11661d77071SPavan Nikhilesh count = (node->ctx[i + 9] * RTE_GRAPH_BURST_SIZE) / 100;
11761d77071SPavan Nikhilesh rte_node_next_stream_get(graph, node, node->ctx[i + 1], count);
11861d77071SPavan Nikhilesh rte_node_next_stream_put(graph, node, node->ctx[i + 1], count);
11961d77071SPavan Nikhilesh }
12061d77071SPavan Nikhilesh
12161d77071SPavan Nikhilesh return RTE_GRAPH_BURST_SIZE;
12261d77071SPavan Nikhilesh }
12361d77071SPavan Nikhilesh
12461d77071SPavan Nikhilesh static struct rte_node_register test_graph_perf_source = {
12561d77071SPavan Nikhilesh .name = TEST_GRAPH_SRC_NAME,
12661d77071SPavan Nikhilesh .process = test_perf_node_worker_source,
12761d77071SPavan Nikhilesh .flags = RTE_NODE_SOURCE_F,
12861d77071SPavan Nikhilesh .init = test_node_ctx_init,
12961d77071SPavan Nikhilesh };
13061d77071SPavan Nikhilesh
13161d77071SPavan Nikhilesh RTE_NODE_REGISTER(test_graph_perf_source);
13261d77071SPavan Nikhilesh
13361d77071SPavan Nikhilesh static uint16_t
test_perf_node_worker_source_burst_one(struct rte_graph * graph,struct rte_node * node,void ** objs,uint16_t nb_objs)13461d77071SPavan Nikhilesh test_perf_node_worker_source_burst_one(struct rte_graph *graph,
13561d77071SPavan Nikhilesh struct rte_node *node, void **objs,
13661d77071SPavan Nikhilesh uint16_t nb_objs)
13761d77071SPavan Nikhilesh {
13861d77071SPavan Nikhilesh uint16_t count;
13961d77071SPavan Nikhilesh int i;
14061d77071SPavan Nikhilesh
14161d77071SPavan Nikhilesh RTE_SET_USED(objs);
14261d77071SPavan Nikhilesh RTE_SET_USED(nb_objs);
14361d77071SPavan Nikhilesh
14461d77071SPavan Nikhilesh /* Create a proportional stream for every next */
14561d77071SPavan Nikhilesh for (i = 0; i < node->ctx[0]; i++) {
14661d77071SPavan Nikhilesh count = (node->ctx[i + 9]) / 100;
14761d77071SPavan Nikhilesh rte_node_next_stream_get(graph, node, node->ctx[i + 1], count);
14861d77071SPavan Nikhilesh rte_node_next_stream_put(graph, node, node->ctx[i + 1], count);
14961d77071SPavan Nikhilesh }
15061d77071SPavan Nikhilesh
15161d77071SPavan Nikhilesh return 1;
15261d77071SPavan Nikhilesh }
15361d77071SPavan Nikhilesh
15461d77071SPavan Nikhilesh static struct rte_node_register test_graph_perf_source_burst_one = {
15561d77071SPavan Nikhilesh .name = TEST_GRAPH_SRC_BRST_ONE_NAME,
15661d77071SPavan Nikhilesh .process = test_perf_node_worker_source_burst_one,
15761d77071SPavan Nikhilesh .flags = RTE_NODE_SOURCE_F,
15861d77071SPavan Nikhilesh .init = test_node_ctx_init,
15961d77071SPavan Nikhilesh };
16061d77071SPavan Nikhilesh
16161d77071SPavan Nikhilesh RTE_NODE_REGISTER(test_graph_perf_source_burst_one);
16261d77071SPavan Nikhilesh
16361d77071SPavan Nikhilesh /* Worker node function */
16461d77071SPavan Nikhilesh static uint16_t
test_perf_node_worker(struct rte_graph * graph,struct rte_node * node,void ** objs,uint16_t nb_objs)16561d77071SPavan Nikhilesh test_perf_node_worker(struct rte_graph *graph, struct rte_node *node,
16661d77071SPavan Nikhilesh void **objs, uint16_t nb_objs)
16761d77071SPavan Nikhilesh {
16861d77071SPavan Nikhilesh uint16_t next = 0;
16961d77071SPavan Nikhilesh uint16_t enq = 0;
17061d77071SPavan Nikhilesh uint16_t count;
17161d77071SPavan Nikhilesh int i;
17261d77071SPavan Nikhilesh
17361d77071SPavan Nikhilesh /* Move stream for single next node */
17461d77071SPavan Nikhilesh if (node->ctx[0] == 1) {
17561d77071SPavan Nikhilesh rte_node_next_stream_move(graph, node, node->ctx[1]);
17661d77071SPavan Nikhilesh return nb_objs;
17761d77071SPavan Nikhilesh }
17861d77071SPavan Nikhilesh
17961d77071SPavan Nikhilesh /* Enqueue objects to next nodes proportionally */
18061d77071SPavan Nikhilesh for (i = 0; i < node->ctx[0]; i++) {
18161d77071SPavan Nikhilesh next = node->ctx[i + 1];
18261d77071SPavan Nikhilesh count = (node->ctx[i + 9] * nb_objs) / 100;
18361d77071SPavan Nikhilesh enq += count;
18461d77071SPavan Nikhilesh while (count) {
18561d77071SPavan Nikhilesh switch (count & (4 - 1)) {
18661d77071SPavan Nikhilesh case 0:
18761d77071SPavan Nikhilesh rte_node_enqueue_x4(graph, node, next, objs[0],
18861d77071SPavan Nikhilesh objs[1], objs[2], objs[3]);
18961d77071SPavan Nikhilesh objs += 4;
19061d77071SPavan Nikhilesh count -= 4;
19161d77071SPavan Nikhilesh break;
19261d77071SPavan Nikhilesh case 1:
19361d77071SPavan Nikhilesh rte_node_enqueue_x1(graph, node, next, objs[0]);
19461d77071SPavan Nikhilesh objs += 1;
19561d77071SPavan Nikhilesh count -= 1;
19661d77071SPavan Nikhilesh break;
19761d77071SPavan Nikhilesh case 2:
19861d77071SPavan Nikhilesh rte_node_enqueue_x2(graph, node, next, objs[0],
19961d77071SPavan Nikhilesh objs[1]);
20061d77071SPavan Nikhilesh objs += 2;
20161d77071SPavan Nikhilesh count -= 2;
20261d77071SPavan Nikhilesh break;
20361d77071SPavan Nikhilesh case 3:
20461d77071SPavan Nikhilesh rte_node_enqueue_x2(graph, node, next, objs[0],
20561d77071SPavan Nikhilesh objs[1]);
20661d77071SPavan Nikhilesh rte_node_enqueue_x1(graph, node, next, objs[0]);
20761d77071SPavan Nikhilesh objs += 3;
20861d77071SPavan Nikhilesh count -= 3;
20961d77071SPavan Nikhilesh break;
21061d77071SPavan Nikhilesh }
21161d77071SPavan Nikhilesh }
21261d77071SPavan Nikhilesh }
21361d77071SPavan Nikhilesh
21461d77071SPavan Nikhilesh if (enq != nb_objs)
21561d77071SPavan Nikhilesh rte_node_enqueue(graph, node, next, objs, nb_objs - enq);
21661d77071SPavan Nikhilesh
21761d77071SPavan Nikhilesh return nb_objs;
21861d77071SPavan Nikhilesh }
21961d77071SPavan Nikhilesh
22061d77071SPavan Nikhilesh static struct rte_node_register test_graph_perf_worker = {
22161d77071SPavan Nikhilesh .name = TEST_GRAPH_WRK_NAME,
22261d77071SPavan Nikhilesh .process = test_perf_node_worker,
22361d77071SPavan Nikhilesh .init = test_node_ctx_init,
22461d77071SPavan Nikhilesh };
22561d77071SPavan Nikhilesh
22661d77071SPavan Nikhilesh RTE_NODE_REGISTER(test_graph_perf_worker);
22761d77071SPavan Nikhilesh
22861d77071SPavan Nikhilesh /* Last node in graph a.k.a sink node */
22961d77071SPavan Nikhilesh static uint16_t
test_perf_node_sink(struct rte_graph * graph,struct rte_node * node,void ** objs,uint16_t nb_objs)23061d77071SPavan Nikhilesh test_perf_node_sink(struct rte_graph *graph, struct rte_node *node, void **objs,
23161d77071SPavan Nikhilesh uint16_t nb_objs)
23261d77071SPavan Nikhilesh {
23361d77071SPavan Nikhilesh RTE_SET_USED(graph);
23461d77071SPavan Nikhilesh RTE_SET_USED(node);
23561d77071SPavan Nikhilesh RTE_SET_USED(objs);
23661d77071SPavan Nikhilesh RTE_SET_USED(nb_objs);
23761d77071SPavan Nikhilesh
23861d77071SPavan Nikhilesh return nb_objs;
23961d77071SPavan Nikhilesh }
24061d77071SPavan Nikhilesh
24161d77071SPavan Nikhilesh static struct rte_node_register test_graph_perf_sink = {
24261d77071SPavan Nikhilesh .name = TEST_GRAPH_SNK_NAME,
24361d77071SPavan Nikhilesh .process = test_perf_node_sink,
24461d77071SPavan Nikhilesh .init = test_node_ctx_init,
24561d77071SPavan Nikhilesh };
24661d77071SPavan Nikhilesh
24761d77071SPavan Nikhilesh RTE_NODE_REGISTER(test_graph_perf_sink);
24861d77071SPavan Nikhilesh
24961d77071SPavan Nikhilesh static int
graph_perf_setup(void)25061d77071SPavan Nikhilesh graph_perf_setup(void)
25161d77071SPavan Nikhilesh {
25261d77071SPavan Nikhilesh if (rte_lcore_count() < 2) {
25361d77071SPavan Nikhilesh printf("Test requires at least 2 lcores\n");
25461d77071SPavan Nikhilesh return TEST_SKIPPED;
25561d77071SPavan Nikhilesh }
25661d77071SPavan Nikhilesh
25761d77071SPavan Nikhilesh return 0;
25861d77071SPavan Nikhilesh }
25961d77071SPavan Nikhilesh
26061d77071SPavan Nikhilesh static void
graph_perf_teardown(void)26161d77071SPavan Nikhilesh graph_perf_teardown(void)
26261d77071SPavan Nikhilesh {
26361d77071SPavan Nikhilesh }
26461d77071SPavan Nikhilesh
26561d77071SPavan Nikhilesh static inline rte_node_t
graph_node_get(const char * pname,char * nname)26661d77071SPavan Nikhilesh graph_node_get(const char *pname, char *nname)
26761d77071SPavan Nikhilesh {
26861d77071SPavan Nikhilesh rte_node_t pnode_id = rte_node_from_name(pname);
26961d77071SPavan Nikhilesh char lookup_name[RTE_NODE_NAMESIZE];
27061d77071SPavan Nikhilesh rte_node_t node_id;
27161d77071SPavan Nikhilesh
27261d77071SPavan Nikhilesh snprintf(lookup_name, RTE_NODE_NAMESIZE, "%s-%s", pname, nname);
27361d77071SPavan Nikhilesh node_id = rte_node_from_name(lookup_name);
27461d77071SPavan Nikhilesh
27561d77071SPavan Nikhilesh if (node_id != RTE_NODE_ID_INVALID) {
27661d77071SPavan Nikhilesh if (rte_node_edge_count(node_id))
27761d77071SPavan Nikhilesh rte_node_edge_shrink(node_id, 0);
27861d77071SPavan Nikhilesh return node_id;
27961d77071SPavan Nikhilesh }
28061d77071SPavan Nikhilesh
28161d77071SPavan Nikhilesh return rte_node_clone(pnode_id, nname);
28261d77071SPavan Nikhilesh }
28361d77071SPavan Nikhilesh
28461d77071SPavan Nikhilesh static uint16_t
graph_node_count_edges(uint32_t stage,uint16_t node,uint16_t nodes_per_stage,uint8_t edge_map[][nodes_per_stage][nodes_per_stage],char * ename[],struct test_node_data * node_data,rte_node_t ** node_map)28561d77071SPavan Nikhilesh graph_node_count_edges(uint32_t stage, uint16_t node, uint16_t nodes_per_stage,
28661d77071SPavan Nikhilesh uint8_t edge_map[][nodes_per_stage][nodes_per_stage],
28761d77071SPavan Nikhilesh char *ename[], struct test_node_data *node_data,
28861d77071SPavan Nikhilesh rte_node_t **node_map)
28961d77071SPavan Nikhilesh {
29061d77071SPavan Nikhilesh uint8_t total_percent = 0;
29161d77071SPavan Nikhilesh uint16_t edges = 0;
29261d77071SPavan Nikhilesh int i;
29361d77071SPavan Nikhilesh
29461d77071SPavan Nikhilesh for (i = 0; i < nodes_per_stage && edges < MAX_EDGES_PER_NODE; i++) {
29561d77071SPavan Nikhilesh if (edge_map[stage + 1][i][node]) {
29661d77071SPavan Nikhilesh ename[edges] = malloc(sizeof(char) * RTE_NODE_NAMESIZE);
29761d77071SPavan Nikhilesh snprintf(ename[edges], RTE_NODE_NAMESIZE, "%s",
29861d77071SPavan Nikhilesh rte_node_id_to_name(node_map[stage + 1][i]));
29961d77071SPavan Nikhilesh node_data->next_nodes[edges] = node_map[stage + 1][i];
30061d77071SPavan Nikhilesh node_data->next_percentage[edges] =
30161d77071SPavan Nikhilesh edge_map[stage + 1][i][node];
30261d77071SPavan Nikhilesh edges++;
30361d77071SPavan Nikhilesh total_percent += edge_map[stage + 1][i][node];
30461d77071SPavan Nikhilesh }
30561d77071SPavan Nikhilesh }
30661d77071SPavan Nikhilesh
30761d77071SPavan Nikhilesh if (edges >= MAX_EDGES_PER_NODE || (edges && total_percent != 100)) {
30861d77071SPavan Nikhilesh for (i = 0; i < edges; i++)
30961d77071SPavan Nikhilesh free(ename[i]);
31061d77071SPavan Nikhilesh return RTE_EDGE_ID_INVALID;
31161d77071SPavan Nikhilesh }
31261d77071SPavan Nikhilesh
31361d77071SPavan Nikhilesh return edges;
31461d77071SPavan Nikhilesh }
31561d77071SPavan Nikhilesh
31661d77071SPavan Nikhilesh static int
graph_init(const char * gname,uint8_t nb_srcs,uint8_t nb_sinks,uint32_t stages,uint16_t nodes_per_stage,uint8_t src_map[][nodes_per_stage],uint8_t snk_map[][nb_sinks],uint8_t edge_map[][nodes_per_stage][nodes_per_stage],uint8_t burst_one)31761d77071SPavan Nikhilesh graph_init(const char *gname, uint8_t nb_srcs, uint8_t nb_sinks,
31861d77071SPavan Nikhilesh uint32_t stages, uint16_t nodes_per_stage,
31961d77071SPavan Nikhilesh uint8_t src_map[][nodes_per_stage], uint8_t snk_map[][nb_sinks],
32061d77071SPavan Nikhilesh uint8_t edge_map[][nodes_per_stage][nodes_per_stage],
32161d77071SPavan Nikhilesh uint8_t burst_one)
32261d77071SPavan Nikhilesh {
32361d77071SPavan Nikhilesh struct test_graph_perf *graph_data;
32461d77071SPavan Nikhilesh char nname[RTE_NODE_NAMESIZE / 2];
32561d77071SPavan Nikhilesh struct test_node_data *node_data;
32661d77071SPavan Nikhilesh char *ename[nodes_per_stage];
3279b72ea1fSAmit Prakash Shukla struct rte_graph_param gconf = {0};
32861d77071SPavan Nikhilesh const struct rte_memzone *mz;
32961d77071SPavan Nikhilesh uint8_t total_percent = 0;
33061d77071SPavan Nikhilesh rte_node_t *src_nodes;
33161d77071SPavan Nikhilesh rte_node_t *snk_nodes;
33261d77071SPavan Nikhilesh rte_node_t **node_map;
33361d77071SPavan Nikhilesh char **node_patterns;
33461d77071SPavan Nikhilesh rte_graph_t graph_id;
33561d77071SPavan Nikhilesh rte_edge_t edges;
33661d77071SPavan Nikhilesh rte_edge_t count;
33761d77071SPavan Nikhilesh uint32_t i, j, k;
33861d77071SPavan Nikhilesh
33961d77071SPavan Nikhilesh mz = rte_memzone_reserve(TEST_GRAPH_PERF_MZ,
34061d77071SPavan Nikhilesh sizeof(struct test_graph_perf), 0, 0);
34161d77071SPavan Nikhilesh if (mz == NULL) {
34261d77071SPavan Nikhilesh printf("Failed to allocate graph common memory\n");
34361d77071SPavan Nikhilesh return -ENOMEM;
34461d77071SPavan Nikhilesh }
34561d77071SPavan Nikhilesh
34661d77071SPavan Nikhilesh graph_data = mz->addr;
34761d77071SPavan Nikhilesh graph_data->nb_nodes = 0;
34861d77071SPavan Nikhilesh graph_data->node_data =
34961d77071SPavan Nikhilesh malloc(sizeof(struct test_node_data) *
35061d77071SPavan Nikhilesh (nb_srcs + nb_sinks + stages * nodes_per_stage));
35161d77071SPavan Nikhilesh if (graph_data->node_data == NULL) {
35261d77071SPavan Nikhilesh printf("Failed to reserve memzone for graph data\n");
35361d77071SPavan Nikhilesh goto memzone_free;
35461d77071SPavan Nikhilesh }
35561d77071SPavan Nikhilesh
35661d77071SPavan Nikhilesh node_patterns = malloc(sizeof(char *) *
35761d77071SPavan Nikhilesh (nb_srcs + nb_sinks + stages * nodes_per_stage));
35861d77071SPavan Nikhilesh if (node_patterns == NULL) {
35961d77071SPavan Nikhilesh printf("Failed to reserve memory for node patterns\n");
36061d77071SPavan Nikhilesh goto data_free;
36161d77071SPavan Nikhilesh }
36261d77071SPavan Nikhilesh
36361d77071SPavan Nikhilesh src_nodes = malloc(sizeof(rte_node_t) * nb_srcs);
36461d77071SPavan Nikhilesh if (src_nodes == NULL) {
36561d77071SPavan Nikhilesh printf("Failed to reserve memory for src nodes\n");
36661d77071SPavan Nikhilesh goto pattern_free;
36761d77071SPavan Nikhilesh }
36861d77071SPavan Nikhilesh
36961d77071SPavan Nikhilesh snk_nodes = malloc(sizeof(rte_node_t) * nb_sinks);
37061d77071SPavan Nikhilesh if (snk_nodes == NULL) {
37161d77071SPavan Nikhilesh printf("Failed to reserve memory for snk nodes\n");
37261d77071SPavan Nikhilesh goto src_free;
37361d77071SPavan Nikhilesh }
37461d77071SPavan Nikhilesh
37561d77071SPavan Nikhilesh node_map = malloc(sizeof(rte_node_t *) * stages +
37661d77071SPavan Nikhilesh sizeof(rte_node_t) * nodes_per_stage * stages);
37761d77071SPavan Nikhilesh if (node_map == NULL) {
37861d77071SPavan Nikhilesh printf("Failed to reserve memory for node map\n");
37961d77071SPavan Nikhilesh goto snk_free;
38061d77071SPavan Nikhilesh }
38161d77071SPavan Nikhilesh
38261d77071SPavan Nikhilesh /* Setup the Graph */
38361d77071SPavan Nikhilesh for (i = 0; i < stages; i++) {
38461d77071SPavan Nikhilesh node_map[i] =
38561d77071SPavan Nikhilesh (rte_node_t *)(node_map + stages) + nodes_per_stage * i;
38661d77071SPavan Nikhilesh for (j = 0; j < nodes_per_stage; j++) {
38761d77071SPavan Nikhilesh total_percent = 0;
38861d77071SPavan Nikhilesh for (k = 0; k < nodes_per_stage; k++)
38961d77071SPavan Nikhilesh total_percent += edge_map[i][j][k];
39061d77071SPavan Nikhilesh if (!total_percent)
39161d77071SPavan Nikhilesh continue;
39261d77071SPavan Nikhilesh node_patterns[graph_data->nb_nodes] =
39361d77071SPavan Nikhilesh malloc(RTE_NODE_NAMESIZE);
39461d77071SPavan Nikhilesh if (node_patterns[graph_data->nb_nodes] == NULL) {
39561d77071SPavan Nikhilesh printf("Failed to create memory for pattern\n");
39661d77071SPavan Nikhilesh goto pattern_name_free;
39761d77071SPavan Nikhilesh }
39861d77071SPavan Nikhilesh
39961d77071SPavan Nikhilesh /* Clone a worker node */
40061d77071SPavan Nikhilesh snprintf(nname, sizeof(nname), "%d-%d", i, j);
40161d77071SPavan Nikhilesh node_map[i][j] =
40261d77071SPavan Nikhilesh graph_node_get(TEST_GRAPH_WRK_NAME, nname);
40361d77071SPavan Nikhilesh if (node_map[i][j] == RTE_NODE_ID_INVALID) {
40461d77071SPavan Nikhilesh printf("Failed to create node[%s]\n", nname);
40561d77071SPavan Nikhilesh graph_data->nb_nodes++;
40661d77071SPavan Nikhilesh goto pattern_name_free;
40761d77071SPavan Nikhilesh }
40861d77071SPavan Nikhilesh snprintf(node_patterns[graph_data->nb_nodes],
40961d77071SPavan Nikhilesh RTE_NODE_NAMESIZE, "%s",
41061d77071SPavan Nikhilesh rte_node_id_to_name(node_map[i][j]));
41161d77071SPavan Nikhilesh node_data =
41261d77071SPavan Nikhilesh &graph_data->node_data[graph_data->nb_nodes];
41361d77071SPavan Nikhilesh node_data->node_id = node_map[i][j];
41461d77071SPavan Nikhilesh node_data->is_sink = false;
41561d77071SPavan Nikhilesh graph_data->nb_nodes++;
41661d77071SPavan Nikhilesh }
41761d77071SPavan Nikhilesh }
41861d77071SPavan Nikhilesh
41961d77071SPavan Nikhilesh for (i = 0; i < stages - 1; i++) {
42061d77071SPavan Nikhilesh for (j = 0; j < nodes_per_stage; j++) {
42161d77071SPavan Nikhilesh /* Count edges i.e connections of worker node to next */
42261d77071SPavan Nikhilesh node_data =
42361d77071SPavan Nikhilesh graph_get_node_data(graph_data, node_map[i][j]);
42461d77071SPavan Nikhilesh edges = graph_node_count_edges(i, j, nodes_per_stage,
42561d77071SPavan Nikhilesh edge_map, ename,
42661d77071SPavan Nikhilesh node_data, node_map);
42761d77071SPavan Nikhilesh if (edges == RTE_EDGE_ID_INVALID) {
42861d77071SPavan Nikhilesh printf("Invalid edge configuration\n");
42961d77071SPavan Nikhilesh goto pattern_name_free;
43061d77071SPavan Nikhilesh }
43161d77071SPavan Nikhilesh if (!edges)
43261d77071SPavan Nikhilesh continue;
43361d77071SPavan Nikhilesh
43461d77071SPavan Nikhilesh /* Connect a node in stage 'i' to nodes
43561d77071SPavan Nikhilesh * in stage 'i + 1' with edges.
43661d77071SPavan Nikhilesh */
43761d77071SPavan Nikhilesh count = rte_node_edge_update(
43861d77071SPavan Nikhilesh node_map[i][j], 0,
43961d77071SPavan Nikhilesh (const char **)(uintptr_t)ename, edges);
44061d77071SPavan Nikhilesh for (k = 0; k < edges; k++)
44161d77071SPavan Nikhilesh free(ename[k]);
44261d77071SPavan Nikhilesh if (count != edges) {
44361d77071SPavan Nikhilesh printf("Couldn't add edges %d %d\n", edges,
44461d77071SPavan Nikhilesh count);
44561d77071SPavan Nikhilesh goto pattern_name_free;
44661d77071SPavan Nikhilesh }
44761d77071SPavan Nikhilesh }
44861d77071SPavan Nikhilesh }
44961d77071SPavan Nikhilesh
45061d77071SPavan Nikhilesh /* Setup Source nodes */
45161d77071SPavan Nikhilesh for (i = 0; i < nb_srcs; i++) {
45261d77071SPavan Nikhilesh edges = 0;
45361d77071SPavan Nikhilesh total_percent = 0;
45461d77071SPavan Nikhilesh node_patterns[graph_data->nb_nodes] = malloc(RTE_NODE_NAMESIZE);
45561d77071SPavan Nikhilesh if (node_patterns[graph_data->nb_nodes] == NULL) {
45661d77071SPavan Nikhilesh printf("Failed to create memory for pattern\n");
45761d77071SPavan Nikhilesh goto pattern_name_free;
45861d77071SPavan Nikhilesh }
45961d77071SPavan Nikhilesh /* Clone a source node */
46061d77071SPavan Nikhilesh snprintf(nname, sizeof(nname), "%d", i);
46161d77071SPavan Nikhilesh src_nodes[i] =
46261d77071SPavan Nikhilesh graph_node_get(burst_one ? TEST_GRAPH_SRC_BRST_ONE_NAME
46361d77071SPavan Nikhilesh : TEST_GRAPH_SRC_NAME,
46461d77071SPavan Nikhilesh nname);
46561d77071SPavan Nikhilesh if (src_nodes[i] == RTE_NODE_ID_INVALID) {
46661d77071SPavan Nikhilesh printf("Failed to create node[%s]\n", nname);
46761d77071SPavan Nikhilesh graph_data->nb_nodes++;
46861d77071SPavan Nikhilesh goto pattern_name_free;
46961d77071SPavan Nikhilesh }
47061d77071SPavan Nikhilesh snprintf(node_patterns[graph_data->nb_nodes], RTE_NODE_NAMESIZE,
47161d77071SPavan Nikhilesh "%s", rte_node_id_to_name(src_nodes[i]));
47261d77071SPavan Nikhilesh node_data = &graph_data->node_data[graph_data->nb_nodes];
47361d77071SPavan Nikhilesh node_data->node_id = src_nodes[i];
47461d77071SPavan Nikhilesh node_data->is_sink = false;
47561d77071SPavan Nikhilesh graph_data->nb_nodes++;
47661d77071SPavan Nikhilesh
47761d77071SPavan Nikhilesh /* Prepare next node list to connect to */
47861d77071SPavan Nikhilesh for (j = 0; j < nodes_per_stage; j++) {
47961d77071SPavan Nikhilesh if (!src_map[i][j])
48061d77071SPavan Nikhilesh continue;
48161d77071SPavan Nikhilesh ename[edges] = malloc(sizeof(char) * RTE_NODE_NAMESIZE);
48261d77071SPavan Nikhilesh snprintf(ename[edges], RTE_NODE_NAMESIZE, "%s",
48361d77071SPavan Nikhilesh rte_node_id_to_name(node_map[0][j]));
48461d77071SPavan Nikhilesh node_data->next_nodes[edges] = node_map[0][j];
48561d77071SPavan Nikhilesh node_data->next_percentage[edges] = src_map[i][j];
48661d77071SPavan Nikhilesh edges++;
48761d77071SPavan Nikhilesh total_percent += src_map[i][j];
48861d77071SPavan Nikhilesh }
48961d77071SPavan Nikhilesh
49061d77071SPavan Nikhilesh if (!edges)
49161d77071SPavan Nikhilesh continue;
49261d77071SPavan Nikhilesh if (edges >= MAX_EDGES_PER_NODE || total_percent != 100) {
49361d77071SPavan Nikhilesh printf("Invalid edge configuration\n");
49461d77071SPavan Nikhilesh for (j = 0; j < edges; j++)
49561d77071SPavan Nikhilesh free(ename[j]);
49661d77071SPavan Nikhilesh goto pattern_name_free;
49761d77071SPavan Nikhilesh }
49861d77071SPavan Nikhilesh
49961d77071SPavan Nikhilesh /* Connect to list of next nodes using edges */
50061d77071SPavan Nikhilesh count = rte_node_edge_update(src_nodes[i], 0,
50161d77071SPavan Nikhilesh (const char **)(uintptr_t)ename,
50261d77071SPavan Nikhilesh edges);
50361d77071SPavan Nikhilesh for (k = 0; k < edges; k++)
50461d77071SPavan Nikhilesh free(ename[k]);
50561d77071SPavan Nikhilesh if (count != edges) {
50661d77071SPavan Nikhilesh printf("Couldn't add edges %d %d\n", edges, count);
50761d77071SPavan Nikhilesh goto pattern_name_free;
50861d77071SPavan Nikhilesh }
50961d77071SPavan Nikhilesh }
51061d77071SPavan Nikhilesh
51161d77071SPavan Nikhilesh /* Setup Sink nodes */
51261d77071SPavan Nikhilesh for (i = 0; i < nb_sinks; i++) {
51361d77071SPavan Nikhilesh node_patterns[graph_data->nb_nodes] = malloc(RTE_NODE_NAMESIZE);
51461d77071SPavan Nikhilesh if (node_patterns[graph_data->nb_nodes] == NULL) {
51561d77071SPavan Nikhilesh printf("Failed to create memory for pattern\n");
51661d77071SPavan Nikhilesh goto pattern_name_free;
51761d77071SPavan Nikhilesh }
51861d77071SPavan Nikhilesh
51961d77071SPavan Nikhilesh /* Clone a sink node */
52061d77071SPavan Nikhilesh snprintf(nname, sizeof(nname), "%d", i);
52161d77071SPavan Nikhilesh snk_nodes[i] = graph_node_get(TEST_GRAPH_SNK_NAME, nname);
52261d77071SPavan Nikhilesh if (snk_nodes[i] == RTE_NODE_ID_INVALID) {
52361d77071SPavan Nikhilesh printf("Failed to create node[%s]\n", nname);
52461d77071SPavan Nikhilesh graph_data->nb_nodes++;
52561d77071SPavan Nikhilesh goto pattern_name_free;
52661d77071SPavan Nikhilesh }
52761d77071SPavan Nikhilesh snprintf(node_patterns[graph_data->nb_nodes], RTE_NODE_NAMESIZE,
52861d77071SPavan Nikhilesh "%s", rte_node_id_to_name(snk_nodes[i]));
52961d77071SPavan Nikhilesh node_data = &graph_data->node_data[graph_data->nb_nodes];
53061d77071SPavan Nikhilesh node_data->node_id = snk_nodes[i];
53161d77071SPavan Nikhilesh node_data->is_sink = true;
53261d77071SPavan Nikhilesh graph_data->nb_nodes++;
53361d77071SPavan Nikhilesh }
53461d77071SPavan Nikhilesh
53561d77071SPavan Nikhilesh /* Connect last stage worker nodes to sink nodes */
53661d77071SPavan Nikhilesh for (i = 0; i < nodes_per_stage; i++) {
53761d77071SPavan Nikhilesh edges = 0;
53861d77071SPavan Nikhilesh total_percent = 0;
53961d77071SPavan Nikhilesh node_data = graph_get_node_data(graph_data,
54061d77071SPavan Nikhilesh node_map[stages - 1][i]);
54161d77071SPavan Nikhilesh /* Prepare list of sink nodes to connect to */
54261d77071SPavan Nikhilesh for (j = 0; j < nb_sinks; j++) {
54361d77071SPavan Nikhilesh if (!snk_map[i][j])
54461d77071SPavan Nikhilesh continue;
54561d77071SPavan Nikhilesh ename[edges] = malloc(sizeof(char) * RTE_NODE_NAMESIZE);
54661d77071SPavan Nikhilesh snprintf(ename[edges], RTE_NODE_NAMESIZE, "%s",
54761d77071SPavan Nikhilesh rte_node_id_to_name(snk_nodes[j]));
54861d77071SPavan Nikhilesh node_data->next_nodes[edges] = snk_nodes[j];
54961d77071SPavan Nikhilesh node_data->next_percentage[edges] = snk_map[i][j];
55061d77071SPavan Nikhilesh edges++;
55161d77071SPavan Nikhilesh total_percent += snk_map[i][j];
55261d77071SPavan Nikhilesh }
55361d77071SPavan Nikhilesh if (!edges)
55461d77071SPavan Nikhilesh continue;
55561d77071SPavan Nikhilesh if (edges >= MAX_EDGES_PER_NODE || total_percent != 100) {
55661d77071SPavan Nikhilesh printf("Invalid edge configuration\n");
55761d77071SPavan Nikhilesh for (j = 0; j < edges; j++)
55861d77071SPavan Nikhilesh free(ename[i]);
55961d77071SPavan Nikhilesh goto pattern_name_free;
56061d77071SPavan Nikhilesh }
56161d77071SPavan Nikhilesh
56261d77071SPavan Nikhilesh /* Connect a worker node to a list of sink nodes */
56361d77071SPavan Nikhilesh count = rte_node_edge_update(node_map[stages - 1][i], 0,
56461d77071SPavan Nikhilesh (const char **)(uintptr_t)ename,
56561d77071SPavan Nikhilesh edges);
56661d77071SPavan Nikhilesh for (k = 0; k < edges; k++)
56761d77071SPavan Nikhilesh free(ename[k]);
56861d77071SPavan Nikhilesh if (count != edges) {
56961d77071SPavan Nikhilesh printf("Couldn't add edges %d %d\n", edges, count);
57061d77071SPavan Nikhilesh goto pattern_name_free;
57161d77071SPavan Nikhilesh }
57261d77071SPavan Nikhilesh }
57361d77071SPavan Nikhilesh
57461d77071SPavan Nikhilesh /* Create a Graph */
57561d77071SPavan Nikhilesh gconf.socket_id = SOCKET_ID_ANY;
57661d77071SPavan Nikhilesh gconf.nb_node_patterns = graph_data->nb_nodes;
57761d77071SPavan Nikhilesh gconf.node_patterns = (const char **)(uintptr_t)node_patterns;
57861d77071SPavan Nikhilesh
57961d77071SPavan Nikhilesh graph_id = rte_graph_create(gname, &gconf);
58061d77071SPavan Nikhilesh if (graph_id == RTE_GRAPH_ID_INVALID) {
58161d77071SPavan Nikhilesh printf("Graph creation failed with error = %d\n", rte_errno);
58261d77071SPavan Nikhilesh goto pattern_name_free;
58361d77071SPavan Nikhilesh }
58461d77071SPavan Nikhilesh graph_data->graph_id = graph_id;
58561d77071SPavan Nikhilesh
5862e908855SPavan Nikhilesh free(node_map);
58761d77071SPavan Nikhilesh for (i = 0; i < graph_data->nb_nodes; i++)
58861d77071SPavan Nikhilesh free(node_patterns[i]);
58961d77071SPavan Nikhilesh free(snk_nodes);
59061d77071SPavan Nikhilesh free(src_nodes);
59161d77071SPavan Nikhilesh free(node_patterns);
59261d77071SPavan Nikhilesh return 0;
59361d77071SPavan Nikhilesh
59461d77071SPavan Nikhilesh pattern_name_free:
5952e908855SPavan Nikhilesh free(node_map);
59661d77071SPavan Nikhilesh for (i = 0; i < graph_data->nb_nodes; i++)
59761d77071SPavan Nikhilesh free(node_patterns[i]);
59861d77071SPavan Nikhilesh snk_free:
59961d77071SPavan Nikhilesh free(snk_nodes);
60061d77071SPavan Nikhilesh src_free:
60161d77071SPavan Nikhilesh free(src_nodes);
60261d77071SPavan Nikhilesh pattern_free:
60361d77071SPavan Nikhilesh free(node_patterns);
60461d77071SPavan Nikhilesh data_free:
60561d77071SPavan Nikhilesh free(graph_data->node_data);
60661d77071SPavan Nikhilesh memzone_free:
60761d77071SPavan Nikhilesh rte_memzone_free(mz);
60861d77071SPavan Nikhilesh return -ENOMEM;
60961d77071SPavan Nikhilesh }
61061d77071SPavan Nikhilesh
61161d77071SPavan Nikhilesh /* Worker thread function */
61261d77071SPavan Nikhilesh static int
_graph_perf_wrapper(void * args)61361d77071SPavan Nikhilesh _graph_perf_wrapper(void *args)
61461d77071SPavan Nikhilesh {
61561d77071SPavan Nikhilesh struct graph_lcore_data *data = args;
61661d77071SPavan Nikhilesh struct rte_graph *graph;
61761d77071SPavan Nikhilesh
61861d77071SPavan Nikhilesh /* Lookup graph */
61961d77071SPavan Nikhilesh graph = rte_graph_lookup(rte_graph_id_to_name(data->graph_id));
62061d77071SPavan Nikhilesh
62161d77071SPavan Nikhilesh /* Graph walk until done */
62261d77071SPavan Nikhilesh while (!data->done)
62361d77071SPavan Nikhilesh rte_graph_walk(graph);
62461d77071SPavan Nikhilesh
62561d77071SPavan Nikhilesh return 0;
62661d77071SPavan Nikhilesh }
62761d77071SPavan Nikhilesh
62861d77071SPavan Nikhilesh static int
measure_perf_get(rte_graph_t graph_id)62961d77071SPavan Nikhilesh measure_perf_get(rte_graph_t graph_id)
63061d77071SPavan Nikhilesh {
63161d77071SPavan Nikhilesh const char *pattern = rte_graph_id_to_name(graph_id);
63261d77071SPavan Nikhilesh uint32_t lcore_id = rte_get_next_lcore(-1, 1, 0);
63361d77071SPavan Nikhilesh struct rte_graph_cluster_stats_param param;
63461d77071SPavan Nikhilesh struct rte_graph_cluster_stats *stats;
63561d77071SPavan Nikhilesh struct graph_lcore_data *data;
63661d77071SPavan Nikhilesh
63761d77071SPavan Nikhilesh data = rte_zmalloc("Graph_perf", sizeof(struct graph_lcore_data),
63861d77071SPavan Nikhilesh RTE_CACHE_LINE_SIZE);
63961d77071SPavan Nikhilesh data->graph_id = graph_id;
64061d77071SPavan Nikhilesh data->done = 0;
64161d77071SPavan Nikhilesh
64261d77071SPavan Nikhilesh /* Run graph worker thread function */
64361d77071SPavan Nikhilesh rte_eal_remote_launch(_graph_perf_wrapper, data, lcore_id);
64461d77071SPavan Nikhilesh
64561d77071SPavan Nikhilesh /* Collect stats for few msecs */
64661d77071SPavan Nikhilesh if (rte_graph_has_stats_feature()) {
64761d77071SPavan Nikhilesh memset(¶m, 0, sizeof(param));
64861d77071SPavan Nikhilesh param.f = stdout;
64961d77071SPavan Nikhilesh param.socket_id = SOCKET_ID_ANY;
65061d77071SPavan Nikhilesh param.graph_patterns = &pattern;
65161d77071SPavan Nikhilesh param.nb_graph_patterns = 1;
65261d77071SPavan Nikhilesh
65361d77071SPavan Nikhilesh stats = rte_graph_cluster_stats_create(¶m);
65461d77071SPavan Nikhilesh if (stats == NULL) {
65561d77071SPavan Nikhilesh printf("Failed to create stats\n");
65661d77071SPavan Nikhilesh return -ENOMEM;
65761d77071SPavan Nikhilesh }
65861d77071SPavan Nikhilesh
65961d77071SPavan Nikhilesh rte_delay_ms(3E2);
66061d77071SPavan Nikhilesh rte_graph_cluster_stats_get(stats, true);
66161d77071SPavan Nikhilesh rte_delay_ms(1E3);
66261d77071SPavan Nikhilesh rte_graph_cluster_stats_get(stats, false);
66361d77071SPavan Nikhilesh rte_graph_cluster_stats_destroy(stats);
66461d77071SPavan Nikhilesh } else
66561d77071SPavan Nikhilesh rte_delay_ms(1E3);
66661d77071SPavan Nikhilesh
66761d77071SPavan Nikhilesh data->done = 1;
66861d77071SPavan Nikhilesh rte_eal_wait_lcore(lcore_id);
66961d77071SPavan Nikhilesh
67061d77071SPavan Nikhilesh return 0;
67161d77071SPavan Nikhilesh }
67261d77071SPavan Nikhilesh
67361d77071SPavan Nikhilesh static inline void
graph_fini(void)67461d77071SPavan Nikhilesh graph_fini(void)
67561d77071SPavan Nikhilesh {
67661d77071SPavan Nikhilesh const struct rte_memzone *mz = rte_memzone_lookup(TEST_GRAPH_PERF_MZ);
67761d77071SPavan Nikhilesh struct test_graph_perf *graph_data;
67861d77071SPavan Nikhilesh
67961d77071SPavan Nikhilesh if (mz == NULL)
68061d77071SPavan Nikhilesh return;
68161d77071SPavan Nikhilesh graph_data = mz->addr;
68261d77071SPavan Nikhilesh
68361d77071SPavan Nikhilesh rte_graph_destroy(graph_data->graph_id);
68461d77071SPavan Nikhilesh free(graph_data->node_data);
68561d77071SPavan Nikhilesh rte_memzone_free(rte_memzone_lookup(TEST_GRAPH_PERF_MZ));
68661d77071SPavan Nikhilesh }
68761d77071SPavan Nikhilesh
68861d77071SPavan Nikhilesh static int
measure_perf(void)68961d77071SPavan Nikhilesh measure_perf(void)
69061d77071SPavan Nikhilesh {
69161d77071SPavan Nikhilesh const struct rte_memzone *mz;
69261d77071SPavan Nikhilesh struct test_graph_perf *graph_data;
69361d77071SPavan Nikhilesh
69461d77071SPavan Nikhilesh mz = rte_memzone_lookup(TEST_GRAPH_PERF_MZ);
6952e908855SPavan Nikhilesh if (mz == NULL)
6962e908855SPavan Nikhilesh return -ENOMEM;
69761d77071SPavan Nikhilesh graph_data = mz->addr;
69861d77071SPavan Nikhilesh
69961d77071SPavan Nikhilesh return measure_perf_get(graph_data->graph_id);
70061d77071SPavan Nikhilesh }
70161d77071SPavan Nikhilesh
70261d77071SPavan Nikhilesh static inline int
graph_hr_4s_1n_1src_1snk(void)70361d77071SPavan Nikhilesh graph_hr_4s_1n_1src_1snk(void)
70461d77071SPavan Nikhilesh {
70561d77071SPavan Nikhilesh return measure_perf();
70661d77071SPavan Nikhilesh }
70761d77071SPavan Nikhilesh
70861d77071SPavan Nikhilesh static inline int
graph_hr_4s_1n_1src_1snk_brst_one(void)70961d77071SPavan Nikhilesh graph_hr_4s_1n_1src_1snk_brst_one(void)
71061d77071SPavan Nikhilesh {
71161d77071SPavan Nikhilesh return measure_perf();
71261d77071SPavan Nikhilesh }
71361d77071SPavan Nikhilesh
71461d77071SPavan Nikhilesh static inline int
graph_hr_4s_1n_2src_1snk(void)71561d77071SPavan Nikhilesh graph_hr_4s_1n_2src_1snk(void)
71661d77071SPavan Nikhilesh {
71761d77071SPavan Nikhilesh return measure_perf();
71861d77071SPavan Nikhilesh }
71961d77071SPavan Nikhilesh
72061d77071SPavan Nikhilesh static inline int
graph_hr_4s_1n_1src_2snk(void)72161d77071SPavan Nikhilesh graph_hr_4s_1n_1src_2snk(void)
72261d77071SPavan Nikhilesh {
72361d77071SPavan Nikhilesh return measure_perf();
72461d77071SPavan Nikhilesh }
72561d77071SPavan Nikhilesh
72661d77071SPavan Nikhilesh static inline int
graph_tree_4s_4n_1src_4snk(void)72761d77071SPavan Nikhilesh graph_tree_4s_4n_1src_4snk(void)
72861d77071SPavan Nikhilesh {
72961d77071SPavan Nikhilesh return measure_perf();
73061d77071SPavan Nikhilesh }
73161d77071SPavan Nikhilesh
73261d77071SPavan Nikhilesh static inline int
graph_reverse_tree_3s_4n_1src_1snk(void)73361d77071SPavan Nikhilesh graph_reverse_tree_3s_4n_1src_1snk(void)
73461d77071SPavan Nikhilesh {
73561d77071SPavan Nikhilesh return measure_perf();
73661d77071SPavan Nikhilesh }
73761d77071SPavan Nikhilesh
73861d77071SPavan Nikhilesh static inline int
graph_parallel_tree_5s_4n_4src_4snk(void)73961d77071SPavan Nikhilesh graph_parallel_tree_5s_4n_4src_4snk(void)
74061d77071SPavan Nikhilesh {
74161d77071SPavan Nikhilesh return measure_perf();
74261d77071SPavan Nikhilesh }
74361d77071SPavan Nikhilesh
74461d77071SPavan Nikhilesh /* Graph Topology
74561d77071SPavan Nikhilesh * nodes per stage: 1
74661d77071SPavan Nikhilesh * stages: 4
74761d77071SPavan Nikhilesh * src: 1
74861d77071SPavan Nikhilesh * sink: 1
74961d77071SPavan Nikhilesh */
75061d77071SPavan Nikhilesh static inline int
graph_init_hr(void)75161d77071SPavan Nikhilesh graph_init_hr(void)
75261d77071SPavan Nikhilesh {
75361d77071SPavan Nikhilesh uint8_t edge_map[][1][1] = {
75461d77071SPavan Nikhilesh { {100} },
75561d77071SPavan Nikhilesh { {100} },
75661d77071SPavan Nikhilesh { {100} },
75761d77071SPavan Nikhilesh { {100} },
75861d77071SPavan Nikhilesh };
75961d77071SPavan Nikhilesh uint8_t src_map[][1] = { {100} };
76061d77071SPavan Nikhilesh uint8_t snk_map[][1] = { {100} };
76161d77071SPavan Nikhilesh
76261d77071SPavan Nikhilesh return graph_init("graph_hr", SOURCES(src_map), SINKS(snk_map),
76361d77071SPavan Nikhilesh STAGES(edge_map), NODES_PER_STAGE(edge_map), src_map,
76461d77071SPavan Nikhilesh snk_map, edge_map, 0);
76561d77071SPavan Nikhilesh }
76661d77071SPavan Nikhilesh
76761d77071SPavan Nikhilesh /* Graph Topology
76861d77071SPavan Nikhilesh * nodes per stage: 1
76961d77071SPavan Nikhilesh * stages: 4
77061d77071SPavan Nikhilesh * src: 1
77161d77071SPavan Nikhilesh * sink: 1
77261d77071SPavan Nikhilesh */
77361d77071SPavan Nikhilesh static inline int
graph_init_hr_brst_one(void)77461d77071SPavan Nikhilesh graph_init_hr_brst_one(void)
77561d77071SPavan Nikhilesh {
77661d77071SPavan Nikhilesh uint8_t edge_map[][1][1] = {
77761d77071SPavan Nikhilesh { {100} },
77861d77071SPavan Nikhilesh { {100} },
77961d77071SPavan Nikhilesh { {100} },
78061d77071SPavan Nikhilesh { {100} },
78161d77071SPavan Nikhilesh };
78261d77071SPavan Nikhilesh uint8_t src_map[][1] = { {100} };
78361d77071SPavan Nikhilesh uint8_t snk_map[][1] = { {100} };
78461d77071SPavan Nikhilesh
78561d77071SPavan Nikhilesh return graph_init("graph_hr", SOURCES(src_map), SINKS(snk_map),
78661d77071SPavan Nikhilesh STAGES(edge_map), NODES_PER_STAGE(edge_map), src_map,
78761d77071SPavan Nikhilesh snk_map, edge_map, 1);
78861d77071SPavan Nikhilesh }
78961d77071SPavan Nikhilesh
79061d77071SPavan Nikhilesh /* Graph Topology
79161d77071SPavan Nikhilesh * nodes per stage: 1
79261d77071SPavan Nikhilesh * stages: 4
79361d77071SPavan Nikhilesh * src: 2
79461d77071SPavan Nikhilesh * sink: 1
79561d77071SPavan Nikhilesh */
79661d77071SPavan Nikhilesh static inline int
graph_init_hr_multi_src(void)79761d77071SPavan Nikhilesh graph_init_hr_multi_src(void)
79861d77071SPavan Nikhilesh {
79961d77071SPavan Nikhilesh uint8_t edge_map[][1][1] = {
80061d77071SPavan Nikhilesh { {100} },
80161d77071SPavan Nikhilesh { {100} },
80261d77071SPavan Nikhilesh { {100} },
80361d77071SPavan Nikhilesh { {100} },
80461d77071SPavan Nikhilesh };
80561d77071SPavan Nikhilesh uint8_t src_map[][1] = {
80661d77071SPavan Nikhilesh {100}, {100}
80761d77071SPavan Nikhilesh };
80861d77071SPavan Nikhilesh uint8_t snk_map[][1] = { {100} };
80961d77071SPavan Nikhilesh
81061d77071SPavan Nikhilesh return graph_init("graph_hr", SOURCES(src_map), SINKS(snk_map),
81161d77071SPavan Nikhilesh STAGES(edge_map), NODES_PER_STAGE(edge_map), src_map,
81261d77071SPavan Nikhilesh snk_map, edge_map, 0);
81361d77071SPavan Nikhilesh }
81461d77071SPavan Nikhilesh
81561d77071SPavan Nikhilesh /* Graph Topology
81661d77071SPavan Nikhilesh * nodes per stage: 1
81761d77071SPavan Nikhilesh * stages: 4
81861d77071SPavan Nikhilesh * src: 1
81961d77071SPavan Nikhilesh * sink: 2
82061d77071SPavan Nikhilesh */
82161d77071SPavan Nikhilesh static inline int
graph_init_hr_multi_snk(void)82261d77071SPavan Nikhilesh graph_init_hr_multi_snk(void)
82361d77071SPavan Nikhilesh {
82461d77071SPavan Nikhilesh uint8_t edge_map[][1][1] = {
82561d77071SPavan Nikhilesh { {100} },
82661d77071SPavan Nikhilesh { {100} },
82761d77071SPavan Nikhilesh { {100} },
82861d77071SPavan Nikhilesh { {100} },
82961d77071SPavan Nikhilesh };
83061d77071SPavan Nikhilesh uint8_t src_map[][1] = { {100} };
83161d77071SPavan Nikhilesh uint8_t snk_map[][2] = { {50, 50} };
83261d77071SPavan Nikhilesh
83361d77071SPavan Nikhilesh return graph_init("graph_hr", SOURCES(src_map), SINKS(snk_map),
83461d77071SPavan Nikhilesh STAGES(edge_map), NODES_PER_STAGE(edge_map), src_map,
83561d77071SPavan Nikhilesh snk_map, edge_map, 0);
83661d77071SPavan Nikhilesh }
83761d77071SPavan Nikhilesh
83861d77071SPavan Nikhilesh /* Graph Topology
83961d77071SPavan Nikhilesh * nodes per stage: 4
84061d77071SPavan Nikhilesh * stages: 4
84161d77071SPavan Nikhilesh * src: 1
84261d77071SPavan Nikhilesh * sink: 4
84361d77071SPavan Nikhilesh */
84461d77071SPavan Nikhilesh static inline int
graph_init_tree(void)84561d77071SPavan Nikhilesh graph_init_tree(void)
84661d77071SPavan Nikhilesh {
84761d77071SPavan Nikhilesh uint8_t edge_map[][4][4] = {
84861d77071SPavan Nikhilesh {
84961d77071SPavan Nikhilesh {100, 0, 0, 0},
85061d77071SPavan Nikhilesh {0, 0, 0, 0},
85161d77071SPavan Nikhilesh {0, 0, 0, 0},
85261d77071SPavan Nikhilesh {0, 0, 0, 0}
85361d77071SPavan Nikhilesh },
85461d77071SPavan Nikhilesh {
85561d77071SPavan Nikhilesh {50, 0, 0, 0},
85661d77071SPavan Nikhilesh {50, 0, 0, 0},
85761d77071SPavan Nikhilesh {0, 0, 0, 0},
85861d77071SPavan Nikhilesh {0, 0, 0, 0}
85961d77071SPavan Nikhilesh },
86061d77071SPavan Nikhilesh {
86161d77071SPavan Nikhilesh {33, 33, 0, 0},
86261d77071SPavan Nikhilesh {34, 34, 0, 0},
86361d77071SPavan Nikhilesh {33, 33, 0, 0},
86461d77071SPavan Nikhilesh {0, 0, 0, 0}
86561d77071SPavan Nikhilesh },
86661d77071SPavan Nikhilesh {
86761d77071SPavan Nikhilesh {25, 25, 25, 0},
86861d77071SPavan Nikhilesh {25, 25, 25, 0},
86961d77071SPavan Nikhilesh {25, 25, 25, 0},
87061d77071SPavan Nikhilesh {25, 25, 25, 0}
87161d77071SPavan Nikhilesh }
87261d77071SPavan Nikhilesh };
87361d77071SPavan Nikhilesh uint8_t src_map[][4] = { {100, 0, 0, 0} };
87461d77071SPavan Nikhilesh uint8_t snk_map[][4] = {
87561d77071SPavan Nikhilesh {100, 0, 0, 0},
87661d77071SPavan Nikhilesh {0, 100, 0, 0},
87761d77071SPavan Nikhilesh {0, 0, 100, 0},
87861d77071SPavan Nikhilesh {0, 0, 0, 100}
87961d77071SPavan Nikhilesh };
88061d77071SPavan Nikhilesh
88161d77071SPavan Nikhilesh return graph_init("graph_full_split", SOURCES(src_map), SINKS(snk_map),
88261d77071SPavan Nikhilesh STAGES(edge_map), NODES_PER_STAGE(edge_map), src_map,
88361d77071SPavan Nikhilesh snk_map, edge_map, 0);
88461d77071SPavan Nikhilesh }
88561d77071SPavan Nikhilesh
88661d77071SPavan Nikhilesh /* Graph Topology
88761d77071SPavan Nikhilesh * nodes per stage: 4
88861d77071SPavan Nikhilesh * stages: 3
88961d77071SPavan Nikhilesh * src: 1
89061d77071SPavan Nikhilesh * sink: 1
89161d77071SPavan Nikhilesh */
89261d77071SPavan Nikhilesh static inline int
graph_init_reverse_tree(void)89361d77071SPavan Nikhilesh graph_init_reverse_tree(void)
89461d77071SPavan Nikhilesh {
89561d77071SPavan Nikhilesh uint8_t edge_map[][4][4] = {
89661d77071SPavan Nikhilesh {
89761d77071SPavan Nikhilesh {25, 25, 25, 25},
89861d77071SPavan Nikhilesh {25, 25, 25, 25},
89961d77071SPavan Nikhilesh {25, 25, 25, 25},
90061d77071SPavan Nikhilesh {25, 25, 25, 25}
90161d77071SPavan Nikhilesh },
90261d77071SPavan Nikhilesh {
90361d77071SPavan Nikhilesh {33, 33, 33, 33},
90461d77071SPavan Nikhilesh {33, 33, 33, 33},
90561d77071SPavan Nikhilesh {34, 34, 34, 34},
90661d77071SPavan Nikhilesh {0, 0, 0, 0}
90761d77071SPavan Nikhilesh },
90861d77071SPavan Nikhilesh {
90961d77071SPavan Nikhilesh {50, 50, 50, 0},
91061d77071SPavan Nikhilesh {50, 50, 50, 0},
91161d77071SPavan Nikhilesh {0, 0, 0, 0},
91261d77071SPavan Nikhilesh {0, 0, 0, 0}
91361d77071SPavan Nikhilesh },
91461d77071SPavan Nikhilesh };
91561d77071SPavan Nikhilesh uint8_t src_map[][4] = { {25, 25, 25, 25} };
91661d77071SPavan Nikhilesh uint8_t snk_map[][1] = { {100}, {100}, {0}, {0} };
91761d77071SPavan Nikhilesh
91861d77071SPavan Nikhilesh return graph_init("graph_full_split", SOURCES(src_map), SINKS(snk_map),
91961d77071SPavan Nikhilesh STAGES(edge_map), NODES_PER_STAGE(edge_map), src_map,
92061d77071SPavan Nikhilesh snk_map, edge_map, 0);
92161d77071SPavan Nikhilesh }
92261d77071SPavan Nikhilesh
92361d77071SPavan Nikhilesh /* Graph Topology
92461d77071SPavan Nikhilesh * nodes per stage: 4
92561d77071SPavan Nikhilesh * stages: 5
92661d77071SPavan Nikhilesh * src: 4
92761d77071SPavan Nikhilesh * sink: 4
92861d77071SPavan Nikhilesh */
92961d77071SPavan Nikhilesh static inline int
graph_init_parallel_tree(void)93061d77071SPavan Nikhilesh graph_init_parallel_tree(void)
93161d77071SPavan Nikhilesh {
93261d77071SPavan Nikhilesh uint8_t edge_map[][4][4] = {
93361d77071SPavan Nikhilesh {
93461d77071SPavan Nikhilesh {100, 0, 0, 0},
93561d77071SPavan Nikhilesh {0, 100, 0, 0},
93661d77071SPavan Nikhilesh {0, 0, 100, 0},
93761d77071SPavan Nikhilesh {0, 0, 0, 100}
93861d77071SPavan Nikhilesh },
93961d77071SPavan Nikhilesh {
94061d77071SPavan Nikhilesh {100, 0, 0, 0},
94161d77071SPavan Nikhilesh {0, 100, 0, 0},
94261d77071SPavan Nikhilesh {0, 0, 100, 0},
94361d77071SPavan Nikhilesh {0, 0, 0, 100}
94461d77071SPavan Nikhilesh },
94561d77071SPavan Nikhilesh {
94661d77071SPavan Nikhilesh {100, 0, 0, 0},
94761d77071SPavan Nikhilesh {0, 100, 0, 0},
94861d77071SPavan Nikhilesh {0, 0, 100, 0},
94961d77071SPavan Nikhilesh {0, 0, 0, 100}
95061d77071SPavan Nikhilesh },
95161d77071SPavan Nikhilesh {
95261d77071SPavan Nikhilesh {100, 0, 0, 0},
95361d77071SPavan Nikhilesh {0, 100, 0, 0},
95461d77071SPavan Nikhilesh {0, 0, 100, 0},
95561d77071SPavan Nikhilesh {0, 0, 0, 100}
95661d77071SPavan Nikhilesh },
95761d77071SPavan Nikhilesh {
95861d77071SPavan Nikhilesh {100, 0, 0, 0},
95961d77071SPavan Nikhilesh {0, 100, 0, 0},
96061d77071SPavan Nikhilesh {0, 0, 100, 0},
96161d77071SPavan Nikhilesh {0, 0, 0, 100}
96261d77071SPavan Nikhilesh },
96361d77071SPavan Nikhilesh };
96461d77071SPavan Nikhilesh uint8_t src_map[][4] = {
96561d77071SPavan Nikhilesh {100, 0, 0, 0},
96661d77071SPavan Nikhilesh {0, 100, 0, 0},
96761d77071SPavan Nikhilesh {0, 0, 100, 0},
96861d77071SPavan Nikhilesh {0, 0, 0, 100}
96961d77071SPavan Nikhilesh };
97061d77071SPavan Nikhilesh uint8_t snk_map[][4] = {
97161d77071SPavan Nikhilesh {100, 0, 0, 0},
97261d77071SPavan Nikhilesh {0, 100, 0, 0},
97361d77071SPavan Nikhilesh {0, 0, 100, 0},
97461d77071SPavan Nikhilesh {0, 0, 0, 100}
97561d77071SPavan Nikhilesh };
97661d77071SPavan Nikhilesh
97761d77071SPavan Nikhilesh return graph_init("graph_parallel", SOURCES(src_map), SINKS(snk_map),
97861d77071SPavan Nikhilesh STAGES(edge_map), NODES_PER_STAGE(edge_map), src_map,
97961d77071SPavan Nikhilesh snk_map, edge_map, 0);
98061d77071SPavan Nikhilesh }
98161d77071SPavan Nikhilesh
98261d77071SPavan Nikhilesh /** Graph Creation cheat sheet
98361d77071SPavan Nikhilesh * edge_map -> dictates graph flow from worker stage 0 to worker stage n-1.
98461d77071SPavan Nikhilesh * src_map -> dictates source nodes enqueue percentage to worker stage 0.
98561d77071SPavan Nikhilesh * snk_map -> dictates stage n-1 enqueue percentage to sink.
98661d77071SPavan Nikhilesh *
98761d77071SPavan Nikhilesh * Layout:
98861d77071SPavan Nikhilesh * edge_map[<nb_stages>][<nodes_per_stg>][<nodes_in_nxt_stg = nodes_per_stg>]
98961d77071SPavan Nikhilesh * src_map[<nb_sources>][<nodes_in_stage0 = nodes_per_stage>]
99061d77071SPavan Nikhilesh * snk_map[<nodes_in_stage(n-1) = nodes_per_stage>][<nb_sinks>]
99161d77071SPavan Nikhilesh *
99261d77071SPavan Nikhilesh * The last array dictates the percentage of received objs to enqueue to next
99361d77071SPavan Nikhilesh * stage.
99461d77071SPavan Nikhilesh *
99561d77071SPavan Nikhilesh * Note: edge_map[][0][] will always be unused as it will receive from source
99661d77071SPavan Nikhilesh *
99761d77071SPavan Nikhilesh * Example:
99861d77071SPavan Nikhilesh * Graph:
99961d77071SPavan Nikhilesh * http://bit.ly/2PqbqOy
100061d77071SPavan Nikhilesh * Each stage(n) connects to all nodes in the next stage in decreasing
100161d77071SPavan Nikhilesh * order.
100261d77071SPavan Nikhilesh * Since we can't resize the edge_map dynamically we get away by creating
100361d77071SPavan Nikhilesh * dummy nodes and assigning 0 percentages.
100461d77071SPavan Nikhilesh * Max nodes across all stages = 4
100561d77071SPavan Nikhilesh * stages = 3
100661d77071SPavan Nikhilesh * nb_src = 1
100761d77071SPavan Nikhilesh * nb_snk = 1
100861d77071SPavan Nikhilesh * // Stages
100961d77071SPavan Nikhilesh * edge_map[][4][4] = {
101061d77071SPavan Nikhilesh * // Nodes per stage
101161d77071SPavan Nikhilesh * {
101261d77071SPavan Nikhilesh * {25, 25, 25, 25},
101361d77071SPavan Nikhilesh * {25, 25, 25, 25},
101461d77071SPavan Nikhilesh * {25, 25, 25, 25},
101561d77071SPavan Nikhilesh * {25, 25, 25, 25}
101661d77071SPavan Nikhilesh * }, // This will be unused.
101761d77071SPavan Nikhilesh * {
101861d77071SPavan Nikhilesh * // Nodes enabled in current stage + prev stage enq %
101961d77071SPavan Nikhilesh * {33, 33, 33, 33},
102061d77071SPavan Nikhilesh * {33, 33, 33, 33},
102161d77071SPavan Nikhilesh * {34, 34, 34, 34},
102261d77071SPavan Nikhilesh * {0, 0, 0, 0}
102361d77071SPavan Nikhilesh * },
102461d77071SPavan Nikhilesh * {
102561d77071SPavan Nikhilesh * {50, 50, 50, 0},
102661d77071SPavan Nikhilesh * {50, 50, 50, 0},
102761d77071SPavan Nikhilesh * {0, 0, 0, 0},
102861d77071SPavan Nikhilesh * {0, 0, 0, 0}
102961d77071SPavan Nikhilesh * },
103061d77071SPavan Nikhilesh * };
103161d77071SPavan Nikhilesh * Above, each stage tells how much it should receive from previous except
103261d77071SPavan Nikhilesh * from stage_0.
103361d77071SPavan Nikhilesh *
103461d77071SPavan Nikhilesh * src_map[][4] = { {25, 25, 25, 25} };
103561d77071SPavan Nikhilesh * Here, we tell each source the % it has to send to stage_0 nodes. In
103661d77071SPavan Nikhilesh * case we want 2 source node we can declare as
103761d77071SPavan Nikhilesh * src_map[][4] = { {25, 25, 25, 25}, {25, 25, 25, 25} };
103861d77071SPavan Nikhilesh *
103961d77071SPavan Nikhilesh * snk_map[][1] = { {100}, {100}, {0}, {0} }
104061d77071SPavan Nikhilesh * Here, we tell stage - 1 nodes how much to enqueue to sink_0.
104161d77071SPavan Nikhilesh * If we have 2 sinks we can do as follows
104261d77071SPavan Nikhilesh * snk_map[][2] = { {50, 50}, {50, 50}, {0, 0}, {0, 0} }
104361d77071SPavan Nikhilesh */
104461d77071SPavan Nikhilesh
104561d77071SPavan Nikhilesh static struct unit_test_suite graph_perf_testsuite = {
104661d77071SPavan Nikhilesh .suite_name = "Graph library performance test suite",
104761d77071SPavan Nikhilesh .setup = graph_perf_setup,
104861d77071SPavan Nikhilesh .teardown = graph_perf_teardown,
104961d77071SPavan Nikhilesh .unit_test_cases = {
105061d77071SPavan Nikhilesh TEST_CASE_ST(graph_init_hr, graph_fini,
105161d77071SPavan Nikhilesh graph_hr_4s_1n_1src_1snk),
105261d77071SPavan Nikhilesh TEST_CASE_ST(graph_init_hr_brst_one, graph_fini,
105361d77071SPavan Nikhilesh graph_hr_4s_1n_1src_1snk_brst_one),
105461d77071SPavan Nikhilesh TEST_CASE_ST(graph_init_hr_multi_src, graph_fini,
105561d77071SPavan Nikhilesh graph_hr_4s_1n_2src_1snk),
105661d77071SPavan Nikhilesh TEST_CASE_ST(graph_init_hr_multi_snk, graph_fini,
105761d77071SPavan Nikhilesh graph_hr_4s_1n_1src_2snk),
105861d77071SPavan Nikhilesh TEST_CASE_ST(graph_init_tree, graph_fini,
105961d77071SPavan Nikhilesh graph_tree_4s_4n_1src_4snk),
106061d77071SPavan Nikhilesh TEST_CASE_ST(graph_init_reverse_tree, graph_fini,
106161d77071SPavan Nikhilesh graph_reverse_tree_3s_4n_1src_1snk),
106261d77071SPavan Nikhilesh TEST_CASE_ST(graph_init_parallel_tree, graph_fini,
106361d77071SPavan Nikhilesh graph_parallel_tree_5s_4n_4src_4snk),
106461d77071SPavan Nikhilesh TEST_CASES_END(), /**< NULL terminate unit test array */
106561d77071SPavan Nikhilesh },
106661d77071SPavan Nikhilesh };
106761d77071SPavan Nikhilesh
106861d77071SPavan Nikhilesh static int
test_graph_perf_func(void)106961d77071SPavan Nikhilesh test_graph_perf_func(void)
107061d77071SPavan Nikhilesh {
107161d77071SPavan Nikhilesh return unit_test_suite_runner(&graph_perf_testsuite);
107261d77071SPavan Nikhilesh }
107361d77071SPavan Nikhilesh
10743c60274cSJie Zhou #endif /* !RTE_EXEC_ENV_WINDOWS */
10753c60274cSJie Zhou
1076*d83fb967SDavid Marchand REGISTER_PERF_TEST(graph_perf_autotest, test_graph_perf_func);
1077