From 88167726f2403a18941cdc4828c00ef4f46db431 Mon Sep 17 00:00:00 2001 From: "jijoong.moon" Date: Wed, 28 Nov 2018 11:33:42 +0900 Subject: [PATCH] [DummyLSTM] Add Dummy LSTM custom example Add Dymmy LSTM custom example. Two input stream and two outputstream. First input is recursion and Second input is new input stream. First output is recursion stream which is matched with first inputstream and the second output stream is matched with second input stream. - in2_tmp0 = (in2+in1)/2 (in2_tmp0 : mimic sigmoid) - in2_tmp1 = tanh(in2) - in0 = in0 x in2_tmp0 - in0 = in0 + (in2_tmp0 x in2_tmp1) - out0 = in0 - out1 = in1 = (tanh(in0) x in2_tmp0) +------------+ in0 ------->| |----> out0 in1 ------->| dummy LSTM |----> out1 in2 (new)-->| | | +------------+ +--> out (equal out1) **Self evaluation:** 1. Build test: [X]Passed [ ]Failed [ ]Skipped 2. Run test: [X]Passed [ ]Failed [ ]Skipped Signed-off-by: jijoong.moon --- nnstreamer_example/CMakeLists.txt | 1 + .../custom_example_LSTM/CMakeLists.txt | 8 + .../custom_example_LSTM/dummy_LSTM.c | 166 +++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 nnstreamer_example/custom_example_LSTM/CMakeLists.txt create mode 100644 nnstreamer_example/custom_example_LSTM/dummy_LSTM.c diff --git a/nnstreamer_example/CMakeLists.txt b/nnstreamer_example/CMakeLists.txt index fdd9f0b..d0868d5 100644 --- a/nnstreamer_example/CMakeLists.txt +++ b/nnstreamer_example/CMakeLists.txt @@ -15,6 +15,7 @@ ADD_SUBDIRECTORY(custom_example_scaler) ADD_SUBDIRECTORY(custom_example_average) ADD_SUBDIRECTORY(custom_example_opencv) ADD_SUBDIRECTORY(custom_example_RNN) +ADD_SUBDIRECTORY(custom_example_LSTM) ADD_SUBDIRECTORY(example_cam) ADD_SUBDIRECTORY(example_sink) ADD_SUBDIRECTORY(example_filter) diff --git a/nnstreamer_example/custom_example_LSTM/CMakeLists.txt b/nnstreamer_example/custom_example_LSTM/CMakeLists.txt new file mode 100644 index 0000000..9ba8391 --- /dev/null +++ b/nnstreamer_example/custom_example_LSTM/CMakeLists.txt @@ -0,0 +1,8 @@ +ADD_LIBRARY(dummyLSTM SHARED dummy_LSTM.c) + +TARGET_LINK_LIBRARIES(dummyLSTM nnstreamer) + +INSTALL(TARGETS dummyLSTM + LIBRARY DESTINATION ${LIB_INSTALL_DIR} + ARCHIVE DESTINATION ${LIB_INSTALL_DIR} + ) diff --git a/nnstreamer_example/custom_example_LSTM/dummy_LSTM.c b/nnstreamer_example/custom_example_LSTM/dummy_LSTM.c new file mode 100644 index 0000000..79b0840 --- /dev/null +++ b/nnstreamer_example/custom_example_LSTM/dummy_LSTM.c @@ -0,0 +1,166 @@ +/** + * NNStreamer Custom Filter LSTM Example, "dummyLSTM" + * Copyright (C) 2018 Jijoong Moon + * + * LICENSE: LGPL-2.1 + * + * @file dummy_LSTM.c + * @date 28 Nov 2018 + * @brief Custom NNStreamer LSTM Model. "Dummy LSTM" + * @author Jijoong Moon + * @bug No known bugs except for NYI items + * + * This supports two "4:4:4:1" float32 tensors, where the first one is the new tensor and the second one is "recurring" tensor (output of the previous frame). + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TSIZE (4) + +/** + * @brief _pt_data + */ +typedef struct _pt_data +{ + uint32_t id; /***< Just for testing */ + uint32_t counter; /**< Internal frame counter for debugging/demo */ + GstTensorInfo info[3]; /**< tensor info. 0:new frame / 1:recurring frame 2:recurring frame*/ +} pt_data; + +/** + * @brief Initialize dummy-LSTM + */ +static void * +pt_init (const GstTensorFilterProperties * prop) +{ + pt_data *data = (pt_data *) malloc (sizeof (pt_data)); + int i; + + data->id = 0; + data->counter = 0; + data->info[0].dimension[0] = TSIZE; + data->info[0].dimension[1] = TSIZE; + data->info[0].dimension[2] = TSIZE; + for (i = 3; i < NNS_TENSOR_RANK_LIMIT; i++) + data->info[0].dimension[i] = 1; + data->info[0].type = _NNS_FLOAT32; + data->info[1] = data->info[0]; + data->info[2] = data->info[0]; + + return data; +} + +/** + * @brief Exit dummy-LSTM + */ +static void +pt_exit (void *private_data, const GstTensorFilterProperties * prop) +{ + pt_data *data = private_data; + assert (data); + free (data); +} + +/** + * @brief get the input tensor dimensions of dummy-LSTM (4:4:4 float32, 4:4:4 float32) + */ +static int +get_inputDim (void *private_data, const GstTensorFilterProperties * prop, + GstTensorsInfo * info) +{ + pt_data *data = private_data; + + assert (data); + assert (NNS_TENSOR_RANK_LIMIT >= 3); + + info->num_tensors = 3; + info->info[0] = data->info[0]; + info->info[1] = data->info[1]; + info->info[2] = data->info[2]; + return 0; +} + +/** + * @brief get the output tensor dimensions of dummy-LSTM (4:4:4 float32) + */ +static int +get_outputDim (void *private_data, const GstTensorFilterProperties * prop, + GstTensorsInfo * info) +{ + pt_data *data = private_data; + + assert (data); + assert (NNS_TENSOR_RANK_LIMIT >= 3); + + info->num_tensors = 2; + info->info[0] = data->info[0]; + info->info[1] = data->info[1]; + return 0; +} + +/** + * @brief Get the offset of the tensor data blob pointer. + */ +static size_t +location (uint32_t c, uint32_t w, uint32_t h) +{ + return c + TSIZE * (w + TSIZE * h); +} + +/** + * @brief INFERENCE! + */ +static int +pt_invoke (void *private_data, const GstTensorFilterProperties * prop, + const GstTensorMemory * input, GstTensorMemory * output) +{ + pt_data *data = private_data; + uint32_t c, w, h; + float *in0, *in1, *in2, *out0, *out1; + float in2_tmp0, in2_tmp1; + + if (!data || !input || !output) + return -EINVAL; + + in0 = input[0].data; + in1 = input[1].data; + in2 = input[2].data; + out0 = output[0].data; + out1 = output[1].data; + + if (!in0 || !in1 || !in2 || !out0 || !out1) + return -EINVAL; + + for (h = 0; h < TSIZE; h++) { + for (w = 0; w < TSIZE; w++) { + for (c = 0; c < TSIZE; c++) { + in2_tmp0 = (in2[location (c, w, h)] + in1[location (c, w, h)]) / 2; + in2_tmp1 = tanh (in2[location (c, w, h)]); + in0[location (c, w, h)] = in0[location (c, w, h)] * in2_tmp0; + in0[location (c, w, h)] += (in2_tmp0 * in2_tmp1); + out0[location (c, w, h)] = in0[location (c, w, h)]; + out1[location (c, w, h)] = tanh (in0[location (c, w, h)]) * in2_tmp0; + } + } + } + + return 0; +} + +static NNStreamer_custom_class NNStreamer_custom_body = { + .initfunc = pt_init, + .exitfunc = pt_exit, + .getInputDim = get_inputDim, + .getOutputDim = get_outputDim, + .invoke = pt_invoke, +}; + +/* The dyn-loaded object */ +NNStreamer_custom_class *NNStreamer_custom = &NNStreamer_custom_body; -- 2.7.4