Commit 4b9703bb authored by zhaoyunfei's avatar zhaoyunfei

Merge branch 'dev' into 'master'

更新tengine

See merge request !2
parents ae1681a9 826e1018
......@@ -31,14 +31,14 @@ extern "C" {
// cpu model list
#define CPU_GENERIC 0
#define CPU_A72 1
#define CPU_A53 2
#define CPU_A53 CPU_A72
#define CPU_A17 3
#define CPU_A7 4
#define CPU_A55 5
#define CPU_A7 CPU_A17
#define CPU_A55 CPU_A72
#define CPU_KRYO 6
#define CPU_A73 7
#define CPU_A9 8
#define CPU_A15 9
#define CPU_A73 CPU_A72
#define CPU_A9 CPU_A17
#define CPU_A15 CPU_A17
#define ARCH_GENERIC 0
#define ARCH_ARM_V8 1
......
This diff is collapsed.
......@@ -358,29 +358,6 @@ graph_t create_graph(context_t context, const char* model_format, const char* fi
int save_graph(graph_t graph, const char* model_format, const char* file_name, ...);
/*!
* @brief save the quant param into graph
*
* @param [in] graph, the graph handle
* @param [in] the quant param file
*
* @return 0 success or -1 fail
*/
int post_train_graph(graph_t graph,const char*file_name);
/*!
* @brief quant the graph according to the quant mode
*
* @param [in/out] graph, the graph handle
* @param [in] quant_mode, the quant mode(fp16, int8 or uint8). see TENGINE_QUANT_FP16 etc.
* @param [in] node_no_quant_idxs, the index array of nodes not quant
* @param [in] node_no_quant_number, the number of nodes not quant
*
* @return 0 success or -1 fail
*/
void dump_graph_tensor_scale(graph_t graph);
int quant_graph(graph_t graph, int quant_mode, int node_no_quant_idxs[], int node_no_quant_number);
/*!
* @brief Set the layout type of the graph
* the default layout of graph is NCHW
......
File mode changed from 100755 to 100644
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* License); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2020, OPEN AI LAB
* Author: qtang@openailab.com
*/
#ifndef __TENGINE_CPP_API_H__
#define __TENGINE_CPP_API_H__
#include <vector>
#include <string>
#include <mutex>
#include "tengine_c_api.h"
/* layout type, not real layout */
#define TENGINE_LAYOUT_NCHW 0
#define TENGINE_LAYOUT_NHWC 1
enum EKernelMode
{
eKernelMode_Float32 = 0,
eKernelMode_Int8 = 2,
eKernelMode_Int8Perchannel,
};
namespace tengine {
class Tensor;
class Net
{
public:
static void Init();
static void Deinit();
// Net initial
Net();
// Net clear
~Net();
// load model
int load_model(context_t context, const char* model_format, const char* model_file, ...);
// set device
int set_device(std::string device);
// set input shape
int input_shape(int n, int c, int h, int w, const char* node_name);
// input data by buffer
int input_tensor(const float* buffer, const int buffer_size, const char* node_name);
// output data by buffer
int extract_tensor(float*& buffer, int& buffer_size, const char* node_name);
// input data by tensor
int input_tensor(std::string name, Tensor& t);
// output data by node num and tensor index
int input_tensor(int node_index, int tensor_index, Tensor& t);
// output data by tensor
int extract_tensor(std::string name, Tensor& t);
// output data by node num and tensor index
int extract_tensor(int node_index, int tensor_index, Tensor& t);
public:
// set kenel mode
static int set_kernel_mode(EKernelMode kernel_mode);
// turn on/off wino
static int switch_wino(bool is_open);
// bind cpu
static int set_worker_cpu_list(const int* cpu_list,int num);
// run
int run(int block = 1);
void dump();
public:
graph_t graph;
bool b_preruned;
private:
// prerun
int prerun();
};
class Tensor
{
public:
// empty
Tensor();
// vec
Tensor(int w, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
// image
Tensor(int w, int h, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
// dim
Tensor(int w, int h, int c, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
Tensor(int n, int w, int h, int c, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
// copy
Tensor(const Tensor& m);
// release
~Tensor();
// assign
// Tensor& operator=(const Tensor& m);
// set all
void fill(float v);
template <typename T> void fill(T v);
// deep copy
Tensor clone() const;
// reshape vec
Tensor reshape(int w) const;
// reshape image
Tensor reshape(int w, int h) const;
// reshape dim
Tensor reshape(int w, int h, int c) const;
// allocate vec
void create(int w, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
// allocate image
void create(int w, int h, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
// allocate dim
void create(int w, int h, int c, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
void create(int n, int w, int h, int c, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
bool empty() const;
size_t total() const;
// // convenient construct from pixel data and resize to specific size, type is RGB/BGR
// static Tensor from_pixels_resize(const unsigned char* pixels, int type, int c, int h, int w, int target_width,
// int target_height);
// // substract channel-wise mean values, then multiply by normalize values, pass 0 to skip, type maybe ONNX / MXNet
// /
// // Caffe
// void substract_mean_normalize(const float* mean_vals, const float* norm_vals, const int type);
public:
uint8_t dim_num;
// nchw or nhwc
uint8_t layout;
// element size in bytes
// 4 = float32/int32
// 2 = float16
// 1 = int8/uint8
// 0 = empty
size_t elem_size;
// total num
int elem_num;
// point data
void* data;
// shape
int n;
int c;
int h;
int w;
// quantziation params
std::vector<float> scales;
std::vector<float> zero_points;
};
inline Tensor::Tensor() : dim_num(0), layout(0), elem_size(0), elem_num(0), data(0), n(0), c(0), h(0), w(0)
{
}
inline Tensor::Tensor(int _w, size_t _elem_size, uint8_t _layout)
: dim_num(0), layout(0), elem_size(0), elem_num(0), data(0), n(0), c(0), h(0), w(0)
{
create(_w, _elem_size, _layout);
}
inline Tensor::Tensor(int _w, int _h, size_t _elem_size, uint8_t _layout)
: dim_num(0), layout(0), elem_size(0), elem_num(0), data(0), n(0), c(0), h(0), w(0)
{
create(_w, _h, _elem_size, _layout);
}
inline Tensor::Tensor(int _w, int _h, int _c, size_t _elem_size, uint8_t _layout)
: dim_num(0), layout(0), elem_size(0), elem_num(0), data(0), n(0), c(0), h(0), w(0)
{
create(_w, _h, _c, _elem_size, _layout);
}
inline Tensor::Tensor(int _n,int _w, int _h, int _c, size_t _elem_size, uint8_t _layout)
:dim_num(0), layout(0), elem_size(0), elem_num(0), data(0), n(0), c(0), h(0), w(0)
{
create(_n, _w, _h, _c, _elem_size, _layout);
}
} // namespace tengine
#endif
File mode changed from 100755 to 100644
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef _LAMBDA_COMMON_DISPLAY_H_
#define _LAMBDA_COMMON_DISPLAY_H_
#include <iostream>
#include "lambda/lambda_struct.h"
namespace lambda {
std::string to_string(const EngineType& var);
std::string to_string(const QuantizedType& var);
std::string to_string(const DeviceType& var);
std::string to_string(const PlatformType& var);
std::string to_string(const DataType& var);
std::string to_string(const Shape4d& var);
std::string to_string(const InStream& var);
std::string to_string(const TargetInfo& var);
std::string to_string(const OutStream& var);
std::string to_string(const Consumer& var);
std::string to_string(const Slot& var);
} // namespace lambda
#endif
\ No newline at end of file
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef _LAMBDA_COMMON_FILESYSTEM_H_
#define _LAMBDA_COMMON_FILESYSTEM_H_
#ifndef BUILD_ON_ANDROID
#include <experimental/filesystem>
#endif
#include <string>
#include <vector>
#include "macros.h"
namespace lambda {
namespace fs {
inline std::string GetCurrentPath() {
#ifdef _LAMBDA_ANDROID
RAISE_NOT_IMPLEMENTED(__FUNCTION__);
#else
return std::move(std::experimental::filesystem::current_path().string());
#endif
}
inline std::string GetFileName(const std::string& path) {
#ifdef _LAMBDA_ANDROID
RAISE_NOT_IMPLEMENTED(__FUNCTION__);
#else
std::experimental::filesystem::path p(path);
return p.filename().string();
#endif
}
// e.g. /h1/h2/filename.ext1.ext2
// returns .ext2
inline std::string GetFileExt(const std::string& path) {
#ifdef _LAMBDA_ANDROID
RAISE_NOT_IMPLEMENTED(__FUNCTION__);
#else
std::experimental::filesystem::path p(path);
return std::move(p.extension().string());
#endif
}
// remove the last extension
// e.g. Filename.ext1.ext2.ext3
// Returns: Filename.ext1.ext2
inline std::string GetFileNameWithoutExt(const std::string& path) {
#ifdef _LAMBDA_ANDROID
RAISE_NOT_IMPLEMENTED(__FUNCTION__);
#else
auto p = GetFileName(path);
return std::move(p.substr(0, p.find_last_of('.')));
#endif
}
inline bool IsFileExist(const std::string& path) {
#ifdef BUILD_ON_ANDROID
struct stat buffer;
if (stat(path.c_str(), &buffer) == 0) {
if (S_ISREG(buffer.st_mode)) return true;
return false;
}
return false;
#else
if (std::experimental::filesystem::status(path).type() ==
std::experimental::filesystem::file_type::regular) {
return true;
} else {
return false;
}
#endif
}
inline std::string GetPathDirectory(const std::string& path) {
#ifdef _LAMBDA_ANDROID
RAISE_NOT_IMPLEMENTED(__FUNCTION__);
#else
std::experimental::filesystem::path p(path);
if (IsFileExist(path)) {
return p.parent_path().string();
} else {
return path;
}
#endif
}
inline bool IsPathExist(const std::string& path) {
#ifdef BUILD_ON_ANDROID
struct stat buffer;
return (stat(path.c_str(), &buffer) == 0);
#else
if (std::experimental::filesystem::status(path).type() ==
std::experimental::filesystem::file_type::not_found) {
return false;
} else {
return true;
}
#endif
}
inline bool IsFolderExist(const std::string& path) {
#ifdef BUILD_ON_ANDROID
struct stat buffer;
if (stat(path.c_str(), &buffer) == 0) {
if (S_ISDIR(buffer.st_mode)) return true;
return false;
}
return false;
#else
if (std::experimental::filesystem::status(path).type() ==
std::experimental::filesystem::file_type::directory) {
return true;
} else {
return false;
}
#endif
}
inline void CreateFolder(const std::string& path) {
#ifdef _LAMBDA_ANDROID
RAISE_NOT_IMPLEMENTED(__FUNCTION__);
#else
if (!IsFolderExist(path)) {
std::experimental::filesystem::create_directories(path);
}
#endif
}
inline void CopyFile(const std::string& src, const std::string& dst) {
#ifdef _LAMBDA_ANDROID
RAISE_NOT_IMPLEMENTED(__FUNCTION__);
#else
std::experimental::filesystem::copy_file(src, dst);
#endif
}
inline void RemoveFile(const std::string& path) {
#ifdef _LAMBDA_ANDROID
RAISE_NOT_IMPLEMENTED(__FUNCTION__);
#else
std::experimental::filesystem::remove(path);
#endif
}
inline void RemoveFolder(const std::string& path) {
#ifdef _LAMBDA_ANDROID
RAISE_NOT_IMPLEMENTED(__FUNCTION__);
#else
std::experimental::filesystem::remove_all(path);
#endif
}
// Path should be to a folder.
inline std::vector<std::string> GetDirectoryEntries(const std::string& path) {
#ifdef _LAMBDA_ANDROID
RAISE_NOT_IMPLEMENTED(__FUNCTION__);
#else
std::experimental::filesystem::directory_iterator _pos(path);
std::experimental::filesystem::directory_iterator _end;
std::vector<std::string> _RetList;
for (; _pos != _end; ++_pos) {
_RetList.push_back(_pos->path().string());
}
return std::move(_RetList);
#endif
}
inline std::vector<std::string> GetRecursiveDirectoryEntries(
const std::string& path) {
std::experimental::filesystem::recursive_directory_iterator _pos(path);
std::experimental::filesystem::recursive_directory_iterator _end;
std::vector<std::string> _RetList;
for (; _pos != _end; ++_pos) {
_RetList.push_back(_pos->path().string());
}
return std::move(_RetList);
}
} // namespace fs
} // namespace lambda
#endif
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef _LAMBDA_COMMON_LOGGER_H_
#define _LAMBDA_COMMON_LOGGER_H_
#include <iostream>
#include <memory>
#include <string>
#ifdef _MSC_VER
#pragma warning(disable : 4819)
#endif
#ifdef __ANDROID__
#include "glog/logging.h"
#else
#include "g3log/g3log.hpp"
#include "g3log/logworker.hpp"
#endif
// Usage:
// class A {
// public:
// A() { logger_ = new Logger(name, dir, true); }
// ~A() {delete logger_;}
// private:
// Logger* logger_;
// };
namespace lambda {
#ifdef __ANDROID__
class Logger final {
public:
explicit Logger(const std::string& log_name,
const std::string& log_dir = "./",
bool is_stdout = false) {
// do nothing
}
// destructor
~Logger() {}
// move-copy
Logger(Logger& logger) {}
};
#else
class LoggerCustomSink final {
public:
void RedirectToStdout(g3::LogMessageMover logEntry) {
auto level = logEntry.get()._level;
std::cout << logEntry.get().toString();
}
};
class Logger final {
public:
explicit Logger(const std::string& log_name,
const std::string& log_dir = "./",
bool is_stdout = true) {
// when has initialized
if (g3::internal::isLoggingInitialized()) return;
worker_ = g3::LogWorker::createLogWorker();
auto handle = worker_->addDefaultLogger(log_name, log_dir, "");
g3::initializeLogging(worker_.get());
if (is_stdout) {
worker_->addSink(std::make_unique<LoggerCustomSink>(),
&LoggerCustomSink::RedirectToStdout);
}
}
// destructor
~Logger() { g3::internal::shutDownLogging(); }
// move-copy
Logger(Logger& logger) { worker_ = std::move(logger.worker_); }
private:
std::unique_ptr<g3::LogWorker> worker_;
};
#endif
} // namespace lambda
#endif
\ No newline at end of file
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef _LAMBDA_COMMON_MACROS_H_
#define _LAMBDA_COMMON_MACROS_H_
#include <atomic>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include "lambda/lambda_struct.h"
#include "logger.h"
#include "timer.h"
namespace lambda {
//------------------------------------------------------------------------------
// SYSTEM GLOBAL STAT
//------------------------------------------------------------------------------
extern Status __TengineCore;
extern Status __MNNCore;
extern Status __NCNNCore;
extern Status __OpenVINOCore;
extern Status __MACECore;
extern Status __PaddleCore;
//------------------------------------------------------------------------------
// STREAM
//------------------------------------------------------------------------------
#define OSLEFT(x) std::setw(x) << std::setiosflags(std::ios::left)
// gb -> number of bytes
constexpr float _perGB = 1073741824.0f;
// mb -> number of bytes
constexpr float _perMB = 1048576.0f;
// kb -> number of bytes
constexpr float _perKB = 1024.0f;
//------------------------------------------------------------------------------
// ENFORCE
//------------------------------------------------------------------------------
#define ENFORCE_CHECK_OP(name, op, val1, val2) \
if (!(val1 op val2)) { \
LOG(FATAL) << __FUNCTION__ << " " << __LINE__ << " " << #name << " " \
<< #op << " " << #val1 << " " << #val2; \
}
// ENFORCE_CHECK_EQ/NE/...
#define ENFORCE_CHECK_EQ(val1, val2) ENFORCE_CHECK_OP(Check_EQ, ==, val1, val2)
#define ENFORCE_CHECK_NE(val1, val2) ENFORCE_CHECK_OP(Check_NE, !=, val1, val2)
#define ENFORCE_CHECK_LE(val1, val2) ENFORCE_CHECK_OP(Check_LE, <=, val1, val2)
#define ENFORCE_CHECK_LT(val1, val2) ENFORCE_CHECK_OP(Check_LT, <, val1, val2)
#define ENFORCE_CHECK_GE(val1, val2) ENFORCE_CHECK_OP(Check_GE, >=, val1, val2)
#define ENFORCE_CHECK_GT(val1, val2) ENFORCE_CHECK_OP(Check_GT, >, val1, val2)
#define ENFORCE_CHECK_IN(val1, first, end) \
ENFORCE_CHECK_GE(val1, first) TEA_ENFORCE_CHECK_LT(val1, end)
// zero
#define ENFORCE_ZERO(val) ENFORCE_CHECK_EQ(val, 0)
// multimap hash
#define ENFORCE_HAS_HASH(mm, key) ENFORCE_CHECK_NE(mm.find(key), mm.end())
#define ENFORCE_NO_HASH(mm, key) ENFORCE_CHECK_EQ(mm.find(key), mm.end())
#define CALL(fn) ENFORCE_CHECK_EQ(fn, Status::SUCCESS)
// raise error
#define RAISE_HAS_EXISTED(x) LOG(FATAL) << x << " has existed.";
#define RAISE_INVALID_INPUT(x) LOG(FATAL) << x << " is invalid input.";
#define RAISE_NOT_IMPLEMENTED(x) LOG(FATAL) << x << " not implemented.";
#define RAISE_NOT_IMPLEMENTED_FUNCTION RAISE_NOT_IMPLEMENTED(__FUNCTION__)
#define RAISE_INVALID_VIRTUAL_CALLING LOG(FATAL) << __FUNCTION__;
#define RAISE_RUNTIME(x) LOG(FATAL) << x;
#define RAISE_CALL_INVALID_RESOURCE LOG(FATAL) << "visit invalid resource.";
} // namespace lambda
#endif
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef _LAMBDA_COMMON_MISC_H_
#define _LAMBDA_COMMON_MISC_H_
#include <numeric>
#include <regex>
#include <cmath>
#include <unordered_map>
#include "lambda/lambda_struct.h"
#include "macros.h"
namespace lambda {
namespace misc {
inline bool PairCompare(const std::pair<float, int>& lhs,
const std::pair<float, int>& rhs) {
return lhs.first > rhs.first;
}
inline std::vector<int> ArgMax(const std::vector<float>& v, const 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;
}
inline float ComputeIoU(OutStream& a, OutStream& b) {
float delta_w = 0.0, delta_h = 0.0;
if (a.x1 < b.x1) {
delta_w = a.x2 - b.x1 > 0 ? a.x2 - b.x1 : 0;
} else {
delta_w = b.x2 - a.x1 > 0 ? b.x2 - a.x1 : 0;
}
if (a.y1 < b.y1) {
delta_h = a.y2 - b.y1 > 0 ? a.y2 - b.y1 : 0;
} else {
delta_h = b.y2 - a.y1 > 0 ? b.y2 - a.y1 : 0;
}
float box_i = delta_w * delta_h;
float area_a = (a.x2 - a.x1) * (a.y2 - a.y1);
float area_b = (b.x2 - b.x1) * (b.y2 - b.y1);
float box_u = area_a + area_b - box_i;
return box_i / box_u;
}
inline void DoNMS(std::unordered_map<int, std::vector<OutStream>>& objs,
int num_classes,
float nms_thresh = (float)0.45) {
for (int c = 0; c < num_classes; c++) {
if (objs[c].size() <= 1) continue;
std::sort(objs[c].begin(), objs[c].end(), [](OutStream& a, OutStream& b) {
return a.prob > b.prob ? true : false;
});
for (size_t i = 0; i < objs[c].size(); i++) {
if (objs[c][i].prob == 0) continue;
for (size_t j = i + 1; j < objs[c].size(); j++) {
if (ComputeIoU(objs[c][i], objs[c][j]) > nms_thresh) {
objs[c][j].prob = 0;
}
}
}
}
}
template <class _ForwardType>
inline std::pair<size_t, _ForwardType> argmax(_ForwardType* __first,
_ForwardType* __last) {
auto _max_val = *__first;
auto _max_loc = 0;
for (auto ptr = __first; ptr != __last; ptr++) {
if (*ptr > _max_val) {
_max_val = *ptr;
_max_loc = ptr - __first;
}
}
return std::make_pair(_max_loc, _max_val);
}
// part of library is not supported for it.
template <class _InputIterator, class _Tp, class _BinaryOp>
_Tp reduce(_InputIterator __first,
_InputIterator __last,
_Tp __init,
_BinaryOp __b) {
for (; __first != __last; ++__first) __init = __b(__init, *__first);
return __init;
}
template <class _InputIterator, class _Tp>
float sum(_InputIterator __first, _InputIterator __end) {
return misc::reduce(__first, __end, 0, [](_Tp _cur, _Tp _last) -> float {
return _cur + _last;
});
}
template <class _InputIterator, class _Tp>
float mean(_InputIterator __first, _InputIterator __end) {
return misc::sum<_InputIterator, _Tp>(__first, __end) / (__end - __first);
}
template <class _InputIterator, class _Tp>
float max(_InputIterator __first, _InputIterator __end) {
return misc::reduce(
__first,
__end,
std::numeric_limits<_Tp>::min(),
[&](_Tp _cur, _Tp _last) -> float { return _cur < _last ? _last : _cur; });
}
template <class _InputIterator, class _Tp>
float min(_InputIterator __first, _InputIterator __end) {
return misc::reduce(
__first,
__end,
std::numeric_limits<_Tp>::max(),
[&](_Tp _cur, _Tp _last) -> float { return _cur >= _last ? _last : _cur; });
}
template <class _InputIterator, class _Tp>
float var(_InputIterator __first, _InputIterator __end) {
auto avg = mean<_InputIterator, _Tp>(__first, __end);
return misc::reduce(__first, __end, 0, [&](_Tp _cur, _Tp _last) -> float {
return _cur + std::pow(_last - avg, 2) / (__end - __first);
});
}
// access keys from unordered_map
template <class _KeyType, class _ValueType>
std::vector<_KeyType> keys(std::unordered_map<_KeyType, _ValueType>& mm) {
std::vector<_KeyType> ks;
for (auto m : mm) {
ks.push_back(m.first);
}
return ks;
}
inline std::vector<std::string> split(const std::string& input,
const std::string& regex) {
std::regex re(regex);
std::sregex_token_iterator first{input.begin(), input.end(), re, -1}, last;
return {first, last};
}
inline size_t unit(DataType dtype) {
switch (dtype) {
case DataType::UINT8:
return EnumToType<DataType::UINT8>::size;
case DataType::HALF:
return EnumToType<DataType::HALF>::size;
case DataType::FLOAT:
return EnumToType<DataType::FLOAT>::size;
case DataType::INT32:
return EnumToType<DataType::INT32>::size;
case DataType::DOUBLE:
return EnumToType<DataType::DOUBLE>::size;
}
return 0;
}
inline size_t numel(const Shape4d& shape) {
return shape.n * shape.c * shape.h * shape.w;
}
} // namespace misc
} // namespace lambda
#endif
\ No newline at end of file
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef _LAMBDA_COMMON_STATISTICS_H_
#define _LAMBDA_COMMON_STATISTICS_H_
#include <assert.h>
#include <initializer_list>
#include <numeric>
#include <unordered_map>
#include <vector>
// stat helper
// to store a series of values and compute mean/var/max/min
// it allow to insert a set of key-values
// insert({{"init", 32.4}, {"inf", 34.2}, {"end", 23.4}})
template <typename _Ty>
class Statistic {
public:
Statistic(std::initializer_list<std::string> keys) : keys_(keys) {}
// insert values in terms of initialized sequence
void insert(const std::vector<_Ty>& values) {
assert(values.size() == keys_.size());
for (size_t i = 0; i < keys_.size(); i++) {
dicts_[keys_[i]].push_back(values[i]);
}
}
// get count
std::vector<size_t> count() {
std::vector<size_t> counts;
for (size_t i = 0; i < keys_.size(); i++) {
counts.push_back(dicts_[keys_[i]].size());
}
return counts;
}
// get mean
std::vector<_Ty> mean() {
std::vector<_Ty> rets;
for (size_t i = 0; i < keys_.size(); i++) {
auto& vs = dicts_[keys_[i]];
auto sum = std::accumulate(vs.begin(), vs.end(), _Ty(0));
rets.push_back(sum / float(vs.size()));
}
return rets;
}
// get max
std::vector<_Ty> max() {
std::vector<_Ty> rets;
for (size_t i = 0; i < keys_.size(); i++) {
auto& vs = dicts_[keys_[i]];
rets.push_back(
std::accumulate(vs.begin(),
vs.end(),
-std::numeric_limits<_Ty>::max(),
[](_Ty a, _Ty b) { return a >= b ? a : b; }));
}
return rets;
}
// get min
std::vector<_Ty> min() {
std::vector<_Ty> rets;
for (size_t i = 0; i < keys_.size(); i++) {
auto& vs = dicts_[keys_[i]];
rets.push_back(
std::accumulate(vs.begin(),
vs.end(),
std::numeric_limits<_Ty>::max(),
[](_Ty a, _Ty b) { return a < b ? a : b; }));
}
return rets;
}
// get keys
const std::vector<std::string>& keys() { return keys_; }
private:
const std::vector<std::string> keys_;
std::unordered_map<std::string, std::vector<_Ty>> dicts_;
};
#endif
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef _LAMBDA_COMMON_TIMER_H_
#define _LAMBDA_COMMON_TIMER_H_
#include <chrono>
namespace lambda {
namespace time {
inline auto TICK() {
// return current time
return std::chrono::high_resolution_clock::now();
}
template <typename _TyTick>
inline float DURATION(_TyTick end, _TyTick start) {
using dur_f = std::chrono::duration<float>;
return std::chrono::duration_cast<dur_f>(end - start).count() * 1000.0;
}
inline long long UTC() {
// return utc time from 1970
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
}
} // namespace time
} // namespace lambda
#endif
\ No newline at end of file
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef _LAMBDA_KERNEL_SCHEDULER_H_
#define _LAMBDA_KERNEL_SCHEDULER_H_
#include <atomic>
#include <future>
#include <mutex>
#include <unordered_map>
#include "lambda/lambda_struct.h"
#ifdef _LAMBDA_USE_OPENCV
#include "opencv2/opencv.hpp"
#endif
namespace lambda {
class Engine;
class Logger;
class Routine;
class BlockManager;
class Graph;
class Scheduler final {
public:
Scheduler();
Scheduler(const Scheduler&) = delete; // copy
Scheduler(Scheduler&&) = delete; // move
Scheduler& operator=(const Scheduler&) = delete; // copy assign
Scheduler& operator=(Scheduler&&) = delete; // move assgin
~Scheduler();
//----------------------------------------------------------------------------
// Target OPERATOR
//----------------------------------------------------------------------------
public:
// add target - the function could be called multi-times, but the
// target id could not be same.
Status AddTarget(TargetInfo& target);
// add targets
Status AddTargets(const std::vector<TargetInfo>& targets);
// remove targets
Status RemoveTarget(target_id_t target_id);
// NOTE(not used): freeze scheduler to prevent adding undefined targets.
Status FreezeScheduler();
//----------------------------------------------------------------------------
// SLOT OPERATOR
//----------------------------------------------------------------------------
public:
// copy a segment from another
const Slot* slot(const target_id_t tid);
Slot* mutable_slot(const target_id_t tid);
// each target should have at least a slot.
Slot* CreateSlot(const target_id_t tid,
const std::string& name,
Shape4d dims,
DataType dtype);
// copy a segment memory to slot
Status AssignSlot(Slot* slot, void* source, size_t nbytes);
#ifdef _LAMBDA_USE_OPENCV
Slot* CreateSlot(const target_id_t tid,
const std::string& name,
const cv::Mat& mat);
Status AssignSlot(Slot* slot, const cv::Mat& mat);
#endif
//----------------------------------------------------------------------------
// THREAD OPERATOR
//----------------------------------------------------------------------------
public:
// Inference: return a handler
void Inference(const target_id_t tid);
// Async Query Result: true for ready
TargetStatus AsyncInferenceRequest(const target_id_t tid);
// Sync Query Result: wait utils reciving result
TargetStatus SyncInferenceRequest(const target_id_t tid);
// Reset request
void ResetReadyRequest(const target_id_t tid, TargetStatus& state);
private:
std::atomic<Status> state_;
std::atomic_int calling_count_;
std::unordered_map<EngineType, Engine*, EnumClassHash> maps_;
std::unordered_map<target_id_t, std::unique_ptr<Routine>> routines_;
std::unique_ptr<Logger> logger_;
};
} // namespace lambda
#endif
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef _LAMBDA_STRUCT_H_
#define _LAMBDA_STRUCT_H_
#include <string>
#include <vector>
namespace lambda {
//------------------------------------------------------------------------------
// Type
//------------------------------------------------------------------------------
enum Status {
SUCCESS = 0,
RUNTIME_ERROR = 1,
NOT_SUPPORTED = 2,
INVALID_PATH = 3,
INVALID_INDEX = 4,
UNDEFINED = 5,
INITIALIZED = 6,
DESTROYED = 7,
UNINITIALIZED = 8,
PREPARE_DESTROY = 9,
};
enum class LAYOUT {
NCHW = 0,
NHWC = 1,
};
enum class TargetStatus {
INVALID = 0,
READY = 1,
RUNNING = 2,
};
enum class AccessStatus {
READ_ONLY = 0,
WRITE_ONLY = 1,
READ_WRITE = 2,
};
enum class DataType {
UINT8 = 0,
FLOAT = 1,
HALF = 2,
INT32 = 3,
DOUBLE = 4,
};
// target_id
using target_id_t = int;
using uint8 = unsigned char;
using uchar = unsigned char;
// enum hash
struct EnumClassHash {
template <typename T>
size_t operator()(T t) const {
return static_cast<size_t>(t);
}
};
template <DataType T>
struct EnumToType;
template <typename T>
struct TypeToEnum;
#define LAMBDA_ENUM_TO_TYPE_MAPPING(ENUM, TYPE, SIZE) \
template <> \
struct EnumToType<ENUM> { \
using type = TYPE; \
static constexpr TYPE size = SIZE; \
}; \
template <> \
struct TypeToEnum<TYPE> { \
static DataType dtype() { return ENUM; } \
static constexpr DataType item = ENUM; \
};
LAMBDA_ENUM_TO_TYPE_MAPPING(DataType::UINT8, uint8, 1)
LAMBDA_ENUM_TO_TYPE_MAPPING(DataType::HALF, int16_t, 2)
LAMBDA_ENUM_TO_TYPE_MAPPING(DataType::FLOAT, float, 4)
LAMBDA_ENUM_TO_TYPE_MAPPING(DataType::INT32, int, 4)
LAMBDA_ENUM_TO_TYPE_MAPPING(DataType::DOUBLE, double, 8)
//------------------------------------------------------------------------------
// Data
//------------------------------------------------------------------------------
struct Shape4d {
int n = 1;
int c = 0;
int h = 0;
int w = 0;
};
struct InStream {
void* raw;
DataType type;
Shape4d shape;
};
//------------------------------------------------------------------------------
// Device Type
//------------------------------------------------------------------------------
enum class QuantizedType {
FLOAT = 0,
HALF = 1,
INT8 = 2,
};
enum class DeviceType {
CPU = 0,
OPENCL = 1,
VULKAN = 2,
OPENGL = 3,
};
enum class PlatformType {
TENSORFLOW = 0,
PYTORCH = 1,
MXNET = 2,
DARKNET = 3,
CAFFE = 4,
CAFFE2 = 5,
ONNX = 6,
TENGINE = 7,
LAMBDA = 8,
OPENVINO = 9,
MNN = 10,
NCNN = 11,
MACE = 12,
PADDLE = 13,
};
enum class EngineType {
TENGINE = 0,
NCNN = 1,
MACE = 2,
TVM = 3,
TFLITE = 4,
MNN = 5,
SNPE = 6,
OPENVINO = 7,
PADDLE = 8,
};
//------------------------------------------------------------------------------
// Description
//------------------------------------------------------------------------------
struct TargetInfo {
int id; // id for each target
std::string info; // store target info
EngineType engine; // inference engine
DeviceType device; // executed device
QuantizedType quant; // quantization method
std::string weight; // path-to-weights
std::string define; // path-to-proto
std::string graph; // model method
PlatformType platform; // platform for model src
Shape4d inshape; // inshape
};
//------------------------------------------------------------------------------
// IN / OUT
// classification: prob, cls, info
// detection: y1, x1, y2, x2, conf, prob, cls, info
// keypoints: y1, x1, prob, cls
//------------------------------------------------------------------------------
enum class StreamType {
CLASSIFICATION = 0,
DETECTION = 1,
KEYPOINTS = 2,
SEGMENTATION = 3,
};
struct OutStream {
StreamType type; // task type
float y1 = 0; // top
float x1 = 0; // left
float y2 = 1; // bottom
float x2 = 1; // right
float conf = 0; // bbox score
float prob = 0; // cls score
size_t cls = 0; // cls idx
std::string info; // extra
std::vector<float> feature; // feature
std::vector<float> placeholder; // placeholder
};
struct Consumer {
long long create = 0;
long long finish = 0;
float preprocess = 0;
float inference = 0;
float postprocess = 0;
float total = 0;
};
struct Slot {
int id; // target id
std::vector<InStream> inputs; // input
std::vector<OutStream> outputs; // output
Consumer elapsed; // time consumer
};
} // namespace lambda
#endif
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Created by zqw on 19-9-23.
//
#ifndef _LAMBDA_PROFILER_CPU_INFO_H_
#define _LAMBDA_PROFILER_CPU_INFO_H_
#include <string>
#include <vector>
#include "lambda/lambda_struct.h"
namespace lambda {
struct CPUInfo {
int processor;
//系统中逻辑处理核的编号
std::string vendor_id;
// CPU制造商
int cpu_family;
// CPU产品系列代号
int model;
// CPU属于其系列中的哪一代的代号
std::string model_name;
// CPU属于的名字及其编号、标称主频
int stepping;
// CPU属于制作更新版本
int microcode;
double cpu_mhz;
// CPU的实际使用主频
double cache_size;
// CPU二级缓存大小
int physical_id;
//单个CPU的标号
int siblings;
//单个CPU逻辑物理核数
int core_id;
//当前物理核在其所处CPU中的编号,这个编号不一定连续
int cpu_cores;
//该逻辑核所处CPU的物理核数
//用来区分不同逻辑核的编号,系统中每个逻辑核的此编号必然不同,此编号不一定连续
int apicid;
int initial_apicid;
std::string fpu;
//是否具有浮点运算单元(Floating Point Unit)
std::string fpu_exception;
//是否支持浮点计算异常
int cpuid_level;
//执行cpuid指令前,eax寄存器中的值,根据不同的值cpuid指令会返回不同的内容
std::string wp;
//表明当前CPU是否在内核态支持对用户空间的写保护
std::vector<std::string> flags;
//当前CPU支持的功能
std::vector<std::string> bugs;
int bogomips;
//在系统内核启动时粗略测算的CPU速度
int clflush_size;
//每次刷新缓存的大小单位
int cache_alignment;
//缓存地址对齐单位
std::string address_size;
//可访问地址空间位数
std::string power_management;
//可访问地址空间位数
};
struct CpuStat {
std::vector<int> single_user_time;
// 用户态时间
std::vector<int> single_nice_time;
//用户态时间(nice>0,低优先级)
std::vector<int> single_system_time;
// 内核态时间
std::vector<int> single_idle_time;
// 空闲时间
std::vector<int> single_iowait_time;
// i/o等待时间
std::vector<int> single_irq_time;
// 硬中断时间
std::vector<int> single_softirq_time;
// 软中断时间
//总时间;
int all_user_time;
int all_nice_time;
int all_system_time;
int all_idle_time;
int all_iowait_time;
int all_irq_time;
int all_softirq_time;
int ctxt_nums;
// 系统上下文切换次数
//启动时长(单位:秒),从Epoch(即1970零时)开始到系统启动所经过的时长,每次启动会改变
int btime_sec;
int processes_nums;
// 系统启动后所创建过的进程数量
int procs_running_nums;
// 处于runnable状态的进程个数
int procs_block_nums;
// 处于等待i/o完成的进程个数
};
enum class CPUKeyType : int {
BEGIN = 0,
PROCESSOR,
VENDOR_ID,
CPU_FAMILY,
MODEL,
MODEL_NAME,
STEPPING,
MICROCODE,
CPU_MHZ,
CACHE_SIZE,
PHYSICAL_ID,
SIBLINGS,
CORE_ID,
CPU_CORES,
APICID,
INITIAL_APICID,
FPU,
FPU_EXCEPTION,
CPUID_LEVEL,
WP,
FLAGS,
BUGS,
BOGOMIPS,
CLFLUSH_SIZE,
CACHE_ALIGNMENT,
ADDRESS_SIZES,
POWER_MANAGEMENT,
FEATURES,
CPU_IMPLEMENTER,
CPU_ARCHITECTURE,
CPU_VARIANT,
CPU_PART,
CPU_REVISION,
END
};
std::string to_string(const CPUInfo& change) {
std::stringstream ss;
std::string ans = "";
std::string tem = "";
int len;
ss << "processor = " << change.processor << std::endl;
ss << "vendor_id = " << change.vendor_id << std::endl;
ss << "cpu_family = " << change.cpu_family << std::endl;
ss << "model = " << change.model << std::endl;
ss << "mode name = " << change.model_name << std::endl;
ss << "stepping = " << change.stepping << std::endl;
ss << "microcode = " << change.microcode << std::endl;
ss << "cpu_mhz = " << change.cpu_mhz << std::endl;
ss << "cache_size = " << change.cache_size << " KB" << std::endl;
ss << "physical_id = " << change.physical_id << std::endl;
ss << "siblings = " << change.siblings << std::endl;
ss << "core_id = " << change.core_id << std::endl;
ss << "cpu_cores = " << change.cpu_cores << std::endl;
ss << "apicid = " << change.apicid << std::endl;
ss << "initial_apicid = " << change.initial_apicid << std::endl;
ss << "fpu = " << change.fpu << std::endl;
ss << "fpu_exception = " << change.fpu_exception << std::endl;
ss << "cpuid_level = " << change.cpuid_level << std::endl;
ss << "wp = " << change.wp << std::endl;
ss << "flags = ";
len = change.flags.size();
for (int i = 0; i < len; ++i) ss << change.flags[i] << " ";
ss << std::endl;
ss << "bugs = ";
len = change.bugs.size();
for (int i = 0; i < len; ++i) ss << change.bugs[i] << " ";
ss << std::endl;
ss << "bogomips = " << change.bogomips << std::endl;
ss << "clflush_size = " << change.clflush_size << std::endl;
ss << "cache_alignment = " << change.cache_alignment << std::endl;
ss << "address_size = " << change.address_size << std::endl;
while (getline(ss, tem)) {
ans = ans + tem;
ans = ans + "\n";
}
return ans;
}
} // namespace lambda
#endif // LAMBDA_CPUINFO_H
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Created by zqw on 19-9-23.
//
#ifndef _LAMBDA_PROFILER_MEMORY_INFO_H_
#define _LAMBDA_PROFILER_MEMORY_INFO_H_
#include "lambda/lambda_struct.h"
namespace lambda {
struct MemInfo {
//是可使用内存的总量,单位是KB,物理内存减去一些保留内存和内核二进制代码占用的内存
int memtotal;
int memfree;
//剩下没有被使用的物理内存,单位是kibibytes,即KB
int memavailable;
int buffers;
// Buffers 临时存储原始磁盘块的总量,单位是KB
int cached;
// Cached 用作缓存内存的物理内存总量,单位是KB
int swapcached;
// SwapCached
// 曾经被移入到swap,然后又回到主内存,但是仍然也在swapfile中保留的总内存大小。这样可以节省I/O,应为内存不需要再移入到swap
int active;
// Active 最近经常被使用的内存大小总量,单位是KB
int inactive;
// Inactive 最近不是经常使用的内存,单位是KB
int active_anon;
// 匿名和tmpfs/shmem内存总量,单位是KB.
// 自上次系统移动一些什么东西到swap后处于活动使用状态或者之前处于活动使用状态的内存
int inactive_anon;
// 作为候选收回的匿名和tmpfs/shmen内存总量,单位是KB
// 文件缓存内存的总量,单位是KB。处于活动使用状态,或者之前自上次系统召回内存处于活动使用状态的内存
int active_file;
int inactive_file;
int unevictable;
int mlocked;
//因为被用户程序锁住不能被回收的内存总量,单位是KB
int swaptotal;
// swap总量,单位是KB
int swapfree;
//空闲swap总量
int dirty;
//等待写回到磁盘内存总量,单位是KB
int writeback;
//正在写回到磁盘的内存总量,单位是KB
int anonpages;
//由文件未备份并映射到用户空间页表的页面使用的总内存量
int mapped;
// The memory,in kibibytes, used for files that have been
// mmaped,such as libraries
int shmem;
// The total amount of memeory,in kibibytes,used by shared
// memeory(shmem) and tmpfs
int slab;
//内核用于缓存数据结构以供自己使用的内存总量
int sreclaimable;
//可以回收的Slab部分,例如缓存
int sunreclaim;
// Slab的一部分即使在缺乏记忆的情况下也无法回收
//为系统中的每个任务完成的内核堆栈分配使用的以kibibytes为单位的内存量
int kernelstack;
int pagetables;
// The total amount of memeory,in kibibytes,dedicated to the
// lowest page table level.
int nfs_unstable;
// The amount,in kibibytes,of NFS page sent to the server
// but not yet committed to the stable storage
int bounce; // The amount of memory,in kibibytes,used for the block device
// "bounce buffers"
int writebacktmp;
// The amount of memory,in kibibytes, used by FUSE for
// temporary writeback buffers
int commitlimit;
// The total amount of memory currently avaiable to be
// allocated on the system based on the overcommit
// ratio(vm.overcommit_ratio) This limit is only adhered of
// if stric overcommit accounting is enabled(mode 2 in
// vm.overcommit_memory)
int committed_as;
// The total amount of memory,in kibibytes,estimated to
// complete the workload.
int vmalloctotal;
// The total amount of memory,in kibibytes,of total
// allocated virtual address space
int vmallocused;
// The total amount of memory, in kibibytes, of used virtual
// address space.
int vmallocchunk;
// The largest contiguous block of memory, in kibibytes, of
// available virtual address space.
int hardwarecorrupted;
// The amount of memory, in kibibytes, with physical
// memory corruption problems, identified by the hardware
// and set aside by the kernel so it does not get used.
int anonhugepages;
// The total amount of memory, in kibibytes, used by huge
// pages that are not backed by files and are mapped into
// userspace page tables
int shmemhugepages;
int shmempmdmapped;
int cmatotal;
int cmafree;
int hugepages_total;
// The total number of hugepages for the system. The
// number is derived by dividing Hugepagesize by the
// megabytes set aside for hugepages specified in
// /proc/sys/vm/hugetlb_pool
int hugepages_free;
// he total number of hugepages available for the system.
// This statistic only appears on the x86, Itanium, and
// AMD64 architectures.
int hugepages_rsvd;
// The number of unused huge pages reserved for
// hugetlbfs.
int hugepages_surp;
// The number of surplus huge pages.
int hugepagesize;
// The size for each hugepages unit in kibibytes
int directmap4k;
// The amount of memory, in kibibytes, mapped into kernel
// address space with 4 kB page mappings.
int directmap2m;
// The amount of memory, in kibibytes, mapped into kernel
// address space with 2 MB page mappings.
int directmap1g;
};
enum class MemKeyType : int {
BEGIN = 0,
MEMTOTAL,
MEMFREE,
MEMAVAILABLE,
BUFFERS,
CACHED,
SWAPCACHED,
ACTIVE,
INACTIVE,
ACTIVE_ANON,
INACTIVE_ANON,
ACTIVE_FILE,
INACTIVE_FILE,
UNEVICTABLE,
MLOCKED,
SWAPTOTAL,
SWAPFREE,
DIRTY,
WRITEBACK,
ANONPAGES,
MAPPED,
SHMEM,
SLAB,
SRECLAIMABLE,
SUNRECLAIM,
KERNELSTACK,
PAGETABLES,
NFS_UNSTABLE,
BOUNCE,
WRITEBACKTMP,
COMMITLIMIT,
COMMITTED_AS,
VMALLOCTOTAL,
VMALLOCUSED,
VMALLOCCHUNK,
HARDWARECORRUPTED,
ANONHUGEPAGES,
SHMEMHUGEPAGES,
SHMEMPMDMAPPED,
CMATOTAL,
CMAFREE,
HUGEPAGES_TOTAL,
HUGEPAGES_FREE,
HUGEPAGES_RSVD,
HUGEPAGES_SURP,
HUGEPAGESIZE,
DIRECTMAP4K,
DIRECTMAP2M,
DIRECTMAP1G,
END
};
std::string to_string(const MemInfo& change) {
std::stringstream ss;
std::string ans = "";
std::string tem = "";
ss << "memtotal = " << change.memtotal << std::endl;
ss << "memfree = " << change.memfree << std::endl;
ss << "memavailable = " << change.memavailable << std::endl;
ss << "buffers = " << change.buffers << std::endl;
ss << "cached = " << change.cached << std::endl;
ss << "swapcached = " << change.swapcached << std::endl;
ss << "active = " << change.active << std::endl;
ss << "inactive = " << change.inactive << std::endl;
ss << "active(anon) = " << change.active_anon << std::endl;
ss << "inactive(anon) = " << change.inactive_anon << std::endl;
ss << "active(file) = " << change.active_file << std::endl;
ss << "inactive(file) = " << change.inactive_file << std::endl;
ss << "unevictable = " << change.unevictable << std::endl;
ss << "mlocked = " << change.mlocked << std::endl;
ss << "swaptotal = " << change.swaptotal << std::endl;
ss << "swapfree = " << change.swapfree << std::endl;
ss << "dirty = " << change.dirty << std::endl;
ss << "writeback = " << change.writeback << std::endl;
ss << "anonpages = " << change.anonpages << std::endl;
ss << "mapped = " << change.mapped << std::endl;
ss << "shmem = " << change.shmem << std::endl;
ss << "slab = " << change.slab << std::endl;
ss << "sreclaimable = " << change.sreclaimable << std::endl;
ss << "sunreclaim = " << change.sunreclaim << std::endl;
ss << "kernelstack = " << change.kernelstack << std::endl;
ss << "pagetables = " << change.pagetables << std::endl;
ss << "nfs_unstable = " << change.nfs_unstable << std::endl;
ss << "bounce = " << change.bounce << std::endl;
ss << "writebacktmp = " << change.writebacktmp << std::endl;
ss << "commitlimit = " << change.commitlimit << std::endl;
ss << "committed_as = " << change.committed_as << std::endl;
ss << "vmalloctotal = " << change.vmalloctotal << std::endl;
ss << "vmallocused = " << change.vmallocused << std::endl;
ss << "vmallocchunk = " << change.vmallocchunk << std::endl;
ss << "hardwarecorrupted = " << change.hardwarecorrupted << std::endl;
ss << "anonhugepages = " << change.anonhugepages << std::endl;
ss << "shmemhugepages = " << change.shmemhugepages << std::endl;
ss << "shmempmdmapped = " << change.shmempmdmapped << std::endl;
ss << "cmatotal = " << change.cmatotal << std::endl;
ss << "cmafree = " << change.cmafree << std::endl;
ss << "hugepages_total = " << change.hugepages_total << std::endl;
ss << "hugepages_free = " << change.hugepages_free << std::endl;
ss << "hugepages_rsvd = " << change.hugepages_rsvd << std::endl;
ss << "hugepages_surp = " << change.hugepages_surp << std::endl;
ss << "hugepagesize = " << change.hugepagesize << std::endl;
ss << "directmap4k = " << change.directmap4k << std::endl;
ss << "directmap2m = " << change.directmap2m << std::endl;
ss << "directmap1g = " << change.directmap1g << std::endl;
while (getline(ss, tem)) {
ans = ans + tem;
ans = ans + "\n";
}
return ans;
}
} // namespace lambda
#endif // LAMBDA_MEMINFO_H
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Created by zqw on 19-9-23.
//
#ifndef _LAMBDA_PROFILER_PROCESS_INFO_H_
#define _LAMBDA_PROFILER_PROCESS_INFO_H_
#include <map>
#include <string>
#include <vector>
#include "lambda/lambda_struct.h"
namespace lambda {
struct ProcessInfo {
double cpu_rate;
double mem_rate;
int pid;
int ppid;
//父进程id;
std::string name;
//程序名字
std::string tast_state;
//任务的状态。R:runnign, S:sleeping (TASK_INTERRUPTIBLE),
// D:disk sleep (TASK_UNINTERRUPTIBLE), T: stopped, T:tracing
// stop, Z:zombie, X:dead。
int sid;
//会话id
long long min_flt;
//该任务不需要从硬盘拷贝数据发生的缺页次数
long long maj_flt;
//该任务需要从硬盘拷贝数据发生的缺页次数
long long utime;
//该任务在用户态运行的时间.单位jiffies;
long long stime;
//该任务在和心态运行的时间,单位jiffies;
long long cutime;
//累计的该任务的所有的waited-for进程曾经在用户态运行的时间
long long cstime;
//累计的该任务的所有的waited-for进程曾经在核心态运行的时间
long long priority;
//动态优先级别
long long nice;
//任务静态优先级别
long long vsize;
//该任务的虚拟地址大小
long long rss;
//该任务当前驻留物理地址空间大小
int tast_cpu;
//运行在那个cpu上。
};
enum class ProcessKey : int {
PID = 1,
NAME = 2,
TAST_STATE = 3,
PPID = 4,
SID = 6,
MIN_FLT = 10,
MAJ_FLT = 12,
UTIME = 14,
STIME = 15,
CUTIME = 16,
CSTIME = 17,
PRIORITY = 18,
NICE = 19,
VSIZE = 23,
RSS = 24,
TAST_CPU = 39
};
} // namespace lambda
#endif
// MIT License
// Copyright (c) 2019 kaiJIN
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Created by zqw on 19-9-19.
//
#ifndef _LAMBDA_PROFILER_PROFILE_H_
#define _LAMBDA_PROFILER_PROFILE_H_
#include <dirent.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <algorithm>
#include <chrono>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
#include "lambda/common/macros.h"
#include "cpu_info.h"
#include "memory_info.h"
#include "process_info.h"
namespace lambda {
enum class SortKey : int {
CPU_RATE = 1,
MEM_RATE = 2,
};
class ProFile {
public:
ProFile();
const CPUInfo& cpu_info(int index);
const MemInfo& mem_info(int index);
const std::vector<CPUInfo>& cpu_infos();
const std::vector<MemInfo>& mem_infos();
void ShowTopnProcessInfo(SortKey op, int topn, int usec);
void MonitorProcess(
std::string name_tem, int usec, int topn, SortKey op, std::string tags);
void ShowTree(std::string name, int usec);
protected:
void InternalUpdateCpuStat();
void InternalUpdateProcess();
void InternalUpdateCpuInfo();
void InternalUpdateMemInfo();
void InternalmapToCpuInfo(std::unordered_map<std::string, std::string>& mp,
CPUInfo& temp);
void InternalmapToMemInfo(std::unordered_map<std::string, std::string>& mp,
MemInfo& temp);
void PrintTree(int cnt,
int father_pid,
int diff_CpuTime,
std::unordered_map<int, std::vector<int>>& tree,
std::unordered_map<int, ProcessInfo>& pre_process);
private:
//从文件读进cpu_vec中
std::vector<std::unordered_map<std::string, std::string>> cpu_vec_;
std::vector<std::unordered_map<std::string, std::string>> mem_vec_;
std::unordered_map<CPUKeyType, std::string, EnumClassHash> cpu_hash_;
std::unordered_map<MemKeyType, std::string, EnumClassHash> mem_hash_;
std::vector<CPUInfo> cpu_infos_;
std::vector<MemInfo> mem_infos_;
CpuStat cpu_stat_;
std::unordered_map<int, ProcessInfo> process_infos_;
};
} // namespace lambda
#endif
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* License); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2018, Open AI Lab
* Author: haitao@openailab.com
*/
#ifndef __CPU_DEVICE_H__
#define __CPU_DEVICE_H__
#ifdef __cplusplus
extern "C" {
#endif
// cpu model list
#define CPU_GENERIC 0
#define CPU_A72 1
#define CPU_A53 CPU_A72
#define CPU_A17 3
#define CPU_A7 CPU_A17
#define CPU_A55 CPU_A72
#define CPU_KRYO 6
#define CPU_A73 CPU_A72
#define CPU_A9 CPU_A17
#define CPU_A15 CPU_A17
#define ARCH_GENERIC 0
#define ARCH_ARM_V8 1
#define ARCH_ARM_V7 2
#define ARCH_ARM_V8_2 3
#define MAX_CLUSTER_CPU_NUMBER 8
struct cpu_cluster
{
int cpu_number;
int max_freq;
int cpu_model;
int cpu_arch;
int l1_size;
int l2_size;
int hw_cpu_id[MAX_CLUSTER_CPU_NUMBER];
};
struct cpu_info
{
const char* cpu_name;
const char* board_name; // optional
int cluster_number;
int l3_size;
struct cpu_cluster* cluster;
int online_cpu_number;
int* online_cpu_list;
};
const struct cpu_info* get_predefined_cpu(const char* cpu_name);
int create_cpu_device(const char* dev_name, const struct cpu_info* cpu_info);
const struct cpu_info* get_cpu_info(const char* dev_name);
void set_online_cpu(struct cpu_info* cpu_info, const int* cpu_list, int cpu_number);
#define set_working_cpu(cpu_list, cpu_number) set_online_cpu(NULL, cpu_list, cpu_number);
#ifdef __cplusplus
}
#endif
#endif
This diff is collapsed.
This diff is collapsed.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* License); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2020, OPEN AI LAB
* Author: qtang@openailab.com
*/
#ifndef __TENGINE_CPP_API_H__
#define __TENGINE_CPP_API_H__
#include <vector>
#include <string>
#include <mutex>
#include "tengine_c_api.h"
/* layout type, not real layout */
#define TENGINE_LAYOUT_NCHW 0
#define TENGINE_LAYOUT_NHWC 1
enum EKernelMode
{
eKernelMode_Float32 = 0,
eKernelMode_Int8 = 2,
eKernelMode_Int8Perchannel,
};
namespace tengine {
class Tensor;
class Net
{
public:
static void Init();
static void Deinit();
// Net initial
Net();
// Net clear
~Net();
// load model
int load_model(context_t context, const char* model_format, const char* model_file, ...);
// set device
int set_device(std::string device);
// set input shape
int input_shape(int n, int c, int h, int w, const char* node_name);
// input data by buffer
int input_tensor(const float* buffer, const int buffer_size, const char* node_name);
// output data by buffer
int extract_tensor(float*& buffer, int& buffer_size, const char* node_name);
// input data by tensor
int input_tensor(std::string name, Tensor& t);
// output data by node num and tensor index
int input_tensor(int node_index, int tensor_index, Tensor& t);
// output data by tensor
int extract_tensor(std::string name, Tensor& t);
// output data by node num and tensor index
int extract_tensor(int node_index, int tensor_index, Tensor& t);
public:
// set kenel mode
static int set_kernel_mode(EKernelMode kernel_mode);
// turn on/off wino
static int switch_wino(bool is_open);
// bind cpu
static int set_worker_cpu_list(const int* cpu_list,int num);
// run
int run(int block = 1);
void dump();
public:
graph_t graph;
bool b_preruned;
private:
// prerun
int prerun();
};
class Tensor
{
public:
// empty
Tensor();
// vec
Tensor(int w, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
// image
Tensor(int w, int h, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
// dim
Tensor(int w, int h, int c, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
Tensor(int n, int w, int h, int c, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
// copy
Tensor(const Tensor& m);
// release
~Tensor();
// assign
// Tensor& operator=(const Tensor& m);
// set all
void fill(float v);
template <typename T> void fill(T v);
// deep copy
Tensor clone() const;
// reshape vec
Tensor reshape(int w) const;
// reshape image
Tensor reshape(int w, int h) const;
// reshape dim
Tensor reshape(int w, int h, int c) const;
// allocate vec
void create(int w, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
// allocate image
void create(int w, int h, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
// allocate dim
void create(int w, int h, int c, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
void create(int n, int w, int h, int c, size_t elem_size = 4u, uint8_t layout = TENGINE_LAYOUT_NCHW);
bool empty() const;
size_t total() const;
// // convenient construct from pixel data and resize to specific size, type is RGB/BGR
// static Tensor from_pixels_resize(const unsigned char* pixels, int type, int c, int h, int w, int target_width,
// int target_height);
// // substract channel-wise mean values, then multiply by normalize values, pass 0 to skip, type maybe ONNX / MXNet
// /
// // Caffe
// void substract_mean_normalize(const float* mean_vals, const float* norm_vals, const int type);
public:
uint8_t dim_num;
// nchw or nhwc
uint8_t layout;
// element size in bytes
// 4 = float32/int32
// 2 = float16
// 1 = int8/uint8
// 0 = empty
size_t elem_size;
// total num
int elem_num;
// point data
void* data;
// shape
int n;
int c;
int h;
int w;
// quantziation params
std::vector<float> scales;
std::vector<float> zero_points;
};
inline Tensor::Tensor() : dim_num(0), layout(0), elem_size(0), elem_num(0), data(0), n(0), c(0), h(0), w(0)
{
}
inline Tensor::Tensor(int _w, size_t _elem_size, uint8_t _layout)
: dim_num(0), layout(0), elem_size(0), elem_num(0), data(0), n(0), c(0), h(0), w(0)
{
create(_w, _elem_size, _layout);
}
inline Tensor::Tensor(int _w, int _h, size_t _elem_size, uint8_t _layout)
: dim_num(0), layout(0), elem_size(0), elem_num(0), data(0), n(0), c(0), h(0), w(0)
{
create(_w, _h, _elem_size, _layout);
}
inline Tensor::Tensor(int _w, int _h, int _c, size_t _elem_size, uint8_t _layout)
: dim_num(0), layout(0), elem_size(0), elem_num(0), data(0), n(0), c(0), h(0), w(0)
{
create(_w, _h, _c, _elem_size, _layout);
}
inline Tensor::Tensor(int _n,int _w, int _h, int _c, size_t _elem_size, uint8_t _layout)
:dim_num(0), layout(0), elem_size(0), elem_num(0), data(0), n(0), c(0), h(0), w(0)
{
create(_n, _w, _h, _c, _elem_size, _layout);
}
} // namespace tengine
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment