From d219042cf95ee768d1242f99251a600186253e7c Mon Sep 17 00:00:00 2001 From: MyungJoo Ham Date: Mon, 11 Jun 2018 18:33:37 +0900 Subject: [PATCH] [Filter/Custom] Add testcase. Fix bugs found by the testcase. 1. Added "passthrough with 3x280x4 tensors" Custom Filter Example 2. Added test case with the example. 3. Fixed filter/custom bugs with the test case 4. Relocated headers and their install paths Signed-off-by: MyungJoo Ham --- CMakeLists.txt | 12 ++- {tensor_filter => include}/tensor_filter_custom.h | 1 + nnstreamer.pc.in | 2 +- nnstreamer_example/CMakeLists.txt | 3 + .../custom_example_passthrough/CMakeLists.txt | 13 +++ .../nnstreamer_customfilter_example_passthrough.c | 108 +++++++++++++++++++++ tensor_filter/CMakeLists.txt | 3 - tensor_filter/tensor_filter_custom.c | 5 +- tests/nnstreamer_filter_custom/runTest.sh | 22 +++++ tests/nnstreamer_filter_custom/testcase01.sh | 37 +++++++ 10 files changed, 198 insertions(+), 8 deletions(-) rename {tensor_filter => include}/tensor_filter_custom.h (99%) create mode 100644 nnstreamer_example/CMakeLists.txt create mode 100644 nnstreamer_example/custom_example_passthrough/CMakeLists.txt create mode 100644 nnstreamer_example/custom_example_passthrough/nnstreamer_customfilter_example_passthrough.c create mode 100755 tests/nnstreamer_filter_custom/runTest.sh create mode 100755 tests/nnstreamer_filter_custom/testcase01.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e17bfc..6ef37aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,8 +59,8 @@ LINK_DIRECTORIES(${pkgs_LIBRARY_DIRS}) FOREACH(flag ${pkgs_CFALGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror -fPIC") -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -Wall -Werror -fPIC") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror -fPIC -g") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -Wall -Werror -fPIC -g") # Provide common data ADD_LIBRARY(common STATIC common/tensor_common.c) @@ -76,12 +76,20 @@ TARGET_LINK_LIBRARIES(unittest_common ${pkgs_LIBRARIES} ${gtestLink}) ADD_SUBDIRECTORY(tensor_converter) ADD_SUBDIRECTORY(tensor_filter) ADD_SUBDIRECTORY(tensor_decoder) +ADD_SUBDIRECTORY(nnstreamer_example) CONFIGURE_FILE(nnstreamer.pc.in nnstreamer.pc @ONLY) +# For nnstreamer users (gst app developers using via gstreamer API) INSTALL(FILES include/tensor_typedef.h DESTINATION ${INCLUDE_INSTALL_DIR}/nnstreamer ) + +# For nnstreamer custom filter developers +INSTALL(FILES include/tensor_common.h include/tensor_filter_custom.h + DESTINATION ${INCLUDE_INSTALL_DIR}/nnstreamer + ) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/nnstreamer.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig ) diff --git a/tensor_filter/tensor_filter_custom.h b/include/tensor_filter_custom.h similarity index 99% rename from tensor_filter/tensor_filter_custom.h rename to include/tensor_filter_custom.h index 791416e..c182f3b 100644 --- a/tensor_filter/tensor_filter_custom.h +++ b/include/tensor_filter_custom.h @@ -61,6 +61,7 @@ #define __NNS_TENSOR_FILTER_CUSTOM_H__ #include +#include /** * @brief A function that is called before calling other functions. diff --git a/nnstreamer.pc.in b/nnstreamer.pc.in index 75a2f16..efb4b91 100644 --- a/nnstreamer.pc.in +++ b/nnstreamer.pc.in @@ -10,4 +10,4 @@ Description: Neural Network Suite for GStreamer Version: @VERSION@ Requires: Libs: -Cflags: -I${includedir} +Cflags: -I${includedir}/nnstreamer diff --git a/nnstreamer_example/CMakeLists.txt b/nnstreamer_example/CMakeLists.txt new file mode 100644 index 0000000..f14578b --- /dev/null +++ b/nnstreamer_example/CMakeLists.txt @@ -0,0 +1,3 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +ADD_SUBDIRECTORY(custom_example_passthrough) diff --git a/nnstreamer_example/custom_example_passthrough/CMakeLists.txt b/nnstreamer_example/custom_example_passthrough/CMakeLists.txt new file mode 100644 index 0000000..0f3c917 --- /dev/null +++ b/nnstreamer_example/custom_example_passthrough/CMakeLists.txt @@ -0,0 +1,13 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +ADD_LIBRARY(nnstreamer_customfilter_passthrough SHARED nnstreamer_customfilter_example_passthrough.c) + +TARGET_LINK_LIBRARIES(nnstreamer_customfilter_passthrough ${pkgs_LIBRARIES}) +TARGET_INCLUDE_DIRECTORIES(nnstreamer_customfilter_passthrough PUBLIC ${pkgs_INCLUDE_DIRS}) +TARGET_COMPILE_OPTIONS(nnstreamer_customfilter_passthrough PUBLIC ${pkgs_CFLAGS_OTHER}) + +INSTALL(TARGETS nnstreamer_customfilter_passthrough + RUNTIME DESTINATION ${EXEC_PREFIX} + LIBRARY DESTINATION ${LIB_INSTALL_DIR} + ARCHIVE DESTINATION ${LIB_INSTALL_DIR} + ) diff --git a/nnstreamer_example/custom_example_passthrough/nnstreamer_customfilter_example_passthrough.c b/nnstreamer_example/custom_example_passthrough/nnstreamer_customfilter_example_passthrough.c new file mode 100644 index 0000000..e8d00ac --- /dev/null +++ b/nnstreamer_example/custom_example_passthrough/nnstreamer_customfilter_example_passthrough.c @@ -0,0 +1,108 @@ +/** + * NNStreamer Custom Filter Example 1. Pass-Through + * Copyright (C) 2018 MyungJoo Ham + * + * LICENSE: Apache-2.0 + * + * @file nnstreamer_customfilter_example_passthrough.c + * @date 11 Jun 2018 + * @brief Custom NNStreamer Filter Example 1. "Pass-Through" + * @author MyungJoo Ham + * + * As a test, before #71 is resolved, this will support "3x280x40" uint8 tensors. + */ + +#include +#include +#include +#include + +#define D1 (3) +#define D2 (280) +#define D3 (40) + +typedef struct _pt_data { + uint32_t id; /***< Just for testing */ + uint32_t dim[NNS_TENSOR_RANK_LIMIT]; + tensor_type type; +} pt_data; + +static void *pt_init() { + pt_data *data = (pt_data *)malloc(sizeof (pt_data)); + int i; + + data->id = 0; + data->dim[0] = D1; + data->dim[1] = D2; + data->dim[2] = D3; + for (i = 3; i < NNS_TENSOR_RANK_LIMIT; i++) + data->dim[i] = 1; + data->type = _NNS_UINT8; + + return data; +} + +static void pt_exit(void *private_data) { + pt_data *data = private_data; + g_assert(data); + free(data); +} + +static int get_inputDim(void *private_data, uint32_t inputDimension[NNS_TENSOR_RANK_LIMIT], tensor_type *type) { + pt_data *data = private_data; + int i; + + g_assert(data); + g_assert(NNS_TENSOR_RANK_LIMIT >= 3); + inputDimension[0] = D1; + inputDimension[1] = D2; + inputDimension[2] = D3; + for (i = 3; i < NNS_TENSOR_RANK_LIMIT; i++) + inputDimension[i] = 1; + *type = _NNS_UINT8; + return 0; + return 0; +} + +static int get_outputDim(void *private_data, uint32_t outputDimension[NNS_TENSOR_RANK_LIMIT], tensor_type *type) { + pt_data *data = private_data; + int i; + + g_assert(data); + g_assert(NNS_TENSOR_RANK_LIMIT >= 3); + outputDimension[0] = D1; + outputDimension[1] = D2; + outputDimension[2] = D3; + for (i = 3; i < NNS_TENSOR_RANK_LIMIT; i++) + outputDimension[i] = 1; + *type = _NNS_UINT8; + return 0; +} + +static int pt_invoke(void *private_data, uint8_t *inptr, uint8_t *outptr) { + pt_data *data = private_data; + size_t size; + + g_assert(data); + g_assert(inptr); + g_assert(outptr); + + size = get_tensor_element_count(data->dim) * tensor_element_size[data->type]; + + g_assert(inptr != outptr); + memcpy(outptr, inptr, size); + + 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; + diff --git a/tensor_filter/CMakeLists.txt b/tensor_filter/CMakeLists.txt index 1db2d76..c0e9fc2 100644 --- a/tensor_filter/CMakeLists.txt +++ b/tensor_filter/CMakeLists.txt @@ -15,6 +15,3 @@ INSTALL(TARGETS tensor_filter LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} ) -INSTALL(FILES tensor_filter_custom.h - DESTINATION ${INCLUDE_INSTALL_DIR}/nnstreamer - ) diff --git a/tensor_filter/tensor_filter_custom.c b/tensor_filter/tensor_filter_custom.c index 1a950a7..491de97 100644 --- a/tensor_filter/tensor_filter_custom.c +++ b/tensor_filter/tensor_filter_custom.c @@ -80,7 +80,7 @@ static int custom_loadlib(GstTensor_Filter *filter) { return 1; } - ptr = g_new0(internal_data, 0); /* Fill Zero! */ + ptr = g_new0(internal_data, 1); /* Fill Zero! */ filter->privateData = ptr; ptr->parent = filter; @@ -93,7 +93,7 @@ static int custom_loadlib(GstTensor_Filter *filter) { } dlerror(); - ptr->methods = (NNStreamer_custom_class *) dlsym(ptr->handle, "NNStreamer_custom"); + ptr->methods = *((NNStreamer_custom_class **) dlsym(ptr->handle, "NNStreamer_custom")); dlsym_error = dlerror(); if (dlsym_error) { g_printerr("tensor_filter_custom:loadlib error: %s\n", dlsym_error); @@ -103,6 +103,7 @@ static int custom_loadlib(GstTensor_Filter *filter) { return -1; } + g_assert(ptr->methods->initfunc); ptr->customFW_private_data = ptr->methods->initfunc(); return 0; } diff --git a/tests/nnstreamer_filter_custom/runTest.sh b/tests/nnstreamer_filter_custom/runTest.sh new file mode 100755 index 0000000..a529ff3 --- /dev/null +++ b/tests/nnstreamer_filter_custom/runTest.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +failed=0 +sopath="" + +./testcase01.sh $sopath || failed=1 + +echo "" +echo "" +echo "==================================================" +echo " Test for tensor_filter_custom" +echo "==================================================" +if [ "$failed" -eq "0" ] +then + echo SUCCESS + echo "" + exit 0 +else + echo FAILED + echo "" + exit -1 +fi diff --git a/tests/nnstreamer_filter_custom/testcase01.sh b/tests/nnstreamer_filter_custom/testcase01.sh new file mode 100755 index 0000000..42e2f9f --- /dev/null +++ b/tests/nnstreamer_filter_custom/testcase01.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +## +# Copyright (C) 2018 Samsung Electronics +# License: Apache-2.0 +# +# @file testcase01.sh +# @brief Test tensor_converter for testcase 01 +# @author MyungJoo Ham +# @dependency cmp + +if [ $# -eq 0 ] +then + PATH_TO_PLUGIN="$PWD/../../build/tensor_converter:$PWD/../../build/tensor_filter" +else + PATH_TO_PLUGIN="$1" +fi + +PATH_TO_MODEL="../../build/nnstreamer_example/custom_example_passthrough/libnnstreamer_customfilter_passthrough.so" + +failed=0 + +# Generate one frame only (num-buffers=1) + +gst-launch-1.0 -v --gst-debug=GST_CAPS:4 --gst-plugin-path=${PATH_TO_PLUGIN} videotestsrc num-buffers=1 ! video/x-raw,format=RGB,width=280,height=40,framerate=0/1 ! videoconvert ! video/x-raw, format=RGB ! tensor_converter silent=FALSE ! tee name=t ! queue ! tensor_filter debug=TRUE framework='custom' model="${PATH_TO_MODEL}" input='3:280:40' inputtype='uint8' output='3:280:40' outputtype='uint8' ! filesink location="testcase01.passthrough.log" sync=true t. ! queue ! filesink location="testcase01.direct.log" sync=true || failed=1 + +# Check the results (test.rgb.log, test.bgrx.log) +cmp testcase01.passthrough.log testcase01.direct.log || failed=1 + +if [ "$failed" -eq "0" ] +then + echo Testcase 01: SUCCESS + exit 0 +else + echo Testcase 01: FAILED + exit -1 +fi -- 2.7.4