#include "example.h"
#include "misc.h"
#if LITE_BUILD_WITH_MGE
#include "lite-c/global_c.h"
#include "lite-c/network_c.h"
#include "lite-c/tensor_c.h"
#include <thread>
#define LITE_CAPI_CHECK(_expr) \
do { \
int _ret = (_expr); \
if (_ret) { \
LITE_THROW(LITE_get_last_error()); \
} \
} while (0)
bool basic_c_interface(const lite::example::Args& args) {
std::string network_path = args.model_path;
std::string input_path = args.input_path;
auto src_tensor = lite::example::parse_npy(input_path);
void* src_ptr = src_tensor->get_memory_ptr();
LiteNetwork c_network;
LITE_CAPI_CHECK(
LITE_make_network(&c_network, *default_config(), *default_network_io()));
LITE_CAPI_CHECK(LITE_load_model_from_path(c_network, network_path.c_str()));
LiteTensor c_input_tensor;
LITE_CAPI_CHECK(LITE_get_io_tensor(c_network, "data", LITE_IO, &c_input_tensor));
void* dst_ptr;
size_t length_in_byte;
LITE_CAPI_CHECK(
LITE_get_tensor_total_size_in_byte(c_input_tensor, &length_in_byte));
LITE_CAPI_CHECK(LITE_get_tensor_memory(c_input_tensor, &dst_ptr));
memcpy(dst_ptr, src_ptr, length_in_byte);
LITE_CAPI_CHECK(LITE_forward(c_network));
LITE_CAPI_CHECK(LITE_wait(c_network));
const char* output_name;
LiteTensor c_output_tensor;
LITE_CAPI_CHECK(LITE_get_output_name(c_network, 0, &output_name));
LITE_CAPI_CHECK(
LITE_get_io_tensor(c_network, output_name, LITE_IO, &c_output_tensor));
void* output_ptr;
size_t length_output_in_byte;
LITE_CAPI_CHECK(LITE_get_tensor_memory(c_output_tensor, &output_ptr));
LITE_CAPI_CHECK(LITE_get_tensor_total_size_in_byte(
c_output_tensor, &length_output_in_byte));
size_t out_length = length_output_in_byte / sizeof(float);
printf("length=%zu\n", out_length);
float max = -1.0f;
float sum = 0.0f;
for (size_t i = 0; i < out_length; i++) {
float data = static_cast<float*>(output_ptr)[i];
sum += data;
if (max < data)
max = data;
}
printf("max=%e, sum=%e\n", max, sum);
return true;
}
bool device_io_c_interface(const lite::example::Args& args) {
std::string network_path = args.model_path;
std::string input_path = args.input_path;
auto src_tensor = lite::example::parse_npy(input_path);
void* src_ptr = src_tensor->get_memory_ptr();
size_t length_read_in = src_tensor->get_tensor_total_size_in_byte();
LiteNetwork c_network;
LITE_CAPI_CHECK(
LITE_make_network(&c_network, *default_config(), *default_network_io()));
LITE_CAPI_CHECK(LITE_load_model_from_path(c_network, network_path.c_str()));
LiteTensor c_input_tensor;
size_t length_tensor_in;
LITE_CAPI_CHECK(LITE_get_io_tensor(c_network, "data", LITE_IO, &c_input_tensor));
LITE_CAPI_CHECK(
LITE_get_tensor_total_size_in_byte(c_input_tensor, &length_tensor_in));
if (length_read_in != length_tensor_in) {
LITE_THROW(
"The input data size is not match the network input tensro "
"size,\n");
}
LITE_CAPI_CHECK(
LITE_reset_tensor_memory(c_input_tensor, src_ptr, length_tensor_in));
size_t out_length = 1000;
LiteLayout output_layout{{1, 1000}, 2, LiteDataType::LITE_FLOAT};
std::shared_ptr<float> ptr(new float[out_length], [](float* ptr) { delete[] ptr; });
const char* output_name;
LiteTensor c_output_tensor;
LITE_CAPI_CHECK(LITE_get_output_name(c_network, 0, &output_name));
LITE_CAPI_CHECK(
LITE_get_io_tensor(c_network, output_name, LITE_IO, &c_output_tensor));
LITE_CAPI_CHECK(LITE_reset_tensor(c_output_tensor, output_layout, ptr.get()));
LITE_CAPI_CHECK(LITE_forward(c_network));
LITE_CAPI_CHECK(LITE_wait(c_network));
printf("length=%zu\n", out_length);
float max = -1.0f;
float sum = 0.0f;
void* out_data = ptr.get();
for (size_t i = 0; i < out_length; i++) {
float data = static_cast<float*>(out_data)[i];
sum += data;
if (max < data)
max = data;
}
printf("max=%e, sum=%e\n", max, sum);
return true;
}
namespace {
volatile bool finished = false;
int async_callback(void) {
#if !__DEPLOY_ON_XP_SP2__
std::cout << "worker thread_id:" << std::this_thread::get_id() << std::endl;
#endif
finished = true;
return 0;
}
}
bool async_c_interface(const lite::example::Args& args) {
std::string network_path = args.model_path;
std::string input_path = args.input_path;
auto src_tensor = lite::example::parse_npy(input_path);
void* src_ptr = src_tensor->get_memory_ptr();
LiteNetwork c_network;
LiteConfig config = *default_config();
config.options.var_sanity_check_first_run = false;
LITE_CAPI_CHECK(LITE_make_network(&c_network, config, *default_network_io()));
LITE_CAPI_CHECK(LITE_load_model_from_path(c_network, network_path.c_str()));
LiteTensor c_input_tensor;
size_t length_tensor_in;
LITE_CAPI_CHECK(LITE_get_io_tensor(c_network, "data", LITE_IO, &c_input_tensor));
LITE_CAPI_CHECK(
LITE_get_tensor_total_size_in_byte(c_input_tensor, &length_tensor_in));
LITE_CAPI_CHECK(
LITE_reset_tensor_memory(c_input_tensor, src_ptr, length_tensor_in));
#if !__DEPLOY_ON_XP_SP2__
std::cout << "user thread_id:" << std::this_thread::get_id() << std::endl;
#endif
LITE_CAPI_CHECK(LITE_set_async_callback(c_network, async_callback));
LITE_CAPI_CHECK(LITE_forward(c_network));
size_t count = 0;
while (finished == false) {
count++;
}
printf("The count is %zu\n", count);
finished = false;
const char* output_name;
LiteTensor c_output_tensor;
LITE_CAPI_CHECK(LITE_get_output_name(c_network, 0, &output_name));
LITE_CAPI_CHECK(
LITE_get_io_tensor(c_network, output_name, LITE_IO, &c_output_tensor));
void* output_ptr;
size_t length_output_in_byte;
LITE_CAPI_CHECK(LITE_get_tensor_memory(c_output_tensor, &output_ptr));
LITE_CAPI_CHECK(LITE_get_tensor_total_size_in_byte(
c_output_tensor, &length_output_in_byte));
size_t out_length = length_output_in_byte / sizeof(float);
printf("length=%zu\n", out_length);
float max = -1.0f;
float sum = 0.0f;
for (size_t i = 0; i < out_length; i++) {
float data = static_cast<float*>(output_ptr)[i];
sum += data;
if (max < data)
max = data;
}
printf("max=%e, sum=%e\n", max, sum);
return true;
}
REGIST_EXAMPLE("basic_c_interface", basic_c_interface);
REGIST_EXAMPLE("device_io_c_interface", device_io_c_interface);
REGIST_EXAMPLE("async_c_interface", async_c_interface);
#endif