Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,52 @@ endif()

# add benchncnn to a virtual project group
set_property(TARGET benchncnn PROPERTY FOLDER "benchmark")

# generate model data
include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ncnn_generate_model_data_header.cmake)

set(embedded_model_param_includes "")

set(PARAM_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/squeezenet.param"
"${CMAKE_CURRENT_SOURCE_DIR}/squeezenet_int8.param"
"${CMAKE_CURRENT_SOURCE_DIR}/mobilenet.param"
"${CMAKE_CURRENT_SOURCE_DIR}/mobilenet_int8.param"
"${CMAKE_CURRENT_SOURCE_DIR}/mobilenet_v2.param"
"${CMAKE_CURRENT_SOURCE_DIR}/mobilenet_v3.param"
"${CMAKE_CURRENT_SOURCE_DIR}/shufflenet.param"
"${CMAKE_CURRENT_SOURCE_DIR}/shufflenet_v2.param"
"${CMAKE_CURRENT_SOURCE_DIR}/mnasnet.param"
"${CMAKE_CURRENT_SOURCE_DIR}/proxylessnasnet.param"
"${CMAKE_CURRENT_SOURCE_DIR}/efficientnet_b0.param"
"${CMAKE_CURRENT_SOURCE_DIR}/efficientnetv2_b0.param"
"${CMAKE_CURRENT_SOURCE_DIR}/regnety_400m.param"
"${CMAKE_CURRENT_SOURCE_DIR}/blazeface.param"
"${CMAKE_CURRENT_SOURCE_DIR}/googlenet.param"
"${CMAKE_CURRENT_SOURCE_DIR}/googlenet_int8.param"
"${CMAKE_CURRENT_SOURCE_DIR}/resnet18.param"
"${CMAKE_CURRENT_SOURCE_DIR}/resnet18_int8.param"
"${CMAKE_CURRENT_SOURCE_DIR}/alexnet.param"
"${CMAKE_CURRENT_SOURCE_DIR}/vgg16.param"
"${CMAKE_CURRENT_SOURCE_DIR}/vgg16_int8.param"
"${CMAKE_CURRENT_SOURCE_DIR}/resnet50.param"
"${CMAKE_CURRENT_SOURCE_DIR}/resnet50_int8.param"
"${CMAKE_CURRENT_SOURCE_DIR}/squeezenet_ssd.param"
"${CMAKE_CURRENT_SOURCE_DIR}/squeezenet_ssd_int8.param"
"${CMAKE_CURRENT_SOURCE_DIR}/mobilenet_ssd.param"
"${CMAKE_CURRENT_SOURCE_DIR}/mobilenet_ssd_int8.param"
"${CMAKE_CURRENT_SOURCE_DIR}/mobilenet_yolo.param"
"${CMAKE_CURRENT_SOURCE_DIR}/mobilenetv2_yolov3.param"
"${CMAKE_CURRENT_SOURCE_DIR}/yolov4-tiny.param"
"${CMAKE_CURRENT_SOURCE_DIR}/nanodet_m.param"
"${CMAKE_CURRENT_SOURCE_DIR}/yolo-fastest-1.1.param"
"${CMAKE_CURRENT_SOURCE_DIR}/yolo-fastestv2.param"
"${CMAKE_CURRENT_SOURCE_DIR}/vision_transformer.param"
"${CMAKE_CURRENT_SOURCE_DIR}/FastestDet.param"
)

foreach(PARAM_FILE ${PARAM_FILES})
ncnn_convert_param_file(${PARAM_FILE})
endforeach()

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/embedded_model_params.h "${embedded_model_param_includes}")
96 changes: 46 additions & 50 deletions benchmark/benchncnn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "net.h"
#include "gpu.h"

#include "../benchmark/embedded_model_params.h"

#ifndef NCNN_SIMPLESTL
#include <vector>
#endif
Expand Down Expand Up @@ -46,12 +48,12 @@ static ncnn::VkAllocator* g_blob_vkallocator = 0;
static ncnn::VkAllocator* g_staging_vkallocator = 0;
#endif // NCNN_VULKAN

void benchmark(const char* comment, const std::vector<ncnn::Mat>& _in, const ncnn::Option& opt, bool fixed_path = true)
void benchmark(const char* comment, const std::vector<ncnn::Mat>& _in, const ncnn::Option& opt, const char* model_param_data = NULL)
{
// Skip if int8 model name and using GPU
if (opt.use_vulkan_compute && strstr(comment, "int8") != NULL)
{
if (!fixed_path)
if (!model_param_data)
fprintf(stderr, "%20s skipped (int8+GPU not supported)\n", comment);
return;
}
Expand All @@ -78,17 +80,11 @@ void benchmark(const char* comment, const std::vector<ncnn::Mat>& _in, const ncn
}
#endif // NCNN_VULKAN

#ifdef __EMSCRIPTEN__
#define MODEL_DIR "/working/"
#else
#define MODEL_DIR ""
#endif
const char* model_param = NULL;

if (fixed_path)
if (model_param_data)
{
char parampath[256];
sprintf(parampath, MODEL_DIR "%s.param", comment);
net.load_param(parampath);
net.load_param_mem(model_param_data);
}
else
{
Expand Down Expand Up @@ -173,11 +169,11 @@ void benchmark(const char* comment, const std::vector<ncnn::Mat>& _in, const ncn
fprintf(stderr, "%20s min = %7.2f max = %7.2f avg = %7.2f\n", comment, time_min, time_max, time_avg);
}

void benchmark(const char* comment, const ncnn::Mat& _in, const ncnn::Option& opt, bool fixed_path = true)
void benchmark(const char* comment, const ncnn::Mat& _in, const ncnn::Option& opt, const char* model_param_data = NULL)
{
std::vector<ncnn::Mat> inputs;
inputs.push_back(_in);
return benchmark(comment, inputs, opt, fixed_path);
return benchmark(comment, inputs, opt, model_param_data);
}

void show_usage()
Expand Down Expand Up @@ -387,82 +383,82 @@ int main(int argc, char** argv)
if (model != 0)
{
// run user defined benchmark
benchmark(model, inputs, opt, false);
benchmark(model, inputs, opt);
}
else
{
// run default cases
benchmark("squeezenet", ncnn::Mat(227, 227, 3), opt);
benchmark("squeezenet", ncnn::Mat(227, 227, 3), opt, squeezenet_param_data);

benchmark("squeezenet_int8", ncnn::Mat(227, 227, 3), opt);
benchmark("squeezenet_int8", ncnn::Mat(227, 227, 3), opt, squeezenet_int8_param_data);

benchmark("mobilenet", ncnn::Mat(224, 224, 3), opt);
benchmark("mobilenet", ncnn::Mat(224, 224, 3), opt, mobilenet_param_data);

benchmark("mobilenet_int8", ncnn::Mat(224, 224, 3), opt);
benchmark("mobilenet_int8", ncnn::Mat(224, 224, 3), opt, mobilenet_int8_param_data);

benchmark("mobilenet_v2", ncnn::Mat(224, 224, 3), opt);
benchmark("mobilenet_v2", ncnn::Mat(224, 224, 3), opt, mobilenet_v2_param_data);

// benchmark("mobilenet_v2_int8", ncnn::Mat(224, 224, 3), opt);
// benchmark("mobilenet_v2_int8", ncnn::Mat(224, 224, 3), opt, mobilenet_v2_int8_param_data);

benchmark("mobilenet_v3", ncnn::Mat(224, 224, 3), opt);
benchmark("mobilenet_v3", ncnn::Mat(224, 224, 3), opt, mobilenet_v3_param_data);

benchmark("shufflenet", ncnn::Mat(224, 224, 3), opt);
benchmark("shufflenet", ncnn::Mat(224, 224, 3), opt, shufflenet_param_data);

benchmark("shufflenet_v2", ncnn::Mat(224, 224, 3), opt);
benchmark("shufflenet_v2", ncnn::Mat(224, 224, 3), opt, shufflenet_v2_param_data);

benchmark("mnasnet", ncnn::Mat(224, 224, 3), opt);
benchmark("mnasnet", ncnn::Mat(224, 224, 3), opt, mnasnet_param_data);

benchmark("proxylessnasnet", ncnn::Mat(224, 224, 3), opt);
benchmark("proxylessnasnet", ncnn::Mat(224, 224, 3), opt, proxylessnasnet_param_data);

benchmark("efficientnet_b0", ncnn::Mat(224, 224, 3), opt);
benchmark("efficientnet_b0", ncnn::Mat(224, 224, 3), opt, efficientnet_b0_param_data);

benchmark("efficientnetv2_b0", ncnn::Mat(224, 224, 3), opt);
benchmark("efficientnetv2_b0", ncnn::Mat(224, 224, 3), opt, efficientnetv2_b0_param_data);

benchmark("regnety_400m", ncnn::Mat(224, 224, 3), opt);
benchmark("regnety_400m", ncnn::Mat(224, 224, 3), opt, regnety_400m_param_data);

benchmark("blazeface", ncnn::Mat(128, 128, 3), opt);
benchmark("blazeface", ncnn::Mat(128, 128, 3), opt, blazeface_param_data);

benchmark("googlenet", ncnn::Mat(224, 224, 3), opt);
benchmark("googlenet", ncnn::Mat(224, 224, 3), opt, googlenet_param_data);

benchmark("googlenet_int8", ncnn::Mat(224, 224, 3), opt);
benchmark("googlenet_int8", ncnn::Mat(224, 224, 3), opt, googlenet_int8_param_data);

benchmark("resnet18", ncnn::Mat(224, 224, 3), opt);
benchmark("resnet18", ncnn::Mat(224, 224, 3), opt, resnet18_param_data);

benchmark("resnet18_int8", ncnn::Mat(224, 224, 3), opt);
benchmark("resnet18_int8", ncnn::Mat(224, 224, 3), opt, resnet18_int8_param_data);

benchmark("alexnet", ncnn::Mat(227, 227, 3), opt);
benchmark("alexnet", ncnn::Mat(227, 227, 3), opt, alexnet_param_data);

benchmark("vgg16", ncnn::Mat(224, 224, 3), opt);
benchmark("vgg16", ncnn::Mat(224, 224, 3), opt, vgg16_param_data);

benchmark("vgg16_int8", ncnn::Mat(224, 224, 3), opt);
benchmark("vgg16_int8", ncnn::Mat(224, 224, 3), opt, vgg16_int8_param_data);

benchmark("resnet50", ncnn::Mat(224, 224, 3), opt);
benchmark("resnet50", ncnn::Mat(224, 224, 3), opt, resnet50_param_data);

benchmark("resnet50_int8", ncnn::Mat(224, 224, 3), opt);
benchmark("resnet50_int8", ncnn::Mat(224, 224, 3), opt, resnet50_int8_param_data);

benchmark("squeezenet_ssd", ncnn::Mat(300, 300, 3), opt);
benchmark("squeezenet_ssd", ncnn::Mat(300, 300, 3), opt, squeezenet_ssd_param_data);

benchmark("squeezenet_ssd_int8", ncnn::Mat(300, 300, 3), opt);
benchmark("squeezenet_ssd_int8", ncnn::Mat(300, 300, 3), opt, squeezenet_ssd_int8_param_data);

benchmark("mobilenet_ssd", ncnn::Mat(300, 300, 3), opt);
benchmark("mobilenet_ssd", ncnn::Mat(300, 300, 3), opt, mobilenet_ssd_param_data);

benchmark("mobilenet_ssd_int8", ncnn::Mat(300, 300, 3), opt);
benchmark("mobilenet_ssd_int8", ncnn::Mat(300, 300, 3), opt, mobilenet_ssd_int8_param_data);

benchmark("mobilenet_yolo", ncnn::Mat(416, 416, 3), opt);
benchmark("mobilenet_yolo", ncnn::Mat(416, 416, 3), opt, mobilenet_yolo_param_data);

benchmark("mobilenetv2_yolov3", ncnn::Mat(352, 352, 3), opt);
benchmark("mobilenetv2_yolov3", ncnn::Mat(352, 352, 3), opt, mobilenetv2_yolov3_param_data);

benchmark("yolov4-tiny", ncnn::Mat(416, 416, 3), opt);
benchmark("yolov4-tiny", ncnn::Mat(416, 416, 3), opt, yolov4_tiny_param_data);

benchmark("nanodet_m", ncnn::Mat(320, 320, 3), opt);
benchmark("nanodet_m", ncnn::Mat(320, 320, 3), opt, nanodet_m_param_data);

benchmark("yolo-fastest-1.1", ncnn::Mat(320, 320, 3), opt);
benchmark("yolo-fastest-1.1", ncnn::Mat(320, 320, 3), opt, yolo_fastest_1_1_param_data);

benchmark("yolo-fastestv2", ncnn::Mat(352, 352, 3), opt);
benchmark("yolo-fastestv2", ncnn::Mat(352, 352, 3), opt, yolo_fastestv2_param_data);

benchmark("vision_transformer", ncnn::Mat(384, 384, 3), opt);
benchmark("vision_transformer", ncnn::Mat(384, 384, 3), opt, vision_transformer_param_data);

benchmark("FastestDet", ncnn::Mat(352, 352, 3), opt);
benchmark("FastestDet", ncnn::Mat(352, 352, 3), opt, FastestDet_param_data);
}
#if NCNN_VULKAN
delete g_blob_vkallocator;
Expand Down
41 changes: 41 additions & 0 deletions cmake/ncnn_generate_model_data_header.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

macro(ncnn_convert_param_file PARAM_FILE)
# Use a macro to convert the contents of a single parameter file into memory content
file(READ ${PARAM_FILE} param_file_data)

# remove whitespace
string(REGEX REPLACE "\n +" "\n" param_file_data ${param_file_data})

# remove empty line
string(REGEX REPLACE "\n\n" "\n" param_file_data ${param_file_data})

# Get the file name with extension
get_filename_component(PARAM_FILE_NAME ${PARAM_FILE} NAME)
# Manually remove ".param" since NAME_WE treats ".1.param" as a multi-extension
string(REPLACE ".param" "" PARAM_FILE_NAME_WE "${PARAM_FILE_NAME}")
# Replace characters invalid in C identifiers ('.' and '-') with underscores
string(REPLACE "." "_" PARAM_FILE_NAME_WE "${PARAM_FILE_NAME_WE}")
string(REPLACE "-" "_" PARAM_FILE_NAME_WE "${PARAM_FILE_NAME_WE}")
# Check if the result is empty
if (NOT PARAM_FILE_NAME_WE)
message(FATAL_ERROR "Failed to extract valid filename from '${PARAM_FILE}'")
endif()
# Check if the extracted filename is a valid C identifier
string(REGEX MATCH "^[A-Za-z_][A-Za-z0-9_]*$" is_valid "${PARAM_FILE_NAME_WE}")
if (NOT is_valid)
message(FATAL_ERROR "Extracted filename '${PARAM_FILE_NAME_WE}' is not a valid C identifier")
endif()

# text to hex
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/param_hex_data/${PARAM_FILE_NAME_WE}.text2hex.txt "${param_file_data}")
file(READ ${CMAKE_CURRENT_BINARY_DIR}/param_hex_data/${PARAM_FILE_NAME_WE}.text2hex.txt param_file_data_hex HEX)
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," param_file_data_hex ${param_file_data_hex})
string(FIND "${param_file_data_hex}" "," tail_comma REVERSE)
string(SUBSTRING "${param_file_data_hex}" 0 ${tail_comma} param_file_data_hex)

# generate model param header file
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/model_param_header/${PARAM_FILE_NAME_WE}.comp.hex.h "static const char ${PARAM_FILE_NAME_WE}_param_data[] = {${param_file_data_hex},0x00};\n")

# append include line to a CMake variable for later output
string(APPEND embedded_model_param_includes "#include \"model_param_header/${PARAM_FILE_NAME_WE}.comp.hex.h\"\n")
endmacro()
Loading