mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
Merge pull request #24411 from alexlyulkov:al/dnn-type-inference
Added int32, int64 support and type inference to dnn #24411 **Added a type inference to dnn similar to the shape inference, added int32 and int64 support.** - Added getTypes method for layers that calculates layer outputs types and internals types from inputs types (Similar to getMemoryShapes). By default outputs and internals types = input[0] type - Added type inference pipeline similar to shape inference pipeline. LayersShapes struct (that is used in shape inference pipeline) now contains both shapes and types - All layers output blobs are now allocated using the calculated types from the type inference. - Inputs and constants with int32 and int64 types are not automatically converted into float32 now. - Added int32 and int64 support for all the layers with indexing and for all the layers required in tests. Added int32 and int64 support for CUDA: - Added host<->device data moving for int32 and int64 - Added int32 and int64 support for several layers (just slightly modified CUDA C++ templates) Passed all the accuracy tests on CPU, OCL, OCL_FP16, CUDA, CUDA_FP16. (except RAFT model) **CURRENT PROBLEMS**: - ONNX parser always converts int64 constants and layers attributes to int32, so some models with int64 constants doesn't work (e.g. RAFT). The solution is to disable int64->int32 conversion and fix attributes reading in a lot of ONNX layers parsers (https://github.com/opencv/opencv/issues/25102) - I didn't add type inference and int support to VULCAN, so it doesn't work at all now. - Some layers don't support int yet, so some unknown models may not work. **CURRENT WORKAROUNDS**: - CPU arg_layer indides are implemented in int32 followed by a int32->int64 conversion (the master branch has the same workaround with int32->float conversion) - CPU and OCL pooling_layer indices are implemented in float followed by a float->int64 conversion - CPU gather_layer indices are implemented in int32, so int64 indices are converted to int32 (the master branch has the same workaround with float->int32 conversion) **DISABLED TESTS**: - RAFT model **REMOVED TESTS**: - Greater_input_dtype_int64 (because it doesn't fit ONNX rules, the whole test is just comparing float tensor with int constant) **TODO IN NEXT PULL REQUESTS**: - Add int64 support for ONNX parser - Add int support for more layers - Add int support for OCL (currently int layers just run on CPU) - Add int tests - Add int support for other backends
This commit is contained in:
@@ -62,6 +62,7 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
//! @{
|
||||
|
||||
typedef std::vector<int> MatShape;
|
||||
typedef int MatType;
|
||||
|
||||
/**
|
||||
* @brief Enum of computation backends supported by layers.
|
||||
@@ -205,8 +206,16 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
*/
|
||||
virtual void setHostDirty() = 0;
|
||||
|
||||
int getHostMatDepth() {
|
||||
CV_Assert(hostMatDepth != -1);
|
||||
return hostMatDepth;
|
||||
}
|
||||
|
||||
int backendId; //!< Backend identifier.
|
||||
int targetId; //!< Target identifier.
|
||||
|
||||
protected:
|
||||
int hostMatDepth = -1;
|
||||
};
|
||||
|
||||
class CV_EXPORTS ActivationLayer;
|
||||
@@ -397,6 +406,12 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
std::vector<MatShape> &outputs,
|
||||
std::vector<MatShape> &internals) const;
|
||||
|
||||
virtual void getTypes(const std::vector<MatType>& inputs,
|
||||
const int requiredOutputs,
|
||||
const int requiredInternals,
|
||||
std::vector<MatType>&outputs,
|
||||
std::vector<MatType>&internals) const;
|
||||
|
||||
virtual int64 getFLOPS(const std::vector<MatShape> &inputs,
|
||||
const std::vector<MatShape> &outputs) const {CV_UNUSED(inputs); CV_UNUSED(outputs); return 0;}
|
||||
|
||||
@@ -675,6 +690,7 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
/** @brief Returns input and output shapes for all layers in loaded model;
|
||||
* preliminary inferencing isn't necessary.
|
||||
* @param netInputShapes shapes for all input blobs in net input layer.
|
||||
* @param netInputTypes types for all input blobs in net input layer.
|
||||
* @param layersIds output parameter for layer IDs.
|
||||
* @param inLayersShapes output parameter for input layers shapes;
|
||||
* order is the same as in layersIds
|
||||
@@ -682,12 +698,14 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
* order is the same as in layersIds
|
||||
*/
|
||||
CV_WRAP void getLayersShapes(const std::vector<MatShape>& netInputShapes,
|
||||
const std::vector<int>& netInputTypes,
|
||||
CV_OUT std::vector<int>& layersIds,
|
||||
CV_OUT std::vector<std::vector<MatShape> >& inLayersShapes,
|
||||
CV_OUT std::vector<std::vector<MatShape> >& outLayersShapes) const;
|
||||
|
||||
/** @overload */
|
||||
CV_WRAP void getLayersShapes(const MatShape& netInputShape,
|
||||
const int& netInputType,
|
||||
CV_OUT std::vector<int>& layersIds,
|
||||
CV_OUT std::vector<std::vector<MatShape> >& inLayersShapes,
|
||||
CV_OUT std::vector<std::vector<MatShape> >& outLayersShapes) const;
|
||||
@@ -695,6 +713,7 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
/** @brief Returns input and output shapes for layer with specified
|
||||
* id in loaded model; preliminary inferencing isn't necessary.
|
||||
* @param netInputShape shape input blob in net input layer.
|
||||
* @param netInputType input type in net input layer.
|
||||
* @param layerId id for layer.
|
||||
* @param inLayerShapes output parameter for input layers shapes;
|
||||
* order is the same as in layersIds
|
||||
@@ -702,29 +721,36 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
* order is the same as in layersIds
|
||||
*/
|
||||
void getLayerShapes(const MatShape& netInputShape,
|
||||
const int& netInputType,
|
||||
const int layerId,
|
||||
CV_OUT std::vector<MatShape>& inLayerShapes,
|
||||
CV_OUT std::vector<MatShape>& outLayerShapes) const; // FIXIT: CV_WRAP
|
||||
|
||||
/** @overload */
|
||||
void getLayerShapes(const std::vector<MatShape>& netInputShapes,
|
||||
const std::vector<int>& netInputTypes,
|
||||
const int layerId,
|
||||
CV_OUT std::vector<MatShape>& inLayerShapes,
|
||||
CV_OUT std::vector<MatShape>& outLayerShapes) const; // FIXIT: CV_WRAP
|
||||
|
||||
/** @brief Computes FLOP for whole loaded model with specified input shapes.
|
||||
* @param netInputShapes vector of shapes for all net inputs.
|
||||
* @param netInputTypes vector of types for all net inputs.
|
||||
* @returns computed FLOP.
|
||||
*/
|
||||
CV_WRAP int64 getFLOPS(const std::vector<MatShape>& netInputShapes) const;
|
||||
CV_WRAP int64 getFLOPS(const std::vector<MatShape>& netInputShapes,
|
||||
const std::vector<int>& netInputTypes) const;
|
||||
/** @overload */
|
||||
CV_WRAP int64 getFLOPS(const MatShape& netInputShape) const;
|
||||
CV_WRAP int64 getFLOPS(const MatShape& netInputShape,
|
||||
const int& netInputType) const;
|
||||
/** @overload */
|
||||
CV_WRAP int64 getFLOPS(const int layerId,
|
||||
const std::vector<MatShape>& netInputShapes) const;
|
||||
const std::vector<MatShape>& netInputShapes,
|
||||
const std::vector<int>& netInputTypes) const;
|
||||
/** @overload */
|
||||
CV_WRAP int64 getFLOPS(const int layerId,
|
||||
const MatShape& netInputShape) const;
|
||||
const MatShape& netInputShape,
|
||||
const int& netInputType) const;
|
||||
|
||||
/** @brief Returns list of types for layer used in model.
|
||||
* @param layersTypes output parameter for returning types.
|
||||
@@ -740,36 +766,44 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
/** @brief Computes bytes number which are required to store
|
||||
* all weights and intermediate blobs for model.
|
||||
* @param netInputShapes vector of shapes for all net inputs.
|
||||
* @param netInputTypes vector of types for all net inputs.
|
||||
* @param weights output parameter to store resulting bytes for weights.
|
||||
* @param blobs output parameter to store resulting bytes for intermediate blobs.
|
||||
*/
|
||||
void getMemoryConsumption(const std::vector<MatShape>& netInputShapes,
|
||||
const std::vector<int>& netInputTypes,
|
||||
CV_OUT size_t& weights, CV_OUT size_t& blobs) const; // FIXIT: CV_WRAP
|
||||
/** @overload */
|
||||
CV_WRAP void getMemoryConsumption(const MatShape& netInputShape,
|
||||
const int& netInputType,
|
||||
CV_OUT size_t& weights, CV_OUT size_t& blobs) const;
|
||||
/** @overload */
|
||||
CV_WRAP void getMemoryConsumption(const int layerId,
|
||||
const std::vector<MatShape>& netInputShapes,
|
||||
const std::vector<int>& netInputTypes,
|
||||
CV_OUT size_t& weights, CV_OUT size_t& blobs) const;
|
||||
/** @overload */
|
||||
CV_WRAP void getMemoryConsumption(const int layerId,
|
||||
const MatShape& netInputShape,
|
||||
const int& netInputType,
|
||||
CV_OUT size_t& weights, CV_OUT size_t& blobs) const;
|
||||
|
||||
/** @brief Computes bytes number which are required to store
|
||||
* all weights and intermediate blobs for each layer.
|
||||
* @param netInputShapes vector of shapes for all net inputs.
|
||||
* @param netInputTypes vector of types for all net inputs.
|
||||
* @param layerIds output vector to save layer IDs.
|
||||
* @param weights output parameter to store resulting bytes for weights.
|
||||
* @param blobs output parameter to store resulting bytes for intermediate blobs.
|
||||
*/
|
||||
void getMemoryConsumption(const std::vector<MatShape>& netInputShapes,
|
||||
const std::vector<int>& netInputTypes,
|
||||
CV_OUT std::vector<int>& layerIds,
|
||||
CV_OUT std::vector<size_t>& weights,
|
||||
CV_OUT std::vector<size_t>& blobs) const; // FIXIT: CV_WRAP
|
||||
/** @overload */
|
||||
void getMemoryConsumption(const MatShape& netInputShape,
|
||||
const int& netInputType,
|
||||
CV_OUT std::vector<int>& layerIds,
|
||||
CV_OUT std::vector<size_t>& weights,
|
||||
CV_OUT std::vector<size_t>& blobs) const; // FIXIT: CV_WRAP
|
||||
|
||||
Reference in New Issue
Block a user