3b371741f263501f0d2b6356c7e14953918d19c2
[dpdk.git] / app / test-gpudev / main.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2021 NVIDIA Corporation & Affiliates
3  */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdint.h>
9 #include <inttypes.h>
10 #include <stdarg.h>
11 #include <errno.h>
12 #include <getopt.h>
13
14 #include <rte_common.h>
15 #include <rte_malloc.h>
16 #include <rte_memory.h>
17 #include <rte_eal.h>
18 #include <rte_ether.h>
19 #include <rte_ethdev.h>
20 #include <rte_mempool.h>
21 #include <rte_mbuf.h>
22
23 #include <rte_gpudev.h>
24
25 enum app_args {
26         ARG_HELP,
27         ARG_MEMPOOL
28 };
29
30 static void
31 usage(const char *prog_name)
32 {
33         printf("%s [EAL options] --\n",
34                 prog_name);
35 }
36
37 static void
38 args_parse(int argc, char **argv)
39 {
40         char **argvopt;
41         int opt;
42         int opt_idx;
43
44         static struct option lgopts[] = {
45                 { "help", 0, 0, ARG_HELP},
46                 /* End of options */
47                 { 0, 0, 0, 0 }
48         };
49
50         argvopt = argv;
51         while ((opt = getopt_long(argc, argvopt, "",
52                                 lgopts, &opt_idx)) != EOF) {
53                 switch (opt) {
54                 case ARG_HELP:
55                         usage(argv[0]);
56                         break;
57                 default:
58                         usage(argv[0]);
59                         rte_exit(EXIT_FAILURE, "Invalid option: %s\n", argv[optind]);
60                         break;
61                 }
62         }
63 }
64
65 static int
66 alloc_gpu_memory(uint16_t gpu_id)
67 {
68         void *ptr_1 = NULL;
69         void *ptr_2 = NULL;
70         size_t buf_bytes = 1024;
71         int ret;
72
73         printf("\n=======> TEST: Allocate GPU memory\n");
74
75         /* Alloc memory on GPU 0 */
76         ptr_1 = rte_gpu_mem_alloc(gpu_id, buf_bytes);
77         if (ptr_1 == NULL) {
78                 fprintf(stderr, "rte_gpu_mem_alloc GPU memory returned error\n");
79                 return -1;
80         }
81         printf("GPU memory allocated at 0x%p %zdB\n", ptr_1, buf_bytes);
82
83         ptr_2 = rte_gpu_mem_alloc(gpu_id, buf_bytes);
84         if (ptr_2 == NULL) {
85                 fprintf(stderr, "rte_gpu_mem_alloc GPU memory returned error\n");
86                 return -1;
87         }
88         printf("GPU memory allocated at 0x%p %zdB\n", ptr_2, buf_bytes);
89
90         ret = rte_gpu_mem_free(gpu_id, (uint8_t *)(ptr_1)+0x700);
91         if (ret < 0) {
92                 printf("GPU memory 0x%p + 0x700 NOT freed because of memory address not recognized by driver\n", ptr_1);
93         } else {
94                 fprintf(stderr, "rte_gpu_mem_free erroneously freed GPU memory 0x%p + 0x700\n", ptr_1);
95                 return -1;
96         }
97
98         ret = rte_gpu_mem_free(gpu_id, ptr_2);
99         if (ret < 0) {
100                 fprintf(stderr, "rte_gpu_mem_free returned error %d\n", ret);
101                 return -1;
102         }
103         printf("GPU memory 0x%p freed\n", ptr_2);
104
105         ret = rte_gpu_mem_free(gpu_id, ptr_1);
106         if (ret < 0) {
107                 fprintf(stderr, "rte_gpu_mem_free returned error %d\n", ret);
108                 return -1;
109         }
110         printf("GPU memory 0x%p freed\n", ptr_1);
111
112         return 0;
113 }
114
115 static int
116 register_cpu_memory(uint16_t gpu_id)
117 {
118         void *ptr = NULL;
119         size_t buf_bytes = 1024;
120         int ret;
121
122         printf("\n=======> TEST: Register CPU memory\n");
123
124         /* Alloc memory on CPU visible from GPU 0 */
125         ptr = rte_zmalloc(NULL, buf_bytes, 0);
126         if (ptr == NULL) {
127                 fprintf(stderr, "Failed to allocate CPU memory.\n");
128                 return -1;
129         }
130
131         ret = rte_gpu_mem_register(gpu_id, buf_bytes, ptr);
132         if (ret < 0) {
133                 fprintf(stderr, "rte_gpu_mem_register CPU memory returned error %d\n", ret);
134                 return -1;
135         }
136         printf("CPU memory registered at 0x%p %zdB\n", ptr, buf_bytes);
137
138         ret = rte_gpu_mem_unregister(gpu_id, (uint8_t *)(ptr)+0x700);
139         if (ret < 0) {
140                 printf("CPU memory 0x%p + 0x700 NOT unregistered because of memory address not recognized by driver\n", ptr);
141         } else {
142                 fprintf(stderr, "rte_gpu_mem_free erroneously freed GPU memory 0x%p + 0x700\n", ptr);
143                 return -1;
144         }
145         printf("CPU memory 0x%p unregistered\n", ptr);
146
147         ret = rte_gpu_mem_unregister(gpu_id, ptr);
148         if (ret < 0) {
149                 fprintf(stderr, "rte_gpu_mem_unregister returned error %d\n", ret);
150                 return -1;
151         }
152         printf("CPU memory 0x%p unregistered\n", ptr);
153
154         return 0;
155 }
156
157 static int
158 create_update_comm_flag(uint16_t gpu_id)
159 {
160         struct rte_gpu_comm_flag devflag;
161         int ret = 0;
162         uint32_t set_val;
163         uint32_t get_val;
164
165         printf("\n=======> TEST: Communication flag\n");
166
167         ret = rte_gpu_comm_create_flag(gpu_id, &devflag, RTE_GPU_COMM_FLAG_CPU);
168         if (ret < 0) {
169                 fprintf(stderr, "rte_gpu_comm_create_flag returned error %d\n", ret);
170                 return -1;
171         }
172
173         set_val = 25;
174         ret = rte_gpu_comm_set_flag(&devflag, set_val);
175         if (ret < 0) {
176                 fprintf(stderr, "rte_gpu_comm_set_flag returned error %d\n", ret);
177                 return -1;
178         }
179
180         ret = rte_gpu_comm_get_flag_value(&devflag, &get_val);
181         if (ret < 0) {
182                 fprintf(stderr, "rte_gpu_comm_get_flag_value returned error %d\n", ret);
183                 return -1;
184         }
185
186         printf("Communication flag value at 0x%p was set to %d and current value is %d\n", devflag.ptr, set_val, get_val);
187
188         set_val = 38;
189         ret = rte_gpu_comm_set_flag(&devflag, set_val);
190         if (ret < 0) {
191                 fprintf(stderr, "rte_gpu_comm_set_flag returned error %d\n", ret);
192                 return -1;
193         }
194
195         ret = rte_gpu_comm_get_flag_value(&devflag, &get_val);
196         if (ret < 0) {
197                 fprintf(stderr, "rte_gpu_comm_get_flag_value returned error %d\n", ret);
198                 return -1;
199         }
200
201         printf("Communication flag value at 0x%p was set to %d and current value is %d\n", devflag.ptr, set_val, get_val);
202
203         ret = rte_gpu_comm_destroy_flag(&devflag);
204         if (ret < 0) {
205                 fprintf(stderr, "rte_gpu_comm_destroy_flags returned error %d\n", ret);
206                 return -1;
207         }
208
209         return 0;
210 }
211
212 int
213 main(int argc, char **argv)
214 {
215         int ret;
216         int nb_gpus = 0;
217         int16_t gpu_id = 0;
218         struct rte_gpu_info ginfo;
219
220         /* Init EAL. */
221         ret = rte_eal_init(argc, argv);
222         if (ret < 0)
223                 rte_exit(EXIT_FAILURE, "EAL init failed\n");
224         argc -= ret;
225         argv += ret;
226         if (argc > 1)
227                 args_parse(argc, argv);
228         argc -= ret;
229         argv += ret;
230
231         nb_gpus = rte_gpu_count_avail();
232         printf("\n\nDPDK found %d GPUs:\n", nb_gpus);
233         RTE_GPU_FOREACH(gpu_id)
234         {
235                 if (rte_gpu_info_get(gpu_id, &ginfo))
236                         rte_exit(EXIT_FAILURE, "rte_gpu_info_get error - bye\n");
237
238                 printf("\tGPU ID %d\n\t\tparent ID %d GPU Bus ID %s NUMA node %d Tot memory %.02f MB, Tot processors %d\n",
239                                 ginfo.dev_id,
240                                 ginfo.parent,
241                                 ginfo.name,
242                                 ginfo.numa_node,
243                                 (((float)ginfo.total_memory)/(float)1024)/(float)1024,
244                                 ginfo.processor_count
245                         );
246         }
247         printf("\n\n");
248
249         if (nb_gpus == 0) {
250                 fprintf(stderr, "Need at least one GPU on the system to run the example\n");
251                 return EXIT_FAILURE;
252         }
253
254         gpu_id = 0;
255
256         /**
257          * Memory tests
258          */
259         alloc_gpu_memory(gpu_id);
260         register_cpu_memory(gpu_id);
261
262         /**
263          * Communication items test
264          */
265         create_update_comm_flag(gpu_id);
266
267         /* clean up the EAL */
268         rte_eal_cleanup();
269         printf("Bye...\n");
270
271         return EXIT_SUCCESS;
272 }