K210code using kmodel file instead of C file
parent
d80f0d2ac2
commit
b1e680f1a0
|
@ -1,23 +1,23 @@
|
|||
### *pb* file to C file
|
||||
### *pb* file to *kmodel* file
|
||||
|
||||
Download [nncase](https://github.com/kendryte/nncase) tool and uncompress it. You'll get `ncc` directory.
|
||||
Make a directory named `ncc`. Download [nncase](<https://github.com/kendryte/nncase/releases>) tool and uncompress it to `ncc`.
|
||||
|
||||
#### *pb* file to tflite
|
||||
|
||||
Copy the pretrained model `mobilenetv1_1.0.pb` in `pretrained` directory to `ncc\bin`. Rename it to `mobilenetv1.pb` to avoid the function name error in the following steps.
|
||||
Copy the pretrained model `mobilenetv1_1.0.pb` in `pretrained` directory to `ncc\bin`.
|
||||
|
||||
Enter `ncc\bin` directory from *cmd*.
|
||||
Enter `ncc\bin` directory.
|
||||
|
||||
```shell
|
||||
.\toco.exe --input_file=mobilenetv1.pb --input_format=TENSORFLOW_GRAPHDEF --output_file=mobilenetv1.tflite --output_format=TFLITE --input_shape=1,224,224,3 --input_array=inputs --output_array=MobileNetV1/Bottleneck2/BatchNorm/Reshape_1 --inference=FLOAT
|
||||
./toco --input_file=mobilenetv1_1.0.pb --input_format=TENSORFLOW_GRAPHDEF --output_file=mobilenetv1_1.0.tflite --output_format=TFLITE --input_shape=1,224,224,3 --input_array=inputs --output_array=MobileNetV1/Bottleneck2/BatchNorm/Reshape_1 --inference=FLOAT
|
||||
```
|
||||
|
||||
#### tflite to C code
|
||||
#### tflite to kmodel
|
||||
|
||||
Enter `ncc` directory and place the dataset into `ncc\dataset` directory.
|
||||
|
||||
```shell
|
||||
.\ncc.exe -i tflite -o k210code --dataset .\dataset\ .\bin\mobilenetv1.tflite .\bin\mobilenetv1.c
|
||||
./ncc -i tflite -o k210model --dataset ./dataset ./bin/mobilenetv1_1.0.tflite ./bin/mobilenetv1_1.0.kmodel
|
||||
```
|
||||
|
||||
### Prepare image for test
|
||||
|
|
|
@ -0,0 +1,315 @@
|
|||
/**
|
||||
* @file incbin.h
|
||||
* @author Dale Weiler
|
||||
* @brief Utility for including binary files
|
||||
*
|
||||
* Facilities for including binary files into the current translation unit and
|
||||
* making use from them externally in other translation units.
|
||||
*/
|
||||
#ifndef INCBIN_HDR
|
||||
#define INCBIN_HDR
|
||||
#include <limits.h>
|
||||
|
||||
# define INCBIN_ALIGNMENT_INDEX 8
|
||||
|
||||
/* Lookup table of (1 << n) where `n' is `INCBIN_ALIGNMENT_INDEX' */
|
||||
#define INCBIN_ALIGN_SHIFT_0 1
|
||||
#define INCBIN_ALIGN_SHIFT_1 2
|
||||
#define INCBIN_ALIGN_SHIFT_2 4
|
||||
#define INCBIN_ALIGN_SHIFT_3 8
|
||||
#define INCBIN_ALIGN_SHIFT_4 16
|
||||
#define INCBIN_ALIGN_SHIFT_5 32
|
||||
#define INCBIN_ALIGN_SHIFT_6 64
|
||||
#define INCBIN_ALIGN_SHIFT_7 128
|
||||
#define INCBIN_ALIGN_SHIFT_8 256
|
||||
|
||||
/* Actual alignment value */
|
||||
#define INCBIN_ALIGNMENT \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_CONCATENATE(INCBIN_ALIGN_SHIFT, _), \
|
||||
INCBIN_ALIGNMENT_INDEX)
|
||||
|
||||
/* Stringize */
|
||||
#define INCBIN_STR(X) \
|
||||
#X
|
||||
#define INCBIN_STRINGIZE(X) \
|
||||
INCBIN_STR(X)
|
||||
/* Concatenate */
|
||||
#define INCBIN_CAT(X, Y) \
|
||||
X ## Y
|
||||
#define INCBIN_CONCATENATE(X, Y) \
|
||||
INCBIN_CAT(X, Y)
|
||||
/* Deferred macro expansion */
|
||||
#define INCBIN_EVAL(X) \
|
||||
X
|
||||
#define INCBIN_INVOKE(N, ...) \
|
||||
INCBIN_EVAL(N(__VA_ARGS__))
|
||||
|
||||
/* Green Hills uses a different directive for including binary data */
|
||||
#if defined(__ghs__)
|
||||
# define INCBIN_MACRO "\tINCBIN"
|
||||
#else
|
||||
# define INCBIN_MACRO ".incbin"
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# define INCBIN_ALIGN \
|
||||
__attribute__((aligned(INCBIN_ALIGNMENT)))
|
||||
#else
|
||||
# define INCBIN_ALIGN __declspec(align(INCBIN_ALIGNMENT))
|
||||
#endif
|
||||
|
||||
#if defined(__arm__) || /* GNU C and RealView */ \
|
||||
defined(__arm) || /* Diab */ \
|
||||
defined(_ARM) /* ImageCraft */
|
||||
# define INCBIN_ARM
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
/* Utilize .balign where supported */
|
||||
# define INCBIN_ALIGN_HOST ".balign " INCBIN_STRINGIZE(INCBIN_ALIGNMENT) "\n"
|
||||
# define INCBIN_ALIGN_BYTE ".balign 1\n"
|
||||
#elif defined(INCBIN_ARM)
|
||||
/*
|
||||
* On arm assemblers, the alignment value is calculated as (1 << n) where `n' is
|
||||
* the shift count. This is the value passed to `.align'
|
||||
*/
|
||||
# define INCBIN_ALIGN_HOST ".align" INCBIN_STRINGIZE(INCBIN_ALIGNMENT_INDEX) "\n"
|
||||
# define INCBIN_ALIGN_BYTE ".align 0\n"
|
||||
#else
|
||||
/* We assume other inline assembler's treat `.align' as `.balign' */
|
||||
# define INCBIN_ALIGN_HOST ".align" INCBIN_STRINGIZE(INCBIN_ALIGNMENT) "\n"
|
||||
# define INCBIN_ALIGN_BYTE ".align 1\n"
|
||||
#endif
|
||||
|
||||
/* INCBIN_CONST is used by incbin.c generated files */
|
||||
#if defined(__cplusplus)
|
||||
# define INCBIN_EXTERNAL extern "C"
|
||||
# define INCBIN_CONST extern const
|
||||
#else
|
||||
# define INCBIN_EXTERNAL extern
|
||||
# define INCBIN_CONST const
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* The directives are different for Apple branded compilers */
|
||||
# define INCBIN_SECTION ".data\n"
|
||||
# define INCBIN_GLOBAL(NAME) ".globl " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "\n"
|
||||
# define INCBIN_INT ".long "
|
||||
# define INCBIN_MANGLE "_"
|
||||
# define INCBIN_BYTE ".byte "
|
||||
# define INCBIN_TYPE(...)
|
||||
#else
|
||||
# define INCBIN_SECTION ".section .data\n"
|
||||
# define INCBIN_GLOBAL(NAME) ".global " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "\n"
|
||||
# define INCBIN_INT ".int "
|
||||
# if defined(__USER_LABEL_PREFIX__)
|
||||
# define INCBIN_MANGLE INCBIN_STRINGIZE(__USER_LABEL_PREFIX__)
|
||||
# else
|
||||
# define INCBIN_MANGLE ""
|
||||
# endif
|
||||
# if defined(INCBIN_ARM)
|
||||
/* On arm assemblers, `@' is used as a line comment token */
|
||||
# define INCBIN_TYPE(NAME) ".type " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME ", %object\n"
|
||||
# elif defined(__MINGW32__) || defined(__MINGW64__)
|
||||
/* Mingw doesn't support this directive either */
|
||||
# define INCBIN_TYPE(NAME)
|
||||
# else
|
||||
/* It's safe to use `@' on other architectures */
|
||||
# define INCBIN_TYPE(NAME) ".type " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME ", @object\n"
|
||||
# endif
|
||||
# define INCBIN_BYTE ".byte "
|
||||
#endif
|
||||
|
||||
/* List of style types used for symbol names */
|
||||
#define INCBIN_STYLE_CAMEL 0
|
||||
#define INCBIN_STYLE_SNAKE 1
|
||||
|
||||
/**
|
||||
* @brief Specify the prefix to use for symbol names.
|
||||
*
|
||||
* By default this is `g', producing symbols of the form:
|
||||
* @code
|
||||
* #include "incbin.h"
|
||||
* INCBIN(Foo, "foo.txt");
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // const unsigned char gFooData[];
|
||||
* // const unsigned char gFooEnd;
|
||||
* // const unsigned int gFooSize;
|
||||
* @endcode
|
||||
*
|
||||
* If however you specify a prefix before including: e.g:
|
||||
* @code
|
||||
* #define INCBIN_PREFIX incbin
|
||||
* #include "incbin.h"
|
||||
* INCBIN(Foo, "foo.txt");
|
||||
*
|
||||
* // Now you have the following symbols instead:
|
||||
* // const unsigned char incbinFooData[];
|
||||
* // const unsigned char incbinFooEnd;
|
||||
* // const unsigned int incbinFooSize;
|
||||
* @endcode
|
||||
*/
|
||||
#if !defined(INCBIN_PREFIX)
|
||||
# define INCBIN_PREFIX g
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Specify the style used for symbol names.
|
||||
*
|
||||
* Possible options are
|
||||
* - INCBIN_STYLE_CAMEL "CamelCase"
|
||||
* - INCBIN_STYLE_SNAKE "snake_case"
|
||||
*
|
||||
* Default option is *INCBIN_STYLE_CAMEL* producing symbols of the form:
|
||||
* @code
|
||||
* #include "incbin.h"
|
||||
* INCBIN(Foo, "foo.txt");
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // const unsigned char <prefix>FooData[];
|
||||
* // const unsigned char <prefix>FooEnd;
|
||||
* // const unsigned int <prefix>FooSize;
|
||||
* @endcode
|
||||
*
|
||||
* If however you specify a style before including: e.g:
|
||||
* @code
|
||||
* #define INCBIN_STYLE INCBIN_STYLE_SNAKE
|
||||
* #include "incbin.h"
|
||||
* INCBIN(foo, "foo.txt");
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // const unsigned char <prefix>foo_data[];
|
||||
* // const unsigned char <prefix>foo_end;
|
||||
* // const unsigned int <prefix>foo_size;
|
||||
* @endcode
|
||||
*/
|
||||
#if !defined(INCBIN_STYLE)
|
||||
# define INCBIN_STYLE INCBIN_STYLE_CAMEL
|
||||
#endif
|
||||
|
||||
/* Style lookup tables */
|
||||
#define INCBIN_STYLE_0_DATA Data
|
||||
#define INCBIN_STYLE_0_END End
|
||||
#define INCBIN_STYLE_0_SIZE Size
|
||||
#define INCBIN_STYLE_1_DATA _data
|
||||
#define INCBIN_STYLE_1_END _end
|
||||
#define INCBIN_STYLE_1_SIZE _size
|
||||
|
||||
/* Style lookup: returning identifier */
|
||||
#define INCBIN_STYLE_IDENT(TYPE) \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_STYLE_, \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_EVAL(INCBIN_STYLE), \
|
||||
INCBIN_CONCATENATE(_, TYPE)))
|
||||
|
||||
/* Style lookup: returning string literal */
|
||||
#define INCBIN_STYLE_STRING(TYPE) \
|
||||
INCBIN_STRINGIZE( \
|
||||
INCBIN_STYLE_IDENT(TYPE)) \
|
||||
|
||||
/* Generate the global labels by indirectly invoking the macro with our style
|
||||
* type and concatenating the name against them. */
|
||||
#define INCBIN_GLOBAL_LABELS(NAME, TYPE) \
|
||||
INCBIN_INVOKE( \
|
||||
INCBIN_GLOBAL, \
|
||||
INCBIN_CONCATENATE( \
|
||||
NAME, \
|
||||
INCBIN_INVOKE( \
|
||||
INCBIN_STYLE_IDENT, \
|
||||
TYPE))) \
|
||||
INCBIN_INVOKE( \
|
||||
INCBIN_TYPE, \
|
||||
INCBIN_CONCATENATE( \
|
||||
NAME, \
|
||||
INCBIN_INVOKE( \
|
||||
INCBIN_STYLE_IDENT, \
|
||||
TYPE)))
|
||||
|
||||
/**
|
||||
* @brief Externally reference binary data included in another translation unit.
|
||||
*
|
||||
* Produces three external symbols that reference the binary data included in
|
||||
* another translation unit.
|
||||
*
|
||||
* The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with
|
||||
* "Data", as well as "End" and "Size" after. An example is provided below.
|
||||
*
|
||||
* @param NAME The name given for the binary data
|
||||
*
|
||||
* @code
|
||||
* INCBIN_EXTERN(Foo);
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // extern const unsigned char <prefix>FooData[];
|
||||
* // extern const unsigned char <prefix>FooEnd;
|
||||
* // extern const unsigned int <prefix>FooSize;
|
||||
* @endcode
|
||||
*/
|
||||
#define INCBIN_EXTERN(NAME) \
|
||||
INCBIN_EXTERNAL INCBIN_ALIGN unsigned char \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \
|
||||
INCBIN_STYLE_IDENT(DATA))[]; \
|
||||
INCBIN_EXTERNAL INCBIN_ALIGN unsigned char * \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \
|
||||
INCBIN_STYLE_IDENT(END)); \
|
||||
INCBIN_EXTERNAL unsigned int \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \
|
||||
INCBIN_STYLE_IDENT(SIZE))
|
||||
|
||||
/**
|
||||
* @brief Include a binary file into the current translation unit.
|
||||
*
|
||||
* Includes a binary file into the current translation unit, producing three symbols
|
||||
* for objects that encode the data and size respectively.
|
||||
*
|
||||
* The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with
|
||||
* "Data", as well as "End" and "Size" after. An example is provided below.
|
||||
*
|
||||
* @param NAME The name to associate with this binary data (as an identifier.)
|
||||
* @param FILENAME The file to include (as a string literal.)
|
||||
*
|
||||
* @code
|
||||
* INCBIN(Icon, "icon.png");
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // const unsigned char <prefix>IconData[];
|
||||
* // const unsigned char <prefix>IconEnd;
|
||||
* // const unsigned int <prefix>IconSize;
|
||||
* @endcode
|
||||
*
|
||||
* @warning This must be used in global scope
|
||||
* @warning The identifiers may be different if INCBIN_STYLE is not default
|
||||
*
|
||||
* To externally reference the data included by this in another translation unit
|
||||
* please @see INCBIN_EXTERN.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#define INCBIN(NAME, FILENAME) \
|
||||
INCBIN_EXTERN(NAME)
|
||||
#else
|
||||
#define INCBIN(NAME, FILENAME) \
|
||||
__asm__(INCBIN_SECTION \
|
||||
INCBIN_GLOBAL_LABELS(NAME, DATA) \
|
||||
INCBIN_ALIGN_HOST \
|
||||
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(DATA) ":\n" \
|
||||
INCBIN_MACRO " \"" FILENAME "\"\n" \
|
||||
INCBIN_GLOBAL_LABELS(NAME, END) \
|
||||
INCBIN_ALIGN_BYTE \
|
||||
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(END) ":\n" \
|
||||
INCBIN_BYTE "1\n" \
|
||||
INCBIN_GLOBAL_LABELS(NAME, SIZE) \
|
||||
INCBIN_ALIGN_HOST \
|
||||
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(SIZE) ":\n" \
|
||||
INCBIN_INT INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(END) " - " \
|
||||
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(DATA) "\n" \
|
||||
); \
|
||||
INCBIN_EXTERN(NAME)
|
||||
|
||||
#endif
|
||||
#endif
|
103
K210code/main.c
103
K210code/main.c
|
@ -13,29 +13,24 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "kpu.h"
|
||||
#include <platform.h>
|
||||
#include <printf.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sysctl.h>
|
||||
#include "uarths.h"
|
||||
#include "mobilenetv1.h"
|
||||
#include "kpu.h"
|
||||
#include "incbin.h"
|
||||
|
||||
#define INCBIN_STYLE INCBIN_STYLE_SNAKE
|
||||
#define INCBIN_PREFIX
|
||||
|
||||
#define PLL0_OUTPUT_FREQ 800000000UL
|
||||
#define PLL1_OUTPUT_FREQ 300000000UL
|
||||
|
||||
INCBIN(model, "mobilenetv1_1.0.kmodel");
|
||||
|
||||
kpu_model_context_t task;
|
||||
|
||||
volatile uint32_t g_ai_done_flag;
|
||||
|
||||
#define IN_SIZE 224
|
||||
|
||||
#define OUT_SIZE 7 * 7 * 1024
|
||||
#define FEATURE_SIZE 1000
|
||||
volatile uint32_t g_cnt_layer;
|
||||
uint8_t g_kpu_outbuf[OUT_SIZE] __attribute__((aligned(128)));
|
||||
float features[FEATURE_SIZE];
|
||||
extern const unsigned char gImage_image[] __attribute__((aligned(128)));
|
||||
kpu_task_t task;
|
||||
|
||||
static int ai_done(void *ctx)
|
||||
{
|
||||
|
@ -43,71 +38,35 @@ static int ai_done(void *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ai_step(void *ctx)
|
||||
{
|
||||
switch (g_cnt_layer)
|
||||
{
|
||||
case 0 ... 25:
|
||||
kpu_conv2d(task.layers + g_cnt_layer);
|
||||
break;
|
||||
case 26:
|
||||
kpu_conv2d_output(task.layers + g_cnt_layer, 5, g_kpu_outbuf, ai_step, NULL);
|
||||
break;
|
||||
case 27:
|
||||
{
|
||||
quantize_param_t q1 = { .scale = 0.0163548170351515,.bias = 0 }, q2 = { .scale = 0.0021889562700309,.bias = 0 };
|
||||
kpu_global_average_pool(g_kpu_outbuf, &q1, 7*7, 1024, AI_IO_BASE_ADDR + task.layers[g_cnt_layer].image_addr.data.image_src_addr * 64, &q2);
|
||||
kpu_matmul_begin(task.layers + g_cnt_layer, 5, (uint64_t *)g_kpu_outbuf, ai_done, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("Unexpcted.\n");
|
||||
while (1);
|
||||
break;
|
||||
}
|
||||
|
||||
printf("%d\n", g_cnt_layer);
|
||||
g_cnt_layer++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
/* Set CPU and dvp clk */
|
||||
/* Set CPU and KPU clk */
|
||||
sysctl_pll_set_freq(SYSCTL_PLL0, PLL0_OUTPUT_FREQ);
|
||||
sysctl_pll_set_freq(SYSCTL_PLL1, PLL1_OUTPUT_FREQ);
|
||||
sysctl_clock_enable(SYSCTL_CLOCK_AI);
|
||||
|
||||
uarths_init();
|
||||
plic_init();
|
||||
sysctl_enable_irq();
|
||||
|
||||
kpu_task_mobilenetv1_init(&task);
|
||||
|
||||
size_t j;
|
||||
for (j = 0; j < 1; j++)
|
||||
{
|
||||
g_cnt_layer = 0;
|
||||
g_ai_done_flag = 0;
|
||||
kpu_init(task.eight_bit_mode, ai_step, NULL);
|
||||
/* start to calculate */
|
||||
uint64_t t1 = sysctl_get_time_us();
|
||||
kpu_input_with_padding(task.layers, gImage_image, IN_SIZE, IN_SIZE, 3);
|
||||
sysctl_disable_irq();
|
||||
ai_step(NULL);
|
||||
sysctl_enable_irq();
|
||||
while (!g_ai_done_flag){}
|
||||
|
||||
quantize_param_t q = { .scale = task.output_scale,.bias = task.output_bias };
|
||||
|
||||
kpu_matmul_end(g_kpu_outbuf, FEATURE_SIZE, features, &q);
|
||||
t1 = sysctl_get_time_us() - t1;
|
||||
printf("takes %f ms\n", t1 / 1000.0);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < FEATURE_SIZE; i++)
|
||||
printf("%f, ", features[i]);
|
||||
printf("done\n");
|
||||
if (kpu_load_kmodel(&task, model_data) != 0)
|
||||
{
|
||||
printf("\nmodel init error\n");
|
||||
return -1;
|
||||
}
|
||||
while (1)
|
||||
;
|
||||
|
||||
sysctl_enable_irq();
|
||||
|
||||
printf("System Start\n");
|
||||
g_ai_done_flag = 0;
|
||||
kpu_run_kmodel(&task, gImage_image, DMAC_CHANNEL5, ai_done, NULL);
|
||||
while (g_ai_done_flag == 0);
|
||||
float *output;
|
||||
size_t output_size;
|
||||
kpu_get_output(&task, 0, (uint8_t **)&output, &output_size);
|
||||
|
||||
for (uint32_t i = 0; i < output_size / (sizeof(float)); i++)
|
||||
printf("%f ", output[i]);
|
||||
printf("\ndone\n");
|
||||
|
||||
while (1);
|
||||
}
|
80697
K210code/mobilenetv1.c
80697
K210code/mobilenetv1.c
File diff suppressed because it is too large
Load Diff
|
@ -1,2 +0,0 @@
|
|||
void kpu_task_mobilenetv1_init(kpu_task_t* task);
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue