Skip to content

Commit

Permalink
[WIP] add the cpp api (#229)
Browse files Browse the repository at this point in the history
* add the c_plus api

* update the c++ api

* update the c++ api
  • Loading branch information
BUG1989 committed Mar 26, 2020
1 parent 2f6fb48 commit e3c8aa9
Show file tree
Hide file tree
Showing 10 changed files with 810 additions and 511 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -19,3 +19,4 @@ sysroot/
android_config.txt
model_src/
.vs/
.vscode/
166 changes: 43 additions & 123 deletions benchmark/src/bench_mobilenet.cpp
Expand Up @@ -18,8 +18,8 @@
*/

/*
* Copyright (c) 2017, Open AI Lab
* Author: haitao@openailab.com
* Copyright (c) 2020, OPEN AI LAB
* Author: qtang@openailab.com
*/
#include <unistd.h>

Expand All @@ -31,6 +31,7 @@

#include "tengine_operations.h"
#include "tengine_c_api.h"
#include "tengine_cpp_api.h"
#include "common_util.hpp"

const char* model_file = "./models/mobilenet.tmfile";
Expand All @@ -42,7 +43,6 @@ const float channel_mean[3] = {104.007, 116.669, 122.679};
using namespace TEngine;

int repeat_count = 100;

void LoadLabelFile(std::vector<std::string>& result, const char* fname)
{
std::ifstream labels(fname);
Expand All @@ -52,6 +52,27 @@ void LoadLabelFile(std::vector<std::string>& result, const char* fname)
{
while(std::getline(labels, line))
result.push_back(line);
}
}

void PrintTopLabels(const char* label_file, float* data)
{
// load labels
std::vector<std::string> labels;
LoadLabelFile(labels, label_file);

float* end = data + 1000;
std::vector<float> result(data, end);
std::vector<int> top_N = Argmax(result, 5);

for(unsigned int i = 0; i < top_N.size(); i++)
{
int idx = top_N[i];
if(labels.size())
std::cout << std::fixed << std::setprecision(4) << result[idx] << " - \"" << labels[idx] << "\"\n";
else
std::cout << std::fixed << std::setprecision(4) << result[idx] << " - " << idx << "\n";

}
}

Expand Down Expand Up @@ -109,139 +130,38 @@ int main(int argc, char* argv[])
int img_h = 224;
int img_w = 224;

std::string sub_dir = "/repo.log";
tengine::Net mobilenet;
tengine::Tensor input_tensor;
tengine::Tensor output_tensor;

std::string filename = "";
if("" != file_path)
{
filename = file_path + sub_dir;
}
/* load model */
mobilenet.load_model(NULL, "tengine", model_file);

/* prepare input data */
float* input_data = ( float* )malloc(sizeof(float) * img_h * img_w * 3);

get_input_data(image_file, input_data, img_h, img_w, channel_mean, 0.017);

if(cpu_list_str)
set_cpu_list(cpu_list_str);

init_tengine();

std::cout << "run-time library version: " << get_tengine_version() << "\n";

if(request_tengine_version("0.9") < 0)
return -1;

graph_t graph = create_graph(nullptr, "tengine", model_file);

if(graph == nullptr)
{
std::cout << "Create graph0 failed\n";
std::cout << "errno: " << get_tengine_errno() << "\n";
return -1;
}

/* get input tensor */
int node_idx = 0;
int tensor_idx = 0;

tensor_t input_tensor = get_graph_input_tensor(graph, node_idx, tensor_idx);

if(input_tensor == nullptr)
{
std::printf("Cannot find input tensor,node_idx: %d,tensor_idx: %d\n", node_idx, tensor_idx);
return -1;
}

int dims[] = {1, 3, img_h, img_w};

set_tensor_shape(input_tensor, dims, 4);

/* setup input buffer */

if(set_tensor_buffer(input_tensor, input_data, 3 * img_h * img_w * 4) < 0)
{
std::printf("Set buffer for tensor failed\n");
return -1;
}

if(!device.empty())
set_graph_device(graph, device.c_str());

/* run the graph */
int ret_prerun = prerun_graph(graph);
if(ret_prerun < 0)
{
std::printf("prerun failed\n");
return -1;
}
run_graph(graph, 1);

// benchmark start here
printf("REPEAT COUNT= %d\n", repeat_count);
input_tensor.create(img_w, img_h, 3);
get_input_data(image_file, (float* )input_tensor.data, img_h, img_w, channel_mean, 0.017);

/* forward */
mobilenet.input_tensor("data", input_tensor);

unsigned long start_time = get_cur_time();

for(int i = 0; i < repeat_count; i++)
run_graph(graph, 1);
mobilenet.run();

unsigned long end_time = get_cur_time();
unsigned long off_time = end_time - start_time;

unsigned long off_time = end_time - start_time;
std::printf("Repeat [%d] time %.2f us per RUN. used %lu us\n", repeat_count, 1.0f * off_time / repeat_count,
off_time);

if(filename != "")
{
FILE* fp = fopen(filename.c_str(), "a");

fprintf(fp, "device:%20s, repeat_count:%5d, per use_time:%10.2f,", device.c_str(), repeat_count,
1.0f * off_time / repeat_count);
fprintf(fp, "\n");

fclose(fp);
}

/* get output tensor */
tensor_t output_tensor = get_graph_output_tensor(graph, node_idx, tensor_idx);

if(output_tensor == nullptr)
{
std::printf("Cannot find output tensor , node_idx: %d,tensor_idx: %d\n", node_idx, tensor_idx);
return -1;
}

int count = get_tensor_buffer_size(output_tensor) / 4;

float* data = ( float* )(get_tensor_buffer(output_tensor));
float* end = data + count;

std::vector<float> result(data, end);

std::vector<int> top_N = Argmax(result, 5);

std::vector<std::string> labels;

LoadLabelFile(labels, label_file);

for(unsigned int i = 0; i < top_N.size(); i++)
{
int idx = top_N[i];
if(labels.size())
std::cout << std::fixed << std::setprecision(4) << result[idx] << " - \"" << labels[idx] << "\"\n";
else
std::cout << std::fixed << std::setprecision(4) << result[idx] << " - " << idx << "\n";
}

release_graph_tensor(output_tensor);
release_graph_tensor(input_tensor);
postrun_graph(graph);
destroy_graph(graph);
std::printf("Repeat [%d] time %.2f us per RUN. used %lu us\n", repeat_count, 1.0f * off_time / repeat_count, off_time);

free(input_data);
/* get result */
mobilenet.extract_tensor("fc7", output_tensor);

/* after process */
PrintTopLabels(label_file, (float*)output_tensor.data);

std::cout << "--------------------------------------\n";
std::cout << "ALL TEST DONE\n";

release_tengine();
return 0;
}
Expand Up @@ -22,7 +22,6 @@
* Author: haitao@openailab.com
*/
#include <unistd.h>
#include <sys/time.h>

#include <iostream>
#include <functional>
Expand All @@ -32,49 +31,28 @@

#include "tengine_operations.h"
#include "tengine_c_api.h"
#include "common_util.hpp"

const char* model_file = "./models/mobilenet.tmfile";
const char* image_file = "./tests/images/cat.jpg";
const char* label_file = "./models/synset_words.txt";

const float channel_mean[3] = {104.007, 116.669, 122.679};

int repeat_count = 100;

unsigned long get_cur_time(void)
{
struct timeval tv;
using namespace TEngine;

gettimeofday(&tv, NULL);

return (tv.tv_sec * 1000000 + tv.tv_usec);
}
int repeat_count = 100;

void LoadLabelFile(std::vector<std::string>& result, const char* fname)
{
std::ifstream labels(fname);

std::string line;
while(std::getline(labels, line))
result.push_back(line);
}

static inline bool PairCompare(const std::pair<float, int>& lhs, const std::pair<float, int>& rhs)
{
return lhs.first > rhs.first;
}

static inline std::vector<int> Argmax(const std::vector<float>& v, int N)
{
std::vector<std::pair<float, int>> pairs;
for(size_t i = 0; i < v.size(); ++i)
pairs.push_back(std::make_pair(v[i], i));
std::partial_sort(pairs.begin(), pairs.begin() + N, pairs.end(), PairCompare);

std::vector<int> result;
for(int i = 0; i < N; ++i)
result.push_back(pairs[i].second);
return result;
if(labels.is_open())
{
while(std::getline(labels, line))
result.push_back(line);
}
}

void get_input_data(const char* image_file, float* input_data, int img_h, int img_w, const float* mean, float scale)
Expand All @@ -96,12 +74,29 @@ void get_input_data(const char* image_file, float* input_data, int img_h, int im

int main(int argc, char* argv[])
{
std::string device = "";
std::string file_path = "";
char* cpu_list_str = nullptr;
;

int res;

while((res = getopt(argc, argv, "r:")) != -1)
while((res = getopt(argc, argv, "p:d:f:r:")) != -1)
{
switch(res)
{
case 'p':
cpu_list_str = optarg;
break;

case 'd':
device = optarg;
break;

case 'f':
file_path = optarg;
break;

case 'r':
repeat_count = strtoul(optarg, NULL, 10);
break;
Expand All @@ -114,19 +109,27 @@ int main(int argc, char* argv[])
int img_h = 224;
int img_w = 224;

std::string sub_dir = "/repo.log";

std::string filename = "";
if("" != file_path)
{
filename = file_path + sub_dir;
}

/* prepare input data */
float* input_data = ( float* )malloc(sizeof(float) * img_h * img_w * 3);

get_input_data(image_file, input_data, img_h, img_w, channel_mean, 0.017);

for(int i = 0; i < 10; ++i)
printf("%f\n", input_data[i]);
if(cpu_list_str)
set_cpu_list(cpu_list_str);

init_tengine();

std::cout << "run-time library version: " << get_tengine_version() << "\n";

if(request_tengine_version("1.0") < 0)
if(request_tengine_version("0.9") < 0)
return -1;

graph_t graph = create_graph(nullptr, "tengine", model_file);
Expand Down Expand Up @@ -162,16 +165,16 @@ int main(int argc, char* argv[])
return -1;
}

if(!device.empty())
set_graph_device(graph, device.c_str());

/* run the graph */
int ret_prerun = prerun_graph(graph);
if(ret_prerun < 0)
{
std::printf("prerun failed\n");
return -1;
}

dump_graph(graph);

run_graph(graph, 1);

// benchmark start here
Expand All @@ -188,6 +191,17 @@ int main(int argc, char* argv[])
std::printf("Repeat [%d] time %.2f us per RUN. used %lu us\n", repeat_count, 1.0f * off_time / repeat_count,
off_time);

if(filename != "")
{
FILE* fp = fopen(filename.c_str(), "a");

fprintf(fp, "device:%20s, repeat_count:%5d, per use_time:%10.2f,", device.c_str(), repeat_count,
1.0f * off_time / repeat_count);
fprintf(fp, "\n");

fclose(fp);
}

/* get output tensor */
tensor_t output_tensor = get_graph_output_tensor(graph, node_idx, tensor_idx);

Expand All @@ -213,9 +227,10 @@ int main(int argc, char* argv[])
for(unsigned int i = 0; i < top_N.size(); i++)
{
int idx = top_N[i];

std::cout << std::fixed << std::setprecision(4) << result[idx] << " - \"";
std::cout << labels[idx] << "\"\n";
if(labels.size())
std::cout << std::fixed << std::setprecision(4) << result[idx] << " - \"" << labels[idx] << "\"\n";
else
std::cout << std::fixed << std::setprecision(4) << result[idx] << " - " << idx << "\n";
}

release_graph_tensor(output_tensor);
Expand Down

0 comments on commit e3c8aa9

Please sign in to comment.