Compare commits
3 Commits
8de1dfb3aa
...
09bdd8007d
| Author | SHA1 | Date | |
|---|---|---|---|
| 09bdd8007d | |||
| cd9d81e0e4 | |||
| 4b43617901 |
1
.vscode/c_cpp_properties.json
vendored
1
.vscode/c_cpp_properties.json
vendored
@@ -5,6 +5,7 @@
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/3rd/**",
|
||||
"${workspaceFolder}/models/**",
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
|
||||
62
.vscode/settings.json
vendored
Normal file
62
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.inc": "c",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"complex": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
}
|
||||
}
|
||||
6
.vscode/tasks.json
vendored
6
.vscode/tasks.json
vendored
@@ -11,13 +11,13 @@
|
||||
"-build_type",
|
||||
"Release",
|
||||
"-build_and_run",
|
||||
"false",
|
||||
"true",
|
||||
"-platform",
|
||||
"win"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
@@ -40,7 +40,7 @@
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
|
||||
58
3rd/win/mnn/include/MNN/AutoTime.hpp
Normal file
58
3rd/win/mnn/include/MNN/AutoTime.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// AutoTime.hpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2018/07/27.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#ifndef AutoTime_hpp
|
||||
#define AutoTime_hpp
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <MNN/MNNDefine.h>
|
||||
|
||||
namespace MNN {
|
||||
|
||||
class MNN_PUBLIC Timer {
|
||||
public:
|
||||
Timer();
|
||||
~Timer();
|
||||
Timer(const Timer&) = delete;
|
||||
Timer(const Timer&&) = delete;
|
||||
Timer& operator=(const Timer&) = delete;
|
||||
Timer& operator=(const Timer&&) = delete;
|
||||
|
||||
// reset timer
|
||||
void reset();
|
||||
// get duration (us) from init or latest reset.
|
||||
uint64_t durationInUs();
|
||||
|
||||
protected:
|
||||
uint64_t mLastResetTime;
|
||||
};
|
||||
|
||||
/** time tracing util. prints duration between init and deinit. */
|
||||
class MNN_PUBLIC AutoTime : Timer {
|
||||
public:
|
||||
AutoTime(int line, const char* func);
|
||||
~AutoTime();
|
||||
AutoTime(const AutoTime&) = delete;
|
||||
AutoTime(const AutoTime&&) = delete;
|
||||
AutoTime& operator=(const AutoTime&) = delete;
|
||||
AutoTime& operator=(const AutoTime&&) = delete;
|
||||
|
||||
private:
|
||||
int mLine;
|
||||
char* mName;
|
||||
};
|
||||
} // namespace MNN
|
||||
|
||||
#ifdef MNN_OPEN_TIME_TRACE
|
||||
#define AUTOTIME MNN::AutoTime ___t(__LINE__, __func__)
|
||||
#else
|
||||
#define AUTOTIME
|
||||
#endif
|
||||
|
||||
#endif /* AutoTime_hpp */
|
||||
34
3rd/win/mnn/include/MNN/ErrorCode.hpp
Normal file
34
3rd/win/mnn/include/MNN/ErrorCode.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// ErrorCode.hpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2018/09/18.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#ifndef ErrorCode_h
|
||||
#define ErrorCode_h
|
||||
|
||||
namespace MNN {
|
||||
enum ErrorCode {
|
||||
#ifdef NO_ERROR
|
||||
#undef NO_ERROR
|
||||
#endif // NO_ERROR
|
||||
NO_ERROR = 0,
|
||||
OUT_OF_MEMORY = 1,
|
||||
NOT_SUPPORT = 2,
|
||||
COMPUTE_SIZE_ERROR = 3,
|
||||
NO_EXECUTION = 4,
|
||||
INVALID_VALUE = 5,
|
||||
|
||||
// User error
|
||||
INPUT_DATA_ERROR = 10,
|
||||
CALL_BACK_STOP = 11,
|
||||
|
||||
// Op Resize Error
|
||||
TENSOR_NOT_SUPPORT = 20,
|
||||
TENSOR_NEED_DIVIDE = 21,
|
||||
};
|
||||
} // namespace MNN
|
||||
|
||||
#endif /* ErrorCode_h */
|
||||
307
3rd/win/mnn/include/MNN/HalideRuntime.h
Normal file
307
3rd/win/mnn/include/MNN/HalideRuntime.h
Normal file
@@ -0,0 +1,307 @@
|
||||
#ifndef HALIDE_HALIDERUNTIME_H
|
||||
#define HALIDE_HALIDERUNTIME_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Note that you should not use "inline" along with HALIDE_ALWAYS_INLINE;
|
||||
// it is not necessary, and may produce warnings for some build configurations.
|
||||
#ifdef _MSC_VER
|
||||
#define HALIDE_ALWAYS_INLINE __forceinline
|
||||
#define HALIDE_NEVER_INLINE __declspec(noinline)
|
||||
#else
|
||||
#define HALIDE_ALWAYS_INLINE __attribute__((always_inline)) inline
|
||||
#define HALIDE_NEVER_INLINE __attribute__((noinline))
|
||||
#endif
|
||||
|
||||
/** \file
|
||||
*
|
||||
* This file declares the routines used by Halide internally in its
|
||||
* runtime. On platforms that support weak linking, these can be
|
||||
* replaced with user-defined versions by defining an extern "C"
|
||||
* function with the same name and signature.
|
||||
*
|
||||
* When doing Just In Time (JIT) compilation methods on the Func being
|
||||
* compiled must be called instead. The corresponding methods are
|
||||
* documented below.
|
||||
*
|
||||
* All of these functions take a "void *user_context" parameter as their
|
||||
* first argument; if the Halide kernel that calls back to any of these
|
||||
* functions has been compiled with the UserContext feature set on its Target,
|
||||
* then the value of that pointer passed from the code that calls the
|
||||
* Halide kernel is piped through to the function.
|
||||
*
|
||||
* Some of these are also useful to call when using the default
|
||||
* implementation. E.g. halide_shutdown_thread_pool.
|
||||
*
|
||||
* Note that even on platforms with weak linking, some linker setups
|
||||
* may not respect the override you provide. E.g. if the override is
|
||||
* in a shared library and the halide object files are linked directly
|
||||
* into the output, the builtin versions of the runtime functions will
|
||||
* be called. See your linker documentation for more details. On
|
||||
* Linux, LD_DYNAMIC_WEAK=1 may help.
|
||||
*
|
||||
*/
|
||||
|
||||
// Forward-declare to suppress warnings if compiling as C.
|
||||
struct halide_buffer_t;
|
||||
|
||||
/** Types in the halide type system. They can be ints, unsigned ints,
|
||||
* or floats (of various bit-widths), or a handle (which is always 64-bits).
|
||||
* Note that the int/uint/float values do not imply a specific bit width
|
||||
* (the bit width is expected to be encoded in a separate value).
|
||||
*/
|
||||
typedef enum halide_type_code_t
|
||||
{
|
||||
halide_type_int = 0, //!< signed integers
|
||||
halide_type_uint = 1, //!< unsigned integers
|
||||
halide_type_float = 2, //!< floating point numbers
|
||||
halide_type_handle = 3 //!< opaque pointer type (void *)
|
||||
} halide_type_code_t;
|
||||
|
||||
// Note that while __attribute__ can go before or after the declaration,
|
||||
// __declspec apparently is only allowed before.
|
||||
#ifndef HALIDE_ATTRIBUTE_ALIGN
|
||||
#ifdef _MSC_VER
|
||||
#define HALIDE_ATTRIBUTE_ALIGN(x) __declspec(align(x))
|
||||
#else
|
||||
#define HALIDE_ATTRIBUTE_ALIGN(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** A runtime tag for a type in the halide type system. Can be ints,
|
||||
* unsigned ints, or floats of various bit-widths (the 'bits'
|
||||
* field). Can also be vectors of the same (by setting the 'lanes'
|
||||
* field to something larger than one). This struct should be
|
||||
* exactly 32-bits in size. */
|
||||
struct halide_type_t {
|
||||
/** The basic type code: signed integer, unsigned integer, or floating point. */
|
||||
#if __cplusplus >= 201103L
|
||||
HALIDE_ATTRIBUTE_ALIGN(1) halide_type_code_t code; // halide_type_code_t
|
||||
#else
|
||||
HALIDE_ATTRIBUTE_ALIGN(1) uint8_t code; // halide_type_code_t
|
||||
#endif
|
||||
|
||||
/** The number of bits of precision of a single scalar value of this type. */
|
||||
HALIDE_ATTRIBUTE_ALIGN(1) uint8_t bits;
|
||||
|
||||
/** How many elements in a vector. This is 1 for scalar types. */
|
||||
HALIDE_ATTRIBUTE_ALIGN(2) uint16_t lanes;
|
||||
|
||||
#ifdef __cplusplus
|
||||
/** Construct a runtime representation of a Halide type from:
|
||||
* code: The fundamental type from an enum.
|
||||
* bits: The bit size of one element.
|
||||
* lanes: The number of vector elements in the type. */
|
||||
HALIDE_ALWAYS_INLINE halide_type_t(halide_type_code_t code, uint8_t bits, uint16_t lanes = 1)
|
||||
: code(code), bits(bits), lanes(lanes) {
|
||||
}
|
||||
|
||||
/** Default constructor is required e.g. to declare halide_trace_event
|
||||
* instances. */
|
||||
HALIDE_ALWAYS_INLINE halide_type_t() : code((halide_type_code_t)0), bits(0), lanes(0) {}
|
||||
|
||||
/** Compare two types for equality. */
|
||||
HALIDE_ALWAYS_INLINE bool operator==(const halide_type_t &other) const {
|
||||
return (code == other.code &&
|
||||
bits == other.bits &&
|
||||
lanes == other.lanes);
|
||||
}
|
||||
|
||||
HALIDE_ALWAYS_INLINE bool operator!=(const halide_type_t &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/** Size in bytes for a single element, even if width is not 1, of this type. */
|
||||
HALIDE_ALWAYS_INLINE int bytes() const { return (bits + 7) / 8; }
|
||||
#endif
|
||||
};
|
||||
|
||||
/** An opaque struct containing per-GPU API implementations of the
|
||||
* device functions. */
|
||||
struct halide_device_interface_impl_t;
|
||||
|
||||
/** Each GPU API provides a halide_device_interface_t struct pointing
|
||||
* to the code that manages device allocations. You can access these
|
||||
* functions directly from the struct member function pointers, or by
|
||||
* calling the functions declared below. Note that the global
|
||||
* functions are not available when using Halide as a JIT compiler.
|
||||
* If you are using raw halide_buffer_t in that context you must use
|
||||
* the function pointers in the device_interface struct.
|
||||
*
|
||||
* The function pointers below are currently the same for every GPU
|
||||
* API; only the impl field varies. These top-level functions do the
|
||||
* bookkeeping that is common across all GPU APIs, and then dispatch
|
||||
* to more API-specific functions via another set of function pointers
|
||||
* hidden inside the impl field.
|
||||
*/
|
||||
struct halide_device_interface_t {
|
||||
int (*device_malloc)(void *user_context, struct halide_buffer_t *buf,
|
||||
const struct halide_device_interface_t *device_interface);
|
||||
int (*device_free)(void *user_context, struct halide_buffer_t *buf);
|
||||
int (*device_sync)(void *user_context, struct halide_buffer_t *buf);
|
||||
void (*device_release)(void *user_context,
|
||||
const struct halide_device_interface_t *device_interface);
|
||||
int (*copy_to_host)(void *user_context, struct halide_buffer_t *buf);
|
||||
int (*copy_to_device)(void *user_context, struct halide_buffer_t *buf,
|
||||
const struct halide_device_interface_t *device_interface);
|
||||
int (*device_and_host_malloc)(void *user_context, struct halide_buffer_t *buf,
|
||||
const struct halide_device_interface_t *device_interface);
|
||||
int (*device_and_host_free)(void *user_context, struct halide_buffer_t *buf);
|
||||
int (*buffer_copy)(void *user_context, struct halide_buffer_t *src,
|
||||
const struct halide_device_interface_t *dst_device_interface, struct halide_buffer_t *dst);
|
||||
int (*device_crop)(void *user_context, const struct halide_buffer_t *src,
|
||||
struct halide_buffer_t *dst);
|
||||
int (*device_release_crop)(void *user_context, struct halide_buffer_t *buf);
|
||||
int (*wrap_native)(void *user_context, struct halide_buffer_t *buf, uint64_t handle,
|
||||
const struct halide_device_interface_t *device_interface);
|
||||
int (*detach_native)(void *user_context, struct halide_buffer_t *buf);
|
||||
const struct halide_device_interface_impl_t *impl;
|
||||
};
|
||||
|
||||
typedef struct halide_dimension_t {
|
||||
int32_t min, extent, stride;
|
||||
|
||||
// Per-dimension flags. None are defined yet (This is reserved for future use).
|
||||
uint32_t flags;
|
||||
|
||||
#ifdef __cplusplus
|
||||
HALIDE_ALWAYS_INLINE halide_dimension_t() : min(0), extent(0), stride(0), flags(0) {}
|
||||
HALIDE_ALWAYS_INLINE halide_dimension_t(int32_t m, int32_t e, int32_t s, uint32_t f = 0) :
|
||||
min(m), extent(e), stride(s), flags(f) {}
|
||||
|
||||
HALIDE_ALWAYS_INLINE bool operator==(const halide_dimension_t &other) const {
|
||||
return (min == other.min) &&
|
||||
(extent == other.extent) &&
|
||||
(stride == other.stride) &&
|
||||
(flags == other.flags);
|
||||
}
|
||||
|
||||
HALIDE_ALWAYS_INLINE bool operator!=(const halide_dimension_t &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
#endif
|
||||
} halide_dimension_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
typedef enum {halide_buffer_flag_host_dirty = 1,
|
||||
halide_buffer_flag_device_dirty = 2} halide_buffer_flags;
|
||||
|
||||
/**
|
||||
* The raw representation of an image passed around by generated
|
||||
* Halide code. It includes some stuff to track whether the image is
|
||||
* not actually in main memory, but instead on a device (like a
|
||||
* GPU). For a more convenient C++ wrapper, use Halide::Buffer<T>. */
|
||||
typedef struct halide_buffer_t {
|
||||
/** A device-handle for e.g. GPU memory used to back this buffer. */
|
||||
uint64_t device;
|
||||
|
||||
/** The interface used to interpret the above handle. */
|
||||
const struct halide_device_interface_t *device_interface;
|
||||
|
||||
/** A pointer to the start of the data in main memory. In terms of
|
||||
* the Halide coordinate system, this is the address of the min
|
||||
* coordinates (defined below). */
|
||||
uint8_t* host;
|
||||
|
||||
/** flags with various meanings. */
|
||||
uint64_t flags;
|
||||
|
||||
/** The type of each buffer element. */
|
||||
struct halide_type_t type;
|
||||
|
||||
/** The dimensionality of the buffer. */
|
||||
int32_t dimensions;
|
||||
|
||||
/** The shape of the buffer. Halide does not own this array - you
|
||||
* must manage the memory for it yourself. */
|
||||
halide_dimension_t *dim;
|
||||
|
||||
/** Pads the buffer up to a multiple of 8 bytes */
|
||||
void *padding;
|
||||
} halide_buffer_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace {
|
||||
template<typename T> struct check_is_pointer;
|
||||
template<typename T> struct check_is_pointer<T *> {};
|
||||
}
|
||||
|
||||
/** Construct the halide equivalent of a C type */
|
||||
template<typename T>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of() {
|
||||
// Create a compile-time error if T is not a pointer (without
|
||||
// using any includes - this code goes into the runtime).
|
||||
check_is_pointer<T> check;
|
||||
(void)check;
|
||||
return halide_type_t(halide_type_handle, 64);
|
||||
}
|
||||
|
||||
template<>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<float>() {
|
||||
return halide_type_t(halide_type_float, 32);
|
||||
}
|
||||
|
||||
template<>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<double>() {
|
||||
return halide_type_t(halide_type_float, 64);
|
||||
}
|
||||
|
||||
template<>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<bool>() {
|
||||
return halide_type_t(halide_type_uint, 1);
|
||||
}
|
||||
|
||||
template<>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<uint8_t>() {
|
||||
return halide_type_t(halide_type_uint, 8);
|
||||
}
|
||||
|
||||
template<>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<uint16_t>() {
|
||||
return halide_type_t(halide_type_uint, 16);
|
||||
}
|
||||
|
||||
template<>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<uint32_t>() {
|
||||
return halide_type_t(halide_type_uint, 32);
|
||||
}
|
||||
|
||||
template<>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<uint64_t>() {
|
||||
return halide_type_t(halide_type_uint, 64);
|
||||
}
|
||||
|
||||
template<>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<int8_t>() {
|
||||
return halide_type_t(halide_type_int, 8);
|
||||
}
|
||||
|
||||
template<>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<int16_t>() {
|
||||
return halide_type_t(halide_type_int, 16);
|
||||
}
|
||||
|
||||
template<>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<int32_t>() {
|
||||
return halide_type_t(halide_type_int, 32);
|
||||
}
|
||||
|
||||
template<>
|
||||
HALIDE_ALWAYS_INLINE halide_type_t halide_type_of<int64_t>() {
|
||||
return halide_type_t(halide_type_int, 64);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // HALIDE_HALIDERUNTIME_H
|
||||
145
3rd/win/mnn/include/MNN/ImageProcess.hpp
Normal file
145
3rd/win/mnn/include/MNN/ImageProcess.hpp
Normal file
@@ -0,0 +1,145 @@
|
||||
//
|
||||
// ImageProcess.hpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2018/09/19.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#ifndef ImageProcess_hpp
|
||||
#define ImageProcess_hpp
|
||||
|
||||
#include <MNN/ErrorCode.hpp>
|
||||
#include <MNN/Matrix.h>
|
||||
#include <MNN/Tensor.hpp>
|
||||
|
||||
namespace MNN {
|
||||
namespace CV {
|
||||
enum ImageFormat {
|
||||
RGBA = 0,
|
||||
RGB,
|
||||
BGR,
|
||||
GRAY,
|
||||
BGRA,
|
||||
YUV_NV21 = 11,
|
||||
YUV_NV12 = 12,
|
||||
YUV_I420 = 13,
|
||||
};
|
||||
|
||||
enum Filter { NEAREST = 0, BILINEAR = 1, BICUBIC = 2 };
|
||||
|
||||
enum Wrap { CLAMP_TO_EDGE = 0, ZERO = 1, REPEAT = 2 };
|
||||
|
||||
/**
|
||||
* handle image process for tensor.
|
||||
* step:
|
||||
* 1: Do transform compute and get points
|
||||
* 2: Sample line and do format convert
|
||||
* 3: Turn RGBA to float tensor, and do sub and normalize
|
||||
*/
|
||||
class MNN_PUBLIC ImageProcess {
|
||||
public:
|
||||
struct Inside;
|
||||
struct Config {
|
||||
/** data filter */
|
||||
Filter filterType = NEAREST;
|
||||
/** format of source data */
|
||||
ImageFormat sourceFormat = RGBA;
|
||||
/** format of destination data */
|
||||
ImageFormat destFormat = RGBA;
|
||||
|
||||
// Only valid if the dest type is float
|
||||
float mean[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
float normal[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
/** edge wrapper */
|
||||
Wrap wrap = CLAMP_TO_EDGE;
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief create image process with given config for given tensor.
|
||||
* @param config given config.
|
||||
* @param dstTensor given tensor.
|
||||
* @return image processor.
|
||||
*/
|
||||
static ImageProcess* create(const Config& config, const Tensor* dstTensor = nullptr);
|
||||
|
||||
/**
|
||||
* @brief create image process with given config for given tensor.
|
||||
* @param means given means
|
||||
* @param meanCount given means count
|
||||
* @param normals given normals
|
||||
* @param normalCount given normal count
|
||||
* @param sourceFormat format of source data
|
||||
* @param destFormat format of destination data
|
||||
* @param dstTensor given tensor.
|
||||
* @return image processor.
|
||||
*/
|
||||
static ImageProcess* create(const ImageFormat sourceFormat = RGBA, const ImageFormat destFormat = RGBA,
|
||||
const float* means = nullptr, const int meanCount = 0, const float* normals = nullptr,
|
||||
const int normalCount = 0, const Tensor* dstTensor = nullptr);
|
||||
|
||||
~ImageProcess();
|
||||
|
||||
/**
|
||||
* @brief get affine transform matrix.
|
||||
* @return affine transform matrix.
|
||||
*/
|
||||
inline const Matrix& matrix() const {
|
||||
return mTransform;
|
||||
}
|
||||
void setMatrix(const Matrix& matrix);
|
||||
|
||||
/**
|
||||
* @brief convert source data to given tensor.
|
||||
* @param source source data.
|
||||
* @param iw source width.
|
||||
* @param ih source height.
|
||||
* @param stride number of elements per row. eg: 100 width RGB contains at least 300 elements.
|
||||
* @param dest given tensor.
|
||||
* @return result code.
|
||||
*/
|
||||
ErrorCode convert(const uint8_t* source, int iw, int ih, int stride, Tensor* dest);
|
||||
|
||||
/**
|
||||
* @brief convert source data to given tensor.
|
||||
* @param source source data.
|
||||
* @param iw source width.
|
||||
* @param ih source height.
|
||||
* @param stride number of elements per row. eg: 100 width RGB contains at least 300 elements.
|
||||
* @param dest dest data.
|
||||
* @param ow output width.
|
||||
* @param oh output height.
|
||||
* @param outputBpp output bpp, if 0, set as the save and config.destFormat.
|
||||
* @param outputStride output stride, if 0, set as ow * outputBpp.
|
||||
* @param type Only support halide_type_of<uint8_t> and halide_type_of<float>.
|
||||
* @return result code.
|
||||
*/
|
||||
ErrorCode convert(const uint8_t* source, int iw, int ih, int stride, void* dest, int ow, int oh, int outputBpp = 0,
|
||||
int outputStride = 0, halide_type_t type = halide_type_of<float>());
|
||||
|
||||
/**
|
||||
* @brief create tensor with given data.
|
||||
* @param w image width.
|
||||
* @param h image height.
|
||||
* @param bpp bytes per pixel.
|
||||
* @param p pixel data pointer.
|
||||
* @return created tensor.
|
||||
*/
|
||||
template <typename T>
|
||||
static Tensor* createImageTensor(int w, int h, int bpp, void* p = nullptr) {
|
||||
return createImageTensor(halide_type_of<T>(), w, h, bpp, p);
|
||||
}
|
||||
static Tensor* createImageTensor(halide_type_t type, int w, int h, int bpp, void* p = nullptr);
|
||||
|
||||
private:
|
||||
ImageProcess(const Config& config);
|
||||
Matrix mTransform;
|
||||
Matrix mTransformInvert;
|
||||
Inside* mInside;
|
||||
};
|
||||
} // namespace CV
|
||||
} // namespace MNN
|
||||
|
||||
#endif /* ImageProcess_hpp */
|
||||
340
3rd/win/mnn/include/MNN/Interpreter.hpp
Normal file
340
3rd/win/mnn/include/MNN/Interpreter.hpp
Normal file
@@ -0,0 +1,340 @@
|
||||
//
|
||||
// Interpreter.hpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2018/07/23.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#ifndef Interpreter_hpp
|
||||
#define Interpreter_hpp
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <MNN/ErrorCode.hpp>
|
||||
#include <MNN/MNNForwardType.h>
|
||||
#include <MNN/Tensor.hpp>
|
||||
|
||||
namespace MNN {
|
||||
|
||||
/** session schedule config */
|
||||
struct ScheduleConfig {
|
||||
/** which tensor should be kept */
|
||||
std::vector<std::string> saveTensors;
|
||||
/** forward type */
|
||||
MNNForwardType type = MNN_FORWARD_CPU;
|
||||
/** number of threads in parallel */
|
||||
int numThread = 4;
|
||||
|
||||
/** subpath to run */
|
||||
struct Path {
|
||||
std::vector<std::string> inputs;
|
||||
std::vector<std::string> outputs;
|
||||
|
||||
enum Mode {
|
||||
/**
|
||||
* Op Mode
|
||||
* - inputs means the source op, can NOT be empty.
|
||||
* - outputs means the sink op, can be empty.
|
||||
* The path will start from source op, then flow when encounter the sink op.
|
||||
* The sink op will not be compute in this path.
|
||||
*/
|
||||
Op = 0,
|
||||
|
||||
/**
|
||||
* Tensor Mode (NOT supported yet)
|
||||
* - inputs means the inputs tensors, can NOT be empty.
|
||||
* - outputs means the outputs tensors, can NOT be empty.
|
||||
* It will find the pipeline that compute outputs from inputs.
|
||||
*/
|
||||
Tensor = 1
|
||||
};
|
||||
|
||||
/** running mode */
|
||||
Mode mode = Op;
|
||||
};
|
||||
Path path;
|
||||
|
||||
/** backup backend used to create execution when desinated backend do NOT support any op */
|
||||
MNNForwardType backupType = MNN_FORWARD_CPU;
|
||||
|
||||
/** extra backend config */
|
||||
BackendConfig* backendConfig = nullptr;
|
||||
};
|
||||
|
||||
class Session;
|
||||
struct Content;
|
||||
class Tensor;
|
||||
class Backend;
|
||||
class Runtime;
|
||||
|
||||
class MNN_PUBLIC OperatorInfo {
|
||||
struct Info;
|
||||
|
||||
public:
|
||||
/** Operator's name*/
|
||||
const std::string& name() const;
|
||||
|
||||
/** Operator's type*/
|
||||
const std::string& type() const;
|
||||
|
||||
/** Operator's flops, in M*/
|
||||
float flops() const;
|
||||
|
||||
protected:
|
||||
OperatorInfo();
|
||||
~OperatorInfo();
|
||||
Info* mContent;
|
||||
};
|
||||
|
||||
typedef std::function<bool(const std::vector<Tensor*>&, const std::string& /*opName*/)> TensorCallBack;
|
||||
typedef std::function<bool(const std::vector<Tensor*>&, const OperatorInfo*)> TensorCallBackWithInfo;
|
||||
typedef std::pair<std::map<MNNForwardType, std::shared_ptr<Runtime>>, std::shared_ptr<Runtime>> RuntimeInfo;
|
||||
|
||||
/** net data holder. multiple sessions could share same net. */
|
||||
class MNN_PUBLIC Interpreter {
|
||||
public:
|
||||
/**
|
||||
* @brief create net from file.
|
||||
* @param file given file.
|
||||
* @return created net if success, NULL otherwise.
|
||||
*/
|
||||
static Interpreter* createFromFile(const char* file);
|
||||
/**
|
||||
* @brief create net from buffer.
|
||||
* @param buffer given data buffer.
|
||||
* @param size size of data buffer.
|
||||
* @return created net if success, NULL otherwise.
|
||||
*/
|
||||
static Interpreter* createFromBuffer(const void* buffer, size_t size);
|
||||
~Interpreter();
|
||||
|
||||
enum SessionMode {
|
||||
/** About CallBack, Default Session_Debug*/
|
||||
/** runSessionWithCallBack is allowed and can get internal op info*/
|
||||
Session_Debug = 0,
|
||||
/** runSessionWithCallBack is not valid and can't get any info of op in session*/
|
||||
Session_Release = 1,
|
||||
|
||||
/** About input tenosr, Default Session_Input_Inside*/
|
||||
/** The input tensor is alloced by session, input data after session resized*/
|
||||
Session_Input_Inside = 2,
|
||||
/** The input tensor is alloced by user, set input data before session resize*/
|
||||
Session_Input_User = 3,
|
||||
};
|
||||
/**
|
||||
* @brief The API shoud be called before create session.
|
||||
* @param mode session mode
|
||||
* @return void
|
||||
*/
|
||||
void setSessionMode(SessionMode mode);
|
||||
|
||||
/**
|
||||
* @brief The API shoud be called before create session.
|
||||
* If the cache exist, try to load cache from file.
|
||||
* After createSession, try to save cache to file.
|
||||
* @param cacheFile cache file name
|
||||
* @param keySize the first `keySize` bytes used as the key to check if the `cacheFile` exists.
|
||||
* @return void
|
||||
*/
|
||||
void setCacheFile(const char* cacheFile, size_t keySize = 128);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief create runtimeInfo seperately with schedule config.
|
||||
* @param config session schedule configs.
|
||||
*/
|
||||
static RuntimeInfo createRuntime(const std::vector<ScheduleConfig>& configs);
|
||||
|
||||
/**
|
||||
* @brief create session with schedule config. created session will be managed in net.
|
||||
* @param config session schedule config.
|
||||
* @return created session if success, NULL otherwise.
|
||||
*/
|
||||
Session* createSession(const ScheduleConfig& config);
|
||||
|
||||
/**
|
||||
* @brief create session with schedule config and user-specified runtime.
|
||||
* @param config session schedule config, runtime runtimeInfo used by the created session.
|
||||
* @return created session if success, NULL otherwise.
|
||||
*/
|
||||
Session* createSession(const ScheduleConfig& config, const RuntimeInfo& runtime);
|
||||
|
||||
/**
|
||||
* @brief create multi-path session with schedule configs. created session will be managed in net.
|
||||
* @param configs session schedule configs.
|
||||
* @return created session if success, NULL otherwise.
|
||||
*/
|
||||
Session* createMultiPathSession(const std::vector<ScheduleConfig>& configs);
|
||||
|
||||
/**
|
||||
* @brief create multi-path session with schedule configs and user-specified runtime.
|
||||
created session will be managed in net.
|
||||
* @param configs session schedule configs.
|
||||
* @return created session if success, NULL otherwise.
|
||||
*/
|
||||
Session* createMultiPathSession(const std::vector<ScheduleConfig>& configs, const RuntimeInfo& runtime);
|
||||
|
||||
/**
|
||||
* @brief release session.
|
||||
* @param session given session.
|
||||
* @return true if given session is held by net and is freed.
|
||||
*/
|
||||
bool releaseSession(Session* session);
|
||||
|
||||
/**
|
||||
* @brief call this function to get tensors ready. output tensor buffer (host or deviceId) should be retrieved
|
||||
* after resize of any input tensor.
|
||||
* @param session given session.
|
||||
*/
|
||||
void resizeSession(Session* session);
|
||||
|
||||
/**
|
||||
* @brief call this function if don't need resize or create session any more, it will save a few memory that equal
|
||||
* to the size of model buffer
|
||||
*/
|
||||
void releaseModel();
|
||||
|
||||
/**
|
||||
* @brief Get the model buffer for user to save
|
||||
* @return std::make_pair(modleBuffer, modelSize).
|
||||
* @example:
|
||||
* std::ofstream output("trainResult.alinn")
|
||||
* auto buffer = net->getModelBuffer();
|
||||
* output.write((const char*)buffer.first, buffer.second);
|
||||
*/
|
||||
std::pair<const void*, size_t> getModelBuffer() const;
|
||||
|
||||
/**
|
||||
* @brief update Session's Tensor to model's Const Op
|
||||
* @param session given session.
|
||||
* @return result of running.
|
||||
*/
|
||||
ErrorCode updateSessionToModel(Session* session);
|
||||
|
||||
/**
|
||||
* @brief run session.
|
||||
* @param session given session.
|
||||
* @return result of running.
|
||||
*/
|
||||
ErrorCode runSession(Session* session) const;
|
||||
|
||||
/*
|
||||
* @brief run session.
|
||||
* @param session given session.
|
||||
* @param before callback before each op. return true to run the op; return false to skip the op.
|
||||
* @param after callback after each op. return true to continue running; return false to interrupt the session.
|
||||
* @param sync synchronously wait for finish of execution or not.
|
||||
* @return result of running.
|
||||
*/
|
||||
ErrorCode runSessionWithCallBack(const Session* session, const TensorCallBack& before, const TensorCallBack& end,
|
||||
bool sync = false) const;
|
||||
|
||||
/*
|
||||
* @brief run session.
|
||||
* @param session given session.
|
||||
* @param before callback before each op. return true to run the op; return false to skip the op.
|
||||
* @param after callback after each op. return true to continue running; return false to interrupt the session.
|
||||
* @param sync synchronously wait for finish of execution or not.
|
||||
* @return result of running.
|
||||
*/
|
||||
ErrorCode runSessionWithCallBackInfo(const Session* session, const TensorCallBackWithInfo& before,
|
||||
const TensorCallBackWithInfo& end, bool sync = false) const;
|
||||
|
||||
/**
|
||||
* @brief get input tensor for given name.
|
||||
* @param session given session.
|
||||
* @param name given name. if NULL, return first input.
|
||||
* @return tensor if found, NULL otherwise.
|
||||
*/
|
||||
Tensor* getSessionInput(const Session* session, const char* name);
|
||||
/**
|
||||
* @brief get output tensor for given name.
|
||||
* @param session given session.
|
||||
* @param name given name. if NULL, return first output.
|
||||
* @return tensor if found, NULL otherwise.
|
||||
*/
|
||||
Tensor* getSessionOutput(const Session* session, const char* name);
|
||||
|
||||
enum SessionInfoCode {
|
||||
/** memory session used in MB, float* */
|
||||
MEMORY = 0,
|
||||
|
||||
/** float operation needed in session in M, float* */
|
||||
FLOPS = 1,
|
||||
|
||||
/** Backends in session in M, int*, length >= the configs when create session */
|
||||
BACKENDS = 2,
|
||||
|
||||
ALL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief get session info
|
||||
* @param session given session.
|
||||
* @param code given info code.
|
||||
* @param void* given info ptr, see SessionInfoCode for detail
|
||||
* @return true if support the code, false otherwise.
|
||||
*/
|
||||
bool getSesionInfo(const Session* session, SessionInfoCode code, void* ptr);
|
||||
|
||||
/**
|
||||
* @brief get all output tensors.
|
||||
* @param session given session.
|
||||
* @return all output tensors mapped with name.
|
||||
*/
|
||||
const std::map<std::string, Tensor*>& getSessionOutputAll(const Session* session) const;
|
||||
/**
|
||||
* @brief get all input tensors.
|
||||
* @param session given session.
|
||||
* @return all input tensors mapped with name.
|
||||
*/
|
||||
const std::map<std::string, Tensor*>& getSessionInputAll(const Session* session) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief resize given tensor.
|
||||
* @param tensor given tensor.
|
||||
* @param dims new dims. at most 6 dims.
|
||||
*/
|
||||
void resizeTensor(Tensor* tensor, const std::vector<int>& dims);
|
||||
|
||||
/**
|
||||
* @brief resize given tensor by nchw.
|
||||
* @param batch / N.
|
||||
* @param channel / C.
|
||||
* @param height / H.
|
||||
* @param width / W
|
||||
*/
|
||||
void resizeTensor(Tensor* tensor, int batch, int channel, int height, int width);
|
||||
|
||||
/**
|
||||
* @brief get backend used to create given tensor.
|
||||
* @param session given session.
|
||||
* @param tensor given tensor.
|
||||
* @return backend used to create given tensor, may be NULL.
|
||||
*/
|
||||
const Backend* getBackend(const Session* session, const Tensor* tensor) const;
|
||||
|
||||
/**
|
||||
* @brief get business code (model identifier).
|
||||
* @return business code.
|
||||
*/
|
||||
const char* bizCode() const;
|
||||
|
||||
private:
|
||||
static Interpreter* createFromBufferInternal(Content* net);
|
||||
|
||||
Content* mNet = nullptr;
|
||||
Interpreter(Content* net);
|
||||
|
||||
Interpreter(const Interpreter&) = delete;
|
||||
Interpreter(const Interpreter&&) = delete;
|
||||
Interpreter& operator=(const Interpreter&) = delete;
|
||||
Interpreter& operator=(const Interpreter&&) = delete;
|
||||
};
|
||||
} // namespace MNN
|
||||
|
||||
#endif /* Interpreter_hpp */
|
||||
64
3rd/win/mnn/include/MNN/MNNDefine.h
Normal file
64
3rd/win/mnn/include/MNN/MNNDefine.h
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// MNNDefine.h
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2018/08/09.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#ifndef MNNDefine_h
|
||||
#define MNNDefine_h
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_IPHONE
|
||||
#define MNN_BUILD_FOR_IOS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MNN_USE_LOGCAT
|
||||
#include <android/log.h>
|
||||
#define MNN_ERROR(format, ...) __android_log_print(ANDROID_LOG_ERROR, "MNNJNI", format, ##__VA_ARGS__)
|
||||
#define MNN_PRINT(format, ...) __android_log_print(ANDROID_LOG_INFO, "MNNJNI", format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define MNN_PRINT(format, ...) printf(format, ##__VA_ARGS__)
|
||||
#define MNN_ERROR(format, ...) printf(format, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define MNN_ASSERT(x) \
|
||||
{ \
|
||||
int res = (x); \
|
||||
if (!res) { \
|
||||
MNN_ERROR("Error for %s, %d\n", __FILE__, __LINE__); \
|
||||
assert(res); \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define MNN_ASSERT(x)
|
||||
#endif
|
||||
|
||||
#define FUNC_PRINT(x) MNN_PRINT(#x "=%d in %s, %d \n", x, __func__, __LINE__);
|
||||
#define FUNC_PRINT_ALL(x, type) MNN_PRINT(#x "=" #type " %" #type " in %s, %d \n", x, __func__, __LINE__);
|
||||
|
||||
#define MNN_CHECK(success, log) \
|
||||
if(!(success)){ \
|
||||
MNN_ERROR("Check failed: %s ==> %s\n", #success, #log); \
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(BUILDING_MNN_DLL)
|
||||
#define MNN_PUBLIC __declspec(dllexport)
|
||||
#elif defined(USING_MNN_DLL)
|
||||
#define MNN_PUBLIC __declspec(dllimport)
|
||||
#else
|
||||
#define MNN_PUBLIC
|
||||
#endif
|
||||
#else
|
||||
#define MNN_PUBLIC __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
#endif /* MNNDefine_h */
|
||||
75
3rd/win/mnn/include/MNN/MNNForwardType.h
Normal file
75
3rd/win/mnn/include/MNN/MNNForwardType.h
Normal file
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// MNNForwardType.h
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2019/01/19.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#ifndef MNNForwardType_h
|
||||
#define MNNForwardType_h
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef enum {
|
||||
MNN_FORWARD_CPU = 0,
|
||||
|
||||
/*
|
||||
Firtly find the first available backends not equal to CPU
|
||||
If no other backends, use cpu
|
||||
*/
|
||||
MNN_FORWARD_AUTO = 4,
|
||||
|
||||
/*Hand write metal*/
|
||||
MNN_FORWARD_METAL = 1,
|
||||
|
||||
/*NVIDIA GPU API*/
|
||||
MNN_FORWARD_CUDA = 2,
|
||||
|
||||
/*Android / Common Device GPU API*/
|
||||
MNN_FORWARD_OPENCL = 3,
|
||||
MNN_FORWARD_OPENGL = 6,
|
||||
MNN_FORWARD_VULKAN = 7,
|
||||
|
||||
/*Android 8.1's NNAPI, Not Support yet*/
|
||||
MNN_FORWARD_NN = 5,
|
||||
|
||||
/*User can use API from Backend.hpp to add or search Backend*/
|
||||
MNN_FORWARD_USER_0 = 8,
|
||||
MNN_FORWARD_USER_1 = 9,
|
||||
MNN_FORWARD_USER_2 = 10,
|
||||
MNN_FORWARD_USER_3 = 11,
|
||||
|
||||
MNN_FORWARD_ALL,
|
||||
|
||||
/* Apply arm extension instruction set to accelerate some Ops, this forward type
|
||||
is only used in MNN internal, and will be active automatically when user set forward type
|
||||
to be MNN_FORWARD_CPU and extension instruction set is valid on hardware.
|
||||
*/
|
||||
MNN_FORWARD_CPU_EXTENSION
|
||||
|
||||
} MNNForwardType;
|
||||
#ifdef __cplusplus
|
||||
namespace MNN {
|
||||
struct BackendConfig {
|
||||
enum MemoryMode { Memory_Normal = 0, Memory_High, Memory_Low };
|
||||
|
||||
MemoryMode memory = Memory_Normal;
|
||||
|
||||
enum PowerMode { Power_Normal = 0, Power_High, Power_Low };
|
||||
|
||||
PowerMode power = Power_Normal;
|
||||
|
||||
enum PrecisionMode { Precision_Normal = 0, Precision_High, Precision_Low };
|
||||
|
||||
PrecisionMode precision = Precision_Normal;
|
||||
|
||||
/** user defined context */
|
||||
union {
|
||||
void* sharedContext = nullptr;
|
||||
size_t flags; // Valid for CPU Backend
|
||||
};
|
||||
};
|
||||
}; // namespace MNN
|
||||
#endif
|
||||
#endif /* MNNForwardType_h */
|
||||
1615
3rd/win/mnn/include/MNN/Matrix.h
Normal file
1615
3rd/win/mnn/include/MNN/Matrix.h
Normal file
File diff suppressed because it is too large
Load Diff
580
3rd/win/mnn/include/MNN/Rect.h
Normal file
580
3rd/win/mnn/include/MNN/Rect.h
Normal file
@@ -0,0 +1,580 @@
|
||||
//
|
||||
// Rect.h
|
||||
// MNN
|
||||
//
|
||||
// Modified by jiangxiaotang on 2018/09/19.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/* Generated by tools/bookmaker from include/core/Rect.h and docs/SkRect_Reference.bmh
|
||||
on 2018-07-13 08:15:11. Additional documentation and examples can be found at:
|
||||
https://skia.org/user/api/SkRect_Reference
|
||||
|
||||
You may edit either file directly. Structural changes to public interfaces require
|
||||
editing both files. After editing docs/SkRect_Reference.bmh, run:
|
||||
bookmaker -b docs -i include/core/Rect.h -p
|
||||
to create an updated version of this file.
|
||||
*/
|
||||
|
||||
#ifndef SkRect_DEFINED
|
||||
#define SkRect_DEFINED
|
||||
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <MNN/MNNDefine.h>
|
||||
|
||||
namespace MNN {
|
||||
namespace CV {
|
||||
|
||||
struct Point {
|
||||
float fX;
|
||||
float fY;
|
||||
|
||||
void set(float x, float y) {
|
||||
fX = x;
|
||||
fY = y;
|
||||
}
|
||||
};
|
||||
|
||||
/** \struct Rect
|
||||
Rect holds four float coordinates describing the upper and
|
||||
lower bounds of a rectangle. Rect may be created from outer bounds or
|
||||
from position, width, and height. Rect describes an area; if its right
|
||||
is less than or equal to its left, or if its bottom is less than or equal to
|
||||
its top, it is considered empty.
|
||||
*/
|
||||
struct MNN_PUBLIC Rect {
|
||||
float fLeft; //!< smaller x-axis bounds
|
||||
float fTop; //!< smaller y-axis bounds
|
||||
float fRight; //!< larger x-axis bounds
|
||||
float fBottom; //!< larger y-axis bounds
|
||||
|
||||
/** Returns constructed Rect set to (0, 0, 0, 0).
|
||||
Many other rectangles are empty; if left is equal to or greater than right,
|
||||
or if top is equal to or greater than bottom. Setting all members to zero
|
||||
is a convenience, but does not designate a special empty rectangle.
|
||||
|
||||
@return bounds (0, 0, 0, 0)
|
||||
*/
|
||||
static constexpr Rect MakeEmpty() {
|
||||
return Rect{0, 0, 0, 0};
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_RECTMAKELARGEST
|
||||
/** Deprecated.
|
||||
*/
|
||||
static Rect MakeLargest() {
|
||||
return {SK_ScalarMin, SK_ScalarMin, SK_ScalarMax, SK_ScalarMax};
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Returns constructed Rect set to float values (0, 0, w, h). Does not
|
||||
validate input; w or h may be negative.
|
||||
|
||||
Passing integer values may generate a compiler warning since Rect cannot
|
||||
represent 32-bit integers exactly. Use SkIRect for an exact integer rectangle.
|
||||
|
||||
@param w float width of constructed Rect
|
||||
@param h float height of constructed Rect
|
||||
@return bounds (0, 0, w, h)
|
||||
*/
|
||||
static constexpr Rect MakeWH(float w, float h) {
|
||||
return Rect{0, 0, w, h};
|
||||
}
|
||||
|
||||
/** Returns constructed Rect set to integer values (0, 0, w, h). Does not validate
|
||||
input; w or h may be negative.
|
||||
|
||||
Use to avoid a compiler warning that input may lose precision when stored.
|
||||
Use SkIRect for an exact integer rectangle.
|
||||
|
||||
@param w integer width of constructed Rect
|
||||
@param h integer height of constructed Rect
|
||||
@return bounds (0, 0, w, h)
|
||||
*/
|
||||
static Rect MakeIWH(int w, int h) {
|
||||
Rect r;
|
||||
r.set(0, 0, (float)(w), (float)(h));
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Returns constructed Rect set to (l, t, r, b). Does not sort input; Rect may
|
||||
result in fLeft greater than fRight, or fTop greater than fBottom.
|
||||
|
||||
@param l float stored in fLeft
|
||||
@param t float stored in fTop
|
||||
@param r float stored in fRight
|
||||
@param b float stored in fBottom
|
||||
@return bounds (l, t, r, b)
|
||||
*/
|
||||
static constexpr Rect MakeLTRB(float l, float t, float r, float b) {
|
||||
return Rect{l, t, r, b};
|
||||
}
|
||||
|
||||
/** Returns constructed Rect set to (x, y, x + w, y + h). Does not validate input;
|
||||
w or h may be negative.
|
||||
|
||||
@param x stored in fLeft
|
||||
@param y stored in fTop
|
||||
@param w added to x and stored in fRight
|
||||
@param h added to y and stored in fBottom
|
||||
@return bounds at (x, y) with width w and height h
|
||||
*/
|
||||
static constexpr Rect MakeXYWH(float x, float y, float w, float h) {
|
||||
return Rect{x, y, x + w, y + h};
|
||||
}
|
||||
|
||||
/** Returns true if fLeft is equal to or greater than fRight, or if fTop is equal
|
||||
to or greater than fBottom. Call sort() to reverse rectangles with negative
|
||||
width() or height().
|
||||
|
||||
@return true if width() or height() are zero or negative
|
||||
*/
|
||||
bool isEmpty() const {
|
||||
// We write it as the NOT of a non-empty rect, so we will return true if any values
|
||||
// are NaN.
|
||||
return !(fLeft < fRight && fTop < fBottom);
|
||||
}
|
||||
|
||||
/** Returns true if fLeft is equal to or less than fRight, or if fTop is equal
|
||||
to or less than fBottom. Call sort() to reverse rectangles with negative
|
||||
width() or height().
|
||||
|
||||
@return true if width() or height() are zero or positive
|
||||
*/
|
||||
bool isSorted() const {
|
||||
return fLeft <= fRight && fTop <= fBottom;
|
||||
}
|
||||
|
||||
/** Returns left edge of Rect, if sorted. Call isSorted() to see if Rect is valid.
|
||||
Call sort() to reverse fLeft and fRight if needed.
|
||||
|
||||
@return fLeft
|
||||
*/
|
||||
float x() const {
|
||||
return fLeft;
|
||||
}
|
||||
|
||||
/** Returns top edge of Rect, if sorted. Call isEmpty() to see if Rect may be invalid,
|
||||
and sort() to reverse fTop and fBottom if needed.
|
||||
|
||||
@return fTop
|
||||
*/
|
||||
float y() const {
|
||||
return fTop;
|
||||
}
|
||||
|
||||
/** Returns left edge of Rect, if sorted. Call isSorted() to see if Rect is valid.
|
||||
Call sort() to reverse fLeft and fRight if needed.
|
||||
|
||||
@return fLeft
|
||||
*/
|
||||
float left() const {
|
||||
return fLeft;
|
||||
}
|
||||
|
||||
/** Returns top edge of Rect, if sorted. Call isEmpty() to see if Rect may be invalid,
|
||||
and sort() to reverse fTop and fBottom if needed.
|
||||
|
||||
@return fTop
|
||||
*/
|
||||
float top() const {
|
||||
return fTop;
|
||||
}
|
||||
|
||||
/** Returns right edge of Rect, if sorted. Call isSorted() to see if Rect is valid.
|
||||
Call sort() to reverse fLeft and fRight if needed.
|
||||
|
||||
@return fRight
|
||||
*/
|
||||
float right() const {
|
||||
return fRight;
|
||||
}
|
||||
|
||||
/** Returns bottom edge of Rect, if sorted. Call isEmpty() to see if Rect may be invalid,
|
||||
and sort() to reverse fTop and fBottom if needed.
|
||||
|
||||
@return fBottom
|
||||
*/
|
||||
float bottom() const {
|
||||
return fBottom;
|
||||
}
|
||||
|
||||
/** Returns span on the x-axis. This does not check if Rect is sorted, or if
|
||||
result fits in 32-bit float; result may be negative or infinity.
|
||||
|
||||
@return fRight minus fLeft
|
||||
*/
|
||||
float width() const {
|
||||
return fRight - fLeft;
|
||||
}
|
||||
|
||||
/** Returns span on the y-axis. This does not check if Rect is sorted, or if
|
||||
result fits in 32-bit float; result may be negative or infinity.
|
||||
|
||||
@return fBottom minus fTop
|
||||
*/
|
||||
float height() const {
|
||||
return fBottom - fTop;
|
||||
}
|
||||
|
||||
/** Returns average of left edge and right edge. Result does not change if Rect
|
||||
is sorted. Result may overflow to infinity if Rect is far from the origin.
|
||||
|
||||
@return midpoint in x
|
||||
*/
|
||||
float centerX() const {
|
||||
// don't use floatHalf(fLeft + fBottom) as that might overflow before the 0.5
|
||||
return 0.5f * (fLeft) + 0.5f * (fRight);
|
||||
}
|
||||
|
||||
/** Returns average of top edge and bottom edge. Result does not change if Rect
|
||||
is sorted.
|
||||
|
||||
@return midpoint in y
|
||||
*/
|
||||
float centerY() const {
|
||||
// don't use floatHalf(fTop + fBottom) as that might overflow before the 0.5
|
||||
return 0.5f * (fTop) + 0.5f * (fBottom);
|
||||
}
|
||||
|
||||
/** Sets Rect to (0, 0, 0, 0).
|
||||
|
||||
Many other rectangles are empty; if left is equal to or greater than right,
|
||||
or if top is equal to or greater than bottom. Setting all members to zero
|
||||
is a convenience, but does not designate a special empty rectangle.
|
||||
*/
|
||||
void setEmpty() {
|
||||
*this = MakeEmpty();
|
||||
}
|
||||
|
||||
/** Sets Rect to (left, top, right, bottom).
|
||||
left and right are not sorted; left is not necessarily less than right.
|
||||
top and bottom are not sorted; top is not necessarily less than bottom.
|
||||
|
||||
@param left stored in fLeft
|
||||
@param top stored in fTop
|
||||
@param right stored in fRight
|
||||
@param bottom stored in fBottom
|
||||
*/
|
||||
void set(float left, float top, float right, float bottom) {
|
||||
fLeft = left;
|
||||
fTop = top;
|
||||
fRight = right;
|
||||
fBottom = bottom;
|
||||
}
|
||||
|
||||
/** Sets Rect to (left, top, right, bottom).
|
||||
left and right are not sorted; left is not necessarily less than right.
|
||||
top and bottom are not sorted; top is not necessarily less than bottom.
|
||||
|
||||
@param left stored in fLeft
|
||||
@param top stored in fTop
|
||||
@param right stored in fRight
|
||||
@param bottom stored in fBottom
|
||||
*/
|
||||
void setLTRB(float left, float top, float right, float bottom) {
|
||||
this->set(left, top, right, bottom);
|
||||
}
|
||||
|
||||
/** Sets Rect to (left, top, right, bottom).
|
||||
All parameters are promoted from integer to scalar.
|
||||
left and right are not sorted; left is not necessarily less than right.
|
||||
top and bottom are not sorted; top is not necessarily less than bottom.
|
||||
|
||||
@param left promoted to float and stored in fLeft
|
||||
@param top promoted to float and stored in fTop
|
||||
@param right promoted to float and stored in fRight
|
||||
@param bottom promoted to float and stored in fBottom
|
||||
*/
|
||||
void iset(int left, int top, int right, int bottom) {
|
||||
fLeft = (float)(left);
|
||||
fTop = (float)(top);
|
||||
fRight = (float)(right);
|
||||
fBottom = (float)(bottom);
|
||||
}
|
||||
|
||||
/** Sets Rect to (0, 0, width, height).
|
||||
width and height may be zero or negative. width and height are promoted from
|
||||
integer to float, large values may lose precision.
|
||||
|
||||
@param width promoted to float and stored in fRight
|
||||
@param height promoted to float and stored in fBottom
|
||||
*/
|
||||
void isetWH(int width, int height) {
|
||||
fLeft = fTop = 0;
|
||||
fRight = (float)(width);
|
||||
fBottom = (float)(height);
|
||||
}
|
||||
|
||||
/** Sets Rect to (x, y, x + width, y + height). Does not validate input;
|
||||
width or height may be negative.
|
||||
|
||||
@param x stored in fLeft
|
||||
@param y stored in fTop
|
||||
@param width added to x and stored in fRight
|
||||
@param height added to y and stored in fBottom
|
||||
*/
|
||||
void setXYWH(float x, float y, float width, float height) {
|
||||
fLeft = x;
|
||||
fTop = y;
|
||||
fRight = x + width;
|
||||
fBottom = y + height;
|
||||
}
|
||||
|
||||
/** Sets Rect to (0, 0, width, height). Does not validate input;
|
||||
width or height may be negative.
|
||||
|
||||
@param width stored in fRight
|
||||
@param height stored in fBottom
|
||||
*/
|
||||
void setWH(float width, float height) {
|
||||
fLeft = 0;
|
||||
fTop = 0;
|
||||
fRight = width;
|
||||
fBottom = height;
|
||||
}
|
||||
|
||||
/** Returns Rect offset by (dx, dy).
|
||||
|
||||
If dx is negative, Rect returned is moved to the left.
|
||||
If dx is positive, Rect returned is moved to the right.
|
||||
If dy is negative, Rect returned is moved upward.
|
||||
If dy is positive, Rect returned is moved downward.
|
||||
|
||||
@param dx added to fLeft and fRight
|
||||
@param dy added to fTop and fBottom
|
||||
@return Rect offset on axes, with original width and height
|
||||
*/
|
||||
Rect makeOffset(float dx, float dy) const {
|
||||
return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy);
|
||||
}
|
||||
|
||||
/** Returns Rect, inset by (dx, dy).
|
||||
|
||||
If dx is negative, Rect returned is wider.
|
||||
If dx is positive, Rect returned is narrower.
|
||||
If dy is negative, Rect returned is taller.
|
||||
If dy is positive, Rect returned is shorter.
|
||||
|
||||
@param dx added to fLeft and subtracted from fRight
|
||||
@param dy added to fTop and subtracted from fBottom
|
||||
@return Rect inset symmetrically left and right, top and bottom
|
||||
*/
|
||||
Rect makeInset(float dx, float dy) const {
|
||||
return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy);
|
||||
}
|
||||
|
||||
/** Returns Rect, outset by (dx, dy).
|
||||
|
||||
If dx is negative, Rect returned is narrower.
|
||||
If dx is positive, Rect returned is wider.
|
||||
If dy is negative, Rect returned is shorter.
|
||||
If dy is positive, Rect returned is taller.
|
||||
|
||||
@param dx subtracted to fLeft and added from fRight
|
||||
@param dy subtracted to fTop and added from fBottom
|
||||
@return Rect outset symmetrically left and right, top and bottom
|
||||
*/
|
||||
Rect makeOutset(float dx, float dy) const {
|
||||
return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy);
|
||||
}
|
||||
|
||||
/** Offsets Rect by adding dx to fLeft, fRight; and by adding dy to fTop, fBottom.
|
||||
|
||||
If dx is negative, moves Rect to the left.
|
||||
If dx is positive, moves Rect to the right.
|
||||
If dy is negative, moves Rect upward.
|
||||
If dy is positive, moves Rect downward.
|
||||
|
||||
@param dx offset added to fLeft and fRight
|
||||
@param dy offset added to fTop and fBottom
|
||||
*/
|
||||
void offset(float dx, float dy) {
|
||||
fLeft += dx;
|
||||
fTop += dy;
|
||||
fRight += dx;
|
||||
fBottom += dy;
|
||||
}
|
||||
|
||||
/** Offsets Rect so that fLeft equals newX, and fTop equals newY. width and height
|
||||
are unchanged.
|
||||
|
||||
@param newX stored in fLeft, preserving width()
|
||||
@param newY stored in fTop, preserving height()
|
||||
*/
|
||||
void offsetTo(float newX, float newY) {
|
||||
fRight += newX - fLeft;
|
||||
fBottom += newY - fTop;
|
||||
fLeft = newX;
|
||||
fTop = newY;
|
||||
}
|
||||
|
||||
/** Insets Rect by (dx, dy).
|
||||
|
||||
If dx is positive, makes Rect narrower.
|
||||
If dx is negative, makes Rect wider.
|
||||
If dy is positive, makes Rect shorter.
|
||||
If dy is negative, makes Rect taller.
|
||||
|
||||
@param dx added to fLeft and subtracted from fRight
|
||||
@param dy added to fTop and subtracted from fBottom
|
||||
*/
|
||||
void inset(float dx, float dy) {
|
||||
fLeft += dx;
|
||||
fTop += dy;
|
||||
fRight -= dx;
|
||||
fBottom -= dy;
|
||||
}
|
||||
|
||||
/** Outsets Rect by (dx, dy).
|
||||
|
||||
If dx is positive, makes Rect wider.
|
||||
If dx is negative, makes Rect narrower.
|
||||
If dy is positive, makes Rect taller.
|
||||
If dy is negative, makes Rect shorter.
|
||||
|
||||
@param dx subtracted to fLeft and added from fRight
|
||||
@param dy subtracted to fTop and added from fBottom
|
||||
*/
|
||||
void outset(float dx, float dy) {
|
||||
this->inset(-dx, -dy);
|
||||
}
|
||||
|
||||
private:
|
||||
static bool Intersects(float al, float at, float ar, float ab, float bl, float bt, float br, float bb) {
|
||||
float L = std::max(al, bl);
|
||||
float R = std::min(ar, br);
|
||||
float T = std::max(at, bt);
|
||||
float B = std::min(ab, bb);
|
||||
return L < R && T < B;
|
||||
}
|
||||
|
||||
public:
|
||||
/** Constructs Rect to intersect from (left, top, right, bottom). Does not sort
|
||||
construction.
|
||||
|
||||
Returns true if Rect intersects construction.
|
||||
Returns false if either construction or Rect is empty, or do not intersect.
|
||||
|
||||
@param left x-axis minimum of constructed Rect
|
||||
@param top y-axis minimum of constructed Rect
|
||||
@param right x-axis maximum of constructed Rect
|
||||
@param bottom y-axis maximum of constructed Rect
|
||||
@return true if construction and Rect have area in common
|
||||
*/
|
||||
bool intersects(float left, float top, float right, float bottom) const {
|
||||
return Intersects(fLeft, fTop, fRight, fBottom, left, top, right, bottom);
|
||||
}
|
||||
|
||||
/** Returns true if Rect intersects r.
|
||||
Returns false if either r or Rect is empty, or do not intersect.
|
||||
|
||||
@param r Rect to intersect
|
||||
@return true if r and Rect have area in common
|
||||
*/
|
||||
bool intersects(const Rect& r) const {
|
||||
return Intersects(fLeft, fTop, fRight, fBottom, r.fLeft, r.fTop, r.fRight, r.fBottom);
|
||||
}
|
||||
|
||||
/** Returns true if a intersects b.
|
||||
Returns false if either a or b is empty, or do not intersect.
|
||||
|
||||
@param a Rect to intersect
|
||||
@param b Rect to intersect
|
||||
@return true if a and b have area in common
|
||||
*/
|
||||
static bool Intersects(const Rect& a, const Rect& b) {
|
||||
return Intersects(a.fLeft, a.fTop, a.fRight, a.fBottom, b.fLeft, b.fTop, b.fRight, b.fBottom);
|
||||
}
|
||||
|
||||
/** Sets Rect to the union of itself and r.
|
||||
|
||||
Asserts if r is empty and SK_DEBUG is defined.
|
||||
If Rect is empty, sets Rect to r.
|
||||
|
||||
May produce incorrect results if r is empty.
|
||||
|
||||
@param r expansion Rect
|
||||
*/
|
||||
void joinNonEmptyArg(const Rect& r) {
|
||||
MNN_ASSERT(!r.isEmpty());
|
||||
// if we are empty, just assign
|
||||
if (fLeft >= fRight || fTop >= fBottom) {
|
||||
*this = r;
|
||||
} else {
|
||||
this->joinPossiblyEmptyRect(r);
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets Rect to the union of itself and the construction.
|
||||
|
||||
May produce incorrect results if Rect or r is empty.
|
||||
|
||||
@param r expansion Rect
|
||||
*/
|
||||
void joinPossiblyEmptyRect(const Rect& r) {
|
||||
fLeft = std::min(fLeft, r.left());
|
||||
fTop = std::min(fTop, r.top());
|
||||
fRight = std::max(fRight, r.right());
|
||||
fBottom = std::max(fBottom, r.bottom());
|
||||
}
|
||||
|
||||
/** Returns true if: fLeft <= x < fRight && fTop <= y < fBottom.
|
||||
Returns false if Rect is empty.
|
||||
|
||||
@param x test Point x-coordinate
|
||||
@param y test Point y-coordinate
|
||||
@return true if (x, y) is inside Rect
|
||||
*/
|
||||
bool contains(float x, float y) const {
|
||||
return x >= fLeft && x < fRight && y >= fTop && y < fBottom;
|
||||
}
|
||||
|
||||
/** Swaps fLeft and fRight if fLeft is greater than fRight; and swaps
|
||||
fTop and fBottom if fTop is greater than fBottom. Result may be empty;
|
||||
and width() and height() will be zero or positive.
|
||||
*/
|
||||
void sort() {
|
||||
using std::swap;
|
||||
if (fLeft > fRight) {
|
||||
swap(fLeft, fRight);
|
||||
}
|
||||
|
||||
if (fTop > fBottom) {
|
||||
swap(fTop, fBottom);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns Rect with fLeft and fRight swapped if fLeft is greater than fRight; and
|
||||
with fTop and fBottom swapped if fTop is greater than fBottom. Result may be empty;
|
||||
and width() and height() will be zero or positive.
|
||||
|
||||
@return sorted Rect
|
||||
*/
|
||||
Rect makeSorted() const {
|
||||
return MakeLTRB(std::min(fLeft, fRight), std::min(fTop, fBottom), std::max(fLeft, fRight),
|
||||
std::max(fTop, fBottom));
|
||||
}
|
||||
|
||||
/** Returns pointer to first scalar in Rect, to treat it as an array with four
|
||||
entries.
|
||||
|
||||
@return pointer to fLeft
|
||||
*/
|
||||
const float* asScalars() const {
|
||||
return &fLeft;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace CV
|
||||
} // namespace MNN
|
||||
#endif
|
||||
278
3rd/win/mnn/include/MNN/Tensor.hpp
Normal file
278
3rd/win/mnn/include/MNN/Tensor.hpp
Normal file
@@ -0,0 +1,278 @@
|
||||
//
|
||||
// Tensor.hpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2018/08/14.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#ifndef Tensor_hpp
|
||||
#define Tensor_hpp
|
||||
|
||||
#include <vector>
|
||||
#include <MNN/HalideRuntime.h>
|
||||
#include <MNN/MNNDefine.h>
|
||||
#define MNN_MAX_TENSOR_DIM 6
|
||||
|
||||
namespace MNN {
|
||||
|
||||
/**
|
||||
* data container.
|
||||
* data for host tensor is saved in `host` field. its memory is allocated malloc directly.
|
||||
* data for device tensor is saved in `deviceId` field. its memory is allocated by session's backend.
|
||||
* usually, device tensors are created by engine (like net, session).
|
||||
* meanwhile, host tensors could be created by engine or user.
|
||||
*/
|
||||
class MNN_PUBLIC Tensor {
|
||||
public:
|
||||
struct InsideDescribe;
|
||||
|
||||
/** dimension type used to create tensor */
|
||||
enum DimensionType {
|
||||
/** for tensorflow net type. uses NHWC as data format. */
|
||||
TENSORFLOW,
|
||||
/** for caffe net type. uses NCHW as data format. */
|
||||
CAFFE,
|
||||
/** for caffe net type. uses NC4HW4 as data format. */
|
||||
CAFFE_C4
|
||||
};
|
||||
|
||||
/** handle type */
|
||||
enum HandleDataType {
|
||||
/** default handle type */
|
||||
HANDLE_NONE = 0,
|
||||
/** string handle type */
|
||||
HANDLE_STRING = 1
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief create a tensor with dimension size and type without acquire memory for data.
|
||||
* @param dimSize dimension size.
|
||||
* @param type dimension type.
|
||||
*/
|
||||
Tensor(int dimSize = 4, DimensionType type = CAFFE);
|
||||
|
||||
/**
|
||||
* @brief create a tensor with same shape as given tensor.
|
||||
* @param tensor shape provider.
|
||||
* @param type dimension type.
|
||||
* @param allocMemory acquire memory for data or not.
|
||||
* @warning tensor data won't be copied.
|
||||
*/
|
||||
Tensor(const Tensor* tensor, DimensionType type = CAFFE, bool allocMemory = true);
|
||||
|
||||
/** deinitializer */
|
||||
~Tensor();
|
||||
|
||||
private:
|
||||
// remove all assignment operator
|
||||
Tensor(const Tensor& tensor) = delete;
|
||||
Tensor(const Tensor&& tensor) = delete;
|
||||
Tensor& operator=(const Tensor&) = delete;
|
||||
Tensor& operator=(const Tensor&&) = delete;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief create tensor with shape, data type and dimension type.
|
||||
* @param shape tensor shape.
|
||||
* @param type data type.
|
||||
* @param dimType dimension type.
|
||||
* @return created tensor.
|
||||
* @warning memory for data won't be acquired. call backend's onAcquireBuffer to get memory ready.
|
||||
*/
|
||||
static Tensor* createDevice(const std::vector<int>& shape, halide_type_t type, DimensionType dimType = TENSORFLOW);
|
||||
|
||||
/**
|
||||
* @brief create tensor with shape and dimension type. data type is represented by `T`.
|
||||
* @param shape tensor shape.
|
||||
* @param dimType dimension type.
|
||||
* @return created tensor.
|
||||
* @warning memory for data won't be acquired. call backend's onAcquireBuffer to get memory ready.
|
||||
*/
|
||||
template <typename T>
|
||||
static Tensor* createDevice(const std::vector<int>& shape, DimensionType dimType = TENSORFLOW) {
|
||||
return createDevice(shape, halide_type_of<T>(), dimType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief create tensor with shape, data type, data and dimension type.
|
||||
* @param shape tensor shape.
|
||||
* @param type data type.
|
||||
* @param data data to save.
|
||||
* @param dimType dimension type.
|
||||
* @return created tensor.
|
||||
*/
|
||||
static Tensor* create(const std::vector<int>& shape, halide_type_t type, void* data = NULL,
|
||||
DimensionType dimType = TENSORFLOW);
|
||||
|
||||
/**
|
||||
* @brief create tensor with shape, data and dimension type. data type is represented by `T`.
|
||||
* @param shape tensor shape.
|
||||
* @param data data to save.
|
||||
* @param dimType dimension type.
|
||||
* @return created tensor.
|
||||
*/
|
||||
template <typename T>
|
||||
static Tensor* create(const std::vector<int>& shape, void* data = NULL, DimensionType dimType = TENSORFLOW) {
|
||||
return create(shape, halide_type_of<T>(), data, dimType);
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief for DEVICE tensor, copy data from given host tensor.
|
||||
* @param hostTensor host tensor, the data provider.
|
||||
* @return true for DEVICE tensor, and false for HOST tensor.
|
||||
*/
|
||||
bool copyFromHostTensor(const Tensor* hostTensor);
|
||||
|
||||
/**
|
||||
* @brief for DEVICE tensor, copy data to given host tensor.
|
||||
* @param hostTensor host tensor, the data consumer.
|
||||
* @return true for DEVICE tensor, and false for HOST tensor.
|
||||
*/
|
||||
bool copyToHostTensor(Tensor* hostTensor) const;
|
||||
|
||||
/**
|
||||
* @brief create HOST tensor from DEVICE tensor, with or without data copying.
|
||||
* @param deviceTensor given device tensor.
|
||||
* @param copyData copy data or not.
|
||||
* @return created host tensor.
|
||||
*/
|
||||
static Tensor* createHostTensorFromDevice(const Tensor* deviceTensor, bool copyData = true);
|
||||
|
||||
public:
|
||||
const halide_buffer_t& buffer() const {
|
||||
return mBuffer;
|
||||
}
|
||||
halide_buffer_t& buffer() {
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get dimension type.
|
||||
* @return dimension type.
|
||||
*/
|
||||
DimensionType getDimensionType() const;
|
||||
|
||||
/**
|
||||
* @brief handle data type. used when data type code is halide_type_handle.
|
||||
* @return handle data type.
|
||||
*/
|
||||
HandleDataType getHandleDataType() const;
|
||||
|
||||
/**
|
||||
* @brief set data type.
|
||||
* @param type data type defined in 'Type_generated.h'.
|
||||
*/
|
||||
void setType(int type);
|
||||
|
||||
/**
|
||||
* @brief get data type.
|
||||
* @return data type.
|
||||
*/
|
||||
inline halide_type_t getType() const {
|
||||
return mBuffer.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief visit host memory, data type is represented by `T`.
|
||||
* @return data point in `T` type.
|
||||
*/
|
||||
template <typename T>
|
||||
T* host() const {
|
||||
return (T*)mBuffer.host;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief visit device memory.
|
||||
* @return device data ID. what the ID means varies between backends.
|
||||
*/
|
||||
uint64_t deviceId() const {
|
||||
return mBuffer.device;
|
||||
}
|
||||
|
||||
public:
|
||||
int dimensions() const {
|
||||
return mBuffer.dimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get all dimensions' extent.
|
||||
* @return dimensions' extent.
|
||||
*/
|
||||
std::vector<int> shape() const;
|
||||
|
||||
/**
|
||||
* @brief calculate number of bytes needed to store data taking reordering flag into account.
|
||||
* @return bytes needed to store data
|
||||
*/
|
||||
int size() const;
|
||||
|
||||
/**
|
||||
* @brief calculate number of elements needed to store data taking reordering flag into account.
|
||||
* @return elements needed to store data
|
||||
*/
|
||||
inline int elementSize() const {
|
||||
return size() / mBuffer.type.bytes();
|
||||
}
|
||||
|
||||
public:
|
||||
inline int width() const {
|
||||
if (getDimensionType() == TENSORFLOW) {
|
||||
return mBuffer.dim[2].extent;
|
||||
}
|
||||
|
||||
return mBuffer.dim[3].extent;
|
||||
}
|
||||
inline int height() const {
|
||||
if (getDimensionType() == TENSORFLOW) {
|
||||
return mBuffer.dim[1].extent;
|
||||
}
|
||||
return mBuffer.dim[2].extent;
|
||||
}
|
||||
inline int channel() const {
|
||||
if (getDimensionType() == TENSORFLOW) {
|
||||
return mBuffer.dim[3].extent;
|
||||
}
|
||||
return mBuffer.dim[1].extent;
|
||||
}
|
||||
inline int batch() const {
|
||||
return mBuffer.dim[0].extent;
|
||||
}
|
||||
|
||||
// visit dimension's extent & stride
|
||||
inline int stride(int index) const {
|
||||
return mBuffer.dim[index].stride;
|
||||
}
|
||||
inline int length(int index) const {
|
||||
return mBuffer.dim[index].extent;
|
||||
}
|
||||
inline void setStride(int index, int stride) {
|
||||
mBuffer.dim[index].stride = stride;
|
||||
}
|
||||
inline void setLength(int index, int length) {
|
||||
mBuffer.dim[index].extent = length;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief print tensor data. for DEBUG use only.
|
||||
*/
|
||||
void print() const;
|
||||
|
||||
/**
|
||||
*@brief print tensor shape
|
||||
*/
|
||||
void printShape() const;
|
||||
|
||||
private:
|
||||
halide_buffer_t mBuffer;
|
||||
struct InsideDescribe* mDescribe;
|
||||
|
||||
private:
|
||||
friend class TensorUtils;
|
||||
};
|
||||
} // namespace MNN
|
||||
|
||||
#endif /* Tensor_hpp */
|
||||
72
3rd/win/mnn/include/MNN/expr/Executor.hpp
Normal file
72
3rd/win/mnn/include/MNN/expr/Executor.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// Executor.hpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2019/07/25.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
#ifndef Executor_hpp
|
||||
#define Executor_hpp
|
||||
#include <MNN/ErrorCode.hpp>
|
||||
#include <MNN/expr/Expr.hpp>
|
||||
#include <MNN/Tensor.hpp>
|
||||
#include <MNN/Interpreter.hpp>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <MNN/MNNForwardType.h>
|
||||
namespace MNN {
|
||||
class Backend;
|
||||
class Execution;
|
||||
class Runtime;
|
||||
struct Op;
|
||||
namespace Express {
|
||||
class MNN_PUBLIC Executor {
|
||||
public:
|
||||
class ComputeCache;
|
||||
struct Unit;
|
||||
static void setShapeDirty(ComputeCache* cache);
|
||||
static void setContentDirty(ComputeCache* cache);
|
||||
static void* mapOutput(ComputeCache* cache, int offset, Tensor* dest);
|
||||
struct Requirement {
|
||||
std::vector<bool> contentNeedContent;
|
||||
std::vector<bool> shapeNeedContent;
|
||||
};
|
||||
~Executor();
|
||||
Requirement getRequirement(Expr* expr) const;
|
||||
ErrorCode computeInfo(Expr* expr);
|
||||
void makeCache(const std::vector<EXPRP>& expr, bool forceCPU = false);
|
||||
ErrorCode runCache(std::shared_ptr<ComputeCache> cache);
|
||||
void setGlobalExecutorConfig(MNNForwardType type, const BackendConfig& config, int numberThread);
|
||||
enum GCFlag {
|
||||
FULL,
|
||||
PART
|
||||
};
|
||||
void gc(GCFlag flag = FULL);
|
||||
static std::shared_ptr<Executor> getGlobalExecutor();
|
||||
|
||||
static std::shared_ptr<Executor> newExecutor(MNNForwardType type,
|
||||
const BackendConfig& config,
|
||||
int numberThread);
|
||||
void resetProfile();
|
||||
void dumpProfile();
|
||||
void addOpCostTime(int op, float costTime);
|
||||
void addOpCostTime(const std::string& type, float costTime);
|
||||
void addOpFlops(const std::string& type, float flops);
|
||||
class Profiler;
|
||||
static RuntimeInfo getRuntime();
|
||||
private:
|
||||
void _makeCache(const std::vector<EXPRP>& outputs, bool forceCPU);
|
||||
void _create(const std::vector<EXPRP>& outputs, std::set<std::shared_ptr<Executor::ComputeCache>>&& inputCaches, std::set<std::shared_ptr<Expr::Inside>>&& inputNode, bool forceCPU);
|
||||
|
||||
void _visit(EXPRP expr, std::set<std::shared_ptr<Executor::ComputeCache>>& inputCaches, std::set<std::shared_ptr<Expr::Inside>>& inputNode);
|
||||
|
||||
Executor(std::shared_ptr<Runtime> backend, MNNForwardType type);
|
||||
std::pair<std::shared_ptr<Runtime>, MNNForwardType> mRuntime;
|
||||
std::pair<std::shared_ptr<Runtime>, MNNForwardType> mBackupRuntime;
|
||||
std::mutex mMutex;
|
||||
std::shared_ptr<Profiler> mProfiler;
|
||||
};
|
||||
} // namespace Express
|
||||
} // namespace MNN
|
||||
#endif
|
||||
264
3rd/win/mnn/include/MNN/expr/Expr.hpp
Normal file
264
3rd/win/mnn/include/MNN/expr/Expr.hpp
Normal file
@@ -0,0 +1,264 @@
|
||||
//
|
||||
// Expr.hpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2019/06/10.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#ifndef Expr_hpp
|
||||
#define Expr_hpp
|
||||
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <MNN/HalideRuntime.h>
|
||||
#include <MNN/MNNDefine.h>
|
||||
|
||||
namespace MNN {
|
||||
struct OpT;
|
||||
struct Op;
|
||||
struct NetT;
|
||||
namespace Express {
|
||||
class Variable;
|
||||
class Expr;
|
||||
class Executor;
|
||||
typedef std::shared_ptr<Expr> EXPRP;
|
||||
typedef std::weak_ptr<Expr> WeakEXPRP;
|
||||
typedef std::vector<int> INTS;
|
||||
enum Dimensionformat { NHWC, NC4HW4, NCHW };
|
||||
class MNN_PUBLIC VARP {
|
||||
public:
|
||||
VARP() {
|
||||
// Do nothing
|
||||
}
|
||||
VARP(std::shared_ptr<Variable> c) {
|
||||
mContent = std::move(c);
|
||||
}
|
||||
VARP(Variable* c) {
|
||||
mContent.reset(c);
|
||||
}
|
||||
Variable* get() const {
|
||||
return mContent.get();
|
||||
}
|
||||
~ VARP() {
|
||||
// Do nothing
|
||||
}
|
||||
VARP(const VARP& var) {
|
||||
mContent = var.mContent;
|
||||
}
|
||||
VARP(VARP&& var) {
|
||||
mContent = std::move(var.mContent);
|
||||
}
|
||||
VARP operator+(VARP var) const;
|
||||
VARP operator-(VARP var) const;
|
||||
VARP operator*(VARP var) const;
|
||||
VARP operator/(VARP var) const;
|
||||
VARP mean(INTS dims) const;
|
||||
VARP sum(INTS dims) const;
|
||||
|
||||
bool operator==(const VARP& var) const {
|
||||
return var.mContent == mContent;
|
||||
}
|
||||
bool operator<(const VARP& var) const {
|
||||
return mContent < var.mContent;
|
||||
}
|
||||
bool operator<=(const VARP& var) const {
|
||||
return mContent <= var.mContent;
|
||||
}
|
||||
VARP& operator=(const VARP& var) {
|
||||
mContent = var.mContent;
|
||||
return *this;
|
||||
}
|
||||
VARP& operator=(Variable* var) {
|
||||
mContent.reset(var);
|
||||
return *this;
|
||||
}
|
||||
Variable* operator->() const {
|
||||
return mContent.get();
|
||||
}
|
||||
enum InputType {
|
||||
INPUT = 0,
|
||||
CONSTANT = 1,
|
||||
TRAINABLE = 2,
|
||||
};
|
||||
bool fix(InputType type) const;
|
||||
private:
|
||||
friend class Variable;
|
||||
std::shared_ptr<Variable> mContent;
|
||||
};
|
||||
inline bool operator==(Variable* src, VARP dst) {
|
||||
return src == dst.get();
|
||||
}
|
||||
inline bool operator!=(Variable* src, VARP dst) {
|
||||
return src != dst.get();
|
||||
}
|
||||
// inline bool operator<(VARP src, VARP dst) {
|
||||
// return src.get() < dst.get();
|
||||
// }
|
||||
typedef std::vector<VARP> VARPS;
|
||||
|
||||
class MNN_PUBLIC Variable {
|
||||
public:
|
||||
struct Info {
|
||||
Dimensionformat order = NHWC;
|
||||
INTS dim;
|
||||
halide_type_t type;
|
||||
int size;
|
||||
void syncSize();
|
||||
};
|
||||
const std::string& name() const;
|
||||
void setName(const std::string& name);
|
||||
std::pair<EXPRP, int> expr() const {
|
||||
return std::make_pair(mFrom, mFromIndex);
|
||||
}
|
||||
// If compute info error, return nullptr
|
||||
const Info* getInfo();
|
||||
bool resize(INTS dims);
|
||||
template <typename T>
|
||||
const T* readMap() {
|
||||
return (const T*)readInternal();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* writeMap() {
|
||||
return (T*)writeInternal();
|
||||
}
|
||||
|
||||
//Depecerate
|
||||
void unMap();
|
||||
|
||||
bool input(VARP src);
|
||||
static void replace(VARP dst, VARP src);
|
||||
|
||||
static VARP create(EXPRP expr, int index = 0);
|
||||
|
||||
static std::vector<VARP> load(const char* fileName);
|
||||
static std::map<std::string, VARP> loadMap(const char* fileName);
|
||||
static std::vector<VARP> load(const uint8_t* buffer, size_t length);
|
||||
static std::map<std::string, VARP> loadMap(const uint8_t* buffer, size_t length);
|
||||
static std::pair<std::map<std::string, VARP>, std::map<std::string, VARP>> getInputAndOutput(const std::map<std::string, VARP>& allVariable);
|
||||
static std::vector<VARP> mapToSequence(const std::map<std::string, VARP>& source);
|
||||
static std::vector<EXPRP> getExecuteOrder(const std::vector<VARP>& output);
|
||||
static void save(const std::vector<VARP>& vars, const char* fileName);
|
||||
static void save(const std::vector<VARP>& vars, NetT* dest);
|
||||
|
||||
// Pack a few Variable to compute in one pipeline
|
||||
static void prepareCompute(const std::vector<VARP>& vars, bool forceCPU = false);
|
||||
|
||||
size_t linkNumber() const;
|
||||
const std::vector<WeakEXPRP>& toExprs() const;
|
||||
void setExpr(EXPRP expr, int index) {
|
||||
mFrom = expr;
|
||||
mFromIndex = index;
|
||||
}
|
||||
private:
|
||||
Variable(EXPRP expr, int index) {
|
||||
mFrom = expr;
|
||||
mFromIndex = index;
|
||||
}
|
||||
|
||||
void* readInternal(bool forShape = false);
|
||||
void* writeInternal(bool inform=true);
|
||||
void informDirty();
|
||||
|
||||
friend class Expr;
|
||||
EXPRP mFrom;
|
||||
int mFromIndex;
|
||||
};
|
||||
|
||||
class MNN_PUBLIC Expr {
|
||||
public:
|
||||
struct Inside;
|
||||
static EXPRP create(Variable::Info&& info, const void* ptr, VARP::InputType type, bool copy = true);
|
||||
static EXPRP create(const OpT* op, std::vector<VARP> inputs, int outputSize = 1);
|
||||
static EXPRP create(std::pair<std::shared_ptr<char>, int> extra, std::vector<VARP>&& inputs, int outputSize = 1);
|
||||
static EXPRP create(std::unique_ptr<OpT>&& op, std::vector<VARP> inputs, int outputSize = 1) {
|
||||
return create(op.get(), inputs, outputSize);
|
||||
}
|
||||
void setName(const std::string& name);
|
||||
|
||||
const Op* get() const {
|
||||
return mOp;
|
||||
}
|
||||
const std::vector<VARP>& inputs() const {
|
||||
return mInputs;
|
||||
}
|
||||
int outputSize() const {
|
||||
return (int)mOutputNames.size();
|
||||
}
|
||||
static void replace(EXPRP oldExpr, EXPRP newExpr);
|
||||
bool requireInfo();
|
||||
void visitOutputs(const std::function<bool(EXPRP, int)>& visit);
|
||||
static void visit(EXPRP expr, const std::function<bool(EXPRP)>& before, const std::function<bool(EXPRP)>& after);
|
||||
|
||||
const std::vector<WeakEXPRP>& outputs() const {
|
||||
return mTo;
|
||||
}
|
||||
~Expr();
|
||||
|
||||
bool visited() const {
|
||||
return mVisited;
|
||||
}
|
||||
void setVisited(bool visited) {
|
||||
mVisited = visited;
|
||||
}
|
||||
const std::string& name() const {
|
||||
return mName;
|
||||
}
|
||||
const std::string& outputName(int index) {
|
||||
return mOutputNames[index];
|
||||
}
|
||||
|
||||
VARP::InputType inputType() const {return mType;}
|
||||
Variable::Info* outputInfo(int index) const;
|
||||
std::pair<std::shared_ptr<char>, int> extra() const {
|
||||
return std::make_pair(mExtraBuffer, mOpBufferSize);
|
||||
}
|
||||
bool setInfoDirty();
|
||||
std::shared_ptr<Inside> inside() const {
|
||||
return mInside;
|
||||
}
|
||||
bool valid() const {
|
||||
return mValid;
|
||||
}
|
||||
|
||||
void setEntry(const std::vector<VARP>& entries) {
|
||||
mEntries = entries;
|
||||
}
|
||||
|
||||
const std::vector<VARP>& getEntry() const {
|
||||
return mEntries;
|
||||
}
|
||||
|
||||
private:
|
||||
static void _addLinkForInputs(EXPRP expr);
|
||||
|
||||
Expr(int outputSize);
|
||||
|
||||
friend class Variable;
|
||||
friend class VARP;
|
||||
VARP::InputType mType;
|
||||
const Op* mOp;
|
||||
std::vector<VARP> mInputs;
|
||||
std::vector<std::string> mOutputNames;
|
||||
|
||||
bool mValid = true;
|
||||
std::shared_ptr<char> mExtraBuffer;
|
||||
int mOpBufferSize = 0;
|
||||
std::string mName;
|
||||
std::shared_ptr<Inside> mInside = nullptr;
|
||||
bool mVisited = false;
|
||||
std::vector<WeakEXPRP> mTo;
|
||||
|
||||
// Only the enter input has entries, and it helps to get info for enter
|
||||
// input expression.
|
||||
std::vector<VARP> mEntries;
|
||||
};
|
||||
} // namespace Express
|
||||
} // namespace MNN
|
||||
|
||||
#endif /* Expr_hpp */
|
||||
16
3rd/win/mnn/include/MNN/expr/ExprCreator.hpp
Normal file
16
3rd/win/mnn/include/MNN/expr/ExprCreator.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// ExprCreator.hpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2019/06/27.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#ifndef ExprCreator_hpp
|
||||
#define ExprCreator_hpp
|
||||
|
||||
#include <MNN/expr/Expr.hpp>
|
||||
#include <MNN/expr/MathOp.hpp>
|
||||
#include <MNN/expr/NeuralNetWorkOp.hpp>
|
||||
|
||||
#endif
|
||||
128
3rd/win/mnn/include/MNN/expr/MathOp.hpp
Normal file
128
3rd/win/mnn/include/MNN/expr/MathOp.hpp
Normal file
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// MathOp.hpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2019/06/27.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#ifndef MathOp_HPP
|
||||
#define MathOp_HPP
|
||||
|
||||
namespace MNN {
|
||||
namespace Express {
|
||||
//BinaryOPs
|
||||
MNN_PUBLIC VARP _Add(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _Subtract(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _Multiply(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _Divide(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _Pow(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _Minimum(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _Maximum(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _BiasAdd(VARP value, VARP bias);
|
||||
MNN_PUBLIC VARP _Greater(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _GreaterEqual(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _Less(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _FloorDiv(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _SquaredDifference(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _Equal(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _LessEqual(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _FloorMod(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _Atan2(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _LogicalOr(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _NotEqual(VARP x, VARP y);
|
||||
|
||||
//UnaryOPs
|
||||
MNN_PUBLIC VARP _Sign(VARP a);
|
||||
MNN_PUBLIC VARP _Abs(VARP x);
|
||||
MNN_PUBLIC VARP _Negative(VARP x);
|
||||
MNN_PUBLIC VARP _Floor(VARP x);
|
||||
MNN_PUBLIC VARP _Round(VARP x);
|
||||
MNN_PUBLIC VARP _Ceil(VARP x);
|
||||
MNN_PUBLIC VARP _Square(VARP x);
|
||||
MNN_PUBLIC VARP _Sqrt(VARP x);
|
||||
MNN_PUBLIC VARP _Rsqrt(VARP x);
|
||||
MNN_PUBLIC VARP _Exp(VARP x);
|
||||
MNN_PUBLIC VARP _Log(VARP x);
|
||||
MNN_PUBLIC VARP _Sin(VARP x);
|
||||
MNN_PUBLIC VARP _Sinh(VARP x);
|
||||
MNN_PUBLIC VARP _Cos(VARP x);
|
||||
MNN_PUBLIC VARP _Cosh(VARP x);
|
||||
MNN_PUBLIC VARP _Tan(VARP x);
|
||||
MNN_PUBLIC VARP _Asin(VARP x);
|
||||
MNN_PUBLIC VARP _Asinh(VARP x);
|
||||
MNN_PUBLIC VARP _Acos(VARP x);
|
||||
MNN_PUBLIC VARP _Acosh(VARP x);
|
||||
MNN_PUBLIC VARP _Atan(VARP x);
|
||||
MNN_PUBLIC VARP _Atanh(VARP x);
|
||||
MNN_PUBLIC VARP _Reciprocal(VARP x);
|
||||
MNN_PUBLIC VARP _Log1p(VARP x);
|
||||
//Only one but not in UnaryOPs
|
||||
MNN_PUBLIC VARP _Tanh(VARP x);
|
||||
MNN_PUBLIC VARP _Sigmoid(VARP x);
|
||||
MNN_PUBLIC VARP _Erf(VARP x);
|
||||
MNN_PUBLIC VARP _Erfc(VARP x);
|
||||
MNN_PUBLIC VARP _Erfinv(VARP x);
|
||||
MNN_PUBLIC VARP _Expm1(VARP x);
|
||||
|
||||
|
||||
//ReduceOPs
|
||||
MNN_PUBLIC VARP _ReduceSum(VARP input_variable, INTS axis = {}, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceMean(VARP input_variable, INTS axis = {}, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceMax(VARP input_variable, INTS axis = {}, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceMin(VARP input_variable, INTS axis = {}, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceProd(VARP input_variable, INTS axis = {}, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceAny(VARP input_variable, INTS axis = {}, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceAll(VARP input_variable, INTS axis = {}, bool keepDims = false);
|
||||
|
||||
MNN_PUBLIC VARP _ReduceSumMutable(VARP input_variable, VARP axis, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceMeanMutable(VARP input_variable, VARP axis, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceMaxMutable(VARP input_variable, VARP axis, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceMinMutable(VARP input_variable, VARP axis, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceProdMutable(VARP input_variable, VARP axis, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceAnyMutable(VARP input_variable, VARP axis, bool keepDims = false);
|
||||
MNN_PUBLIC VARP _ReduceAllMutable(VARP input_variable, VARP axis, bool keepDims = false);
|
||||
|
||||
//EltwiseOPs
|
||||
MNN_PUBLIC VARP _Prod(VARP a, VARP b, std::vector<float> coeff);
|
||||
MNN_PUBLIC VARP _Sum(VARP a, VARP b, std::vector<float> coeff);
|
||||
MNN_PUBLIC VARP _Max(VARP a, VARP b, std::vector<float> coeff);
|
||||
MNN_PUBLIC VARP _Sub(VARP a, VARP b, std::vector<float> coeff);
|
||||
MNN_PUBLIC VARP _EltwiseProdInt8(VARP x, VARP y,
|
||||
std::vector<int8_t> x_weight, std::vector<int32_t> x_bias, std::vector<float> x_scale, std::vector<float> x_tensorScale,
|
||||
std::vector<int8_t> y_weight, std::vector<int32_t> y_bias, std::vector<float> y_scale, std::vector<float> y_tensorScale,
|
||||
std::vector<int8_t> output_weight, std::vector<int32_t> output_bias, std::vector<float> output_scale, std::vector<float> output_tensorScale);
|
||||
MNN_PUBLIC VARP _EltwiseSumInt8(VARP x, VARP y,
|
||||
std::vector<int8_t> x_weight, std::vector<int32_t> x_bias, std::vector<float> x_scale, std::vector<float> x_tensorScale,
|
||||
std::vector<int8_t> y_weight, std::vector<int32_t> y_bias, std::vector<float> y_scale, std::vector<float> y_tensorScale,
|
||||
std::vector<int8_t> output_weight, std::vector<int32_t> output_bias, std::vector<float> output_scale, std::vector<float> output_tensorScale);
|
||||
MNN_PUBLIC VARP _EltwiseSubInt8(VARP x, VARP y,
|
||||
std::vector<int8_t> x_weight, std::vector<int32_t> x_bias, std::vector<float> x_scale, std::vector<float> x_tensorScale,
|
||||
std::vector<int8_t> y_weight, std::vector<int32_t> y_bias, std::vector<float> y_scale, std::vector<float> y_tensorScale,
|
||||
std::vector<int8_t> output_weight, std::vector<int32_t> output_bias, std::vector<float> output_scale, std::vector<float> output_tensorScale);
|
||||
MNN_PUBLIC VARP _EltwiseMaxInt8(VARP x, VARP y,
|
||||
std::vector<int8_t> x_weight, std::vector<int32_t> x_bias, std::vector<float> x_scale, std::vector<float> x_tensorScale,
|
||||
std::vector<int8_t> y_weight, std::vector<int32_t> y_bias, std::vector<float> y_scale, std::vector<float> y_tensorScale,
|
||||
std::vector<int8_t> output_weight, std::vector<int32_t> output_bias, std::vector<float> output_scale, std::vector<float> output_tensorScale);
|
||||
|
||||
|
||||
//OtherOPs
|
||||
template<typename T>
|
||||
VARP _Cast(VARP x) {
|
||||
return _Cast(x, halide_type_of<T>());
|
||||
}
|
||||
MNN_PUBLIC VARP _Cast(VARP x, halide_type_t dtype);
|
||||
MNN_PUBLIC VARP _MatMul(VARP a, VARP b, bool tranposeA = false, bool tranposeB = false);
|
||||
MNN_PUBLIC VARP _Normalize(VARP x, int32_t acrossSpatial, int32_t channelShared, float eps, std::vector<float> scale);
|
||||
MNN_PUBLIC VARP _ArgMax(VARP input, int axis = 0);
|
||||
MNN_PUBLIC VARP _ArgMin(VARP input, int axis = 0);
|
||||
MNN_PUBLIC VARP _BatchMatMul(VARP x, VARP y, bool adj_x = false, bool adj_y = false);
|
||||
MNN_PUBLIC VARP _UnravelIndex(VARP indices, VARP dims);
|
||||
MNN_PUBLIC VARP _ScatterNd(VARP indices, VARP updates, VARP shape);
|
||||
MNN_PUBLIC VARP _OneHot(VARP indices, VARP depth, VARP onValue, VARP offValue, int axis = -1);
|
||||
MNN_PUBLIC VARP _BroadcastTo(VARP a, VARP shape);
|
||||
MNN_PUBLIC VARP _LinSpace(VARP start, VARP stop, VARP num);
|
||||
}; // namespace Express
|
||||
}; // namespace MNN
|
||||
|
||||
#endif /* MathOp_HPP */
|
||||
142
3rd/win/mnn/include/MNN/expr/NeuralNetWorkOp.hpp
Normal file
142
3rd/win/mnn/include/MNN/expr/NeuralNetWorkOp.hpp
Normal file
@@ -0,0 +1,142 @@
|
||||
//
|
||||
// NeuralNetWorkOp.hpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2019/06/27.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#ifndef NeuralNetWorkOp_HPP
|
||||
#define NeuralNetWorkOp_HPP
|
||||
|
||||
namespace MNN {
|
||||
namespace Express {
|
||||
enum PaddingMode {CAFFE, VALID, SAME};
|
||||
enum PoolingMode {MAXPOOL, AVEPOOL};
|
||||
enum PadValueMode {CONSTANT, REFLECT, SYMMETRIC};
|
||||
MNN_PUBLIC VARP _Input(INTS shape = {}, Dimensionformat data_format = NC4HW4, halide_type_t dtype = halide_type_of<float>()) ;
|
||||
MNN_PUBLIC VARP _Clone(VARP source, bool deepCopy = false);
|
||||
|
||||
MNN_PUBLIC VARP _Scalar(const void* ptr, halide_type_t type);
|
||||
|
||||
template <typename T>
|
||||
VARP _Scalar(T value) {
|
||||
return _Scalar(&value, halide_type_of<T>());
|
||||
}
|
||||
|
||||
|
||||
MNN_PUBLIC VARP _Const(float value, INTS shape = {}, Dimensionformat format = NHWC);
|
||||
MNN_PUBLIC VARP _Const(const void* ptr, INTS shape = {}, Dimensionformat format = NHWC,
|
||||
halide_type_t type = halide_type_of<float>());
|
||||
MNN_PUBLIC VARP _TrainableParam(float value, INTS dims, Dimensionformat format);
|
||||
MNN_PUBLIC VARP _TrainableParam(const void* ptr, INTS dims, Dimensionformat format,
|
||||
halide_type_t type = halide_type_of<float>());
|
||||
MNN_PUBLIC VARP _InnerProduct(std::vector<float>&& weight, std::vector<float>&& bias, VARP x, INTS outputShape);
|
||||
MNN_PUBLIC VARP _Conv(VARP weight, VARP bias, VARP x, PaddingMode pad = VALID, INTS stride = {1, 1},
|
||||
INTS dilate = {1, 1}, int group = 1, INTS pads = {0, 0});
|
||||
|
||||
MNN_PUBLIC VARP _Conv(float weight, float bias, VARP x, INTS channel, INTS kernelSize, PaddingMode pad = VALID,
|
||||
INTS stride = {1, 1}, INTS dilate = {1, 1}, int group = 1);
|
||||
MNN_PUBLIC VARP _Conv(std::vector<int8_t>&& weight, std::vector<float>&& bias, VARP x, INTS channel, INTS kernelSize,
|
||||
PaddingMode pad = VALID, INTS stride = {1, 1}, INTS dilate = {1, 1}, int group = 1, INTS pads = {0, 0}, bool relu = false, bool relu6 = false, int nbits = 8);
|
||||
MNN_PUBLIC VARP _Conv(std::vector<float>&& weight, std::vector<float>&& bias, VARP x, INTS channel, INTS kernelSize,
|
||||
PaddingMode pad = VALID, INTS stride = {1, 1}, INTS dilate = {1, 1}, int group = 1, INTS pads = {0, 0}, bool relu = false, bool relu6 = false);
|
||||
MNN_PUBLIC VARP _Deconv(VARP weight, VARP bias, VARP x, PaddingMode pad = VALID, INTS stride = {1, 1},
|
||||
INTS dilate = {1, 1}, int group = 1, INTS pads = {0, 0});
|
||||
|
||||
MNN_PUBLIC VARP _Deconv(std::vector<float>&& weight, std::vector<float>&& bias, VARP x, INTS channel, INTS kernelSize,
|
||||
PaddingMode pad, INTS stride = {1, 1}, INTS dilate = {1, 1}, int group = 1, INTS pads = {0, 0}, bool relu = false, bool relu6 = false);
|
||||
|
||||
MNN_PUBLIC VARP _MaxPool(VARP x, INTS kernel, INTS stride = {1, 1}, PaddingMode pad = VALID, INTS pads= {0, 0});
|
||||
MNN_PUBLIC VARP _AvePool(VARP x, INTS kernel, INTS stride = {1, 1}, PaddingMode pad = VALID, INTS pads= {0, 0});
|
||||
MNN_PUBLIC VARP _Reshape(VARP x, INTS shape, Dimensionformat original_format = NCHW);
|
||||
MNN_PUBLIC VARP _Reshape(VARP x, VARP shape);
|
||||
MNN_PUBLIC VARP _Scale(VARP x, int channels, std::vector<float>&& scales, std::vector<float>&& bias);
|
||||
|
||||
MNN_PUBLIC VARP _Relu(VARP x, float slope = 0.0f);
|
||||
MNN_PUBLIC VARP _Relu6(VARP x, float minValue = 0.0f, float maxValue = 6.0f);
|
||||
MNN_PUBLIC VARP _PRelu(VARP x, std::vector<float> &&slopes);
|
||||
MNN_PUBLIC VARP _Softmax(VARP logits, int axis = -1);
|
||||
MNN_PUBLIC VARP _Softplus(VARP features);
|
||||
MNN_PUBLIC VARP _Softsign(VARP features);
|
||||
MNN_PUBLIC std::vector<VARP> _Split(VARP value, INTS size_splits, int axis = 0);
|
||||
MNN_PUBLIC VARP _Slice(VARP x, VARP starts, VARP sizes);
|
||||
MNN_PUBLIC VARP _StridedSlice(VARP input, VARP begin, VARP end, VARP strided,
|
||||
int32_t beginMask, int32_t endMask, int32_t ellipsisMask,
|
||||
int32_t newAxisMask, int32_t shrinkAxisMask);
|
||||
MNN_PUBLIC VARP _Concat(VARPS values, int axis);
|
||||
MNN_PUBLIC VARP _Convert(VARP input, Dimensionformat format);
|
||||
MNN_PUBLIC VARP _Transpose(VARP x, INTS perm);
|
||||
MNN_PUBLIC VARP _Transpose(VARP x, VARP perm);
|
||||
MNN_PUBLIC VARP _ChannelShuffle(VARP x, int group);
|
||||
MNN_PUBLIC VARP _ChangeInputFormat(VARP input, Dimensionformat format);
|
||||
MNN_PUBLIC VARP _Conv2DBackPropFilter(VARP input, VARP inputGrad, INTS kernelSize, PaddingMode pad = VALID, INTS stride = {1, 1}, INTS dilate = {1, 1}, int group = 1, INTS pads = {0, 0});
|
||||
MNN_PUBLIC VARP _PoolGrad(VARP originInput, VARP originOutput, VARP inputGrad, INTS kernel, INTS stride, PoolingMode type, PaddingMode pad = VALID, INTS pads= {0, 0});
|
||||
// FIXME: move the api to Array Ops
|
||||
MNN_PUBLIC VARP _ReverseSequence(VARP x, VARP y, int batchDim, int seqDim);
|
||||
// FIXME: move the api to Image Ops
|
||||
MNN_PUBLIC VARP _Crop(VARP images, VARP size, int axis, INTS offset);
|
||||
MNN_PUBLIC VARP _Resize(VARP images, float xScale, float yScale);
|
||||
MNN_PUBLIC VARP _Pad(VARP x, VARP paddings, PadValueMode mode = CONSTANT);
|
||||
MNN_PUBLIC VARP _ExpandDims(VARP input, int axis);
|
||||
MNN_PUBLIC VARP _ExpandDims(VARP input, VARP axis);
|
||||
|
||||
MNN_PUBLIC VARP _Shape(VARP input, bool nchw = false);
|
||||
MNN_PUBLIC VARP _Stack(VARPS values, int axis=0);
|
||||
enum InterpolationMethod {BILINEAR, NEAREST};
|
||||
MNN_PUBLIC VARP _CropAndResize(VARP image, VARP boxes, VARP box_ind, VARP crop_size,
|
||||
InterpolationMethod method, float extrapolation_value = 0.0);
|
||||
MNN_PUBLIC VARP _Fill(VARP dims, VARP value);
|
||||
MNN_PUBLIC VARP _Tile(VARP input, VARP multiples);
|
||||
MNN_PUBLIC VARP _Gather(VARP params, VARP indices);
|
||||
MNN_PUBLIC VARP _GatherV2(VARP params, VARP indices, VARP axis = nullptr);
|
||||
MNN_PUBLIC VARP _Squeeze(VARP input, INTS axis = {});
|
||||
MNN_PUBLIC VARP _Unsqueeze(VARP input, INTS axis = {});
|
||||
MNN_PUBLIC VARP _BatchToSpaceND(VARP input, VARP block_shape, VARP crops);
|
||||
MNN_PUBLIC VARP _GatherND(VARP params, VARP indices);
|
||||
MNN_PUBLIC VARP _Selu(VARP features, float scale, float alpha);
|
||||
MNN_PUBLIC VARP _Size(VARP input);
|
||||
MNN_PUBLIC VARP _Elu(VARP features, float alpha=1.0);
|
||||
MNN_PUBLIC VARP _Threshold(VARP features, float alpha=1.0);
|
||||
MNN_PUBLIC VARP _MatrixBandPart(VARP input, VARP num_lower, VARP num_upper);
|
||||
MNN_PUBLIC std::vector<VARP> _Moments(VARP x, INTS axis, VARP shift, bool keepDims);
|
||||
MNN_PUBLIC VARP _SetDiff1D(VARP x, VARP y);
|
||||
MNN_PUBLIC VARP _SpaceToDepth(VARP input, int block_size);
|
||||
MNN_PUBLIC VARP _SpaceToBatchND(VARP input, VARP block_shape, VARP paddings);
|
||||
MNN_PUBLIC VARP _ZerosLike(VARP input);
|
||||
MNN_PUBLIC std::vector<VARP> _Unstack(VARP value, int axis=0);
|
||||
MNN_PUBLIC VARP _Rank(VARP input);
|
||||
MNN_PUBLIC VARP _Range(VARP start, VARP limit, VARP delta);
|
||||
MNN_PUBLIC VARP _DepthToSpace(VARP input, int block_size);
|
||||
MNN_PUBLIC VARP _PriorBox(VARP feature, VARP image,
|
||||
std::vector<float> min_size, std::vector<float> max_size, std::vector<float>aspect_ratio,
|
||||
bool flip, bool clip, std::vector<float>variance,
|
||||
unsigned int img_h, unsigned int img_w, float step_h, float step_w, float offset = 0.5);
|
||||
MNN_PUBLIC VARP _Permute(VARP input, INTS dims);
|
||||
MNN_PUBLIC VARP _DetectionOutput(VARP location, VARP confidence, VARP priorbox,
|
||||
unsigned int num_classes, bool share_location, int background_label_id,
|
||||
float nms_threshhold, int nms_topk, int code_type,
|
||||
bool variance_encoded_in_target,
|
||||
int keep_top_k, float confidence_threshold, float visualize_threshold);
|
||||
MNN_PUBLIC std::vector<VARP> _DetectionPostProcess(VARP encode_boxes, VARP class_predictions, VARP anchors,
|
||||
int num_classes, int max_detections,
|
||||
int max_class_per_detection, int detections_per_class,
|
||||
float nms_threshold, float iou_threshold,
|
||||
bool use_regular_nms, std::vector<float> centersize_encoding);
|
||||
MNN_PUBLIC VARP _Interp(VARPS xs, float widthScale, float heightScale, int outputWidth, int outputHeight, int resizeType, bool alignCorners);
|
||||
|
||||
MNN_PUBLIC VARP _ZeroGrad(VARP x);
|
||||
|
||||
// Int8 Inference
|
||||
MNN_PUBLIC VARP _Conv(std::vector<int8_t>&& weight, std::vector<int>&& bias, std::vector<float>&& scale, VARP x, INTS channel, INTS kernelSize,
|
||||
PaddingMode pad, INTS stride, INTS dilate, int group, INTS pads, bool relu, int nbits = 8);
|
||||
MNN_PUBLIC VARP _CosineSimilarity(VARP input0, VARP input1, VARP inputDim);
|
||||
MNN_PUBLIC VARP _FloatToInt8(VARP x, VARP scale, char minValue, char maxValue);
|
||||
MNN_PUBLIC VARP _Int8ToFloat(VARP x, VARP scale);
|
||||
|
||||
MNN_PUBLIC VARP _Select(VARP select, VARP input0, VARP input1);
|
||||
|
||||
} // namespace Express
|
||||
} // namespace MNN
|
||||
|
||||
#endif /* NeuralNetWorkOp_HPP */
|
||||
64
3rd/win/mnn/include/MNN/expr/Optimizer.hpp
Normal file
64
3rd/win/mnn/include/MNN/expr/Optimizer.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// Optimizer.hpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2019/08/20.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
#ifndef Optimizer_hpp
|
||||
#define Optimizer_hpp
|
||||
#include <MNN/expr/Expr.hpp>
|
||||
#include <MNN/MNNForwardType.h>
|
||||
|
||||
namespace MNN {
|
||||
namespace Express {
|
||||
class MNN_PUBLIC Optimizer {
|
||||
public:
|
||||
enum Device {
|
||||
CPU = 0,
|
||||
GPU = 1,
|
||||
OTHER = 2,
|
||||
AUTO = 3
|
||||
};
|
||||
struct Config {
|
||||
Device device = CPU;
|
||||
MNNForwardType forwardType = MNN_FORWARD_ALL;
|
||||
int numThread = 4;
|
||||
};
|
||||
static std::shared_ptr<Optimizer> create(Config config);
|
||||
struct Cost {
|
||||
float compute; // MFlops
|
||||
float memory; // MB
|
||||
};
|
||||
class Parameters {
|
||||
public:
|
||||
Parameters(int n);
|
||||
virtual ~Parameters();
|
||||
|
||||
float* get() const {
|
||||
return mValue;
|
||||
}
|
||||
int size() const {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
private:
|
||||
float* mValue;
|
||||
int mSize;
|
||||
};
|
||||
virtual std::shared_ptr<Parameters> onGetParameters(const std::vector<VARP>& outputs) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//Given paramters and measure cost, the parameters must be the same as onGetParameters
|
||||
virtual Cost onMeasure(const std::vector<VARP>& outputs, std::shared_ptr<Parameters> parameters = nullptr) = 0;
|
||||
|
||||
//Modify the output directly, the parameters must be the same as onGetParameters
|
||||
virtual bool onExecute(const std::vector<VARP>& outputs, std::shared_ptr<Parameters> parameters = nullptr) = 0;
|
||||
|
||||
Optimizer() = default;
|
||||
virtual ~Optimizer() = default;
|
||||
};
|
||||
} // namespace Express
|
||||
} // namespace MNN
|
||||
#endif
|
||||
BIN
3rd/win/mnn/x64/MNN.lib
Normal file
BIN
3rd/win/mnn/x64/MNN.lib
Normal file
Binary file not shown.
@@ -11,7 +11,10 @@ endif()
|
||||
# 根据 platform 值设置 CMake 变量
|
||||
if(${CMAKE_BUILD_PLATFORM} STREQUAL "win")
|
||||
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/3rd/win/opencv/x64/vc15/lib)
|
||||
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/3rd/win/mnn/x64/)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/3rd/win/opencv/include)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/3rd/win/mnn/include)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/models)
|
||||
else()
|
||||
message(FATAL_ERROR "不支持的平台: ${CMAKE_BUILD_PLATFORM}")
|
||||
endif()
|
||||
@@ -19,13 +22,18 @@ endif()
|
||||
include_directories(src)
|
||||
|
||||
aux_source_directory(./src DIR_SRCS)
|
||||
aux_source_directory(./src/util DIR_SRCS)
|
||||
aux_source_directory(./app DIR_SRCS)
|
||||
|
||||
|
||||
add_executable(Demo ${DIR_SRCS})
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_link_libraries(${PROJECT_NAME} opencv_world430d)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE /MTd)
|
||||
target_link_libraries(${PROJECT_NAME} opencv_world430d)
|
||||
target_link_libraries(${PROJECT_NAME} MNN)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} opencv_world430)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE /MT)
|
||||
target_link_libraries(${PROJECT_NAME} opencv_world430)
|
||||
target_link_libraries(${PROJECT_NAME} MNN)
|
||||
endif()
|
||||
|
||||
23
app/main.cpp
23
app/main.cpp
@@ -1,6 +1,27 @@
|
||||
#include <iostream>
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include "util/TimeCount.h"
|
||||
#include "CenterFaceMnn.h"
|
||||
|
||||
int32_t main(int32_t argc, char** argv) {
|
||||
std::cout << "Hello, World!" << std::endl;
|
||||
CenterFaceMnn::GetInstance();
|
||||
std::vector<FaceInfo> faces;
|
||||
cv::Mat img = cv::imread("F:/33.jpg");
|
||||
int32_t count = 0;
|
||||
re_test:
|
||||
count++;
|
||||
{
|
||||
USE_TIME t(USE_TIME_US, "face_detect: ");
|
||||
CenterFaceMnn::GetInstance()->Detect(img, faces, 1);
|
||||
}
|
||||
if (count < 10) {
|
||||
goto re_test;
|
||||
}
|
||||
|
||||
for(auto& face : faces) {
|
||||
cv::rectangle(img, cv::Rect(face.x1, face.y1, face.x2 - face.x1, face.y2 - face.y1), cv::Scalar(0, 0, 255), 2);
|
||||
}
|
||||
cv::imshow("test", img);
|
||||
cv::waitKey(0);
|
||||
return 0;
|
||||
}
|
||||
@@ -42,6 +42,6 @@ Write-Host "build done." -ForegroundColor Darkgreen
|
||||
|
||||
if($build_and_run -eq "true"){
|
||||
Write-Host "################## APP Run ##################" -ForegroundColor Blue
|
||||
$env:PATH += ";3rd\win\opencv\x64\vc15\bin"
|
||||
$env:PATH += ";3rd\win\opencv\x64\vc15\bin;3rd\win\mnn\x64\"
|
||||
Start-Process -FilePath "build\\${build_type}\\Demo.exe"
|
||||
}
|
||||
|
||||
BIN
models/3ddfa.onnx
Normal file
BIN
models/3ddfa.onnx
Normal file
Binary file not shown.
1
models/IRLiveness_mnn.dat
Normal file
1
models/IRLiveness_mnn.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/IRLiveness_mnn1.dat
Normal file
1
models/IRLiveness_mnn1.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/IRLiveness_onnx_v0.16.dat
Normal file
1
models/IRLiveness_onnx_v0.16.dat
Normal file
File diff suppressed because one or more lines are too long
BIN
models/IRLiveness_v0.16.onnx
Normal file
BIN
models/IRLiveness_v0.16.onnx
Normal file
Binary file not shown.
BIN
models/MobileFace/MobileFaceLargeQuality_v6.1.mnn
Normal file
BIN
models/MobileFace/MobileFaceLargeQuality_v6.1.mnn
Normal file
Binary file not shown.
BIN
models/MobileFace/MobileFaceLargeQuality_v6.1.onnx
Normal file
BIN
models/MobileFace/MobileFaceLargeQuality_v6.1.onnx
Normal file
Binary file not shown.
BIN
models/MobileFace/MobileFaceLarge_v6.1.onnx
Normal file
BIN
models/MobileFace/MobileFaceLarge_v6.1.onnx
Normal file
Binary file not shown.
BIN
models/MobileFace/MobileFaceNet_v6.6.4.mnn
Normal file
BIN
models/MobileFace/MobileFaceNet_v6.6.4.mnn
Normal file
Binary file not shown.
BIN
models/MobileFace/MobileFaceNet_v6.6.4.onnx
Normal file
BIN
models/MobileFace/MobileFaceNet_v6.6.4.onnx
Normal file
Binary file not shown.
1
models/MobileFace/mnn_v6.64/mobile_face_mnn_v6.64_p1.dat
Normal file
1
models/MobileFace/mnn_v6.64/mobile_face_mnn_v6.64_p1.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/MobileFace/mnn_v6.64/mobile_face_mnn_v6.64_p2.dat
Normal file
1
models/MobileFace/mnn_v6.64/mobile_face_mnn_v6.64_p2.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/MobileFace/mnn_v6.64/mobile_face_mnn_v6.64_p3.dat
Normal file
1
models/MobileFace/mnn_v6.64/mobile_face_mnn_v6.64_p3.dat
Normal file
File diff suppressed because one or more lines are too long
BIN
models/RGBLiveness.onnx
Normal file
BIN
models/RGBLiveness.onnx
Normal file
Binary file not shown.
1
models/RGBLiveness_mnn.dat
Normal file
1
models/RGBLiveness_mnn.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/RGBLiveness_mnn_v1.42.dat
Normal file
1
models/RGBLiveness_mnn_v1.42.dat
Normal file
File diff suppressed because one or more lines are too long
BIN
models/backpack/deepcam_mask_v1.1.mnn
Normal file
BIN
models/backpack/deepcam_mask_v1.1.mnn
Normal file
Binary file not shown.
BIN
models/backpack/deepcam_mask_v1.1.onnx
Normal file
BIN
models/backpack/deepcam_mask_v1.1.onnx
Normal file
Binary file not shown.
1
models/centerface_small_mnn.dat
Normal file
1
models/centerface_small_mnn.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/centerface_tiny_mnn.dat
Normal file
1
models/centerface_tiny_mnn.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/deepcam_mask_v1.1_mnn.dat
Normal file
1
models/deepcam_mask_v1.1_mnn.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/landmark68.dat
Normal file
1
models/landmark68.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/mobile_face_dnn_p0.dat
Normal file
1
models/mobile_face_dnn_p0.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/mobile_face_dnn_p1.dat
Normal file
1
models/mobile_face_dnn_p1.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/mobile_face_dnn_p2.dat
Normal file
1
models/mobile_face_dnn_p2.dat
Normal file
File diff suppressed because one or more lines are too long
1
models/pose_onnx.dat
Normal file
1
models/pose_onnx.dat
Normal file
File diff suppressed because one or more lines are too long
235
src/CenterFaceMnn.cpp
Normal file
235
src/CenterFaceMnn.cpp
Normal file
@@ -0,0 +1,235 @@
|
||||
#include "CenterFaceMnn.h"
|
||||
|
||||
CenterFaceMnn* CenterFaceMnn::m_hInstance = nullptr;
|
||||
|
||||
static const unsigned char centerface_model[] = {
|
||||
#include "centerface_small_mnn.dat"
|
||||
};
|
||||
|
||||
CenterFaceMnn* CenterFaceMnn::GetInstance(){
|
||||
if (!m_hInstance){
|
||||
m_hInstance = new CenterFaceMnn();
|
||||
}
|
||||
return m_hInstance;
|
||||
}
|
||||
|
||||
CenterFaceMnn::CenterFaceMnn(){
|
||||
m_detector = std::shared_ptr<MNN::Interpreter>(MNN::Interpreter::createFromBuffer(centerface_model, sizeof(centerface_model)));
|
||||
|
||||
MNN::ScheduleConfig config;
|
||||
MNN::BackendConfig backendConfig;
|
||||
backendConfig.precision = MNN::BackendConfig::Precision_High;
|
||||
backendConfig.power = MNN::BackendConfig::Power_High;
|
||||
backendConfig.memory = MNN::BackendConfig::Memory_High;
|
||||
config.backendConfig = &backendConfig;
|
||||
config.type = MNN_FORWARD_CPU;
|
||||
config.numThread = 4;
|
||||
m_session = m_detector->createSession(config);
|
||||
|
||||
const float mean_vals[3] = { 127.5f, 127.5f, 127.5f };
|
||||
const float norm_vals[3] = { 0.0078431373f, 0.0078431373f, 0.0078431373f };
|
||||
::memcpy(m_img_config.mean, mean_vals, sizeof(mean_vals));
|
||||
::memcpy(m_img_config.normal, norm_vals, sizeof(norm_vals));
|
||||
m_img_config.sourceFormat = (MNN::CV::ImageFormat)2;
|
||||
m_img_config.destFormat = (MNN::CV::ImageFormat)1;
|
||||
m_img_config.filterType = (MNN::CV::Filter)(1);
|
||||
m_img_config.wrap = (MNN::CV::Wrap)(1);
|
||||
|
||||
input_tensor = m_detector->getSessionInput(m_session, NULL);
|
||||
hm_tensor = m_detector->getSessionOutput(m_session, "hm");
|
||||
wh_tensor = m_detector->getSessionOutput(m_session, "wh");
|
||||
reg_tensor = m_detector->getSessionOutput(m_session, "reg");
|
||||
lm_tensor = m_detector->getSessionOutput(m_session, "lm");
|
||||
}
|
||||
|
||||
CenterFaceMnn::~CenterFaceMnn(){
|
||||
m_detector->releaseSession(m_session);
|
||||
}
|
||||
|
||||
int CenterFaceMnn::Detect(const cv::Mat& img, std::vector<FaceInfo>& faces, float scale){
|
||||
std::lock_guard<std::mutex> lock(m_mt);
|
||||
faces.clear();
|
||||
if (img.cols * img.rows == 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (scale <= 0 || scale > 1) {
|
||||
scale = img.cols > img.rows ? 160.0f / img.cols : 160.0f / img.rows;
|
||||
}
|
||||
int resize_w = (int)(img.cols * scale) / 32 * 32;
|
||||
int resize_h = (int)(img.rows * scale) / 32 * 32;
|
||||
float scale_w = (float)img.cols / (float)resize_w;
|
||||
float scale_h = (float)img.rows / (float)resize_h;
|
||||
|
||||
|
||||
cv::Mat input;
|
||||
cv::resize(img, input, cv::Size(resize_w, resize_h));
|
||||
m_detector->resizeTensor(input_tensor, 1, 3, resize_h, resize_w);
|
||||
m_detector->resizeSession(m_session);
|
||||
//prepare data
|
||||
std::shared_ptr<MNN::CV::ImageProcess> pretreat(MNN::CV::ImageProcess::create(m_img_config));
|
||||
pretreat->convert(input.data, resize_w, resize_h, input.step[0], input_tensor);
|
||||
m_detector->runSession(m_session);
|
||||
|
||||
MNN::Tensor tensor_hm(hm_tensor, MNN::Tensor::CAFFE);
|
||||
MNN::Tensor tensor_wh(wh_tensor, MNN::Tensor::CAFFE);
|
||||
MNN::Tensor tensor_reg(reg_tensor, MNN::Tensor::CAFFE);
|
||||
MNN::Tensor tensor_lm(lm_tensor, MNN::Tensor::CAFFE);
|
||||
|
||||
hm_tensor->copyToHostTensor(&tensor_hm);
|
||||
wh_tensor->copyToHostTensor(&tensor_wh);
|
||||
reg_tensor->copyToHostTensor(&tensor_reg);
|
||||
lm_tensor->copyToHostTensor(&tensor_lm);
|
||||
|
||||
std::vector<int> hm_shape = tensor_hm.shape();
|
||||
|
||||
float* heatmap = tensor_hm.host<float>();
|
||||
float* wh = tensor_wh.host<float>();
|
||||
float* reg = tensor_reg.host<float>();
|
||||
float* lm = tensor_lm.host<float>();
|
||||
|
||||
Decode(heatmap, wh, reg, lm, hm_shape[2], hm_shape[3], faces, 0.4, 0.3);
|
||||
for (int i = 0; i < faces.size(); i++){
|
||||
FaceInfo& tmp = faces[i];
|
||||
tmp.x1 *= scale_w;
|
||||
tmp.x2 *= scale_w;
|
||||
tmp.y1 *= scale_h;
|
||||
tmp.y2 *= scale_h;
|
||||
|
||||
for (int j = 0; j < 5; j++){
|
||||
tmp.landmarks[j * 2] *= scale_w;
|
||||
tmp.landmarks[j * 2 + 1] *= scale_h;
|
||||
}
|
||||
}
|
||||
return faces.size();
|
||||
}
|
||||
#include <omp.h>
|
||||
|
||||
void CenterFaceMnn::Decode(float* heatmap, float* scale, float* offset, float* landmarks, int h, int w, std::vector<FaceInfo>& faces, float scoreThresh, float nmsThresh){
|
||||
int fea_h = h;
|
||||
int fea_w = w;
|
||||
int d_w = w * 4;
|
||||
int d_h = h * 4;
|
||||
int spacial_size = fea_w * fea_h;
|
||||
|
||||
float *scale1 = (float*)(scale);
|
||||
float *scale0 = scale1 + spacial_size;
|
||||
|
||||
float *offset1 = (float*)(offset);
|
||||
float *offset0 = offset1 + spacial_size;
|
||||
|
||||
std::vector<int> ids = GetIds(heatmap, fea_h, fea_w, scoreThresh);
|
||||
|
||||
std::vector<FaceInfo> faces_tmp;
|
||||
#pragma omp parallel for
|
||||
for (int i = 0; i < ids.size() / 2; i++) {
|
||||
int id_h = ids[2 * i];
|
||||
int id_w = ids[2 * i + 1];
|
||||
int index = id_h * fea_w + id_w;
|
||||
|
||||
float s0 = std::exp(scale0[index]) * 4;
|
||||
float s1 = std::exp(scale1[index]) * 4;
|
||||
float o0 = offset0[index];
|
||||
float o1 = offset1[index];
|
||||
|
||||
float x1 = std::max(0., (id_w + o1 + 0.5) * 4 - s1 / 2);
|
||||
float y1 = std::max(0., (id_h + o0 + 0.5) * 4 - s0 / 2);
|
||||
float x2 = std::max(0., (id_w + o1 + 0.5) * 4 + s1 / 2);
|
||||
float y2 = std::max(0., (id_h + o0 + 0.5) * 4 + s0 / 2);
|
||||
x1 = std::min(x1, (float)d_w);
|
||||
y1 = std::min(y1, (float)d_h);
|
||||
x2 = std::min(x2, (float)d_w);
|
||||
y2 = std::min(y2, (float)d_h);
|
||||
|
||||
FaceInfo facebox;
|
||||
facebox.x1 = x1;
|
||||
facebox.y1 = y1;
|
||||
facebox.x2 = x2;
|
||||
facebox.y2 = y2;
|
||||
facebox.score = heatmap[index];
|
||||
|
||||
float box_w = x2 - x1;
|
||||
float box_h = y2 - y1;
|
||||
|
||||
for (int j = 0; j < 5; j++) {
|
||||
float *xmap = (float*)landmarks + (2 * j) * spacial_size;
|
||||
float *ymap = (float*)landmarks + (2 * j + 1) * spacial_size;
|
||||
facebox.landmarks[2 * j] = x1 + xmap[index] * s1;
|
||||
facebox.landmarks[2 * j + 1] = y1 + ymap[index] * s0;
|
||||
}
|
||||
#pragma omp critical
|
||||
{
|
||||
faces_tmp.push_back(facebox);
|
||||
}
|
||||
}
|
||||
NMS(faces_tmp, faces, nmsThresh);
|
||||
}
|
||||
|
||||
void CenterFaceMnn::NMS(std::vector<FaceInfo>& input, std::vector<FaceInfo>& output, float nmsthreshold) {
|
||||
std::sort(input.begin(), input.end(),
|
||||
[](const FaceInfo& a, const FaceInfo& b) {
|
||||
return a.score > b.score;
|
||||
});
|
||||
|
||||
int box_num = input.size();
|
||||
|
||||
std::vector<int> merged(box_num, 0);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int i = 0; i < box_num; i++) {
|
||||
if (merged[i])
|
||||
continue;
|
||||
|
||||
output.push_back(input[i]);
|
||||
|
||||
float h0 = input[i].y2 - input[i].y1 + 1;
|
||||
float w0 = input[i].x2 - input[i].x1 + 1;
|
||||
|
||||
float area0 = h0 * w0;
|
||||
|
||||
for (int j = i + 1; j < box_num; j++) {
|
||||
if (merged[j])
|
||||
continue;
|
||||
|
||||
float inner_x0 = std::max(input[i].x1, input[j].x1);
|
||||
float inner_y0 = std::max(input[i].y1, input[j].y1);
|
||||
|
||||
float inner_x1 = std::min(input[i].x2, input[j].x2);
|
||||
float inner_y1 = std::min(input[i].y2, input[j].y2);
|
||||
|
||||
float inner_h = inner_y1 - inner_y0 + 1;
|
||||
float inner_w = inner_x1 - inner_x0 + 1;
|
||||
|
||||
if (inner_h <= 0 || inner_w <= 0)
|
||||
continue;
|
||||
|
||||
float inner_area = inner_h * inner_w;
|
||||
|
||||
float h1 = input[j].y2 - input[j].y1 + 1;
|
||||
float w1 = input[j].x2 - input[j].x1 + 1;
|
||||
|
||||
float area1 = h1 * w1;
|
||||
|
||||
float score = inner_area / (area0 + area1 - inner_area);
|
||||
|
||||
if (score > nmsthreshold)
|
||||
merged[j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::vector<int> CenterFaceMnn::GetIds(float *heatmap, int h, int w, float thresh){
|
||||
std::vector<int> ids;
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
if (heatmap[i*w + j] > thresh) {
|
||||
ids.push_back(i);
|
||||
ids.push_back(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
const std::string CenterFaceMnn::GetModelVer(){
|
||||
return m_model_ver;
|
||||
}
|
||||
45
src/CenterFaceMnn.h
Normal file
45
src/CenterFaceMnn.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef CENTERFACE_H
|
||||
#define CENTERFACE_H
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <MNN/Interpreter.hpp>
|
||||
#include <MNN/MNNDefine.h>
|
||||
#include <MNN/ImageProcess.hpp>
|
||||
#include <MNN/Tensor.hpp>
|
||||
#include "TypeInfo.h"
|
||||
|
||||
class CenterFaceMnn{
|
||||
public:
|
||||
static CenterFaceMnn* GetInstance();
|
||||
|
||||
int Detect(const cv::Mat& img, std::vector<FaceInfo>& faces, float scale = 0);
|
||||
|
||||
const std::string GetModelVer();
|
||||
private:
|
||||
CenterFaceMnn();
|
||||
~CenterFaceMnn();
|
||||
void Decode(float* heatmap, float* scale, float* offset, float* landmarks, int h, int w, std::vector<FaceInfo>& faces, float scoreThresh, float nmsThresh);
|
||||
void NMS(std::vector<FaceInfo>& input, std::vector<FaceInfo>& output, float nmsthreshold);
|
||||
std::vector<int> GetIds(float *heatmap, int h, int w, float thresh);
|
||||
|
||||
private:
|
||||
static CenterFaceMnn* m_hInstance;
|
||||
std::mutex m_mt;
|
||||
|
||||
std::shared_ptr<MNN::Interpreter> m_detector;
|
||||
|
||||
MNN::Tensor* input_tensor;
|
||||
MNN::Tensor* hm_tensor;
|
||||
MNN::Tensor* wh_tensor;
|
||||
MNN::Tensor* reg_tensor;
|
||||
MNN::Tensor* lm_tensor;
|
||||
|
||||
MNN::Session* m_session;
|
||||
MNN::CV::ImageProcess::Config m_img_config;
|
||||
|
||||
const std::string m_model_ver = "";
|
||||
};
|
||||
|
||||
#endif
|
||||
1
src/TypeInfo.cpp
Normal file
1
src/TypeInfo.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "TypeInfo.h"
|
||||
32
src/TypeInfo.h
Normal file
32
src/TypeInfo.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef TYPE_INFO_H
|
||||
#define TYPE_INFO_H
|
||||
|
||||
typedef enum _ret_t {
|
||||
RET_OK = 0, // 操作成功
|
||||
RET_AUTHOR, // 授权失败
|
||||
RET_IMG, // 输入图片错误
|
||||
RET_INVALID_FEATURE, // 人脸特征数据无效
|
||||
RET_INVALID_LANDMARK, // 人脸Landmark数据无效
|
||||
} ret_t;
|
||||
|
||||
// #define ERR_FACE_RECT -10 //人脸框无效
|
||||
// #define ERR_INDEX_INVALID -20 //索引无效
|
||||
|
||||
struct FaceInfo {
|
||||
float x1; //人脸框 左上x坐标
|
||||
float y1; //人脸框 左上y坐标
|
||||
float x2; //人脸框 右下x坐标
|
||||
float y2; //人脸框 右下y坐标
|
||||
float score; //人脸框 置信度
|
||||
float landmarks[10]; //人脸框 关键点坐标
|
||||
|
||||
int GetWidth() {
|
||||
return static_cast<int>(x2 - x1);
|
||||
}
|
||||
|
||||
int GetHeight() {
|
||||
return static_cast<int>(y2 - y1);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,20 +1,22 @@
|
||||
#include "TimeCount.h"
|
||||
#include <iostream>
|
||||
|
||||
USE_TIME::USE_TIME(std::string str) :
|
||||
strTmp(str)
|
||||
{
|
||||
start = std::chrono::system_clock::now();
|
||||
USE_TIME::USE_TIME(USE_TIME_UNIT unit, std::string str) :
|
||||
strTmp(str),
|
||||
unit(unit){
|
||||
start = std::chrono::system_clock::now();
|
||||
}
|
||||
|
||||
USE_TIME::~USE_TIME()
|
||||
{
|
||||
USE_TIME::~USE_TIME(){
|
||||
end = std::chrono::system_clock::now();
|
||||
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
||||
std::cout << strTmp << "\t" << float(duration.count()*1.0) * std::chrono::milliseconds::period::num << "ms \t\n";
|
||||
|
||||
//auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
|
||||
//std::cout << strTmp << "\t" << float(duration.count()*1.0) * std::chrono::microseconds::period::num << "ms \t\n";
|
||||
if (unit == USE_TIME_MS) {
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
||||
std::cout << strTmp << "\t" << float(duration.count()*1.0) * std::chrono::milliseconds::period::num << "ms \t\n";
|
||||
}
|
||||
else {
|
||||
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
|
||||
std::cout << strTmp << "\t" << float(duration.count()*1.0) * std::chrono::microseconds::period::num << "us \t\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,14 +4,20 @@
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
|
||||
typedef enum {
|
||||
USE_TIME_MS = 0,
|
||||
USE_TIME_US = 1,
|
||||
}USE_TIME_UNIT;
|
||||
|
||||
class USE_TIME{
|
||||
public:
|
||||
USE_TIME(std::string str = "");
|
||||
USE_TIME(USE_TIME_UNIT unit, std::string str = "");
|
||||
~USE_TIME();
|
||||
|
||||
|
||||
private:
|
||||
std::string strTmp;
|
||||
std::chrono::system_clock::time_point start;
|
||||
std::string strTmp;
|
||||
USE_TIME_UNIT unit;
|
||||
std::chrono::system_clock::time_point start;
|
||||
std::chrono::system_clock::time_point end;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user