From 896888302292c3c85047ae8a12e85f33656a5163 Mon Sep 17 00:00:00 2001 From: "Julian M. Kunkel" Date: Tue, 20 Aug 2019 16:51:25 +0100 Subject: [PATCH] Demonstrator completed --- README.md | 9 +++++++ emulation/ngi.c | 32 +++++++++++++++++++++-- emulation/ngi.h | 23 ++++++++++++++++- test/reduce-ngi.c | 53 ++++++++++++++++++++++++++++++--------- test/reduce-traditional.c | 3 ++- 5 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..4968be5 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Function Shipping Example + +The purpose is to foster discussion of capabilities. + +The library in ./emulation provides a development kit for function shipping. +In test/ there is test code showing + - how a reduction happens traditionally in the client. + - how reduction could be executed on the server (that uses the emulation/dev kit) +The run.sh script contains everything to build and run the both test applications. diff --git a/emulation/ngi.c b/emulation/ngi.c index 913fa87..1f49261 100644 --- a/emulation/ngi.c +++ b/emulation/ngi.c @@ -1,5 +1,33 @@ #include +#include +#include +#include -void server_reduce(FILE * file, size_t off, size_t size){ - +int server_reduce(FILE * file, ngi_op_t op, ngi_type_t type, void * out_buff, size_t off, size_t size){ + fseek(file, off, SEEK_SET); + + assert(type == NGI_TYPE_FLOAT); + assert(op == NGI_OP_MAX); + + float * data = malloc(size); + fread(data, size, 1, file); + + float mx = -INFINITY; + for(size_t i=0; i < size/sizeof(float); i++){ + mx = data[i] > mx ? data[i]: mx; + } + *(float*) out_buff = mx; + + free(data); + return 0; +} + +int server_reduce_any_func(FILE * file, void (*func)(int8_t * data, void * out_buff, size_t off, size_t size), void * out_buff, size_t max_out_data_size, size_t off, size_t size){ + fseek(file, off, SEEK_SET); + + int8_t * data = malloc(size); + fread(data, size, 1, file); + func(data, out_buff, off, size); + free(data); + return 0; } diff --git a/emulation/ngi.h b/emulation/ngi.h index 0a4efdb..d6cbdda 100644 --- a/emulation/ngi.h +++ b/emulation/ngi.h @@ -4,6 +4,27 @@ #include #include -void server_reduce(FILE * file, size_t off, size_t size); +typedef enum NGI_OP{ + NGI_OP_MAX +} ngi_op_t; + +typedef enum NGI_TYPE{ + NGI_TYPE_FLOAT +} ngi_type_t; + +/* + * This function invoces a well known reduction operation on data of a well known type + * Return 0 upon success, any other code, if e.g., short read + */ +int server_reduce(FILE * file, ngi_op_t op, ngi_type_t type, void * out_buff, size_t off, size_t size); + +/* + * This function runs any type of function on the data + * It assumes that the output buffer was initialized accordingly and that it is of max_out_data_size + * func must be associative and needs to read/output the output buffer as intermediate storage + * Return 0 upon success, any other code, if e.g., short read + */ +int server_reduce_any_func(FILE * file, void (*func)(int8_t * data, void * out_buff, size_t off, size_t size), void * out_buff, size_t max_out_data_size, size_t off, size_t size); + #endif diff --git a/test/reduce-ngi.c b/test/reduce-ngi.c index 3376a12..31c6fd9 100644 --- a/test/reduce-ngi.c +++ b/test/reduce-ngi.c @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -14,26 +15,54 @@ // read the data and reduce it void reduce_data(int size){ - float * data = malloc(size * sizeof(float)); FILE * file = fopen("data.bin", "rb"); - fread(data, size*sizeof(float), 1, file); - fclose(file); - - server_reduce(file, 0, size*sizeof(float)); - - float mx = FLT_MIN; - for(int i=0; i < size; i++){ - mx = data[i] > mx ? data[i]: mx; - } - free(data); - + float mx; + server_reduce(file, NGI_OP_MAX, NGI_TYPE_FLOAT, & mx, 0, size*sizeof(float)); printf("Maximum: %f\n", mx); + fclose(file); } +void reduce_min_func(int8_t * data_i, void * out_buff, size_t off, size_t size){ + float * outf = (float*) out_buff; + float mx = *outf; + float * data = (float*) data_i; + for(size_t i=0; i < size/sizeof(float); i++){ + mx = data[i] > mx ? data[i]: mx; + } + *outf = mx; +} + +void reduce_minmax_func(int8_t * data_i, void * out_buff, size_t off, size_t size){ + float * outf = (float*) out_buff; + float mi = outf[0]; + float mx = outf[1]; + float * data = (float*) data_i; + for(size_t i=0; i < size/sizeof(float); i++){ + mx = data[i] > mx ? data[i]: mx; + mi = data[i] < mi ? data[i]: mi; + } + outf[0] = mi; + outf[1] = mx; +} + +// alternative using an external function +void reduce_data_func(int size){ + FILE * file = fopen("data.bin", "rb"); + float mx; + mx = -INFINITY; + server_reduce_any_func(file, reduce_min_func, &mx, sizeof(float), 0, size*sizeof(float)); + printf("Maximum: %f\n", mx); + + float minmax[2] = {INFINITY, -INFINITY}; + server_reduce_any_func(file, reduce_minmax_func, minmax, 2* sizeof(float), 0, size*sizeof(float)); + printf("Min/Max: %f - %f\n", minmax[0], minmax[1]); + fclose(file); +} int main(){ int size = 100; reduce_data(size); + reduce_data_func(size); return 0; } diff --git a/test/reduce-traditional.c b/test/reduce-traditional.c index f97d9e0..dac1f6a 100644 --- a/test/reduce-traditional.c +++ b/test/reduce-traditional.c @@ -5,6 +5,7 @@ #include #include #include +#include /* @@ -18,7 +19,7 @@ void reduce_data(int size){ fread(data, size*sizeof(float), 1, file); fclose(file); - float mx = FLT_MIN; + float mx = -INFINITY; for(int i=0; i < size; i++){ mx = data[i] > mx ? data[i]: mx; }