Update demo apps to use new HIL proc APIs
[processor-sdk/open-amp.git] / apps / matrix_multiply / matrix_multiply.c
1 /* This is a sample demonstration application that showcases usage of remoteproc
2 and rpmsg APIs on the remote core. This application is meant to run on the remote CPU 
3 running baremetal code. This applicationr receives two matrices from the master, 
4 multiplies them and returns the result to the master core. */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <time.h>
10 #include <unistd.h>
11 #include "openamp/open_amp.h"
12 #include "rsc_table.h"
14 #define MAX_SIZE                6
15 #define NUM_MATRIX              2
16 #define SHUTDOWN_MSG            0xEF56A55A
18 #define raw_printf(format, ...) printf(format, ##__VA_ARGS__)
19 #define LPRINTF(format, ...) raw_printf("CLIENT> " format, ##__VA_ARGS__)
20 #define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
22 typedef struct _matrix {
23         unsigned int size;
24         unsigned int elements[MAX_SIZE][MAX_SIZE];
25 } matrix;
27 /* Internal functions */
28 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl);
29 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl);
30 static void rpmsg_read_cb(struct rpmsg_channel *, void *, int, void *,
31                           unsigned long);
33 /* Globals */
34 static struct rpmsg_channel *app_rp_chnl;
35 static struct _matrix i_matrix[2];
36 static struct _matrix e_matrix;
37 static unsigned int result_returned = 0;
38 static int err_cnt = 0;;
39 static struct rpmsg_endpoint *rp_ept;
40 static struct remote_proc *proc = NULL;
41 static struct rsc_table_info rsc_info;
42 extern const struct remote_resource_table resources;
44 /* External functions */
45 extern void init_system();
46 extern void cleanup_system();
47 extern struct hil_proc *platform_create_proc(int proc_index);
49 int __attribute__((weak)) _gettimeofday(struct timeval *tv,
50                                         void *tz)
51 {
52         (void)tv;
53         (void)tz;
54         return 0;
55 }
57 static void matrix_print(struct _matrix *m)
58 {
59         unsigned int i, j;
61         /* Generate two random matrices */
62         LPRINTF("Printing matrix... \n");
64         for (i = 0; i < m->size; ++i) {
65                 for (j = 0; j < m->size; ++j)
66                         raw_printf(" %u ", m->elements[i][j]);
67                 raw_printf("\n");
68         }
69 }
71 static void generate_matrices(int num_matrices,
72                               unsigned int matrix_size, void *p_data)
73 {
74         unsigned int i, j, k;
75         struct _matrix *p_matrix = p_data;
76         unsigned long value;
79         for (i = 0; i < (unsigned int)num_matrices; i++) {
80                 /* Initialize workload */
81                 p_matrix[i].size = matrix_size;
83                 //LPRINTF("Input matrix %d \n", i);
84                 for (j = 0; j < matrix_size; j++) {
85                         //printf("\n");
86                         for (k = 0; k < matrix_size; k++) {
88                                 value = (rand() & 0x7F);
89                                 value = value % 10;
90                                 p_matrix[i].elements[j][k] = value;
91                                 //printf(" %u ", p_matrix[i].elements[j][k]);
92                         }
93                 }
94                 //printf("\n");
95         }
97 }
99 static void matrix_multiply(const matrix * m, const matrix * n, matrix * r)
101         unsigned int i, j, k;
103         memset(r, 0x0, sizeof(matrix));
104         r->size = m->size;
106         for (i = 0; i < m->size; ++i) {
107                 for (j = 0; j < n->size; ++j) {
108                         for (k = 0; k < r->size; ++k) {
109                                 r->elements[i][j] +=
110                                     m->elements[i][k] * n->elements[k][j];
111                         }
112                 }
113         }
116 /* Application entry point */
117 int main()
119         int shutdown_msg = SHUTDOWN_MSG;
120         int c;
121         int status = 0;
122         struct hil_proc *hproc;
124         /* Initialize HW system components */
125         init_system();
127         rsc_info.rsc_tab = (struct resource_table *)&resources;
128         rsc_info.size = sizeof(resources);
130         LPRINTF("Compute thread unblocked ..\n");
131         LPRINTF("It will generate two random matrices.\n");
132         LPRINTF("Send to the remote and get the computation result back.\n");
133         LPRINTF("It will then check if the result is expected.\n");
135         /* Create HIL proc */
136         hproc = platform_create_proc(0);
137         if (!hproc) {
138                 LPERROR("Failed to create hil proc.\n");
139                 return -1;
140         }
141         /* Initialize RPMSG framework */
142         status =
143             remoteproc_resource_init(&rsc_info, hproc,
144                                      rpmsg_channel_created,
145                                      rpmsg_channel_deleted, rpmsg_read_cb,
146                                      &proc, 1);
147         if (status) {
148                 LPERROR("Failed  to initialize remoteproc resource.\n");
149                 return -1;
150         }
152         LPRINTF("Remote proc resource initialized.\n");
153         while (!app_rp_chnl) {
154                 hil_poll(proc->proc, 0);
155         }
157         LPRINTF("RPMSG channel has created.\n");
158         err_cnt = 0;
159         srand(time(NULL));
160         for (c = 0; c < 200; c++) {
161                 generate_matrices(2, MAX_SIZE, i_matrix);
162                 matrix_multiply(&i_matrix[0], &i_matrix[1],
163                                 &e_matrix);
164                 result_returned = 0;
165                 status = rpmsg_send(app_rp_chnl, i_matrix, sizeof(i_matrix));
167                 if (status) {
168                         LPRINTF("Error sending data...\n");
169                         break;
170                 }
171                 LPRINTF("Matrix multiply: sent : %u\n", sizeof(i_matrix));
172                 do {
173                         hil_poll(proc->proc, 0);
174                 } while (!result_returned && !err_cnt && app_rp_chnl);
176                 if (err_cnt && !app_rp_chnl)
177                         break;
178         }
180         if (app_rp_chnl) {
181                 /* Send shutdown message to remote */
182                 rpmsg_send(app_rp_chnl, &shutdown_msg, sizeof(int));
183         }
184         sleep(1);
185         LPRINTF("Quitting application .. Matrix multiplication end\n");
187         LPRINTF("**********************************\n");
188         LPRINTF(" Test Results: Error count = %d \n", err_cnt);
189         LPRINTF("**********************************\n");
191         remoteproc_resource_deinit(proc);
192         cleanup_system();
194         return 0;
197 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
199         app_rp_chnl = rp_chnl;
200         rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
201                                   RPMSG_ADDR_ANY);
204 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
206         (void)rp_chnl;
207         rpmsg_destroy_ept(rp_ept);
208         LPRINTF("%s\n", __func__);
209         app_rp_chnl = NULL;
210         rp_ept = NULL;
213 static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
214                           void *priv, unsigned long src)
216         (void)rp_chnl;
217         (void)priv;
218         (void)src;
219         struct _matrix *r_matrix = (struct _matrix *)data;
220         int i, j;
221         if (len != sizeof(struct _matrix)) {
222                 LPERROR("Received matrix is of invalid len: %d:%d\n",
223                         (int)sizeof(struct _matrix), len);
224                 err_cnt++;
225                 return;
226         }
227         for (i = 0; i < MAX_SIZE; i++) {
228                 for (j = 0; j < MAX_SIZE; j++) {
229                         if (r_matrix->elements[i][j] !=
230                                 e_matrix.elements[i][j]) {
231                                 err_cnt++;
232                                 break;
233                         }
234                 }
235         }
236         if (err_cnt) {
237                 LPERROR("Result mismatched...\n");
238                 LPERROR("Expected matrix:\n");
239                 matrix_print(&e_matrix);
240                 LPERROR("Actual matrix:\n");
241                 matrix_print(r_matrix);
242         } else {
243                 result_returned = 1;
244         }