| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifndef _EIDSP_MEMORY_H_ |
| #define _EIDSP_MEMORY_H_ |
|
|
| |
| #include <functional> |
| #include <stdio.h> |
| #include <memory> |
| #include "../porting/ei_classifier_porting.h" |
| #include "edge-impulse-sdk/classifier/ei_aligned_malloc.h" |
| #include "config.hpp" |
|
|
| extern size_t ei_memory_in_use; |
| extern size_t ei_memory_peak_use; |
|
|
| #if EIDSP_PRINT_ALLOCATIONS == 1 |
| #define ei_dsp_printf printf |
| #else |
| #define ei_dsp_printf (void) |
| #endif |
|
|
| typedef std::unique_ptr<void, std::function<void(void*)>> ei_unique_ptr_t; |
|
|
| |
| |
| #define EI_ALLOCATE_AUTO_POINTER(ptr, size) \ |
| ptr = static_cast<decltype(ptr)>(ei_calloc(size,sizeof(*ptr))); \ |
| ei_unique_ptr_t __ptr__(ptr,ei_free); |
|
|
| #define EI_ERR_AND_RETURN_ON_NULL(ptr,code) \ |
| if( ! (ptr) ) { \ |
| ei_printf("Null check failed\n"); \ |
| return code; \ |
| } |
|
|
| namespace ei { |
|
|
| |
| |
| |
| |
|
|
| #if EIDSP_TRACK_ALLOCATIONS |
| |
| |
| |
| |
| |
| #define ei_dsp_register_alloc_internal(fn, file, line, bytes, ptr) \ |
| ei_memory_in_use += bytes; \ |
| if (ei_memory_in_use > ei_memory_peak_use) { \ |
| ei_memory_peak_use = ei_memory_in_use; \ |
| } \ |
| ei_dsp_printf("alloc %lu bytes (in_use=%lu, peak=%lu) (%s@ %s:%d) %p\n", \ |
| (unsigned long)bytes, (unsigned long)ei_memory_in_use, (unsigned long)ei_memory_peak_use, fn, file, line, ptr); |
|
|
| |
| |
| |
| |
| |
| |
| |
| #define ei_dsp_register_matrix_alloc_internal(fn, file, line, rows, cols, type_size, ptr) \ |
| ei_memory_in_use += (rows * cols * type_size); \ |
| if (ei_memory_in_use > ei_memory_peak_use) { \ |
| ei_memory_peak_use = ei_memory_in_use; \ |
| } \ |
| ei_dsp_printf("alloc matrix %lu x %lu = %lu bytes (in_use=%lu, peak=%lu) (%s@ %s:%d) %p\n", \ |
| (unsigned long)rows, (unsigned long)cols, (unsigned long)(rows * cols * type_size), (unsigned long)ei_memory_in_use, \ |
| (unsigned long)ei_memory_peak_use, fn, file, line, ptr); |
|
|
| |
| |
| |
| |
| #define ei_dsp_register_free_internal(fn, file, line, bytes, ptr) \ |
| ei_memory_in_use -= bytes; \ |
| ei_dsp_printf("free %lu bytes (in_use=%lu, peak=%lu) (%s@ %s:%d) %p\n", \ |
| (unsigned long)bytes, (unsigned long)ei_memory_in_use, (unsigned long)ei_memory_peak_use, fn, file, line, ptr); |
|
|
| |
| |
| |
| |
| |
| |
| |
| #define ei_dsp_register_matrix_free_internal(fn, file, line, rows, cols, type_size, ptr) \ |
| ei_memory_in_use -= (rows * cols * type_size); \ |
| ei_dsp_printf("free matrix %lu x %lu = %lu bytes (in_use=%lu, peak=%lu) (%s@ %s:%d) %p\n", \ |
| (unsigned long)rows, (unsigned long)cols, (unsigned long)(rows * cols * type_size), \ |
| (unsigned long)ei_memory_in_use, (unsigned long)ei_memory_peak_use, fn, file, line, ptr); |
|
|
| #define ei_dsp_register_alloc(...) ei_dsp_register_alloc_internal(__func__, __FILE__, __LINE__, __VA_ARGS__) |
| #define ei_dsp_register_matrix_alloc(...) ei_dsp_register_matrix_alloc_internal(__func__, __FILE__, __LINE__, __VA_ARGS__) |
| #define ei_dsp_register_free(...) ei_dsp_register_free_internal(__func__, __FILE__, __LINE__, __VA_ARGS__) |
| #define ei_dsp_register_matrix_free(...) ei_dsp_register_matrix_free_internal(__func__, __FILE__, __LINE__, __VA_ARGS__) |
| #define ei_dsp_malloc(...) memory::ei_wrapped_malloc(__func__, __FILE__, __LINE__, __VA_ARGS__) |
| #define ei_dsp_calloc(...) memory::ei_wrapped_calloc(__func__, __FILE__, __LINE__, __VA_ARGS__) |
| #define ei_dsp_free(...) memory::ei_wrapped_free(__func__, __FILE__, __LINE__, __VA_ARGS__) |
|
|
| #define EI_DSP_MATRIX(name, ...) matrix_t name(__VA_ARGS__, NULL, __func__, __FILE__, __LINE__); if (!name.buffer) { EIDSP_ERR(EIDSP_OUT_OF_MEM); } |
| #define EI_DSP_MATRIX_B(name, ...) matrix_t name(__VA_ARGS__, __func__, __FILE__, __LINE__); if (!name.buffer) { EIDSP_ERR(EIDSP_OUT_OF_MEM); } |
| #define EI_DSP_QUANTIZED_MATRIX(name, ...) quantized_matrix_t name(__VA_ARGS__, NULL, __func__, __FILE__, __LINE__); if (!name.buffer) { EIDSP_ERR(EIDSP_OUT_OF_MEM); } |
| #define EI_DSP_QUANTIZED_MATRIX_B(name, ...) quantized_matrix_t name(__VA_ARGS__, __func__, __FILE__, __LINE__); if (!name.buffer) { EIDSP_ERR(EIDSP_OUT_OF_MEM); } |
| #else |
| #define ei_dsp_register_alloc(...) (void)0 |
| #define ei_dsp_register_matrix_alloc(...) (void)0 |
| #define ei_dsp_register_free(...) (void)0 |
| #define ei_dsp_register_matrix_free(...) (void)0 |
| #define ei_dsp_malloc ei_malloc |
| #define ei_dsp_calloc ei_calloc |
| #define ei_dsp_free(ptr, size) ei_free(ptr) |
| #define EI_DSP_MATRIX(name, ...) matrix_t name(__VA_ARGS__); if (!name.buffer) { EIDSP_ERR(EIDSP_OUT_OF_MEM); } |
| #define EI_DSP_MATRIX_B(name, ...) matrix_t name(__VA_ARGS__); if (!name.buffer) { EIDSP_ERR(EIDSP_OUT_OF_MEM); } |
| #define EI_DSP_QUANTIZED_MATRIX(name, ...) quantized_matrix_t name(__VA_ARGS__); if (!name.buffer) { EIDSP_ERR(EIDSP_OUT_OF_MEM); } |
| #define EI_DSP_QUANTIZED_MATRIX_B(name, ...) quantized_matrix_t name(__VA_ARGS__); if (!name.buffer) { EIDSP_ERR(EIDSP_OUT_OF_MEM); } |
| #endif |
|
|
| #if EIDSP_TRACK_ALLOCATIONS |
| class memory { |
|
|
|
|
| public: |
| |
| |
| |
| |
| static void *ei_wrapped_malloc(const char *fn, const char *file, int line, size_t size) { |
| void *ptr = ei_malloc(size); |
| if (ptr) { |
| ei_dsp_register_alloc_internal(fn, file, line, size, ptr); |
| } |
| return ptr; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| static void *ei_wrapped_calloc(const char *fn, const char *file, int line, size_t num, size_t size) { |
| void *ptr = ei_calloc(num, size); |
| if (ptr) { |
| ei_dsp_register_alloc_internal(fn, file, line, num * size, ptr); |
| } |
| return ptr; |
| } |
|
|
| |
| |
| |
| |
| |
| static void ei_wrapped_free(const char *fn, const char *file, int line, void *ptr, size_t size) { |
| ei_free(ptr); |
| ei_dsp_register_free_internal(fn, file, line, size, ptr); |
| } |
| }; |
| #endif |
|
|
| |
| __attribute__((unused)) static void ei_dsp_free_func(void *ptr, size_t size) { |
| ei_free(ptr); |
| #if EIDSP_TRACK_ALLOCATIONS |
| ei_dsp_register_free_internal("unique_ptr free", "", 0, size, ptr); |
| #endif |
| } |
|
|
| #if EIDSP_TRACK_ALLOCATIONS |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| static ei_unique_ptr_t make_tracked_unique_ptr(void* ptr_in, size_t size) { |
| auto ptr = reinterpret_cast<void**>(ptr_in); |
| *ptr = ei_dsp_malloc(size); |
| return ei_unique_ptr_t(*ptr, [size](void *ptr) { |
| ei_free(ptr); |
| ei_dsp_register_free_internal("unique_ptr", "", 0, size, ptr); |
| }); |
| } |
| #else |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| __attribute__((warn_unused_result)) __attribute__((unused)) |
| static ei_unique_ptr_t make_tracked_unique_ptr(void* ptr_in, size_t size) |
| { |
| auto ptr = reinterpret_cast<void**>(ptr_in); |
| *ptr = ei_malloc(size); |
| return ei_unique_ptr_t(*ptr, ei_free); |
| } |
| #endif |
|
|
| |
| |
| |
| |
| |
| #define EI_MAKE_TRACKED_POINTER(ptr, size) ei::make_tracked_unique_ptr(&ptr, sizeof(*ptr)*size); |
|
|
| } |
|
|
| |
| #endif |
|
|