diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bd66f1..a7905d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,23 +1,132 @@ -cmake_minimum_required(VERSION 3.0) -project(c-net C) - -add_definitions(-Wall -Wno-unused-function -Ofast) -set(CMAKE_C_STANDARD 99) - -if(NOT DEFINED CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory") -endif() -message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}") - -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE release CACHE STRING "Choose the type of build" FORCE) -endif() - -add_subdirectory(c-utils) -add_subdirectory(c-benchmark) -add_subdirectory(c-tester) -add_subdirectory(c-tensor) -add_subdirectory(c-image) -add_subdirectory(c-network) -add_subdirectory(c-netend) \ No newline at end of file +option(ENABLE_STB_IMAGE "enable stb image" OFF) +option(ENABLE_ESP32 "enable esp32 build" ON) +option(ENABLE_POSIX_PORTS "enable posix ports supported" OFF) +option(ENABLE_DEBUG_MEMORY "enable debug memory allocation" ON) + +macro(cnet_add_operation class file) + # WITH_LAYER_xxx option + if(${ARGC} EQUAL 3) + option(WITH_LAYER_${class} "build with layer ${class}" ${ARGV2}) + else() + option(WITH_LAYER_${class} "build with layer ${class}" ON) + endif() + + message(STATUS "WITH_LAYER_${class} = ${WITH_LAYER_${class}}") + if(WITH_LAYER_${class}) + list(APPEND OPERATION_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/c-network/src/operation/${file}.c") + endif() + + # generate operation_declaration and operation_registry file + if(WITH_LAYER_${class}) + set(operation_names "${operation_names}\t\"${class}\",\n") + set(operation_creators "${operation_creators}/// Creator for ${class}\nDEFINE_OPERATION_CREATOR(${class});\n\n") + set(operation_creator "${operation_creator}\t${class}_operation_creator, // ${class}\n") + else() + set(operation_names "${operation_names}\t\"\",\n") + set(operation_creator "${operation_creator}\t0/*${class}_operation_creator*/, // ${class}\n") + endif() + +endmacro() + +set(UTILS_SRCS + c-utils/src/allocator.c + c-utils/src/container_linked_list.c + c-utils/src/container_vector.c + c-utils/src/threadpool-pthreads.c + c-utils/src/option.c + c-utils/src/ncx-pool/ncx_slab.c + c-utils/src/memory_cached.c + ) + +set(TESTER_SRCS + c-tester/src/tester.c + c-tester/src/unity.c + ) + +set(BENCH_MARK_SRCS + c-benchmark/src/benchmark.c + ) + +set(TENSOR_SRCS + c-tensor/src/tensor.c + c-tensor/src/tensor_softmax.c + c-tensor/src/tensor_padding.c + c-tensor/src/tensor_cut_border.c + c-tensor/src/tensor_resize_bilinear.c + c-tensor/src/tensor_resize_bicubic.c + ) + +cnet_add_operation(convolution convolution ON) +cnet_add_operation(pooling pooling ON) +cnet_add_operation(padding padding ON) +cnet_add_operation(crop crop ON) +cnet_add_operation(inner_product inner_product ON) +cnet_add_operation(activation activation ON) +cnet_add_operation(batch_norm batch_norm ON) +cnet_add_operation(slice slice ON) +cnet_add_operation(concat concat ON) +cnet_add_operation(reshape reshape ON) +cnet_add_operation(sigmoid sigmoid ON) +cnet_add_operation(softmax softmax ON) +cnet_add_operation(permute permute ON) +cnet_add_operation(unary unary ON) +cnet_add_operation(binary binary ON) +cnet_add_operation(upsample upsample ON) +cnet_add_operation(prelu prelu ON) +cnet_add_operation(memory_data memory_data ON) +cnet_add_operation(shuffle_channel shuffle_channel ON) + +# configure_file(c-network/src/operation_registry.c.in +# ${CMAKE_CURRENT_SOURCE_DIR}/c-network/src/operation_registry.c) +set(NETWORK_SRCS + c-network/src/operation.c + c-network/src/network.c + c-network/src/operation_benchmark.c + c-network/src/quantize16.c + c-network/src/operation_registry.c + ${OPERATION_SRCS} + ) + +set(NETEND_SRCS + c-netend/src/detection/object_box.c + c-netend/src/detection/mtcnn.c + c-netend/src/detection/retina_face.c + c-netend/src/detection/affine_matrix.c + c-netend/src/detection/yolov2.c + c-netend/src/detection/yolov3.c + c-netend/src/face/face_info.c + c-netend/src/face/arc_face.c + c-netend/src/face/mtcnn_face_detector.c + c-netend/src/lpr/plate_info.c + c-netend/src/lpr/lpr_recognizer.c + c-netend/src/lpr/lpc_recoginizer.c + c-netend/src/lpr/mtcnn_plate_detector.c + ) + +set(IMAGE_SRCS + c-image/src/imgproc.c + c-image/src/tensor_pixel.c + ) + +set(COMPONENT_SRCS + ${UTILS_SRCS} + ${TESTER_SRCS} + ${BENCH_MARK_SRCS} + ${TENSOR_SRCS} + ${NETWORK_SRCS} + ${NETEND_SRCS} + ${IMAGE_SRCS} + ) + +register_component() + +include_directories(c-utils/include) +include_directories(c-tester/include) +include_directories(c-benchmark/include) +include_directories(c-tensor/include) +include_directories(c-network/include) +include_directories(c-netend/include) +include_directories(c-image/include) +add_definitions(-DESP32) +add_definitions(-Wall -Wno-unused-function -Ofast) \ No newline at end of file diff --git a/Kconfig b/Kconfig new file mode 100644 index 0000000..ac64f45 --- /dev/null +++ b/Kconfig @@ -0,0 +1,7 @@ + + +config COMPONENT_CNET_ENABLE + bool "Enbale cnet component" + default y + select COMPONENT_KENDRYTE_SDK_ENABLE + select COMPONENT_POSIX_ENABLE diff --git a/c-netend/src/detection/affine_matrix.c b/c-netend/src/detection/affine_matrix.c index a6174f1..376c4e2 100644 --- a/c-netend/src/detection/affine_matrix.c +++ b/c-netend/src/detection/affine_matrix.c @@ -105,7 +105,7 @@ void get_affine_matrix_from_5p(float *src_5pts, const float *dst_5pts, float *M) _sqloss += ((pts0[0] + pts1[i] - dst[i]) * (pts0[0] + pts1[i] - dst[i]) + (pts0[1] + pts1[i + 5] - dst[i + 5]) * (pts0[1] + pts1[i + 5] - dst[i + 5])); } - if (abs(_sqloss - sqloss) < 1e-2) { + if (fabs(_sqloss - sqloss) < 1e-2) { break; } sqloss = _sqloss; @@ -241,7 +241,7 @@ int guass_jordan(float m[3][5], float eps) { for (int y = 0; y < h; y++) { int maxrow = y; for (int y2 = y + 1; y2 < h; y2++) { - if (abs(m[y2][y]) > abs(m[maxrow][y])) { + if (fabs(m[y2][y]) > fabs(m[maxrow][y])) { maxrow = y2; } } diff --git a/c-netend/src/detection/object_box.c b/c-netend/src/detection/object_box.c index 31d929c..d8ba835 100644 --- a/c-netend/src/detection/object_box.c +++ b/c-netend/src/detection/object_box.c @@ -9,6 +9,8 @@ #include "detection/object_box.h" #include "tensor_pixel.h" +#include + object_box_t object_box_create_default() { object_box_t box; memset(&box, 0, sizeof(box)); diff --git a/c-network/include/operation.h b/c-network/include/operation.h index ac8794b..b522917 100644 --- a/c-network/include/operation.h +++ b/c-network/include/operation.h @@ -13,6 +13,7 @@ #define CNET_LAYER_H #include "operation_config.h" +#include /// Blob container typedef struct blob_container { diff --git a/c-network/src/network.c b/c-network/src/network.c index e64049d..abc3c4d 100644 --- a/c-network/src/network.c +++ b/c-network/src/network.c @@ -214,7 +214,7 @@ FUNCTION_IRAM static int session_forward_operation( if (opt->light_mode) { - if(*bottom_blobs.data[i].data.refcount == 2){ + if(NULL != bottom_blobs.data[i].data.refcount && *bottom_blobs.data[i].data.refcount == 2){ /// delete after taken in light mode tensor_release(&context->blob_data[bottom_blob_index].data); } else { diff --git a/c-network/src/operation/convolution.c b/c-network/src/operation/convolution.c index 0d77e79..2672336 100644 --- a/c-network/src/operation/convolution.c +++ b/c-network/src/operation/convolution.c @@ -12,6 +12,8 @@ #include "operation_config.h" #include "quantize16.h" +#include + typedef struct conv_int16_context { tensor_t* bottom; tensor_t* top; diff --git a/c-tensor/src/tensor.c b/c-tensor/src/tensor.c index fa784db..f26309f 100644 --- a/c-tensor/src/tensor.c +++ b/c-tensor/src/tensor.c @@ -9,6 +9,7 @@ #include #include "tensor.h" #include "container_vector.h" +#include /** * vector impl for tensor_t @@ -114,7 +115,7 @@ void tensor_print_int32(tensor_t *tensor){ int32_t *data = (int32_t*) m.data; for(int h = 0; h < m.d1; h++){ for(int w = 0; w < m.d0; w ++){ - printf("%d,", data[h*m.d0 + w]); + printf("%ld,", data[h*m.d0 + w]); } printf("\n"); } diff --git a/c-tensor/src/tensor_padding.c b/c-tensor/src/tensor_padding.c index 20a42de..a0a1454 100644 --- a/c-tensor/src/tensor_padding.c +++ b/c-tensor/src/tensor_padding.c @@ -628,4 +628,5 @@ tensor_t tensor_padding( padding_channels_context_t context = {src, &dst, top, left, type, v, elem_size}; PARALLELIZE_1D(padding_channels_thread, context, channels); + return dst; } diff --git a/c-utils/include/container_vector_define.h b/c-utils/include/container_vector_define.h index 816e85d..87caf22 100644 --- a/c-utils/include/container_vector_define.h +++ b/c-utils/include/container_vector_define.h @@ -21,125 +21,144 @@ /** * Define Vector */ -#define VECTOR_DEFINE(type) \ -typedef void element_##type##_operation(type *data, void *args);\ -typedef struct vector##type##_ \ -{\ - long length;\ - long current_size;\ - type *data;\ - void (*free_data)(struct vector##type##_ *);\ - int (*get_element)(struct vector##type##_ *, long index, type *dest);\ - int (*push_element)(struct vector##type##_ *, type *dest);\ - int (*set_element)(struct vector##type##_ *, long index, type *dest);\ - void(*for_each_element)(struct vector##type##_ *, element_##type##_operation, void *args);\ - malloc_func malloc;\ - free_func free;\ -}vector_##type, *vector_##type##_ptr;\ +#define VECTOR_DEFINE(type) \ +typedef void element_##type##_operation(type *data, void *args); \ +typedef struct vector##type##_ \ +{ \ + long length; \ + long current_size; \ + type *data; \ + void (*free_data)(struct vector##type##_ *); \ + int (*get_element)(struct vector##type##_ *, long index, type *dest); \ + int (*push_element)(struct vector##type##_ *, type *dest); \ + int (*set_element)(struct vector##type##_ *, long index, type *dest); \ + void(*for_each_element)(struct vector##type##_ *, element_##type##_operation, void *args); \ + malloc_func malloc; \ + free_func free; \ +}vector_##type, *vector_##type##_ptr; \ vector_##type new_vector_##type##_impl(long length); /** * Impl Vector */ -#define VECTOR_IMPL(type) \ -FUNCTION_IRAM void free_vector_##type##_data_impl(vector_##type##_ptr vec);\ -FUNCTION_IRAM int get_vector_##type##_element_impl(vector_##type##_ptr vec, long index, type *dest);\ -FUNCTION_IRAM int set_vector_##type##_element_impl(vector_##type##_ptr vec, long index, type *dest);\ -FUNCTION_IRAM int push_vector_##type##_element_impl(vector_##type##_ptr vec, type *dest);\ -FUNCTION_IRAM void for_each_vector_##type##_element_impl(vector_##type##_ptr vec, element_##type##_operation, void*);\ -\ -vector_##type new_vector_##type##_impl(long length){\ - vector_##type vector;\ - \ - vector.data = NULL;\ - vector.current_size = 0;\ - vector.length = 0;\ - vector.free_data = &free_vector_##type##_data_impl;\ - vector.get_element = &get_vector_##type##_element_impl;\ - vector.push_element = &push_vector_##type##_element_impl;\ - vector.set_element = &set_vector_##type##_element_impl;\ - vector.for_each_element = &for_each_vector_##type##_element_impl;\ - vector.malloc = allocator_get_malloc_fun(NULL, 0 == (sizeof(type) % 4));\ - vector.free = allocator_get_free_fun(NULL, 0 == (sizeof(type) % 4));\ - \ - if (length > 0 ){\ - type *data = (type*)vector.malloc(length * sizeof(type));\ - if (data){\ - vector.data = data;\ - vector.length = length;\ - }\ - }\ - \ - return vector;\ -}\ -\ -void free_vector_##type##_data_impl(vector_##type##_ptr vec){\ - if (NULL != vec->data){\ - vec->free(vec->data);\ - vec->data = NULL;\ - vec->current_size = 0;\ - vec->length = 0;\ - }\ -}\ -\ -int get_vector_##type##_element_impl(vector_##type##_ptr vec, long index, type *dest){\ - if(index < 0 || index >= vec->current_size){\ - return CNET_STATUS_SUCCESS;\ - }\ -\ - *dest = vec->data[index];\ - return CNET_STATUS_SUCCESS;\ -}\ -\ -int set_vector_##type##_element_impl(vector_##type##_ptr vec, long index, type *src){\ - if(index < 0){\ - return CNET_STATUS_FAILED;\ - }\ - \ - if(index >= vec->length){\ - long new_length = index + 1;\ - type *data = (type*)vec->malloc(new_length * sizeof(type));\ - if (data){\ - memcpy(data, vec->data, sizeof(type) * vec->current_size);\ - vec->free(vec->data);\ - vec->data = data;\ - vec->length = new_length;\ - }else{\ - return CNET_STATUS_FAILED;\ - }\ - }\ -\ - if(vec->current_size <= index){\ - vec->current_size = index + 1;\ - }\ - vec->data[index] = *src;\ - return CNET_STATUS_SUCCESS;\ -}\ -\ -int push_vector_##type##_element_impl(vector_##type##_ptr vec, type *src){\ - if(vec->current_size >= vec->length){\ - long new_length = vec->length + VECTOR_EXPAND_SIZE;\ - type *data = (type*)vec->malloc(new_length * sizeof(type));\ - if (data){\ - memcpy(data, vec->data, sizeof(type) * vec->current_size);\ - free(vec->data);\ - vec->data = data;\ - vec->length = new_length;\ - }else{\ - return CNET_STATUS_FAILED;\ - }\ - }\ -\ - vec->data[vec->current_size] = *src;\ - vec->current_size ++;\ - return CNET_STATUS_SUCCESS;\ -}\ -\ -void for_each_vector_##type##_element_impl(vector_##type##_ptr vec, element_##type##_operation operation, void *args){\ - int i;\ - for(i = 0; i < vec->current_size; i ++){\ - operation(vec->data + i, args);\ - }\ +#define VECTOR_IMPL(type) \ +FUNCTION_IRAM void free_vector_##type##_data_impl(vector_##type##_ptr vec); \ +FUNCTION_IRAM int get_vector_##type##_element_impl(vector_##type##_ptr vec, long index, type *dest); \ +FUNCTION_IRAM int set_vector_##type##_element_impl(vector_##type##_ptr vec, long index, type *dest); \ +FUNCTION_IRAM int push_vector_##type##_element_impl(vector_##type##_ptr vec, type *dest); \ +FUNCTION_IRAM void for_each_vector_##type##_element_impl(vector_##type##_ptr vec, element_##type##_operation, void*); \ + \ +vector_##type new_vector_##type##_impl(long length){ \ + vector_##type vector; \ + \ + vector.data = NULL; \ + vector.current_size = 0; \ + vector.length = 0; \ + vector.free_data = &free_vector_##type##_data_impl; \ + vector.get_element = &get_vector_##type##_element_impl; \ + vector.push_element = &push_vector_##type##_element_impl; \ + vector.set_element = &set_vector_##type##_element_impl; \ + vector.for_each_element = &for_each_vector_##type##_element_impl; \ + vector.malloc = allocator_get_malloc_fun(NULL, 0 == (sizeof(type) % 4)); \ + vector.free = allocator_get_free_fun(NULL, 0 == (sizeof(type) % 4)); \ + \ + if (length > 0 ){ \ + type *data = (type*)vector.malloc(length * sizeof(type)); \ + if (data){ \ + vector.data = data; \ + vector.length = length; \ + } \ + } \ + \ + return vector; \ +} \ + \ +void free_vector_##type##_data_impl(vector_##type##_ptr vec){ \ + if (NULL != vec->data){ \ + vec->free(vec->data); \ + vec->data = NULL; \ + vec->current_size = 0; \ + vec->length = 0; \ + } \ +} \ + \ +int get_vector_##type##_element_impl( \ + vector_##type##_ptr vec, \ + long index, \ + type *dest){ \ + \ + if(index < 0 || index >= vec->current_size){ \ + return CNET_STATUS_SUCCESS; \ + } \ + \ + *dest = vec->data[index]; \ + return CNET_STATUS_SUCCESS; \ +} \ + \ +int set_vector_##type##_element_impl( \ + vector_##type##_ptr vec, \ + long index, \ + type *src){ \ + \ + if(index < 0){ \ + return CNET_STATUS_FAILED; \ + } \ + \ + if(index >= vec->length){ \ + long new_length = index + 1; \ + type *data = (type*)vec->malloc(new_length * sizeof(type)); \ + if (data){ \ + memcpy(data, vec->data, sizeof(type) * vec->current_size); \ + vec->free(vec->data); \ + vec->data = data; \ + vec->length = new_length; \ + }else{ \ + return CNET_STATUS_FAILED; \ + } \ + } \ + \ + if(vec->current_size <= index){ \ + vec->current_size = index + 1; \ + } \ + \ + vec->data[index] = *src; \ + return CNET_STATUS_SUCCESS; \ +} \ + \ +int push_vector_##type##_element_impl(vector_##type##_ptr vec, type *src){ \ + if(vec->current_size >= vec->length){ \ + long new_length = vec->length + VECTOR_EXPAND_SIZE; \ + type *data = (type*)vec->malloc(new_length * sizeof(type)); \ + if (data){ \ + if(vec->data != NULL){ \ + memcpy(data, vec->data, sizeof(type) * vec->current_size); \ + vec->free(vec->data); \ + } \ + \ + vec->data = data; \ + vec->length = new_length; \ + }else{ \ + return CNET_STATUS_FAILED; \ + } \ + } \ + \ + vec->data[vec->current_size] = *src; \ + vec->current_size ++; \ + return CNET_STATUS_SUCCESS; \ +} \ + \ +void for_each_vector_##type##_element_impl( \ + vector_##type##_ptr vec, \ + element_##type##_operation operation, \ + void *args){ \ + if(NULL == vec || NULL == operation){ \ + return; \ + } \ + \ + int i; \ + for(i = 0; i < vec->current_size; i ++){ \ + operation(vec->data + i, args); \ + } \ }