xref: /dpdk/app/test/test_graph_perf.c (revision d83fb967212efa19d272e7fa65d17c9ad94b17c1)
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(&param, 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(&param);
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