From 2f37b1bf16bb0101994b28bb7b5d739328e9ea34 Mon Sep 17 00:00:00 2001 From: Wendy Liang Date: Mon, 15 Aug 2016 15:39:56 -0700 Subject: [PATCH 1/1] Add matrix multiplication client demo application This application is to generate random 6*6 matrices, send them to the remote, and wait for the result, and then it will check if the result is as expected. Signed-off-by: Wendy Liang --- apps/matrix_multiply/matrix_multiply.c | 240 +++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 apps/matrix_multiply/matrix_multiply.c diff --git a/apps/matrix_multiply/matrix_multiply.c b/apps/matrix_multiply/matrix_multiply.c new file mode 100644 index 0000000..f49fbbe --- /dev/null +++ b/apps/matrix_multiply/matrix_multiply.c @@ -0,0 +1,240 @@ +/* This is a sample demonstration application that showcases usage of remoteproc +and rpmsg APIs on the remote core. This application is meant to run on the remote CPU +running baremetal code. This applicationr receives two matrices from the master, +multiplies them and returns the result to the master core. */ + +#include +#include +#include +#include +#include +#include "openamp/open_amp.h" +#include "rsc_table.h" +#include "platform_info.h" + +#define MAX_SIZE 6 +#define NUM_MATRIX 2 +#define SHUTDOWN_MSG 0xEF56A55A + +#define raw_printf(format, ...) printf(format, ##__VA_ARGS__) +#define LPRINTF(format, ...) raw_printf("CLIENT> " format, ##__VA_ARGS__) +#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__) + +typedef struct _matrix { + unsigned int size; + unsigned int elements[MAX_SIZE][MAX_SIZE]; +} matrix; + +/* Internal functions */ +static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl); +static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl); +static void rpmsg_read_cb(struct rpmsg_channel *, void *, int, void *, + unsigned long); + +/* Globals */ +static struct rpmsg_channel *app_rp_chnl; +static struct _matrix i_matrix[2]; +static struct _matrix e_matrix; +static unsigned int result_returned = 0; +static int err_cnt = 0;; +static struct rpmsg_endpoint *rp_ept; +static struct remote_proc *proc = NULL; +static struct rsc_table_info rsc_info; +extern const struct remote_resource_table resources; +extern struct rproc_info_plat_local proc_table; + +/* External functions */ +extern void init_system(); +extern void cleanup_system(); + +int __attribute__((weak)) _gettimeofday(struct timeval *tv, + void *tz) +{ + (void)tv; + (void)tz; + return 0; +} + +static void matrix_print(struct _matrix *m) +{ + unsigned int i, j; + + /* Generate two random matrices */ + LPRINTF("Printing matrix... \n"); + + for (i = 0; i < m->size; ++i) { + for (j = 0; j < m->size; ++j) + raw_printf(" %u ", m->elements[i][j]); + raw_printf("\n"); + } +} + +static void generate_matrices(int num_matrices, + unsigned int matrix_size, void *p_data) +{ + unsigned int i, j, k; + struct _matrix *p_matrix = p_data; + unsigned long value; + + + for (i = 0; i < (unsigned int)num_matrices; i++) { + /* Initialize workload */ + p_matrix[i].size = matrix_size; + + //LPRINTF("Input matrix %d \n", i); + for (j = 0; j < matrix_size; j++) { + //printf("\n"); + for (k = 0; k < matrix_size; k++) { + + value = (rand() & 0x7F); + value = value % 10; + p_matrix[i].elements[j][k] = value; + //printf(" %u ", p_matrix[i].elements[j][k]); + } + } + //printf("\n"); + } + +} + +static void matrix_multiply(const matrix * m, const matrix * n, matrix * r) +{ + unsigned int i, j, k; + + memset(r, 0x0, sizeof(matrix)); + r->size = m->size; + + for (i = 0; i < m->size; ++i) { + for (j = 0; j < n->size; ++j) { + for (k = 0; k < r->size; ++k) { + r->elements[i][j] += + m->elements[i][k] * n->elements[k][j]; + } + } + } +} + +/* Application entry point */ +int main() +{ + int shutdown_msg = SHUTDOWN_MSG; + int c; + int status = 0; + + /* Initialize HW system components */ + init_system(); + + rsc_info.rsc_tab = (struct resource_table *)&resources; + rsc_info.size = sizeof(resources); + + LPRINTF("Compute thread unblocked ..\n"); + LPRINTF("It will generate two random matrices.\n"); + LPRINTF("Send to the remote and get the computation result back.\n"); + LPRINTF("It will then check if the result is expected.\n"); + + /* Initialize RPMSG framework */ + status = + remoteproc_resource_init(&rsc_info, &proc_table, + rpmsg_channel_created, + rpmsg_channel_deleted, rpmsg_read_cb, + &proc, 1); + if (status) { + LPERROR("Failed to initialize remoteproc resource.\n"); + return -1; + } + + LPRINTF("Remote proc resource initialized.\n"); + while (!app_rp_chnl) { + hil_poll(proc->proc, 0); + } + + LPRINTF("RPMSG channel has created.\n"); + err_cnt = 0; + srand(time(NULL)); + for (c = 0; c < 200; c++) { + generate_matrices(2, MAX_SIZE, i_matrix); + matrix_multiply(&i_matrix[0], &i_matrix[1], + &e_matrix); + result_returned = 0; + status = rpmsg_send(app_rp_chnl, i_matrix, sizeof(i_matrix)); + + if (status) { + LPRINTF("Error sending data...\n"); + break; + } + LPRINTF("Matrix multiply: sent : %u\n", sizeof(i_matrix)); + do { + hil_poll(proc->proc, 0); + } while (!result_returned && !err_cnt && app_rp_chnl); + + if (err_cnt && !app_rp_chnl) + break; + } + + if (app_rp_chnl) { + /* Send shutdown message to remote */ + rpmsg_send(app_rp_chnl, &shutdown_msg, sizeof(int)); + } + sleep(1); + LPRINTF("Quitting application .. Matrix multiplication end\n"); + + LPRINTF("**********************************\n"); + LPRINTF(" Test Results: Error count = %d \n", err_cnt); + LPRINTF("**********************************\n"); + + remoteproc_resource_deinit(proc); + cleanup_system(); + + return 0; +} + +static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl) +{ + app_rp_chnl = rp_chnl; + rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL, + RPMSG_ADDR_ANY); +} + +static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl) +{ + (void)rp_chnl; + rpmsg_destroy_ept(rp_ept); + LPRINTF("%s\n", __func__); + app_rp_chnl = NULL; + rp_ept = NULL; +} + +static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len, + void *priv, unsigned long src) +{ + (void)rp_chnl; + (void)priv; + (void)src; + struct _matrix *r_matrix = (struct _matrix *)data; + int i, j; + if (len != sizeof(struct _matrix)) { + LPERROR("Received matrix is of invalid len: %d:%d\n", + (int)sizeof(struct _matrix), len); + err_cnt++; + return; + } + for (i = 0; i < MAX_SIZE; i++) { + for (j = 0; j < MAX_SIZE; j++) { + if (r_matrix->elements[i][j] != + e_matrix.elements[i][j]) { + err_cnt++; + break; + } + } + } + if (err_cnt) { + LPERROR("Result mismatched...\n"); + LPERROR("Expected matrix:\n"); + matrix_print(&e_matrix); + LPERROR("Actual matrix:\n"); + matrix_print(r_matrix); + } else { + result_returned = 1; + } +} + -- 2.39.2